View Full Version : A lua script for cropping maps


Dragon2
Dec 15, 2010, 05:43 AM
Here is a simple Lua script to extract a subset of a map. All it does is to set the new width and height and copy the data from the appropriate hexes. Everything else can be done in World Builder.

To use the script:
1. Save the input map from a game of Civ 5, e.g. vanilla Earth, Huge size.
2. Using World Builder, figure out how many rows you want to trim off the bottom and top, and how many columns from the left and the right.
3. Specify the trim values and map names at the top of the script. Be sure the path for your Maps folder relative to your Lua folder is correct. The default version extracts an Indian Ocean map from a saved Huge Earth map.
4. Run the script, which takes a fraction of a second.
5. Load your newly created map into World Builder. Remove World Wrap. Specify an appropriate name and description. You will probably want to clear the resources that were saved and specify random resources and goody huts. Save the map file.
6. At this point the map will be available as a choice when you enter the game setup via Mods. You can use it as the basis for a TSL scenario. After the latest patch, you may need to save it from within the game to get the correct map size.

Here is the complete script. Perhaps someone with more Lua experience can package it up with a nice UI. C programmers should remember that Lua strings are indexed starting from 1, not from 0.

-- The following path assumes that your Lua folder is a subfolder of Documents
-- Start a game of Civ5 on the Huge map of Earth
-- and save the map under the name Huge_Earth
local mapPath = "..//My Games//Sid Meier's Civilization 5//Maps//"
local inputMap = "Huge_Earth"
local outputMap = "Indian_Ocean"
local trimbottom = 6
local trimtop = 29
local trimleft = 67
local trimright = 5
-- open and read a map that was saved by the Save Map command (no mods active)
f = assert(io.open(mapPath..inputMap..".Civ5Map", "rb"))
local data = f:read("*all") -- the file is now a single string
-- Find where the hex data starts (works with map saved from game or WorldBuilder)
-- The next line is correct for patch 135 -- save old maps in a the current version of the game
hexStart = data:find("%z%z",0x2a)+70 -- seek from start of TERRAIN strings
local fout = assert(io.open(mapPath..outputMap..".Civ5Map","wb"))
local s = data:sub(1,1) -- read the first byte
fout:write(s) -- write the first byte
-- read and adjust the map width
s = data:sub(2,5)
local width = s:byte(1) -- cannot exceed 255
s = string.char(s:byte(1)-trimleft-trimright,0,0,0)
fout:write(s)
-- read and adjust the map height
s = data:sub(6,9)
local height = s:byte(1)
s = string.char(s:byte(1)-trimtop-trimbottom,0,0,0)
fout:write(s)
-- copy the rest of the header
s = data:sub(10, hexStart-1)
fout:write(s)
-- read the data for the desired map rows,
-- and write the substring for the desired columns
for i = trimbottom, height - trimtop - 1 , 1 do
s = data:sub(hexStart+i * 8 * width, hexStart+(i + 1)* 8 * width - 1)
s = s:sub(8* trimleft+1, 8 * (width-trimright))
fout:write(s)
end
fout:close()
-- Open and save the new map in World Builder to adjust resources and world wrap
-- and give it a correct name and description.

xtraspatial
Jan 15, 2011, 10:18 AM
Excellent script Dragon2. Thanks for sharing.

Did you have to reverse engineer the *.civ5map file format or do you have some sort of documentation you could share on the format? I'd like to be able to build Civ5Map files outside of World Builder.

Best,
XS

smellymummy
Mar 17, 2011, 10:04 PM
Excellent script Dragon2. Thanks for sharing.

Did you have to reverse engineer the *.civ5map file format or do you have some sort of documentation you could share on the format? I'd like to be able to build Civ5Map files outside of World Builder.

Best,
XS

curious about the same things ^^