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

674 lines
54 KiB
Markdown

# `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.