Devlog

Reading the save file straight out of the loop that writes it

Two Caesar II format pages, .SAV and .ENG/.HELP, sourced entirely from the decompilation's own save/load code and the port's text pipeline - closing the gap the last entry left open the same day it was opened.

A savegame's format is usually reconstructed by staring at hex dumps and guessing where one field ends and the next begins. Caesar II didn't need that: the reconstruction's src/loadsave.c contains savegame()'s actual write loop, and it is a 500-slot table of {pointer, size} pairs written out in order and terminated by the first zero-size entry. Counting the 432 real entries and summing their sizes gives 221,745 bytes, exactly matching the figure the port's own save-testing.md states independently - two unrelated ways of arriving at the same number is about as confident as this site ever gets. A sibling history.dat file, always exactly 4,000 bytes, is appended after with one read() and one write(), untouched by the entry table. Total: 225,745 bytes, every time.

The three memory-mapped tile grids inside that table - city, region and battle maps - cross-checked cleanly against a second, independent source: entities.h's own CITY_W/CITY_H/CITY_CELL_BYTES-style macros multiply out to the exact same byte counts the save table declares. Two people (or rather, two files in the same repository, describing the same engine from different angles) agreeing on 128,000 and 28,800 and 10,816 bytes is the kind of corroboration this site's Caesar III pages have never had the luxury of.

The text format is a different kind of interesting. C2.ENG and HELP.ENG aren't addressed by byte offset at all but by (group, index) and (page, slot) pairs the game's own code compiles into - and the port's from-scratch reimplementation reproduces both files byte-for-byte in every language it was tested against, which is what makes the addressing model citable as fact rather than inference.

It also surfaced two genuine shipped bugs, both now on the format page rather than smoothed over: the English HELP.ENG's four 0x92 apostrophes render as a Danish Æ because the game's font table was never Windows-1252 to begin with, and the 1995 French C2.ENG has NUL bytes splitting strings that shifted four whole groups onto the wrong text - a defect faithfully reproduced by the byte-exact reimplementation and separately corrected in its own translation template, with the correction's reason recorded rather than silently applied.