Files
Cesarus85--mjolnir-vr/docs/object_matching_logs/game_engine_obj.md
T

54 KiB

game_engine.obj exact-match ledger

Scope and provenance

  • Translation unit: source/game/game_engine.c
  • Target object: build/split/source/game/game_engine.obj
  • Candidate object: build/base/source/game/game_engine.obj
  • Target executable: PAL debug cachebeta.exe, SHA-256 4cc87b45f721270392a96f1674ed2b5cd4a7bb4355faeab4531d1cf1884d9520
  • Target object SHA-256: 2c74631e4a056a3d8a94c30d6b4d79ba17971cf4b1fc5d97690fb6be1d0e654b
  • Compiler: XDK 3911 Microsoft 32-bit C/C++ 13.00.9254.1 for 80x86.
  • Repository flags: /O2 /Oy- /DDEBUG /Dxbox and the checked-in include paths. No lane-specific flag changes are permitted.
  • Canonical source baseline: e54ead79c643862cab1bbcb5330fcb2084eadb84.
  • Frozen canonical candidate SHA-256: 3a184a158241bc52c54685ac0f9d5a969661ad1009cc2b519edbabf83343482d.
  • Strict acceptance oracle: tools/coff_compare.py, section_infos_equal, including padded bytes and semantic relocation identities. Every retained batch also checks the complete canonical exact set for regressions.

Validated baseline and current state

Canonical rebuilt baseline:

  • Functions: 125/180 strict exact.
  • Padded code: 13,904/33,760 target bytes.
  • Fifty-three target functions were not emitted by the candidate.
  • Two emitted residuals had target-equal size and relocation count, but failed because the candidate did not own _game_engine and _global_variant.

After retained batch GE01:

  • Functions: 130/180 strict exact.
  • Padded code: 14,304/33,760 target bytes.
  • Candidate SHA-256: bae168dc91f6ce452f4ce9d68ac34b27dcaf5e601beca56c99321b88c5568e63.
  • Canonical regressions: none.

After retained batch GE02:

  • Functions: 133/180 strict exact.
  • Padded code: 14,896/33,760 target bytes.
  • Candidate SHA-256: f19b78c05a4b9986cefed66ca1397de4de9dff629365e206ca86c8ad3e831b0e.
  • Canonical regressions: none.

After retained batch GE03:

  • Functions: 137/180 strict exact.
  • Padded code: 16,496/33,760 target bytes.
  • Candidate SHA-256: 73519e75b279ec453784dc0ea880561a7e461f15b4bd4804e0b41882e861689d.
  • Canonical regressions: none.

After retained batch GE04:

  • Functions: 139/180 strict exact.
  • Padded code: 16,816/33,760 target bytes.
  • Candidate SHA-256: 2b08ed82d77ac468e4530bbfb4ce76726111d94b370f4a3a24dcfbc1b3b5c369.
  • Canonical regressions: none.

After retained batch GE05:

  • Functions: 144/180 strict exact.
  • Padded code: 17,904/33,760 target bytes.
  • Candidate SHA-256: fcfda7a08e0928432e8e9c747774ae3cefa461f164a28d06e5d8fcaf834349d6.
  • Canonical regressions: none.

After retained batch GE06:

  • Functions: 144/180 strict exact.
  • Padded code: 17,904/33,760 target bytes.
  • Candidate SHA-256: 1b8182d561b2909de59a43cbcdb081ffa96830b8c0359e96c574f707a39ad4e8.
  • .bss: strict exact, 1,148/1,148 bytes, zero relocations, target-equal normalized hash.
  • Canonical regressions: none.

After retained batch GE07:

  • Functions: 152/180 strict exact.
  • Padded code: 21,136/33,760 target bytes.
  • Candidate SHA-256: 293feb40ebe414da8932b76f17f87d79ad17be4a0b54fc55c6deff0c7ab3392f.
  • .bss: remains strict exact.
  • Canonical regressions: none.

After retained batch GE08:

  • Functions: 156/180 strict exact.
  • Padded code: 22,256/33,760 target bytes.
  • Candidate SHA-256: a9aa7ce0a0b067003b2b63b78f1559d038307a1124d0b4fe6135b45e5e2f9342.
  • .bss: remains strict exact.
  • Canonical regressions: none.

After retained batch GE09:

  • Functions: 156/180 strict exact.
  • Padded code: 22,256/33,760 target bytes.
  • Candidate SHA-256: ddda326a95808c5a544ebc92886c6ef8526fc1e68f3289c50829984d4df9e1cf.
  • .data: strict exact, 32/32 bytes, zero relocations, target-equal normalized hash.
  • .bss: remains strict exact.
  • Canonical regressions: none.

After retained batch GE10:

  • Functions: 158/180 strict exact.
  • Padded code: 22,512/33,760 target bytes.
  • Candidate SHA-256: b1c099e6b4152671d352e1d9560e904eb344b2a263422593d4a45f5b36eae9fa.
  • Newly exact: _code_00097020 and _code_00096b50.
  • .data: remains strict exact at 32/32 bytes with zero relocations.
  • .bss: remains strict exact at 1,148/1,148 bytes with zero relocations.
  • Canonical regressions: none.
  • _code_0009d140 is now a policy-clean emitted structural checkpoint at 1088/1152 bytes and 70/73 relocations; it receives no exact credit.

After retained batch GE11:

  • Functions: 159/180 strict exact.
  • Padded code: 22,640/33,760 target bytes.
  • Candidate SHA-256: 4b669ac72186e8cbbb4b45663254cb5734d23cdf3dccd89df14b3a06e70d7f39.
  • Newly exact: _code_0009cb60.
  • _populate_statistic_buffer remains strict exact at 560/560 bytes and 27/27 semantic relocations.
  • .data: remains strict exact at 32/32 bytes with zero relocations.
  • .bss: remains strict exact at 1,148/1,148 bytes with zero relocations.
  • Canonical regressions: none.
  • Five policy-clean postgame functions are now emitted as structural checkpoints. They receive no exact credit.

