Skip to content

Add support for The Last Chieftains in the fast parser - #139

Open
Kjir wants to merge 1 commit into
happyleavesaoc:masterfrom
Kjir:master
Open

Kjir wants to merge 1 commit into
happyleavesaoc:masterfrom
Kjir:master

Conversation

@Kjir

@Kjir Kjir commented Feb 21, 2026

Copy link
Copy Markdown
Contributor

Make the necessary changes to support savegames from the Last Chieftains DLC. The full parser changes are not sufficient to make it work yet, more investigation is needed.

Comment thread mgz/header/de.py
"unknown_count"/If(lambda ctx: find_save_version(ctx) >= 66.3, Int32ul),
If(lambda ctx: find_save_version(ctx) >= 66.3, Bytes(12)),
If(lambda ctx: find_save_version(ctx) >= 66.3, Array(lambda ctx: ctx.unknown_count, Bytes(4))),
de_string,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's 2 more de strings in 67.2 saves before this DE String.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before or after? I put them after, I don't think it's possible to know which one comes first unless we know what they contain.

Comment thread mgz/header/de.py Outdated
Comment on lines +179 to +182
If(lambda ctx: find_save_version(ctx) >= 67.2, Struct(
Int32ul,
Int32ul,
)),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct.

Comment thread mgz/header/de.py
Int32ul,
)),
"ver37"/If(lambda ctx: find_save_version(ctx) >= 37, Struct(
Int32ul,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a timestamp. Value seems to be always the same as at the one declared above in the struct.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is a timestamp, I didn't change it here. I have it as a timestamp in my own Rust parser.

Make the necessary changes to support savegames from the Last Chieftains
DLC. The full parser changes are not sufficient to make it work yet,
more investigation is needed.
fahr23 added a commit to fahr23/aoc-mgz that referenced this pull request Feb 28, 2026
CliveUnger added a commit to CliveUnger/aoc-mgz that referenced this pull request Jul 26, 2026
The mid-2026 Definitive Edition patch (build 101.103.48987 / 48086,
VER 9.4, save_version 68.0) changed the recorded-game header in two ways
relative to save_version 66.3/67:

1. Each player entry gained one trailing de_string field (observed empty).
2. The DE header block gained 8 trailing bytes just before the ai section.

Without these, the player array desyncs (ConstError on the next
de_string marker) and, once past that, has_ai is misread so the ai
skip-to-zero-run never fires and map_info lands in the string table.

Reverse-engineered from macOS (Feral) replays; verified against 5 games
across both build 48086 and 48987 via mgz.model.parse_match (header +
body + actions). Patches both the construct parser (header/de.py) and the
fast parser (fast/header.py, used by ModelSummary/parse_match), gated on
save_version >= 67.5 so 66.3/67 paths are untouched. Extends the
save-67 work in PRs happyleavesaoc#139/happyleavesaoc#142.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants