Skip to content

Commit c8e02cb

Browse files
CliveUngerclaude
andcommitted
Add support for DE save_version 68
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>
1 parent 9c1e9cc commit c8e02cb

2 files changed

Lines changed: 9 additions & 1 deletion

File tree

mgz/fast/header.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,8 @@ def parse_de(data, version, save, skip=False):
470470
handicap = struct.unpack_from('<I', handicap_data, 4)[0]
471471
if save >= 64.3:
472472
data.read(4)
473+
if save >= 67.5:
474+
de_string(data) # save_version 68: trailing per-player de_string
473475

474476
players.append(dict(
475477
number=number,
@@ -556,6 +558,8 @@ def parse_de(data, version, save, skip=False):
556558
data.read(8)
557559
if save >= 37:
558560
timestamp, x = unpack('<II', data)
561+
if save >= 67.5:
562+
data.read(8) # save_version 68: 8 trailing bytes before ai section
559563
rms_mod_id = None
560564
rms_filename = None
561565
for s in strings:

mgz/header/de.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
"custom_ai"/Flag,
4646
If(lambda ctx: find_save_version(ctx) >= 25.06, "handicap"/Bytes(8)),
4747
If(lambda ctx: find_save_version(ctx) >= 64.3, "unknown_de_64_3" / Int32ul),
48+
# save_version 68 (mid-2026 DE patch) added a trailing per-player de_string
49+
"unknown_de_68"/If(lambda ctx: find_save_version(ctx) >= 67.5, de_string),
4850
)
4951

5052
string_block = Struct(
@@ -178,5 +180,7 @@
178180
"ver37"/If(lambda ctx: find_save_version(ctx) >= 37, Struct(
179181
Int32ul,
180182
Int32ul
181-
))
183+
)),
184+
# save_version 68 (mid-2026 DE patch) added 8 trailing bytes before the ai section
185+
If(lambda ctx: find_save_version(ctx) >= 67.5, Bytes(8)),
182186
)

0 commit comments

Comments
 (0)