After retained batch GE12:

  • Functions: 159/180 strict exact.
  • Padded code: 22,640/33,760 target bytes.
  • Candidate emission: 180/180 target functions; no candidate symbol is absent.
  • Candidate SHA-256: 421a662a208d69aabf33cebbab2e7067540e093b0b37d93434e514fe78a11ae0.
  • Six ordinary-C target-backed bodies are restored as nonexact structural checkpoints: _code_0009a490, _code_0009b3a0, _code_0009b4f0, _code_0009bdf0, _game_engine_update, and _game_engine_player_killed.
  • .data: remains strict exact at 32/32 bytes with zero relocations.
  • .bss: remains strict exact at 1,148/1,148 bytes with zero relocations.
  • Canonical regressions: none.
  • This is an emission-completeness checkpoint only. It receives no new function credit and the object remains active with 21 strict residuals.

The residual table is measured after GE12. Hashes are normalized SHA-256 prefixes; - means the candidate symbol is absent.

Function Size T/C Relocs T/C Normalized hash T/C First meaningful divergence
_code_00096ba0 112/112 7/7 4ac1ff18279a/9db784535924 Policy-clean body emitted; register scheduling differs
_game_engine_should_spawn_player 256/256 9/9 8259180402f7/c0782ea3a816 Control-flow register allocation differs
_game_engine_get_place 368/368 12/12 91161c382c55/bcf2be6ca02e Placement loop register allocation differs
_code_000994f0 416/416 18/18 211627377053/10c5400d228a Policy-clean body emitted; register scheduling differs
_code_0009a490 496/480 16/16 f30da54283e6/01537066ba3b Complete ordinary-C body emitted; local scheduling is short by 16 bytes
_code_0009a680 448/448 18/18 4c90ec184c40/41e698125368 Policy-clean body emitted; compiler shape differs
_code_0009b3a0 336/336 11/11 7e6f5319e160/dbb1e45ecac4 Complete ordinary-C body emitted; register scheduling differs
_code_0009b4f0 112/96 5/5 048cb68bcbf1/3285bf46e3e7 Complete ordinary-C body emitted; target is 16 bytes longer
_code_0009b6e0 144/144 5/5 675e96da950f/bb509add4c20 One independent terminator store is scheduled before, rather than between, the two HUD call argument pushes
_game_engine_postspawn_player_update 336/336 15/15 4bf0dbc3a0ce/643ef05eed91 Grenade setup local scheduling differs
_code_0009bdf0 992/1008 46/46 2874ef26f3de/dd76f756771b Complete ordinary-C body emitted; policy-clean scratch clearing is 16 bytes longer
_code_0009c460 176/176 10/10 cb6f30979095/a7e62792e4b5 Register allocation differs despite target-equal relocation identities
_game_engine_get_starting_location_rating 96/96 6/6 9b229c3bccdf/601000c33610 Register allocation differs despite target-equal relocation identities
_game_engine_remap_equipment 304/304 15/15 b315e0bf2bb5/5fd2bf5a01d1 Policy-clean body emitted; compiler shape differs
_game_engine_get_state_message 320/320 10/10 20ff545777ef/63ba933b746c Respawn-state local scheduling differs
_code_0009cc20 96/112 4/4 43a24b160b72/35ac6d2c5836 Loop-invariant game type occupies the target's counter register
_code_0009d140 1152/1088 73/70 e261315dfb4e/1a8d99b44cb1 Policy-clean title topology is short by 64 bytes and three relocations
_game_engine_post_rasterize_post_game 2528/2528 148/148 5d9500c231fe/a8bfb78acd0f Policy-clean body emitted; compiler shape differs
_game_engine_update 752/752 67/67 a83ee62930df/1ae46e8434e6 Complete ordinary-C body emitted; compiler scheduling differs
_game_engine_player_killed 832/832 39/39 4d4a8b42b57d/d8d21f2ca76f Complete ordinary-C body emitted; compiler scheduling differs
_code_0009e670 848/848 41/41 28483cea9891/7bacec539a12 Policy-clean body emitted; compiler shape differs

Accepted controls

  • GE01 retains five ordinary C functions recovered from the legal source state at 527fc167705b11887e0aee123bdc9cb91d1ffb15: _code_00096890, _code_00096b30, _code_00096b40, _code_00096c10, and _code_00096d00.
  • Exact callers were expressed through those recovered helpers: game_engine_did_player_win_default, get_postgame_hilite_colors, and _code_00096d30. The whole-TU sweep proves they remain exact.
  • These are source/topology recoveries supported by target symbols and strict object equality. They are not byte-forcing controls.
  • GE02 retains the typed game_engine callback at offset 0x38, its ordinary C objective-weapon scan helpers _code_00096e30 and _code_00096ed0, and the recovered goal-position getter. The callback type changes no structure size or offset; the target symbols and strict function comparisons support the recovered topology.
  • GE03 retains the legal C vehicle/weapon prediction and remap flow plus the local HUD fade/target-name helpers. _code_0009a840 currently calls the still-active _code_0009a680 through an ordinary declaration; no match credit is given to that missing dependency.
  • GE04 retains the recovered ranking comparator and the measured first-eligible-player team scan. Both are strict exact ordinary C.
  • GE05 retains the five map validators. The first build proved four leaf validators exact but expanded _code_0009ccf0 to 1104 bytes and 60 relocations because find_netgame_flags was inlined through _code_0009cbe0. The target dispatcher is 640 bytes and 52 relocations and calls find_netgame_flags. The donor declaration's __declspec(noinline) was therefore restored as target-backed topology; _code_0009ccf0 then became strict exact without any prior regression.
  • GE06 replaces imported/Common storage with ordinary typed zero-initialized definitions. The resulting .bss has the target's exact 1,148-byte layout: global_goal[32] at 0, global_variant at 1024, game_engine at 1128, typed private teleporter state at 1132 and 1136, and the autogenerate pointer/count at 1140 and 1144. The strict section comparator proves the complete uninitialized-data section exact. This batch changes no function credit; renewed measurements show that the two emitted residuals also have register-allocation differences and were therefore correctly left unmatched.
  • GE07 recovers the HUD score-message topology: the player-state initializer, the full message formatter, two small dispatch helpers, both public score wrappers, the ally/enemy dispatcher, and the player-added path. All eight recovered functions are strict exact. The ally/enemy dispatcher uses an ordinary two-arm C control flow that produces the target's 208 bytes without the earlier volatile parameter workaround. _code_0009b6e0 is emitted with target-equal size and ordered relocations, but remains unmatched because its independent final terminator store is scheduled at a different instruction boundary; no assembly or byte forcing was retained.
  • GE08 recovers the statistic score encoder and full ranking buffer plus the weighted item-selection and starting-equipment inventory helpers. All four functions are strict exact ordinary C. The typed callback at game_engine + 0x70 is restored without changing the verified structure layout. Legal source bodies are also retained for their five coupled callers; those callers have target-equal relocation counts but remain unmatched and receive no credit.
  • GE09 recovers the complete typed debug_player_color initializer, including the adjacent teleporter flash type, intensity, color, and duration fields. The resulting 32-byte .data section is strict exact and the complete prior function set remains exact.
  • GE10 restores the natural weighted-permutation for loop independently preserved at b9aa157a957ac54e58a915bf58a2f690179caf7a. XDK 3911 performs the target's four-way loop transformation by itself; no handwritten unrolling or scheduling control is retained. The result is the target's exact 176 bytes and five semantic relocations for _code_00097020.
  • GE10 also restores the policy-clean postgame-title source topology. The named outcome, team-name, and player-entry branches are corroborated by the documented October decomp at C:/Users/isabe/Downloads/halo-main (1)/halo-main/src/halo/game/game_engine.c and by January strings/calls. Referencing _code_00096b50 from that natural private caller restores the target's private ABI and makes the helper strict exact. _code_0009d140 itself remains short by 64 bytes and three relocations and is explicitly parked without credit.
  • GE10 removes three raw structural accesses without changing any admitted bytes: player offset 0xC0 is the offset-asserted statistics.multiplayer_statistics member, and the HUD font fields at 0x54/0x64 are exposed through an offset-asserted game_engine_hud_globals view. The three formatter callbacks at game_engine + 0x4C/+0x50/+0x54 are likewise named and offset-asserted. The target-backed non-inline boundary on find_netgame_flags is kept only on its definition, rather than leaking into the public header. Removing that boundary was measured in GE05a to inline the scan into _code_0009ccf0, expanding the exact target function from 640 to 1104 bytes; the definition-local attribute is therefore an unavoidable recovered call boundary, not a byte-forcing control.
  • GE11 restores the natural postgame renderer and its private display topology. The renderer's ordinary call to _code_0009cb60 recovers that helper's target-private emission boundary and makes its complete 128 padded bytes and six semantic relocations strict exact. Typed, offset-asserted views replace the HUD definition's bitmap-group offset and the player statistic accesses; the postgame display helpers themselves are retained only as nonexact structural checkpoints.
  • The postgame cluster exposed an XDK 3911 whole-translation-unit scheduling interaction in _populate_statistic_buffer: defining the already-exact function after the large renderer reverses two independent local loads. Moving the unchanged natural definition before the postgame functions restores the target order. The retained source has one ordinary definition, no excluded duplicate, and no scheduling primitive. Rebuilt comparison proves both _populate_statistic_buffer and _code_0009cb60 exact simultaneously.
  • GE12 restores the final six target-backed function bodies and their typed support surfaces using ordinary C. _code_0009b4f0 keeps external linkage because the target both emits that symbol and inlines its behavior into _game_engine_update; the rebuilt candidate likewise emits both functions at their target relocation counts. _code_0009bdf0 clears its scratch storage with an ordinary byte loop. No assembly, volatile forcing, scheduling barrier, pragma, excluded duplicate, or object patch is retained. A whole-TU sweep proves all 180 target functions now have candidate symbols, the protected 159-function exact set remains exact, and both owned data sections remain strict exact. The six restored bodies remain residuals and receive no exact credit.

Experiment matrix

ID Source shape Size T/C Relocs T/C Hash / first divergence Siblings Decision
GE00 Rebuild canonical e54ead79c unchanged 13,904/33,760 exact bytes 125/180 functions Baseline object 3a184a158241... Frozen exact set retained baseline
GE01 Recover five small adapters and route their existing callers through them 400/400 target-equal per function All five strict exact 125/125 canonical exact retained
GE02 Recover typed objective-weapon callback scan and goal getter 592/592 target-equal per function All three strict exact 130/130 prior exact retained
GE03 Recover remap/prediction and local HUD fade helpers 1,600/1,600 target-equal per function All four strict exact 133/133 prior exact retained
GE04 Recover ranking comparator and team-presence scan 320/320 target-equal per function Both strict exact 137/137 prior exact retained
GE05a Recover five map validators without the donor noinline declaration _code_0009ccf0 640/1104 52/60 find_netgame_flags body inlined into dispatcher 139/139 prior exact rejected
GE05b Restore target-backed find_netgame_flags non-inline boundary 1,088/1,088 target-equal per function All five strict exact 139/139 prior exact retained
GE06 Own the complete typed zero-initialized data layout .bss 1,148/1,148 0/0 Strict section info exact 144/144 prior exact retained
GE07 Recover HUD formatting, dispatch, score wrappers, and player-added topology 3,232/3,232 exact bytes target-equal per exact function Eight strict-exact functions; one 144-byte helper parked 144/144 prior exact retained
GE08 Recover statistic ranking and weighted starting-equipment helpers 1,120/1,120 exact bytes target-equal per exact function Four strict-exact functions; five coupled callers remain parked 152/152 prior exact retained
GE09 Recover the typed debug/teleporter flash initializer .data 32/32 0/0 Strict section info exact 156/156 prior exact retained
GE10 Restore the natural item-weight loop, postgame title topology, and named offset-asserted structural views 256/256 newly exact bytes target-equal per newly exact function Two strict-exact functions; _code_0009d140 parked at 1088/1152, 70/73 156/156 prior exact retained
GE11 Restore the policy-clean postgame renderer topology and place the unchanged ranking-buffer definition before that cluster 128/128 newly exact bytes 6/6 for _code_0009cb60 _code_0009cb60 strict exact; _populate_statistic_buffer remains exact at 560/560, 27/27 158/158 prior exact retained
GE12 Restore the final six target-backed bodies with ordinary C 180/180 target symbols emitted Restored bodies have 16/16, 11/11, 5/5, 46/46, 67/67, and 39/39 relocations No new exact credit; all six bodies remain measured structural residuals 159/159 prior exact retained emission checkpoint

Post-GE12 retained work

The active lane is codex/game-engine-full-admission-20260729. Its clean restart checkpoint is e311fa706078abeb2ed8cc7b556909cc1de68c51.

After retained batch GE18:

  • Functions: 165/180 strict exact.
  • Padded code: 25,232/33,760 target bytes.
  • Candidate SHA-256: ba69073dfd624a6744e183497ed6e76c4daf642b77e31389d74dca3f723f6c73.
  • Candidate emission: 180/180 target functions.
  • .data and .bss remain strict exact.
  • Canonical regressions: none.

The six retained post-GE12 functions are:

ID Commit Exact function Recovered source topology Result
GE13 e808f2bde7747b02a4c637e19aeba4fa1c03036f _code_0009bdf0 Order the independent teleporter-flash stores as fade function, type, duration, priority, intensity, scale, and color; keep the target-backed non-inline boundary on find_netgame_flag 160/180 exact
GE14 bca69538a4d344230a8290331407ef4351ebc8ba _code_0009b4f0 Use the existing game_engine_has_shield(player_index) predicate and private linkage, then zero both shield fields only for a live unit 161/180 exact
GE15 519f5d2e4db98b26bb2238d745eed52209c1d014 _game_engine_postspawn_player_update Use the exact code_00097c00() infinite-grenade predicate before restoring both starting grenade counts 162/180 exact
GE16 0594405e063dde6a9d29e7ceccc8f5167b2f7c29 _code_0009cc20 Recover the private prototype's second parameter as short, not long 163/180 exact
GE17 1e22811771f276868d0e497f0a99755b850382a5 _game_engine_remap_equipment Name the grenade remap predicate, reuse code_00097c00(), and funnel remapped list indices through list_index_to_weapon_definition_index() 164/180 exact
GE18 e311fa706078abeb2ed8cc7b556909cc1de68c51 _game_engine_update Iterate directly on data_iterator_next, materialize always_invisible through flag/callback arms, and pass iterator.datum_index at the two tail calls 165/180 exact

Each retained step passed a full 180-function section_infos_equal sweep, the policy scan, and a source diff check before commit.

Active residual measurements after GE18

Hashes are normalized SHA-256 prefixes from the hardened comparator.

Function Size T/C Relocs T/C Normalized hash T/C Current classification
_code_00096ba0 112/112 7/7 4ac1ff18279a/9db784535924 draw-line arithmetic CSE/scheduling
_game_engine_should_spawn_player 256/256 9/9 8259180402f7/c0782ea3a816 boolean/control-flow allocation
_game_engine_get_place 368/368 12/12 91161c382c55/bcf2be6ca02e tied/all-tied local allocation
_code_000994f0 416/416 18/18 211627377053/10c5400d228a private draw-line ABI/register allocation
_code_0009a490 496/480 16/16 f30da54283e6/01537066ba3b select-players topology, short by 16 bytes
_code_0009a680 448/448 18/18 4c90ec184c40/41e698125368 closest-player tail block layout
_code_0009b3a0 336/336 11/11 7e6f5319e160/dbb1e45ecac4 prologue/tail scheduling
_code_0009b6e0 144/144 5/5 675e96da950f/bb509add4c20 multiplayer-message push/store scheduling
_code_0009c460 176/176 10/10 cb6f30979095/a7e62792e4b5 private callback ABI, EBX/EDI mirror
_game_engine_get_starting_location_rating 96/96 6/6 9b229c3bccdf/601000c33610 caller half of EBX/EDI private ABI pair
_game_engine_get_state_message 320/320 10/10 20ff545777ef/63ba933b746c target shrink-wrapped prologue
_code_0009d140 1152/1088 73/70 e261315dfb4e/1a8d99b44cb1 postgame title topology, short by 64 bytes/3 calls
_game_engine_post_rasterize_post_game 2528/2528 148/148 5d9500c231fe/a8bfb78acd0f large postgame renderer compiler shape
_game_engine_player_killed 832/832 39/39 4d4a8b42b57d/d8d21f2ca76f event-block ordering
_code_0009e670 848/848 41/41 28483cea9891/7bacec539a12 score-row private ABI/register allocation

Provenance recovered after GE18

  • The January cachebeta.exe symbol atlas identifies _code_00096ba0 as _drawline, _code_000994f0 as _rasterize_in_game_score_draw_line, _code_0009a490 as _select_players_to_display (fuzzy tier), _code_0009a680 as _find_closest_player_index, _code_0009b6e0 as void multiplayer_message(long,long,long), and _code_0009c460 as _default_starting_location_rate_function.
  • Public PC 1.10 maps corroborate the sequence find_closest_player_callback, find_closest_player_index, internal_rasterize_target_name: _code_00096c80, _code_0009a680, _code_0009a840.
  • Tempera and OpenSauce contain call wrappers and symbol maps for these routines, but no public function body suitable as a donor.
  • A direct January PDB module-stream audit found stream 316 contains only S_OBJNAME, S_COMPILE2, and no procedure, local, register, block, or line records. Original local names/order and prototypes cannot be recovered from that PDB. Evidence is recorded in outputs/jan-pdb-game-engine-locals/evidence.md.

Rejected post-GE18 experiments

All entries below were rebuilt with XDK 3911 and restored because they did not produce a strict improvement.

ID Function/cluster Source shape Exact measurement / rejection
GE19a _code_000994f0 / _code_0009e670 Alias the color local; alias the row local; move row_color to function scope; mark formal declarations register; swap the last two formal parameters and all calls Color/row/scope/register spellings produced no object change. Parameter swapping also preserved the compiler's existing private ABI. Baseline hashes remain 10c5400d228a and 7bacec539a12.
GE19b _code_00096ba0 Spell the row ordinate as 2 * (row * 9) + 26, unsigned multiply variants, and separately recomputed expressions No object change. Target recomputes the two ordinates; candidate CSEs the first value and adds 0x1a. Baseline hash remains 9db784535924.
GE19c _game_engine_player_killed Positive unknown_d1 early arm; negative guard without else; merge event 5/event 4 as if/else if Positive early arm shrank/reordered the body to 816 bytes. The two other forms produced no useful change. Target is 832/832, 39/39, with the unknown_d1 loop at 0x1d7, event-5 fallback at 0x226, and event-4 block at 0x276; candidate orders the same blocks at 0x2e7, 0x1d3, and 0x226.
GE19d _code_0009a680 Put the failure return inside the best == NONE block and make the outer conversion explicit 448/448, 18/18, candidate hash 5e0ed18322b9; wrong failure/fast-conversion block order.
GE19e _code_0009a680 Explicit positive object_count guard with do loop 448/448, 18/18, candidate hash 601dd2a2e76d; popped EBX too early and inserted mov edx,eax before the inner conversion.
GE19f _code_0009a680 Explicit positive object_count guard plus ordinary for loop 448/464, 18/18, candidate hash 564a3c340805; redundant entry test expanded the body by 16 bytes.
GE19g _code_0009a680 Direct early conversion return followed by an unwrapped search 448/448, 18/18, candidate hash 83138e3c2851; moved the search body and changed register allocation well before the target tail.
GE19h _code_0009a680 Explicit final if (best == NONE) return best; followed by conversion 448/448, 18/18, candidate hash 5e0ed18322b9; same rejected block order as GE19d.
GE19i _code_0009a680 Read the ternary false arm through a same-type pointer alias 448/448, 18/18, unchanged candidate hash 41e698125368; optimizer sees through the alias.
GE20a _code_0009b6e0 Introduce a block-local wchar_t *message_pointer alias and pass it to hud_print_message No object change: 144/144, 5/5, candidate hash bb509add4c20. The optimizer eliminates the alias and still schedules the terminator store at 0x6c instead of target 0x77.
GE20b _code_0009b6e0 Materialize player->local_player_index as a block-local word before the terminator store 144/144, 5/5, candidate hash c47997f24cc2. The load moves before the store, but becomes a shorter movzx; the store moves after both argument pushes and the real body ends two bytes early.
GE20c _code_0009b6e0 Embed the terminator assignment in the message argument with a comma expression No object change: 144/144, 5/5, candidate hash bb509add4c20; XDK hoists the independent store to the same 0x6c position.
GE21a _game_engine_get_state_message Replace the outer if (game_engine) with an early if (!game_engine) return FALSE guard and an unwrapped body Rejected at 320/304, 10/9, candidate hash 0f94227ea43a. It split the false epilogue, shortened the function by 16 bytes, and disturbed allocation beyond the prologue.
GE21b _game_engine_get_state_message Route the false-engine path to an explicit shared exit: label No object change: 320/320, 10/10, candidate hash 63ba933b746c; XDK canonicalizes the label to the existing outer-if CFG.
GE21c _game_engine_get_state_message Move the initialized result declaration ahead of the four other locals No object change: 320/320, 10/10, candidate hash 63ba933b746c; declaration order does not affect the shrink-wrapped saves.
GE22a _code_00096ba0 Spell the second ordinate directly as row_index * 18 + 26 No object change: 112/112, 7/7, candidate hash 9db784535924; XDK CSEs the first ordinate.
GE22b _code_00096ba0 Use a differently factored second ordinate, row_index * 9 * 2 + 26 No object change: 112/112, 7/7, candidate hash 9db784535924; reassociation canonicalizes to the same CSE.
GE22c _code_00096ba0 Materialize the cast justification as a scoped short between the two ordinate statements No object change: 112/112, 7/7, candidate hash 9db784535924; the local is eliminated and the justification load remains scheduled before the first ordinate calculation.
GE23a _code_0009b3a0 Initialize equipment_index before the empty-block early return 336/336, 11/11, candidate hash 0246a597921d. It moves the zero store before the branch as suggested by target, but changes the entire 16-byte prologue schedule without fixing the tail.
GE23b _code_0009b3a0 Add an explicit scenario local before deriving the equipment-block pointer No additional object change from GE23a; XDK eliminates the alias and retains hash 0246a597921d.
GE23c _code_0009b3a0 Increment equipment_index before refreshing equipment_count at the loop tail No object change from GE23a; store/sign-extension order remains candidate-style.
GE23d _code_0009b3a0 Remove equipment_count and compare the cast index directly with equipment_block->count No object change from GE23a; direct condition canonicalizes to the same tail.
GE24a _game_engine_should_spawn_player Recover should_spawn as boolean instead of long Much closer at 256/256, 9/9, candidate hash 031050d5b5fa, but the real body is two bytes shorter. It emits the target byte initialization/update/test, except TRUE is written with mov bl,1 rather than target mov ebx,1; the later respawn_timer == 1 therefore uses an immediate instead of EBX.
GE24b _game_engine_should_spawn_player In the boolean variant, compare respawn_timer with should_spawn No object change from GE24a; SSA constant-folds the known-true boolean back to immediate 1.
GE24c _game_engine_should_spawn_player Keep should_spawn as long but cast the timer-zero assignment to boolean 256/256, 9/9, candidate hash ccda5c6da927; XDK decrements memory directly, sets CL, then zero-extends into EBX, diverging more broadly.
GE24d _game_engine_should_spawn_player Keep the long assignment and cast only the subsequent false test to boolean 256/256, 9/9, candidate hash 88d4d379707c; the test narrows to BL, but XDK still clears full EBX at initialization and before sete.
GE24e _game_engine_should_spawn_player Add a long true_value, copy it to the boolean result, and reuse it for the one-tick comparison Optimizer eliminates the auxiliary value; identical to GE24a (031050d5b5fa).
GE24f _game_engine_should_spawn_player Keep the long result but stage the timer-zero expression through a block-local boolean 256/256, 9/9, candidate hash ff0a5a6c9795; result moves through AL and a later movzx, changing the update tail and remaining two bytes too long/short in different places.
GE25a _game_engine_get_place Reverse the declarations of tied and all_tied No object change: 368/368, 12/12, candidate hash bcf2be6ca02e; stack-slot allocation follows use/lifetime, not declaration order.
GE25b _game_engine_get_place Initialize tied before all_tied 368/368, 12/12, candidate hash f3df41c318b9; store order changes, but tied remains at [ebp-1] and all-tied at [ebp-2], opposite the target.
GE25c _game_engine_get_place Materialize all_tied & tied as a block-local boolean before building result flags Rejected at 368/384, 12/12, candidate hash 8bd0c13d5f01; it adds a separate AL value and expands the flag-builder by 16 bytes.
GE26 _game_engine_get_starting_location_rating / _code_0009c460 Prior bounded families: split or initialize the player local separately, reverse formal parameter order and calls, inline player_get, and introduce aliases around player_index/starting_location No family changed the coupled private ABI mirror. Metrics remain 96/96, 6/6, hash 601000c33610 for the caller and 176/176, 10/10, hash a7e62792e4b5 for the callee.
GE27a _code_000994f0 / _code_0009e670 Move the font-header pointer declaration to function scope and assign it inside the font block No object change in either function; hashes remain 10c5400d228a and 7bacec539a12.
GE27b _code_000994f0 / _code_0009e670 Move the caller's color declaration ahead of text_color and team_colors No object change; stack allocation and the private call ABI ignore declaration order.
GE27c _code_000994f0 / _code_0009e670 Change private row_index formal from long to short Caller remains unchanged and the callee stays 416/416, 18/18, but changes to nonexact hash cd51e44cd367 through a word compare at the row test.
GE28a _code_0009a490 Rewrite only the move length from maximum_count * 28 - entry_index * 28 - 28 to (maximum_count - entry_index - 1) * 28 Still 496/480, 16/16; candidate hash ce681b033294. First divergence remains the frame immediate at instruction 0x03 (target 0x244, candidate 0x248). The long-lived temporary changes from maximum_count * 28 to the first discarded-entry pointer, but the candidate still removes the target's second comparison and remains 16 bytes short. Full-TU sweep remains the same 165 exact functions and 15 named residuals; rejected and restored.
GE28b _code_0009a490 Spell only the outer guard as player_count > maximum_count, leaving the nested maximum_count < player_count test unchanged Still 496/480, 16/16; candidate hash 62f46588e0c2. First divergence remains the frame immediate at 0x03; XDK still eliminates the nested comparison and merely changes the discarded-entry pointer register schedule. Full-TU sweep remains the same 165 exact functions and 15 named residuals; rejected and restored.
GE28c _code_0009a490 Express the nested gather guard as a one-iteration while (maximum_count < player_count) { ...; break; } Canonicalizes completely to baseline: 496/480, 16/16, candidate hash 01537066ba3b; first divergence is still the frame immediate at 0x03, and only one comparison remains at 0x7e. Full-TU sweep remains 165 exact with the unchanged 15-residual set; rejected and restored.
GE29a _code_0009d140 Give each successful postgame outcome branch a block-local outcome_string before its ustrncpy, matching the one already present in the winning-team arm Regressed from 1152/1088, 73/70, 1a8d99b44cb1 to 1152/1024, 73/66, candidate hash 02877d10d508. First divergence remains the branch at 0x112 (target destination 0x2a7, candidate 0x223). XDK tail-merges even more outcome arms, leaving only two ustrncpy relocations at 0x1f0 and 0x20e; full-TU sweep remains the same 165 exact/15 residuals. Rejected and restored.
GE29b _code_0009d140 Reorder the semantic outcome chain from NONE, false, true to false, true, NONE, preserving every branch body 1152/1088, 73/70, candidate hash 7fca1b217d7d. First divergence is again the branch at 0x112 (target destination 0x2a7, candidate 0x25d). The compare order follows source order, but XDK still merges the same three ustrncpy sites and emits only two at 0x1dd and 0x248; full-TU sweep remains 165 exact with the unchanged residual set. Rejected and restored.
GE29c _code_0009d140 Replace the NONE/false/true if chain with a semantically equivalent switch containing explicit breaks Regressed to 1152/1072, 73/70, candidate hash 9402ff95adec; first divergence remains the branch at 0x112 (target destination 0x2a7, candidate 0x257). The switch retains only two ustrncpy sites at 0x198 and 0x242 and changes compare/layout shape without recovering any missing relocation. Full-TU sweep remains 165 exact/15 residuals; rejected and restored.
GE29d _code_0009d140 Add a block-local outcome_string only to the false/team arm (0x38), leaving the other four outcome arms at baseline Regressed to 1152/1072, 73/69, candidate hash cd14c1e44f9f; first divergence remains the 0x112 branch. XDK coalesces more of the tag/string retrieval and still leaves only two ustrncpy sites at 0x1b9 and 0x239, so the selective-local hypothesis does not incrementally recover a target call. Full-TU sweep remains 165 exact/15 residuals; rejected and restored.
GE30a _game_engine_post_rasterize_post_game Move only the code_0009cb60(0) team-order decision before loading the two team-format strings, as ordered in the target relocations Remains 2528/2528, 148/148; candidate hash changes from a8bfb78acd0f to 2452c802321f. First divergence remains the frame immediate at 0x03 (target 0x670, candidate 0x674). This exactly restores the early semantic call order (code_0009cb60 at candidate 0x173, target 0x173) but 125 relocation addresses and later player/prompt blocks remain displaced. Full-TU sweep remains 165 exact with the unchanged 15 residuals; nonexact source change rejected.
GE30b _game_engine_post_rasterize_post_game On top of GE30a, declare team_order[2] before team_tab_stops[6] Regressed to 2528/2528, 148/146, candidate hash a0960d2334c3; first divergence remains 0x03. The stack allocator does not adopt the target slots and two later string-fetch relocations disappear through changed whole-function optimization. Full-TU exact set remains 165/180; rejected and restored.
GE30c _game_engine_post_rasterize_post_game On GE30a, leave place, string_list_index, and place_string uninitialized at declaration and assign them after the first row color/tab calls, matching target relocation order Improves semantic ordering but shrinks to 2528/2512, 148/148, candidate hash fdab273b3ace. First divergence is still the frame immediate at 0x03; the complete relocation-target sequence then agrees except for the final prompt-bounds cluster, but 126 relocation addresses differ. Full-TU sweep stays 165 exact/15 residuals; rejected.
GE30d _game_engine_post_rasterize_post_game On GE30c, copy bounds = render.camera.window_bounds before assigning prompt_color.alpha 2528/2512, 148/148, candidate hash d63305c7dc08. First divergence remains 0x03. The only remaining semantic relocation-order delta is the placement of the render + 0x3E viewport-word load inside the prompt cluster; full-TU sweep stays 165/180. Rejected.
GE30e _game_engine_post_rasterize_post_game On GE30d, remove explicit prompt bounds.x1 = 640 / bounds.y1 = 480, retaining the copied window bounds as the target disassembly does Still 2528/2512, 148/148, candidate hash 1b8c8c531b65. The two redundant stores disappear without changing padded size; only the render + 0x3E load order remains semantically displaced, the frame is still 0x674 versus target 0x670, and 130 relocation addresses differ. Full-TU sweep remains 165 exact/15 residuals; rejected.
GE30f _game_engine_post_rasterize_post_game On GE30e, remove the block-local draw_row alias and pass entry_index directly to all six row draws No object change from GE30e: 2528/2512, 148/148, candidate hash 1b8c8c531b65; XDK had already coalesced the alias. Full-TU sweep remains unchanged; rejected and restored.
GE31a _game_engine_player_killed Add an explicit positive unknown_d1 jump to a player_quit: label while retaining the negative normal-event guard Canonicalizes exactly to baseline: 832/832, 39/39, candidate hash d8d21f2ca76f. Target and candidate remain byte-identical through the conditional branch instruction at 0x13b; only its destination differs (0x1d7 target versus 0x2e7 candidate), because the quitting-player broadcast block stays at the tail. Full-TU sweep remains 165 exact with the unchanged 15 residuals; rejected and restored.

The target and GE18 candidate for _code_0009a680 are byte-identical through offset 0x190. The remaining target tail uses EAX for both conversion arguments and reloads best_object_index on the zero-count return path. The candidate uses EDX in the outer conversion and constant-folds the failure to -1. Further work on this function requires a genuinely new control-flow family, not a spelling variant of GE19d-i.

_code_0009b6e0 park packet (GE20): target and baseline are identical through offset 0x6c and again from the call at 0x7e through the padded end. Both are 144 bytes with five ordered semantic relocations. The only difference is the legal scheduling of the independent message[NUMBEROF(message) - 1] = 0 store: target places it after the message pointer push and before the player-index push; the candidate places it before the local-player-index reload. Alias, explicit-local, and comma-expression families are exhausted. Reopen only with donor source or a new compiler scheduling dependency that does not use volatile/barriers.

_game_engine_get_state_message park packet (GE21): both objects are 320 bytes with ten ordered semantic relocations, and offsets 0x26 through the padded end are byte-identical. The sole difference is the first 0x26 bytes. Target saves EBX/ESI before the game_engine test and EDI between the test and branch; candidate shrink-wraps all three saves after the false branch. Early-return, explicit-shared-label, and declaration-order families are exhausted. Reopen only with a new target-backed lifetime/CFG lead that explains the callee-save placement.

_code_00096ba0 park packet (GE22): both sections are 112 bytes with seven ordered semantic relocations. Offsets 0x00..0x34 are exact. Target computes row_index * 18 independently into EDX for bounds.y0, then into EAX for bounds.y1, ending its real body at 0x70. Candidate computes it once in EAX, adds 26 for y1, and ends at 0x6c with four padding NOPs. Direct, differently-factored, unsigned variants from GE19b, and a scoped justification-local family all canonicalize to the same candidate. Reopen only with donor topology or a legal alias/lifetime reason for the target's recomputation.

_code_0009b3a0 park packet (GE23): target/candidate are 336/336 with 11/11 ordered semantic relocations. The central body from 0x30 through 0x127 is byte-identical. Baseline differences are confined to pointer/count setup before 0x30 and loop-index/count scheduling at 0x127..0x135. Moving the zero initialization produces a distinct but non-improving 0246a597921d candidate; scenario aliases, source-order swapping, and a direct loop condition do not refine it. The committed dbb1e45ecac4 baseline is restored. Reopen only with original topology that jointly explains target's lea ebx,[eax+0x384] setup and EAX/ECX tail allocation.

_game_engine_should_spawn_player park packet (GE24): target/baseline are 256/256 with nine ordered semantic relocations. The target exhibits a mixed width lifetime in EBX: initial false and the timer-zero result use BL, the intermediate true uses full EBX and is reused for the one-tick comparison. The natural boolean source is the closest candidate (031050d5b5fa) and matches that behavior except for a two-byte-short mov bl,1/immediate compare pair. Natural long, boolean, cast-at-assignment, cast-at-test, auxiliary constant, and boolean-temporary families are exhausted. The committed long baseline is restored; do not synthesize mixed-width storage through union or pointer byte forcing. Reopen only with donor source or a target-backed local type/lifetime explanation.

_game_engine_get_place park packet (GE25): target/baseline are 368/368 with 12/12 ordered semantic relocations. Target assigns tied to [ebp-2] and all-tied to [ebp-1], then loads both before its flag builder and retains their AND in DL. Baseline assigns the logical locals to the opposite byte slots and uses test cl,dl later. Declaration order is ignored, assignment order changes only store scheduling, and materializing the AND expands the body. A previous packed-struct family also worsened allocation. Baseline is restored; reopen only with original local topology or a target-backed lifetime lead, not manual storage overlays.

Starting-location rating park packet (GE26): the caller is exact through 0x33, then target saves player index in EBX while candidate uses EDI. The private callee receives starting location in EAX in both objects; target's hidden player index is EBX and its player pointer is EDI, while candidate mirrors those roles as EDI/EBX. All instruction sizes, control flow, and ordered semantic relocations otherwise agree (96/96, 6/6 and 176/176, 10/10). The January atlas confirms _code_0009c460 is _default_starting_location_rate_function. Local splitting, aliasing, parameter order, and inline-get families are exhausted. Reopen only with a new whole-TU/private-ABI allocation lead; do not add register-forcing syntax.

Score-row draw park packet (GE27): _code_000994f0 and its large caller _code_0009e670 are respectively 416/416, 18/18 and 848/848, 41/41. Target's private helper passes only string/brighten on the stack, row in EAX, and color in ESI; candidate passes row on the stack and color in EDI. Target therefore retains font_index on the helper's stack and uses EAX for the font pointer, while candidate caches them through ESI. In the caller this is visible at the first call: target pushes two arguments, zeros EAX, and computes color in ESI; candidate pushes three arguments and computes color in EDI. Color/row aliases, formal reordering, register keywords, declaration scope and order, and a short-row prototype are exhausted. Baseline is restored. Reopen only with original private-call topology or a whole-TU allocation lead.

_code_0009a490 bounded structural park packet (GE28): target/baseline are 496/480 with 16/16 ordered semantic relocations. The first divergence is the prologue frame at instruction 0x03: target allocates 0x244, candidate 0x248. At 0x7E, target retains two consecutive maximum_count < player_count checks around the zero initialization and recomputes maximum_count * 28 at 0x168; candidate removes the second check and preserves the product in an extra stack temporary. Consequently target ends its real body at 0x1EE and candidate at 0x1E0. Equivalent move-length algebra, reversed outer comparison spelling, and a one-iteration while/break guard either produce distinct non-improving hashes or canonicalize to the 01537066ba3b baseline. Every trial preserved the 165-function exact set. No source/PDB donor contains the original locals. This packet does not grant target-equal size or exact credit; reopen only with original select_players_to_display topology or a measured reason for both the redundant comparison and absent long-lived product.

