.SAV Partially documented

The Caesar savegame format

A Caesar save is a straight dump of the game's data segment, in the writer's order: 128 global words, the actor table, the city's five 100 × 100 layers and the rest. Nothing is compressed or indexed. The blocks' positions and sizes are certain, because the loader reads exactly what the writer writes; what is still partial is the meaning of some words and of the middle of an actor record.

Used by Caesar

Layout

A save is 57,126 bytes (0xDF26), always. The game's writer makes 175 write calls, one per record, from the data segment straight to the file; its loader reads the same 175 records, at the same addresses and sizes, in the same order. So reading and writing are the same list, and Gaius's writer produces a file that is byte-identical to every one of seventeen real saves it was given.

Saves are named CAESARxx.SAV, with xx chosen by the player. Everything is little-endian.

The twenty blocks, in file order

Offsets and sizes in bytes. The block boundaries are confirmed by the loader, and by the footprint of every building in real saves coming out as an exact rectangle.

OffsetSizeTypeFieldDescription
0x0000256u16[128]global wordsThe game's state words. They are not a contiguous run of addresses: the writer takes them in its own order (with 15 discontinuities, skipping one address and writing another twice). The funds are the word at 0x3E.
0x01003500record[70]actorsThe walker and army table: 70 records of 50 bytes. See the record below.
0x0EAC480record[30]Forums16 bytes each: +0 column, +2 row, +4 grade (0 to 7), +6 timer, +8 active, +A a facing counter. The count of forums is capped at 30.
0x108C120record[10]Barracks12 bytes each: +0 column, +2 row, +4 timer, +6 active, +8 facing.
0x1104720record[30]Workshops24 bytes each: +0 column, +2 row, +4 goods type (0 to 7), +6 timer, +8 active, +A facing, +C population nearby, +E sales, +0x10 production level, +0x12 last level, +0x14 industry.
0x13D410000u8[100][100]tilesThe city map: one tile id per cell, row by row (index = row × 100 + column). Ids below 0xC8 are terrain, roads, walls and water; 0xC8 to 0xD7 are the sixteen house grades.
0x3AE410000u8[100][100]service flagsBit flags per cell: water (0x01), forum road access (0x02, a strong inference), bath houses (0x04), market (0x08), administration (0x20), school or hospital (0x40), entertainment (0x80). Rebuilt from the tiles at the end of every month.
0x61F410000i8[100][100]land valueThe Maps panel's "land value" layer, a signed byte per cell, built each month by every service building's reach.
0x890410000u8[100][100]part index and stateLow nibble: the cell's position inside its building, 4 × row offset + column offset, with 0 the anchor. Held by every cell of every multi-cell building in every save. Other bits are state flags, only partly understood.
0xB01410000i8[100][100]unrestThe Maps panel's "trouble areas" layer, drawn on houses: a signed byte per cell, raised by what makes citizens unhappy and lowered by temples, prefectures, barracks and oracles. A low-grade house collapses when its cell exceeds a limit.
0xD7241602EMPIRE2province mapThe current province's map file, with game state written into it. See EMPIRE2.
0xDD6650u8[50]provinces givenOne flag per province already assigned to this governor.
0xDD988u8[8]workshops per goodsHow many workshops of each of the eight goods are built.
0xDDA010u8[10]population milestonesFlags for 200, 1000, 2000, 4000, 8000, 12000, 16000 and 20000 people having been reached. The last two bytes are unused.
0xDDAA60 × 4pair[15] × 4yearly historiesFour tables of 15 (year, value) word pairs: population tax, industrial tax, funds, and population units.
0xDE9A72pair[18]profit historyThe yearly profit or loss; 17 of the 18 records are used.
0xDEE268u16[34]final stateThirty-four more words (twelve of those bytes are the governor's name, padded with spaces to 12 characters; " Octavian " in every save), including the difficulty, the industrial tax rate, the monthly scan counters and last year's Treasurer's report.

An actor record, 50 bytes

The other bytes belong to movement, targets and timers. They are laid out in Gaius's source (systems/actors.hpp) but not tabulated here.

OffsetSizeTypeFieldDescription
+0x002u16frameThe sprite frame drawn: from MOREMEN.PL8 in the city view, SPRITE2.PL8 in the province view.
+0x022u16xWorld x in pixels. The sprite's bottom edge is drawn at y + 8.
+0x042u16yWorld y in pixels.
+0x061u8activeNon-zero for a live record. The exact bit packing is not established.
+0x071u8typeThe actor class, indexing a table of fourteen handlers: 0 to 10 are city walkers (forum citizens, workshop traders, barracks patrols, rioters, invaders), 11 a barbarian army, 12 an army arriving by sea, 13 a Cohort.
+0x082u16indexThe record's own slot number; it matches the slot in every active record in the saves.
+0x122u8, u8destination or cellFor a province actor, its current cell (column, row). For a city actor, where it is heading, not where it is.
+0x182u16positionFor a city actor, row × 100 + column: the reliable position. For a province actor, row × 40 + column.
+0x311u8stateThe behaviour: an index into a second table of sixteen handlers.

Words worth knowing

A few of the 162 words. Every one the writer saves has been identified by what reads and writes it; two (at data-segment addresses 0x6BDC and 0x6CBC) are never used.

funds
The treasury, in denarii, at the global word at file offset 0x3E. Across a real session it falls 7182, 4692, 3210, 3144, which is how the word was pinned.
month, year
The month runs 0 to 11. The year is a signed counter, not a BC or AD date: a new game starts at −13, and one session's saves run from −11 up through 14.
population
Stored as units (a sum over every house cell) and as four times that. Both are saved.
rank, difficulty
The governor's rank (1 for a new game) and the difficulty. The difficulty is the word the loader skips in the global block and keeps in the final state.
ratings
Peace, Culture, Prosperity, Empire, and their average.
Legion
Regular, irregular and auxiliary Centuries, this year and last.
plebs
The pleb count, its five duty assignments and the unassigned remainder, welfare, and the needs each duty has.

Sources