Civilization II Map Structure
This file describes the way the map is encoded in Civilization II maps and savegames. This data is acquired using the Fantastic Worlds add-on (Civ2 version 2.7.8l). Savegame structures from later Civ2 versions (notably Civilization II: Test of Time) may vary significantly.
In this document I assume the reader has some basic knowledge of hexadecimal and binary numbers, as well as some familiarity with a few essential terms like signed short integer or offset. This shouldn't be much of a problem for anyone with a bit of programming or hex editing experience.
Most of the times, I have marked hexadecimals with the prefix 0x. As can be expected with a Windows-based application, data types are stored in Little Endian fashion (e.g. the short integer 10000 is 0x2710 in hexadecimals, but is stored as 0x1027).
Credits go to James Dustin Reichwein, who discovered a few important details of the 6th byte in the second map data section, Angelo Scotto,who pointed out to me that a map wasn't just represented by section 2 in savegames and scenarios, and Harlan Thompson, who directed me towards finding the no-resource bit in the terrain codes.
MercatorMap File Structure
Map Header (49 signed short integers, offset 0x00000000)
Offset | Value |
---|---|
0x00000000 |
Width x 2 (e.g. 100 for a 50 x 80 map) |
0x00000002 |
Height |
0x00000004 |
Surface (width x height) |
0x00000006 |
World shape (0 = round map, 1 or any other value = flat map) |
0x00000008 |
Resource seed. This determines the resource and goody hut patterns. There are 64 distinct patterns, 0 to 63. 64 is the same pattern again as 0, 65 is the same as 1 etc. However, if you start a game on a map with a seed of 0 or 1 (but not their equivalents 64, 65 or any other values) Civilization II will choose a random pattern instead. |
0x0000000A |
width / 2 (rounded up) |
0x0000000C |
height / 4 (rounded up) |
0x0000000E |
X coordinates of all 21 civilization starting points, in the same order as in the RULES.TXT. When a civilization has no starting point, the value will be 0xFFFF. NOTE: Both X and Y coordinates are in the Civ2 coordinate system, NOT the Map Editor coordinate system! |
0x00000038 |
Y coordinates of all 21 civilization starting points, in the same order as in the RULES.TXT. |
Map Data (6 * surface bytes, offset 0x00000062)
Byte | Value (hexadecimal) |
---|---|
1 | Terrain code |
2 | 00 |
3 | 00 |
4 | 00 |
5 | Terrain code |
6 | F0 |
Each square is encoded by the above mentioned 6 bytes. The order of the squares in the file are in regular reading order (i.e. left to right, top to bottom).
Savegame and Scenario Map Structure
The map data in Civilization II savegames and scenarios (they use the same file format) consist of four different parts: First the map header, then 7 blocks for tribe-specific tile information, general map information, and a section with unknown but probably useless information.
Map Header (7 signed short integers, offset 0x00003586)
The first seven values of the map file header. In Test of Time there is an 8th header value that signifies how many additional maps there are. E.g. in a multi-map game with 3 maps it will have a value of 2.
Map Data Section 1 (7 * surface bytes, offset 0x00003594)
This section consists of seven consecutive blocks with 1 byte per square. In order, these blocks contain the terrain improvements as known by each of the seven civilizations. Civilizations that are not part of the game will have their entire block zeroed-out.
The second byte in Section 2 uses these same codes. But in that case they represent the actual terrain improvements, rather than the visible terrain improvements:
Hexadecimal | Binary | Tile improvement |
---|---|---|
00 |
00000000 |
"Nothing", i.e. the square in question contains no (known) units or tile improvements. |
01 |
.......1 |
Unit present |
02 |
......1. |
City present |
04 |
.....1.. |
Irrigation |
08 |
....1... |
Mining |
10 |
...1.... |
Road |
20 |
..1..... |
Railroad |
40 |
.1...... |
Fortress |
80 |
1....... |
Pollution |
Farmland is irrigation plus mining (0x0C). Railroad is actually 0x30, a combination of road and a railroad "upgrade" 0x20. Without the road terrain code, you won't see the railroad graphics nor will you get the trade bonus. You only get the infinite movement. An airbase is a combination of the fortress and city present codes: 0x42. In Civilization II: Test of Time, transport sites are marked with 0x82, an otherwise never occurring combination of the pollution and "city present" codes.
All cities, including unknown cities, are marked. Undiscovered (see 5th byte in Section 2) cities are generally (not always) assumed to be ungarrisoned (i.e. code is 0x02, not 0x03). A city that has never been discovered and is already destroyed will remain on a civilization's map, until the area is "re-explored". Enemy cities or units that are lost out of sight, will remain marked on their last seen location (?), but again only as long as no news about the area is gathered.
Map Data Section 2 (6 * surface bytes)
This section contains only one map, but each square is now represented by a sequence of 6 bytes:
- The first byte determines the terrain type. The terrain codes are exactly the same as the codes used in the map file format.
- The second byte determines the tile improvements. The tile improvement codes are the same as the codes used in the first section.
This byte is an indicator for the city radii. Each civilization color has its own city radius code:
Civilization Byte code (hexadecimal) White 20
Green 40
Blue 60
Yellow 80
Cyan A0
Orange C0
Purple E0
When two cities of two different civilizations share a part of their city radius the squares in question will be given to one of those cities, not both. It's very likely there is some sort of an algorithm to determine how squares are divided, perhaps the tiles are simply assigned randomly.
Barbarian cities and squares that aren't part of a city radius will have the code 00.
The 4th byte is a land/sea body counter. This simply gives every different body of land and every body of water a separate number. Counting starts at the top-left corner and proceeds from left to right and from top to bottom. Water bodies of less than 9 squares always have number 63, but do count towards the total. Both the land and water counters start counting at one.
NOTE: To see what I mean, right-click on a square in Civilization II. In the Status Window you'll see something like this:
Loc: (12, 34) 5
- 12 is the X-coordinate of that square
- 34 is its Y-coordinate
- 5 is this "body counter".
The 5th byte of the 6 bytes represents "visibility", indicating which of the civilizations have explored that particular square:
Hexadecimal Binary Civilization 00
00000000
No-one has discovered this square. 01
.......1
Red (Barbarians) 02
......1.
White 04
.....1..
Green 08
....1...
Blue 10
...1....
Yellow 20
..1.....
Cyan 40
.1......
Orange 80
1.......
Purple The 6th byte actually encodes two things. The first 4 bits concern tile ownership. An indicator for this tile ownership is the color of an airbase. A funny effect that can be created with faulty ownership values is that a civilization attacks its own unit. Goody huts only appear on tiles without an owner (hexadecimal F). Civilization II clears all goody huts by changing the tile ownership of those squares to the barbarians. The used codes are as follows:
Hexadecimal Owner 0.
Red (Barbarians) 1.
White 2.
Green 3.
Blue 4.
Yellow 5.
Cyan 6.
Orange 7.
Purple 8. - E.
Illegal values F.
None The last 4 bits concern tile fertility. Values for fertility range from 0 to 15 (which is 0 to F in hexadecimals), 0 being completely infertile, 15 the most fertile. How the exact algorithm works is not clear to me, but I do have a few valuable clues: Civilization II only assigns fertility values to the Grassland and Plains terrain, all other terrain types initially have a fertility value of 0. This explains why the AI only builds cities on these terrain types. Fertility values of terrain other than Grassland or Plains can, however, increase because of tile improvements. The AI will not build cities on terrapins with a fertility value below 7. Actual values are influenced by production, food and trade as defined in the RULES.TXT as well as tile improvements, such as roads and irrigation. Fertility values within a city radius are decreased by a certain number, effectively preventing the AI from building cities within any existing city radius.
Fertility seems to be much more complicated than just a square by square calculation, though. Data from one game showed that fertility values ranged from 0 to 7 at the first turn of the game. The next turn, when 4 capital cities had been built, all non-zero fertility values had increased by 2, while the city radius squares now had a value of 2. At the end of another game on the same map, city radius squares had values of 6, while other fertile squares now had values ranging from 9 to 15. I am inclined to say that fertility values also depend on the total amount of fertile squares that are still available.
Map Data Section 3 (2 * Qwidth * Qheight bytes)
The size of this section equals twice the multiplication of the 6th and 7th values in the map header. With the Qwidth and Qheight names I refer to those values in the map header.
This section consists of two parts of equal size. The pattern in these two parts roughly equals the map shape, only making a distinction between land and ocean. Because both width and height of these parts are only a fraction of the map's measurements there is no one-to-one relationship between the bits or bytes in this section and the squares on the map. As of yet, I have no idea what the purpose of this section is. It never changes during a game and changing it doesn't seem to influence a game whatsoever.
After Section 3...
The third map data section is followed by 1024 bytes (10240 bytes for Test of Time). I have no idea what they represent, but they don't seem to have anything to do with the map. After these mysterious bytes follows the unit information section.
Terrain Codes
Hexadecimal | Binary | Terrain |
---|---|---|
00 |
....0000 |
Desert |
01 |
....0001 |
Plains |
02 |
....0010 |
Grassland |
03 |
....0011 |
Forest |
04 |
....0100 |
Hills |
05 |
....0101 |
Mountains |
06 |
....0110 |
Tundra |
07 |
....0111 |
Glacier |
08 |
....1000 |
Swamp |
09 |
....1001 |
Jungle |
0A |
....1010 |
Ocean |
10 |
...1.... |
No known effect |
20 |
..1..... |
Resource animation playing (Test of Time only, this only affects squares with resources and only when terrain animation is switched on) |
40 |
.1...... |
Hide resource |
80 |
1....... |
River |
Last updated: 19 July 2004