_code_0009d140 bounded structural park packet (GE29): target/baseline are 1152/1088 with 73/70 semantic relocations. Instructions 0x00..0x112 agree; the first differing instruction is the 0x112 postgame-state branch, whose destination is target 0x2A7 versus candidate 0x25D. In the outcome cluster target emits five distinct ustrncpy calls, while XDK tail-merges the natural source arms into two, exactly accounting for the three missing call relocations. Homogeneous and selective outcome-pointer locals, semantic arm reordering, and a switch form produce 1024, 1072, or 1088-byte nonmatches and never recover a third call site. The January PDB has no local, block, or line records, and the October decomp corroborates behavior but not the target's source topology. This packet does not grant target-equal size or relocation credit; reopen only with donor source or a new CFG family that explains five unmerged return/copy epilogues without forcing code generation.

_game_engine_post_rasterize_post_game bounded compiler-shape park packet (GE30): target/baseline are 2528/2528 with 148/148 semantic relocations. The first divergence is the prologue frame at 0x03 (target 0x670, candidate 0x674) followed by different callee-save and local-slot allocation. Target orders the team-order predicate before the two team-format lookups, and orders the first row color/tab calls before the place-string lookup; baseline source order is the reverse. GE30a and GE30c recover those semantic call orders, and GE30d/e recover the prompt bounds/progress order and remove two target-absent bound stores. The best combined form has all 148 relocations and only one repeated render + 0x3E relocation-order delta, but shrinks the candidate to 2512 bytes, retains the 0x674 frame, and has hash 1b8c8c531b65. Reordering the team locals instead drops two relocations; removing the draw-row alias is a no-op. All trials preserve the 165 exact functions. Baseline is restored because no partial structural change receives admission. Reopen only with original local lifetime/order evidence capable of jointly explaining the four-byte frame difference and whole-function register allocation.

_game_engine_player_killed compiler-layout park packet (GE19c/GE31): target/baseline are 832/832 with 39/39 semantic relocations and are byte-identical through the conditional instruction at 0x13B. Only its destination differs: target places the quitting-player iterator/broadcast block at 0x1D7, candidate at 0x2E7. Target then places the event-5 fallback at 0x226 and event-4 medal block at 0x276; candidate places them at 0x1D3 and 0x226. A positive early quitting arm shrinks the body to 816 bytes; a negative guard without else, event 5/4 else if, and an explicit positive jump label either preserve the d8d21f2ca76f baseline or worsen layout. Every form keeps the same 39 call/data relocations and the 165-function exact set. Reopen only with a genuinely new target-backed CFG that orders the three event blocks without changing their emitted bodies.

Do-not-repeat list

  • Do not import .agent-ge-wave1, raw .obj checkpoints, or their text inventories.
  • Do not cherry-pick either artifact-bearing checkpoint commit.
  • Do not use inline assembly, volatile byte forcing, pointer-past-object storage, _ReadWriteBarrier, compiler pragmas/flags, object patches, or comparator exceptions.
  • Equal size or equal relocation count without ordered semantic relocation identity is not a match and is not sufficient parking evidence.
  • Do not repeat GE19a-i or the older cosmetic spelling trials for _code_0009b6e0, _code_0009c460, and _game_engine_get_starting_location_rating; reopen them only with a new ABI or source-topology lead.
  • Do not repeat GE28a-c, GE29a-d, GE30a-f, or GE31a. Those families cover the remaining arithmetic/guard, postgame-outcome, renderer-order, and kill-event-layout hypotheses and preserve no strict-exact improvement.

Residual classification

  • No candidate symbol is absent; all 180 target functions are emitted.
  • Thirteen target-equal-size residuals are evidence-exhausted compiler scheduling, register-allocation, private-ABI, or basic-block-layout shapes: _code_00096ba0, _game_engine_should_spawn_player, _game_engine_get_place, _code_000994f0, _code_0009a680, _code_0009b3a0, _code_0009b6e0, _code_0009c460, _game_engine_get_starting_location_rating, _game_engine_get_state_message, _game_engine_post_rasterize_post_game, _game_engine_player_killed, and _code_0009e670.
  • Two structural residuals are evidence-exhausted but do not meet target-equal size/relocation gates: _code_0009a490 is 16 bytes short with equal relocation count, and _code_0009d140 is 64 bytes/three calls short.
  • Every one of the 15 residuals has a reproducible bounded packet above. A packet records why ordinary source families are exhausted; it grants no exact or semantic-match credit.
  • No residual is currently granted exact credit or marked complete.

Final clean audit after GE31

  • Clean XDK 3911 rebuild from source checkpoint e311fa706078....
  • Functions: 165/180 strict exact.
  • Padded exact code: 25,232/33,760 target bytes.
  • Candidate emission: 180/180 target functions.
  • Final rebuilt candidate SHA-256: eeadadb05d04c74aad18e31636fe52b9ab111cdbf768b4f78a609484b582194b.
  • .data: strict exact at 32/32, 0/0 relocations, normalized hash daa87eb1c49a on both sides.
  • .bss: strict exact at 1,148/1,148, 0/0 relocations, normalized hash 509607d81ec2 on both sides.
  • The residual names and all 15 baseline metrics reproduce the post-GE18 table exactly.
  • Full policy scan has no hits for inline assembly, volatile, _ReadWriteBarrier, intrinsic pragmas, pointer-past-object markers, UB_ markers, or #if 0.
  • git diff --check passes, and source/header diff is empty. Only this ledger is changed by the bounded-exhaustion pass.

Reopen criteria

A residual may be retained only after an XDK 3911 rebuild proves its complete padded section and semantic relocations exact, with no loss from the frozen canonical exact set. Formal parked-registry admission additionally needs target-equal size and ordered semantic relocation identities; the two bounded structural packets that fail those gates are documentation only. New PDB/source provenance, donor source, or a measured compiler-shape rule is required to reopen any exhausted spelling.

Disposition

Evidence-exhausted at 165/180, with no legal source change retained after GE18. game_engine.obj remains active and must not be marked Matching until all 180 target functions and every owned data/BSS section pass the strict gates.