Complete game_engine title string body (zero credit) and record wave w3c batch 1

_game_engine_generate_title_string was structurally incomplete (1088/70 against
January's 1152/73) and skipped January's common null-termination tail on an
unrecognised win result. The rewritten single-exit body reaches January's size,
relocation count and frame layout with two team-name wchar_t[8] buffers instead
of the union spelling, and 391/391 instructions with one transposed push. It is
still [sha] residual, so it carries ZERO byte credit; the reopen criterion is in
the ledger.

Wave w3c batch 1 (8 groups, 36,384 spendable padded bytes) landed no strict exact
function. The per-object ledgers record the measured blockers, the rejected
_bitmap_2d_smooth reopen (it loses the exact _bitmap_2d_uncompress_from_mipmap
row) and the proposals raised. Full ninja, parks 280/0/0, stable diff vs
scratch/claude250k-start.json: gained 0, regressions 0; fake scan 0 leads.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Jonas VolmanandClaude Opus 5 committed 2026-09-15 16:25:03 -07:00
1 parent 0483bde89e
commit aa2ada3f52
10 files changed
+1388 -101

No files matched your search

@@ -0,0 +1,167 @@
# `actor_combat.obj`: second pass (opus5 250K lane, wave w3c, 2026-09-15)
## Scope and provenance
- Lane `opus/250k-house-clean-20260915`, HEAD `0483bde89`, worktree
`C:\halo-worktrees\opus5-150k-house-clean-20260914`. Worker `w3c:actor_combat`; the only file this worker
could modify is `source/ai/actor_combat.c`. **It is unchanged** (`git diff --stat -- source/ai/actor_combat.c`
is empty). No header, config, build or tool file was touched.
- Target: `build/split/source/ai/actor_combat.obj`. Compiler XDK VC7 13.00.9254, repository flags via
`tools/campaign/gate.py`.
- Worker notes with the per-function report blocks: `scratch/workers/w3c_actor_combat.md`.
Scratch candidates and objects: `scratch/workers/w3c_actor_combat/` (`g1-g4`, `p1-p6`, `r1-r3`, `score.py`).
- Evidence used: January target COFF (disassembly, relocations, per-function relocation census),
HCEA `halocea-review/src/blam/ai/actor_aim_grenade.c` (semantics/topology only), `scratch/atlas/actor_combat.obj.txt`,
`config/parked.json`, and the prior ledgers listed in the notes file.
- Laws applied as detectors: WORKER_BRIEF 9, `scratch/w2/laws_w2.md` (A4, A5, A6, A11, A20, A24 precursor,
A30 in w3), `scratch/w3/laws_w3.md` (A24, A30, A31, A35, R13, R16, E18).
## Baseline and final (real file)
`python -B tools/campaign/gate.py source/ai/actor_combat --all --forbid-emitted-symbol _point_from_line3d`
| | result |
| --- | --- |
| baseline | `== exact 28 residual 6 unwritten 0 (of 34)`; guard passed; parkcheck `parks 4 drift 0` |
| final (real file, unchanged) | identical listing; guard passed; parks 4/4 undrifted; `tools/fake_match_scan.py` 0 leads |
No row is newly exact. Nothing landed; this wave produced evidence, a refined reopen criterion for two parks,
and one owner-ruling request.
## Per-function outcomes
| function | January padded / relocs | state | outcome |
| --- | --- | --- | --- |
| `_actor_aim_grenade` | 544 / 22 (ours 576) | residual `[size]` | NOT-LANDED; 4 shapes; g4 closes the output block, frame + facing-address CSE remain; owner ruling requested |
| `_actor_combat_plan_grenade_trajectory` | 288 / 5 | PARK | scratch-only; **A24 confirmed**: 18 hunks -> 6, frame 0x34 -> 0x30 exact; not exact, no reopen |
| `_actor_combat_reaim_grenade` | 448 / 16 | PARK | scratch-only; 3 shapes, all byte-identical; no reopen |
| `_actor_aim_projectile` | 720 / 27 | PARK | SKIPPED-EXHAUSTED (2-instruction copy-pipelining tie; shared with plan) |
| `_actor_combat_find_nearby_target` | 352 / 12 | PARK | SKIPPED-EXHAUSTED (x87 last-use fold; new counter-example found, no lever) |
| `_actor_start_burst` | 1968 / 67 | residual `[sha]` | SKIPPED-EXHAUSTED (14 spellings across 3 lanes; w1 reopen criterion unmet) |
## `_actor_aim_grenade` (the only non-parked structural row)
Three independent facts now explain the 32-byte gap.
1. **Aim-speed x87 CSE — solved.** January loads `actor->control.grenade_current_aim_speed` once
(`fld [edi+0x6c8]`) and spends it as `fmul st(1)` twice plus a folded `fmul [aim_vector.k]`. Our source
multiplied each component by the field, reloading the 6-byte operand three times. Candidate `g4`
(`real aim_speed = actor->control.grenade_current_aim_speed;` then `aim_speed*aim_vector.i/j/k`, matching
HCEA's `throw_speed`) reproduces January's final block instruction for instruction and takes the differing
target lines from 78 to 73. It cannot land alone (a written residual lands only when strict EXACT).
2. **Facing-vector address CSE — open.** January materialises `lea ecx,[edi+0x174]` and reads the facing vector
as `[ecx]` / `[ecx+4]` in the 2D dot and the 2D cross, then `mov edx,ecx` for the 12-byte
`new_aim_vector` copy. Ours emits seven 6-byte `[edi+0x174..0x17c]` operands. A block-local
`real_vector3d const *facing_vector` (g1) and a genuine inlined `cross_product2d` call with the admitted
`(real_vector2d const *)` cast (g2) are both byte-identical to the current file: VC7 constant-folds the
field address in every spelling we can write, so the register form has some other cause.
3. **Frame 0x24 vs 0x28.** January shares `[-0x24..-0x19]` between `desired_grenade_target` and `aim_vector`,
and packs the `(counterclockwise ? 1 : -1)` fild temp into the dead `aim_vector2d.j` cell `[-8]`. Ours gives
the fild temp its own cell and hands the dead retarget-point cells to `new_aim_vector` instead.
HCEA's lift of the same function uses ONE working triple (`direction_x/y/z`): assigned from the retarget point
in the prop branch, overwritten by the refreshed aim vector on the on-foot path, and multiplied by the throw
speed at the end. That is precisely January's shared `[-0x24..-0x19]` words, and it also explains the
vehicle-plus-retarget behaviour recorded by `actor_combat_obj_grenade_vehicle_semantic_withdrawal_20260905.md`.
**I did not build that arrangement.** The 20260905 audit records an explicit hold ("Do not restore the
point/vector cast or equivalent explicit position-as-velocity carrier"), and laws_w3 R13 makes older holds
binding on later waves.
### Owner ruling asked for (no header/config text)
Rule on whether `_actor_aim_grenade` may use a single working direction vector — the variable that receives
the prop body position (+0.2 z) for the retarget call and is then overwritten by
`actor->control.grenade_current_aim_vector` on the on-foot path — spelled with the already-admitted
`(real_point3d const *)` / `(real_vector3d *)` cast at the retarget call and a
`/* BUG (preserved for exact matching): ... */` note for the vehicle path (where January, like the current
tree, reads the working words without writing them when no retarget happened).
- For: HCEA's independent lift has exactly this shape; it is the only hypothesis that explains January's frame
without an allocator coincidence; the current tree *already* contains the same uninitialised-read path, so
the ruling does not add undefined behaviour, it only changes which variable carries the value.
- Against: brief section 5 forbids representation punning, and the 20260905 audit withheld semantic acceptance
pending a release-time `vehicle_index == NONE` lifecycle proof.
- If allowed: replay g4's `aim_speed` local on top and re-gate; expect the frame to close to 0x24, leaving only
the facing-address CSE (item 2) to adjudicate. 544 padded bytes are at stake.
## `_actor_combat_plan_grenade_trajectory`: A24 confirmed on a pointer parameter
The park is recorded as `register-allocation` with the criterion "authoritative source or a natural
same-compiler stack-lifetime donor". The w3 law A24 (parameter-home offer) is exactly such a donor and it
fires here: January's `&aim_gravity` is `lea edx,[ebp+0x10]`, the incoming home of the `grenade_target`
pointer parameter, which is enregistered into EDI on the entry path; ours allocates a seventh cell
(frame 0x34) and shifts every local by 4.
| shape | result |
| --- | --- |
| `p1` aim_gravity declared first among the scalars | byte-identical (18 hunks / 20 lines) |
| `p2` declarations in the callee's out-parameter order | byte-identical |
| `p3` nested `if`s instead of the `&&` chain | byte-identical |
| **`p4` entry copy `real_point3d const *grenade_target_position = grenade_target;` (2 genuine uses)** | **frame 0x30, all slots match, 18 hunks -> 6, 20 -> 5 lines; 288/5 sha `7454798a13f3419b`** |
| `p5` p4 + the ignore-index store moved after the aim-vector assignment | same 6/5 (store order between fields of one base is canonicalised) |
| `p6` p4 + declaration-order store block | worse (8/6/6) |
What remains under p4 is a 12-byte-copy scheduling tie: January loads `aim_vector.i` and `.j` before the first
store, interleaves the `grenade_current_ignore_object_index` store between `.i` and `.j`, and sinks the `.k`
store past the speed and lob stores. Store-order permutations are measured inert, so no source statement order
reproduces it.
Not proposed as a reopen: p4 is not strict exact, and a bare pointer rename of a parameter is R16-adjacent
(A24's landed precedent `real v_max = base_velocity;` had a semantic role that this alias lacks). The park stays
locked and undrifted.
**Refined reopen criterion** (for `config/parked.json` if the orchestrator wants it recorded): the frame half
is solved by an A24 parameter-home copy; the remaining blocker is VC7's load-ahead pipelining of a 12-byte
struct copy, which is *the same* tie as the whole residual of `_actor_aim_projectile`. One donor closes both
(288 + 720 = 1,008 padded bytes).
## `_actor_combat_reaim_grenade`
January's frame 0x2c packs `aim_gravity` into the dead `aim_vector2d.j` cell `[ebp-0xc]`; ours (0x30) gives it
its own cell and additionally ranks `aim_ticks` above `aim_vector2d` where January's ranking follows the
refs/size rule. Three scope/declaration shapes were measured, all byte-identical to the park body:
`r1` (declare `aim_vector2d` inside the `projectile_aim` block — laws_w2 A6 nested-block packing side law),
`r2` (hoist `aim_velocity`/`aim_gravity` to function scope), `r3` (swap the inner declaration order). With w1's
`g1` (gravity as the `?:` argument temp) that is four inert probes; the packing decision has no source lever we
can find. Park unchanged, criterion unchanged.
## `_actor_aim_projectile` and `_actor_combat_find_nearby_target`
- `aim_projectile`: 6 hunks / 5 lines, all of it the two transposed instructions of the
`actor_debug_info->field_98 = weapon_vector;` copy (January hoists the `.j` load above the `lea` and sinks the
`.j` store past the `field_88` byte store). The park already spent the statement-order matrix; no w2/w3 law
fires (A20 is satisfied, A31(c) needs a parameter-based base). Same behaviour as the plan residual above.
- `find_nearby_target`: unchanged 2-instruction x87 tie (January keeps `distance` live to an explicit
`fstp st(0)`; VC7 folds the last use). New context: the *inverse* of this decision appears in
`_actor_aim_grenade`'s magnitude block (January folds, ours pops), so operand order does not control the
fold; both spellings exist in this one object with opposite outcomes. No shape spent.
## `_actor_start_burst`
Skipped as exhausted: 5 shapes in w1, 9 in the 100K lane and the PDB lane's flips/scoping/`*=` matrix are all
on do-not-repeat lists, and the recorded reopen criterion (a spelling that spills `limit*1.5f` to memory before
the compare yet still sources the origin-radius store from the x87) is not produced by any w2/w3 law. The
"write the capped expression twice" idea is already the shape in the tree.
## Hygiene observation (not landed; laws_w3 E18)
`g2` removes the per-TU `#define cross_product2d cross_product2d_inline` rename *and* the hand-written TU-local
`cross_product2d` definition, calling the genuine `real_math.h` helper at the one site whose expression is a 2D
cross product (`_actor_aim_grenade`'s `counterclockwise`). All 34 rows stay byte-identical, `_cross_product2d`
stays EXACT (now as the header's select-any COMDAT), and the A30 rename defect disappears. Evidence that
January's source really called the helper there: `_cross_product2d` is an owner of January's object
(file offset 0000F9B0) with **zero** call relocations anywhere in the object — a non-static `__inline` emits its
surplus COMDAT only when it is used, so the call site exists and VC7 inlined it. Not landed because brief
section 8 requires an empty file diff in a unit where nothing lands; the orchestrator can take it as a
hygiene hunk. Caveat: it moves the COMDAT's section position earlier in the object (section 8 vs 39; January
has it at 15, adjacent to the trig wrappers and `_add_vectors3d`, which matches the current TU-local position).
## Reopen criteria (summary)
- `_actor_aim_grenade`: owner ruling on the single working direction vector (then replay `g4`), or a donor for
VC7's struct-field address CSE (`lea` + `[reg]` operands) without a helper call.
- `_actor_combat_plan_grenade_trajectory` / `_actor_aim_projectile`: a donor for VC7's load-ahead pipelining of
a 12-byte struct copy. The plan frame is solved by an A24 parameter-home copy (`p4`).
- `_actor_combat_reaim_grenade`: a donor that packs a scalar local into the dead half of an in-scope aggregate.
- `_actor_combat_find_nearby_target`, `_actor_start_burst`: unchanged.
@@ -0,0 +1,156 @@
# `bitmap_utilities.obj` second pass — opus5 250K lane, wave w3c (2026-09-15)
## Result
The real file `source/bitmaps/bitmap_utilities.c` is **unchanged** (`git diff --stat` empty). Final real-file gate is
identical to baseline: `== exact 43 residual 5 unwritten 0`, `_point_from_line3d` guard passes, park drift 0,
owner census identical to `build/base`, fake scan 0 leads.
The wave produced one **strict-exact scratch body** and one **strictly-closer scratch body**, both blocked from
landing by a single sibling regression, plus a new measured VC7 law and a TU-context diagnosis.
| Function | Padded | Baseline | This wave (scratch) | Status |
| --- | ---: | --- | --- | --- |
| `_bitmap_2d_smooth` | 1136 | 1120/27 `50140a12` (park) | **1136/27 `90b74220` = target, strict EXACT** | reopen proposed, BLOCKED |
| `_bitmap_3d_smooth` | 1824 | 1792/28 `dc74abcc` (park) | 1824/28 `f8881250`, 608 of 610 instructions identical | strictly-closer re-baseline |
| `_bitmap_2d_alpha_bleed` | 560 | 560/24, 1 reload transposition | 5 shapes, all byte-identical or worse | tie budget spent |
| `_bitmap_2d_sharpen` | 1152 | 1184/29, 47 hunks | no shape spent; 4 new byte facts recorded | keystone, criterion unmet |
| `_bitmap_sharpen` | 352 | 352/23, normalized sha **equal** | none possible | tooling/owner |
Scratch candidates: `scratch/workers/w3c_bitmap_utilities/` (`m4.c` = 2d_smooth reopen only; `m7.c` = + 3d_smooth;
`m10.c` = m7 + the 16-site assert-cast authenticity fix; `h1.c` = HEAD + that fix alone).
Worker notes with every shape and measurement: `scratch/workers/w3c_bitmap_utilities.md`.
## Baseline and duplicate prevention
Baseline rows (January padded / tags): `_bitmap_2d_alpha_bleed` 560 [sha]; `_bitmap_2d_sharpen` 1152
[size 1184!=1152, sha]; `_bitmap_2d_smooth` 1136 [size 1120!=1136, sha]; `_bitmap_3d_smooth` 1824
[size 1792!=1824, sha]; `_bitmap_sharpen` 352 [reloc-identity]. All five are parked; parkcheck drift 0 at baseline.
Read first: all eight `bitmap_utilities_obj_*` ledgers (w1 150K, smooth/sharpen completion, selective donor
reconciliation, the four jonas ledgers), the w1 worker notes `scratch/workers/bitmap_utilities.md` with its
do-not-repeat list, the 150K checkpoint, `scratch/w2/laws_w2.md` (A1-A22, R1-R12) and `scratch/w3/laws_w3.md`
(A23-A45, R13-R19). `git log --all --oneline -- source/bitmaps/bitmap_utilities.c`: 13 commits, none newer than the
w1 landing; w1's `branch_sweep.py` found no blob better than current. The three functions w1 reopened
(`_bitmap_2d_shrink`, `_bitmap_3d_shrink`, `_bitmap_2d_uncompress_from_mipmap`) are inherited exact and are not
re-claimed here. No C4013/C4133 site exists in this unit (`scratch/gate4/c4013.txt`).
## New law: NAMED-TEMPORARY NORMALIZER (refines laws_w2 A12 / A5; answers the w1 reopen criterion)
**Law.** For a loop-invariant round-and-shift normalisation `(sum + (1 << (2*n - 1))) >> (2*n)`, VC7 assigns the
registers and the two spill slots from the *expression structure*, not from the declaration:
- written as **one expression** (the natural spelling, repeated per channel or through a function-like macro), the
`2*n` CSE is created first and stays in its own register in place — January's
`movsx eax,di; add eax,eax` ... `mov esi,1; shl esi,cl`, slots shift `-0x24`, rounding `-0x28`;
- written as **two named `long` locals** (`shift = 2*n; rounding = 1 << (2*n - 1);`), the doubling is moved out with
`lea esi,[eax+eax]` and the `1 <<` temp takes EAX — registers **and** slots swapped, whatever the order of the
declarations or of the assignments.
**Controls measured this wave.** Declaration-order swap `long rounding, shift;` vs `long shift, rounding;` is
byte-identical (m1 vs m2), so *the slot follows the register, not the declaration*; the macro form alone on the
otherwise unchanged parked body already flips the preheader to January's exact register/slot assignment (m3), which
isolates the lever from the rest of the restructuring. w1's measured negatives stand and are explained by the law:
`rounding = 1 << (shift - 1)` and "no rounding variable" both fall back to 1120 because they still name a normaliser.
**Co-factors, each proven necessary** (removing either loses exactness): one `short x, y;` shared by both passes,
declared at the `if (width >= filter_size && height >= filter_size)` block (m5 = 1136 [sha]); and the coefficient
read placed **after** the pixel load inside the tap loop (m6 = 1136 [sha]). Both were already evidenced by w1.
**Closures.** `_bitmap_2d_smooth` 1136/27, `alndiff` 376/376 instructions with zero non-artifact hunks.
The same three-part treatment of `_bitmap_3d_smooth` takes it from 1792/28 with 49 diff blocks to 1824/28 (January's
size and relocation count) with `alndiff` 610/610 and only two hunks.
## The blocker: a TU-context coin, and the 16 casts that currently buy an exact row
Every exact spelling of `_bitmap_2d_smooth` removes five declarators from the function, and that flips
`_bitmap_2d_uncompress_from_mipmap` (880, EXACT at baseline, **not** parked) to residual. Measured in five contexts
(m4, m7, m10, p1, p2), and the flip also occurs when only `_bitmap_3d_smooth` is reopened (m8). No spelling of
uncompress recovers it: u1-u4 permute every declaration order/grouping of its locals and are byte-identical.
Four rows of this object differ from January by **nothing except the order of two independent register reloads at a
join**, and in each case ours is the exact reverse of January:
| function | site | January | ours |
| --- | --- | --- | --- |
| `_bitmap_2d_alpha_bleed` | +0x191 | `ecx=[ebp-0x10]` (x), `eax=[ebp-0x20]` (x*4) | reversed |
| `_bitmap_2d_uncompress_from_mipmap` | +0x33a | `edi=[ebp-0x24]` (height), `ebx=[ebp+0x10]` (mipmap index) | reversed |
| `_bitmap_3d_smooth` (m7) | +0x522 | `edx=[ebp-0x40]` (-filter_size), `esi=[ebp-8]` (rounding) | reversed |
| `_bitmap_3d_smooth` (m7) | +0x601 | `esi=[ebp-8]` (rounding), `eax=[ebp-0x20]` (shift) | reversed |
Nine body-local shapes across three functions (alpha_bleed a1-a3/a5, uncompress u1-u4, 3d_smooth n2-n3) were
byte-identical: there is no body lever. The coin is set by TU-wide text — w1's definition-order reorder flipped
uncompress on; the 2d_smooth reopen, the 3d_smooth reopen, an unrelated alpha_bleed probe (a4) and the assert-cast
authenticity fix each flip it off.
**Critically, HEAD's uncompress exact row is bought with text January's own assert literals refute.** Sixteen
`match_vassert(file, line, <expr containing a no-op `(short)` cast>, "<same expr without the cast>")` sites exist in
this TU; the literal is January's stringised original, so January's source had no cast. Candidate `h1.c` = HEAD with
those sixteen sites rewritten as `match_assert(file, line, <expr without the cast>)` — nothing else changed — is
`42 exact / 6 residual` with park drift 0: the only row that moves is `_bitmap_2d_uncompress_from_mipmap`. So the
880-byte exact row at HEAD depends on sixteen reconstruction artifacts, and any authentic cleanup of this TU costs it.
**Emission-order evidence for the underlying gap.** The candidate's code-section order still differs from January's.
January defers `_bitmap_2d_height_map`, `_bitmap_3d_height_map` and all three `*_vector_map` statics past the colour
conversions and emits `_rgb_colors_interpolate`/`_and_scale` next to last; our object emits every static in plain
source order. The deferred set is exactly the two statics that call the `real_math.h` helpers (`cross_product3d`,
`normalize3d`, `fast_ftol`) plus their transitive same-TU callers — `_bitmap_cm_height_map`, which calls none of
them, is not deferred — and our object additionally **defines** the eight select-any COMDATs
(`_fast_ftol, _square_root, _scale_vector3d, _magnitude_squared3d, _magnitude3d, _normalize3d, _cross_product3d,
_valid_real`) that January references undefined. That is the header-inline linkage property (laws_w3 A30/A41 and the
header-inline-linkage law), which a worker cannot change from this `.c`.
## `_bitmap_2d_sharpen`: new byte facts (no shape spent)
The w1 reopen criterion ("evidence for why January keeps `temporary_pixels` out of EDI") is still unmet, and no law
in laws_w2/laws_w3 predicts which pointer wins a callee-saved register (A24 does not fire: no January temporary sits
in a parameter home here). Four facts were recovered for the next attempt:
1. January's prologue is `push ebx; mov ebx,[ebp+8]` and it shrink-wraps `push edi` to `+0xf1` inside the
allocation-success block: **`bitmap` owns EBX from entry, EDI is the `y`/`byte_index` web, and
`temporary_pixels` is never enregistered** (`mov [ebp-0x24],eax` at `+0xe4`, reloaded at `+0x158`). Ours is the
mirror image (`push edi; mov edi,[ebp+8]`, `mov ebx,eax` for `temporary_pixels`, `push ebx` at `+0xc4`).
2. The private ABI passes `negative_table` in ESI (`+0x87 test esi,esi`, ESI never pushed); both builds agree.
3. Loops 2 and 3 run as down-counters over `previous_row + byte_index` with `[ebp-0x28] = destination_row -
previous_row` (store `+0x312 mov [ebx+edx],cl`); ours picks `destination_row + x` as the IV representative, which
follows from fact 1 rather than from the kernel term order (w1 already refuted term order with a 417-order sweep).
4. The interior bound is a **16-bit** compare (`+0x25a cmp di,cx`) against `(4*width)-4` and loop 3 reuses that slot
`+= 4`, so the row bounds are short-typed; loop 1 rematerialises `4*bitmap->width + byte_index` from `[ebp+8]`
every iteration (`+0x23b mov ebx,[ebp+8]`), i.e. no long-lived row-size register.
This function is the only remaining structurally wrong body between `_bitmap_2d_smooth` and
`_bitmap_2d_uncompress_from_mipmap` in compile order and is therefore the most likely keystone for the coin class.
## `_bitmap_sharpen`: park evidence refreshed
`relocdiff` reports `size 352/352, relocations 23/23, sha equal`. Only two relocation **spellings** differ, both
resolving to the same image address: `+0x00a6` January `_bitmap_sharpen_negative_table+510` vs ours
`_bitmap_sharpen_positive_table-2` (3260670), and `+0x00bb` January `_extract_data+42` vs ours
`_bitmap_sharpen_negative_table-2` (3260158). The park evidence text is **stale**: it names the second January anchor
`_bss_0031bed4+42`; at this HEAD csplit spells it `_extract_data+42` (a symbol owned by another object). Because the
machine code is byte-identical, no source spelling can change the relocation's target address — this is purely
csplit's nearest-preceding-symbol choice (laws_w3 A45) and needs the comparator-side resolved-equal admission, an
orchestrator action with zero strict credit.
## Rejected / not proposed
- Landing `m4`/`m10` as-is: violates admission checklist item 2 (`_bitmap_2d_uncompress_from_mipmap` would go
exact -> residual). Reported as a blocked park-reopen instead.
- The 16-site assert-cast authenticity fix as a standalone hygiene landing: it costs the same exact row, and
brief section 8 forbids a byte-inert-only diff in a unit where nothing lands.
- Compensating for the coin by perturbing unrelated exact bodies (merging/splitting declarations elsewhere): that is
steering with no authenticity basis; not attempted beyond diagnostics.
- Any further body shapes on the four reload-transposition rows: nine measured-identical shapes say no body lever
exists.
## Reopen criteria
- `_bitmap_2d_smooth` (1136) and `_bitmap_3d_smooth` (1824): land the bodies in
`scratch/workers/w3c_bitmap_utilities/m10.c` together with whatever keeps `_bitmap_2d_uncompress_from_mipmap`
exact in the same context — most plausibly a correct `_bitmap_2d_sharpen` — or with an owner ruling that accepts
the exchange on the grounds that the HEAD row depends on sixteen casts January's assert literals refute
(net +1136 gained, -880 lost, and the 16-site cleanup comes for free).
- `_bitmap_2d_sharpen` (1152): a source-level reason for `bitmap` owning EBX and `temporary_pixels` staying in
memory; start from w1 `s5f.c` plus the four facts above.
- `_bitmap_2d_alpha_bleed` (560): TU-context only; do not spend body shapes again.
- `_bitmap_sharpen` (352): comparator-side resolved-equal admission.
@@ -0,0 +1,171 @@
# `game_engine.obj` opus5 250K house-clean lane, wave w3c (2026-09-15)
## Scope and provenance
- Translation unit: `source/game/game_engine.c` (the only file this worker edited).
- Target: `build/split/source/game/game_engine.obj` (January 2002 Xbox debug split) - the byte authority.
- Compiler: XDK 3911 VC7 13.00.9254, checked-in `build.ninja` flags; every candidate compiled through
`tools/campaign/gate.py --source` only. No ninja, configure, header or config edit.
- Lane: `C:\halo-worktrees\opus5-150k-house-clean-20260914`, branch `opus/250k-house-clean-20260915`.
- Ledgers read in full: `game_engine_obj.md` (GE01-GE31), `_codex_checkpoint`,
`_fable_salvage_admission_20260902`, `_fable_small_families_20260901`, the three `_jonas_*` ledgers,
`_opus5_fresh_graphs_20260914`, `_opus5_100k_waveC_20260914`, `_opus5_150k_w1_20260914`, plus the w1
worker notes (`scratch/workers/game_engine.md`) and the waveC/w1 scratch candidates.
- Laws applied as detectors over every non-exact row and the park: `scratch/w2/laws_w2.md` (A1-A22, R1-R12)
and `scratch/w3/laws_w3.md` (A23-A45, R13-R19).
- Per-function worker blocks: `scratch/workers/w3c_game_engine.md`. Harness:
`scratch/workers/w3c_game_engine/probe.py`; standalone compiler lab `scratch/workers/w3c_game_engine/lab.py`.
## Baseline and result
`python -B tools/campaign/gate.py source/game/game_engine --all --forbid-emitted-symbol _point_from_line3d`
```text
baseline == exact 174 residual 6 unwritten 0 (of 180 listed) guard passed
final == exact 174 residual 6 unwritten 0 (of 180 listed) guard passed
```
Row-by-row diff of the two `--all` listings, the only change:
```text
- residual 1152 _game_engine_generate_title_string [size 1088!=1152, relocs 70!=73, sha]
+ residual 1152 _game_engine_generate_title_string [sha]
```
No new strict-exact row (**newly_exact is empty**). Park drift 0/1, owner census PASS (41 inherited
candidate-only names equal `build/base`, none new, none missing), `tools/fake_match_scan.py` 0 leads,
`git diff --check` clean.
| Function | Outcome | Padded / relocs |
|---|---|---|
| `_game_engine_generate_title_string` | **FUZZY-LANDED** (zero credit, structural closure) | 1152 / 73 (target 1152 / 73) |
| `_drawline` | SKIPPED-EXHAUSTED (new mechanism recorded) | 112 / 7 |
| `_game_engine_post_rasterize_post_game` | NOT-LANDED (blocked on `_drawline`) | 2528 / 148 |
| `_game_engine_get_starting_location_rating` | SKIPPED-EXHAUSTED (EBX/EDI mirror) | 96 / 6 |
| `_default_starting_location_rate_function` | SKIPPED-EXHAUSTED (EBX/EDI mirror) | 176 / 10 |
| `_game_engine_should_spawn_player` (parked) | SKIPPED-EXHAUSTED (constant-register pinning) | 256 / 9 |
## Accepted control: the title-string team buffers are two `wchar_t[8]`
The previous body carried a hand-made storage union
(`union { wchar_t team_names[22]; struct postgame_statistic_entry entry; } branch_storage;` with
`&branch_storage.team_names[14]` for team 0) and per-arm `return`s. It was 1088/70 against a 1152/73 target
- 64 bytes and three call relocations short. The landed body removes the union entirely.
January's frame facts (`alndiff`, target offsets):
| Offset | Object | Evidence |
|---|---|---|
| `[ebp-0x330]` | `score_string[256]` | `lea eax,[ebp-0x330]` at 0x3d9 and 0x44b |
| `[ebp-0x130]` | `life_string[128]` | `lea eax,[ebp-0x130]` at 0xac/0xbd, terminator `mov word [ebp-0x32],0` |
| `[ebp-0x30]` | team 1 name buffer | `lea eax,[ebp-0x30]; push eax; push 1; call [ecx+0x54]` at 0x2d1 |
| `[ebp-0x20]` | `struct postgame_statistic_entry entry` (28 B) | 0x3ce, `rep movsd` ecx=7 at 0x3e8, 0x453 |
| `[ebp-0x14]` | team 0 name buffer | `lea edx,[ebp-0x14]; push edx; push 0; call [eax+0x54]` at 0x2c2 |
| `[ebp-4]` | `secondary_string` | stored at 0x22, reloaded at 0x31a/0x363/0x3aa/0x448 |
Frame `sub esp,0x330` = 512 + 256 + 44 + 4, so the two team buffers plus the entry cell occupy exactly
44 bytes with the entry cell (28 B) overlapping them. Measured allocator behaviour for this block pair:
- two **16-byte** buffers: the first one used is placed at `-0x14` (packed over the top of the
free-for-all `entry` cell) and the second below the entry cell at `-0x30` - **exactly January**;
- `[8]`+`[14]` and `[14]`+`[8]` (waveC G2a/G2b - declaration order is inert): the 28-byte buffer shares the
28-byte `entry` cell at `-0x20` and the 16-byte buffer drops to `-0x30`, i.e. the two teams swap slots;
- `[14]`+`[14]` (waveC G2c): frame 0x33c.
So `wchar_t team0_name[8]; wchar_t team1_name[8];` is the unique measured fit, and it is the natural
spelling: two same-sized buffers, one per team, each handed straight to `game_engine->format_team_name`.
The control flow is waveC's G2i shape, which the SINGLE-EXIT LAW (brief section 9) and January's bytes
require: every postgame arm falls into a shared `ustrncpy` + `title_string[79] = 0` + epilogue tail that
VC7 tail-duplicates into each arm (the previous per-arm `return` body could not produce the three extra
`ustrncpy`/terminator copies, which is where the 64 bytes and 3 relocations were missing). HCEA
`game/game_engine_generate_title_string.c` uses the same `switch (did_win)` over the tri-state result.
Result: 1152/73, `relocdiff --count-by-target` 73/73 with 0 differing rows, frame and every stack slot equal
to the target, **391/391 instructions with a single transposed pair**:
```text
target 448 mov edx,[ebp-4] | 44b lea eax,[ebp-0x330] | 451 push edx | 452 push eax
ours 448 mov edx,[ebp-4] | 44b push edx | 44c lea eax,[ebp-0x330] | 452 push eax
```
That is the last free-for-all `usnprintf`. January emits `mov; push; lea; push` (our order) at both team
`usnprintf` sites (0x31a, 0x3aa); the free-for-all site is the only one whose next argument is a
register-ABI static call (`get_place_string(&entry)`, `lea eax,[ebp-0x20]; call`). A standalone lab TU
(`scratch/workers/w3c_game_engine/l2.c`, `l3.c`) reproduces our order and shows VC7 hoisting a different
argument-input load into the same `mov`/`push` gap, so the remaining difference is a gap-filling scheduler choice on
an identical DAG, not a structural or store-order fact.
Landed under brief section 6 (structurally incomplete row, zero credit): the body is complete, natural,
strictly closer in every measure, and no sibling, park, owner or fake-scan status changes.
## Experiment matrix (this wave)
| ID | Function | Shape | Result | Decision |
|---|---|---|---|---|
| p1 | generate_title_string | G2i control flow + `team0_name[8]` / `team1_name[8]` | **1152/73, 391/391, 1 insn** | landed (as p2) |
| q1 | generate_title_string | p1 + `&score_string[0]` argument | identical | rejected |
| q3 | generate_title_string | p1 + swap `life_string`/`score_string` declaration order | identical (slots unchanged) | rejected |
| q4 | generate_title_string | p1 + `score_string` declared in the free-for-all block | identical (frame preserved) | rejected |
| p2 | generate_title_string | p1 minus a stray blank line | identical | **landed** |
| inc1 | whole unit | `#include "main/console.h"` (the C4013 at game_engine.c:3806) | all 180 rows identical | not landed (see below) |
| d1 lab | drawline | 12 ordinate spellings in one lab TU | 11 straight-line spellings identical to ours | rejected |
| l1-l4 lab | generate_title_string | free-for-all call shape in a standalone TU | reproduces our push order | diagnostic |
## Residual classification
- `_game_engine_generate_title_string`: argument-schedule tie (one transposed pair). Structural debt closed.
- `_drawline`: **new mechanism.** January computes `row*9` twice (`lea edx,[esi+esi*8]; shl edx,1` for `y0`,
then `lea eax,[esi+esi*8]; lea ecx,[eax+eax+0x1a]` for `y1`); ours keeps `row*18` alive in EAX and adds
0x1a. Twelve arithmetic spellings compiled in one lab TU (`d1.c`: `(row+1)*18+8`, `row*18+26`,
`18*row+26`, `row*9*2`, `2*(row*9)+26`, named `short` ordinate, reversed statement order,
`(short)(row*18)+26`, `(short)((row+1)*18)+8`, `row*18+18+8`, `(row*2+2)*9+8`) all emit our bytes, so the
arithmetic spelling is not the lever. The real difference is where the `justification` argument load
(`mov edx,[ebp+0xc]`) is scheduled: January puts it *between* the two ordinate stores, which frees the
register holding `row*18` and forces the rematerialisation; ours issues it first, right after
`offset_rectangle2d` returns. Class: argument-load scheduling / rematerialisation tie.
- `_game_engine_post_rasterize_post_game`: six inlined `drawline` copies carry the same rematerialisation
gap, plus the EBX/EDI colouring of the hoisted 350/500 and 0/1 constants and the `entry_count` spill
order. Best body remains waveC P22 (`scratch/workers/game_engine/pr_p22re.c`, 2528/148, 751/752
instructions, frame 0x670 and every slot equal); it is not strict exact and the row is `[sha]` only
(size and relocations already match), so section 6 does not admit a fuzzy landing.
- Rating pair: private-ABI mirror only - January keeps `player_index` in EBX, ours in EDI (plus one
`mov eax` vs `mov ecx` in the callee). 46/46 and 72/72 instructions, everything else equal.
- `_game_engine_should_spawn_player` (parked): January widens the boolean TRUE store to `mov ebx,1` and
then spends EBX as the 32-bit compare operand for `respawn_timer == 1`; ours writes `mov bl,1` and
rematerialises `cmp eax,1`. Recurring constant-register pinning; no w2/w3 law explains it.
## C4013 census item (orchestrator lead)
`game_engine.c(3806): warning C4013: 'console_printf' undefined`. The genuine owner header is
`source/main/console.h` (`void console_printf(boolean clear, const char *format, ...);`). The call sits in
`_game_engine_update_teleporter`, which is **already strict EXACT** with the implicit declaration, and the
measured include (`scratch/workers/w3c_game_engine/inc1.c`, `#include "main/console.h"` before
`"main/main.h"`) leaves **all 180 rows identical**. It therefore unlocks nothing and is not landed here;
it is available as a byte-inert hygiene hunk if the orchestrator wants the warning gone (laws_w3 E18 class).
## Do-not-repeat (adds to the w1/waveC lists)
- generate_title_string: q1 (`&score_string[0]`), q3 (buffer declaration order), q4 (free-for-all-block
`score_string`) - all byte-identical to p1; do not re-spin team-buffer sizes: `[8]`+`[8]` is the fit,
`[8]`+`[14]`, `[14]`+`[8]`, `[14]`+`[14]` and `team_names[22]` are measured.
- drawline: the twelve `d1.c` lab spellings; no arithmetic spelling defeats the CSE.
- rating pair, should_spawn: no shapes spent; the recorded ties are unchanged and no law fires.
## Reopen criteria
- `_game_engine_generate_title_string`: a measured VC7 control that moves the `lea` of a stack array above
the `push` of a spilled pointer when the next argument is a register-ABI call. Apply it to
`scratch/workers/w3c_game_engine/p2.defs`; everything else is already byte-identical.
- `_drawline` / `_game_engine_post_rasterize_post_game`: a control that delays a stack-parameter argument
load past a store to an escaped local (freeing the ordinate register). Close `_drawline` first, then
re-gate P22.
- Rating pair: a callee register-pressure lever that moves an incoming private-ABI parameter from EDI to EBX.
- `_game_engine_should_spawn_player`: a measured control where a boolean TRUE store is materialised as a
32-bit constant register reused by a later int compare.
## Disposition
Real file stays 174/180 strict exact (no credited bytes this wave). `_game_engine_generate_title_string` is
now structurally complete (size, relocations, frame, slots and 390 of 391 instructions equal to January) and
free of the storage union; the object stays `NonMatching` and active.
@@ -0,0 +1,73 @@
# Opus5 250K house-clean lane: checkpoint ledger (2026-09-15)
Continuation of `opus/150k-house-clean-20260914` (HEAD `0483bde89`, +89,085 strict meaningful) on branch
`opus/250k-house-clean-20260915`, in the same worktree `C:\halo-worktrees\opus5-150k-house-clean-20260914`.
Lane base snapshot: `scratch/claude150k-before.json` (commit `12f7375d4`, 7,149 functions / 1,244,970 meaningful).
Target: +250,000 strict meaningful (`scratch/lane_manifest.py`: `TARGET = 1494970`, remaining computed against 250,000).
## 1. Startup proof (2026-09-15, at 0483bde89)
| check | expected | observed |
| --- | --- | --- |
| tracked tree / HEAD | clean / 0483bde89 | clean / 0483bde89 |
| `ninja` (incl. parked-function check) | pass | pass; "Validated parked compiler ties: 280" |
| stable diff `claude250k-start.json` vs `claude150k-before.json` | gained 144 90112; regressions 0; 8,245 / 7,263 | gained 144 90112 bytes; regressions 0; 8,245 functions, 7,263 exact |
| `tools.parked_functions` | 280 / 0 / 0 | 280 active / 0 stale / 0 invalid |
| `tools.audit_object_admission` | 0 contradicted / 7 rejected / 7 candidates | 0 / 7 / 7 |
| `pytest --basetemp scratch/pytest-250k-start` | 1151 passed, 5 skipped | 1151 passed, 5 skipped, 26 subtests passed |
| `lane_manifest.py` strict_new_meaningful | 89,085 | 89,085 (144 fns, 90,112 padded; 4 non-strict accepted / 2,195 excluded) |
## 2. Owner rulings (2026-09-15, asked at startup; strategy step A)
The owner took the strict option on every held item. Nothing below is landed or credited:
- collision_bsp `_collision_surface_test_sphere` (880; unit-local SSE `__asm` distance macro, p1.c): leave parked.
- env_fog 21-static .bss split (+800) and models 13-static .bss split (+1,296): neither lands.
- editor_flying_camera `is_scripted` linkage-anchor split (304; the w3 ledger says the split alone would also unlock
`_editor_camera_flying_update` 1,408 and `_editor_camera_set_scripted` 432): held.
- The 7 whole-object admission candidates: not admitted. P7 `projection_from_vector3d`: stays reverted, no worker spend.
These are recorded in `scratch/WORKER_BRIEF.md` section 9b as final for this lane.
## 3. Pool at HEAD (scratch/gate4, regenerated 2026-09-15)
`gate.py <unit> --all --forbid-emitted-symbol _point_from_line3d` over the 151 units with non-exact rows (no guard for
action_charge / ai_debug / real_math): 239,536 residual + 192,176 parked + 6,088 unwritten padded bytes. The 90 units
that never got a w3 pass hold 110,832 residual + 100,768 parked + 3,144 unwritten. After removing protected units,
`rasterizer_xbox_transparent_geometry`, do-not-spend, owner-declined/standing holds and laws_w2 D do-not-repeat rows,
`scratch/build_wave3c_groups.py` leaves 157,832 spendable padded bytes in 53 groups / 81 units.
## 4. Strategy step C: C4013 census (zero credit, analysis only)
`CL /Zs /W3` over all 468 source units (`scratch/gate4/c4013.txt`, 112 C4013 + 23 C4133 lines;
`scratch/gate4/c4013_map.json` maps each site to its caller and gate status). Outside libtiff, only 7 sites are inside
non-exact functions (7,392 padded): rasterizer_xbox_models `_rasterizer_model_draw_environment_shader` (park),
action_vehicle `_action_vehicle_evaluate_seat`, light_volumes `_light_volume_render` (park), hud_weapon
`_render_grenade_hud` (`weapon_prevents_grenade_throwing` has no owner prototype), ai_communication
`_ai_communication_update_speech_timers` (park), action_uncover `_action_uncover_perform` (park), main
`_main_game_render` (park). All 7 were already in the w3 census; the un-run units carry them in their w3c group notes.
The other sites are in functions that are already exact (a prototype there is a regression risk, not a lever).
## 5. Strategy step D: static-linkage census (negative)
`scratch/gate4/static_census.py`: 53 external data symbols in January split objects with no January PDB public and no
cross-object relocation, referenced by at least one non-exact function at HEAD (74,880 B of referencing rows, double
counted). A scratch csplit with 50 of them `"static": true` (placeholder `_data_`/`_bss_` names excluded) changed
only the 33 owner objects (`scratch/static_probe/changed_objects.json`).
- Config only (HEAD objects vs the static split): 0 rows changed in all 33 units.
- C `static` added to the definition (tentative COMMON becomes a defined .bss symbol; storage 3 verified in the
candidate objects) with the matching static split: **0 rows changed** in sound_manager, virtual_keyboard,
stack_walk_windows, actor_perception, weather_particle_systems, rasterizer_xbox_active_camouflage, draw_string,
dead_camera, render_particles, props, shader_transparent_chicago_preprocessor, debug_memory, key_agreement,
bitmap_utilities (both tables), rasterizer_transparent_geometry (5 globals), rasterizer_xbox.
- game_engine_king `king_globals` static with the (single-consumer) header extern removed: gains nothing and loses
`_find_next_hill` (112) and `_king_engine_initialize_for_new_map` (272). Same as the w2 static probe.
- Already `static` in C (config flip only, byte-inert): collision_debug x2, rasterizer_lights x4, player_effects x2,
profile_globals, dsound_error_string.
- Not probed: `extern` layout-anchor declarations inside their own .c (ui_widget_globals_storage,
dsound_effects_image, bink_playback x3, xbox_sound_cache_globals); editor_camera_* (owner-declined split); the
header-extern globals lightning, light_volumes, race (w2 measured them as no effect), director x3 (rows are
R3/A17 ruling-blocked) and game_globals (`_game_load` 208).
Conclusion: at HEAD the static-linkage law has no remaining closures for these residuals.
@@ -0,0 +1,143 @@
# `rasterizer_frame_statistics.obj` — opus5 250K lane, wave w3c (2026-09-15)
## Verdict
**No production source change; zero new strict bytes.** All three non-exact rows were re-examined with the
w2/w3 law set as detectors. Two are closed with law-based refutations of their only remaining candidate
shapes; the third (`count_static_vertices`) advanced from "unclassified callee-save schedule" to a fully
decoded two-clause mechanism with two scratch bodies that sit one hunk from exact, but no house-rule-admissible
spelling reaches it. `git diff --stat -- source/rasterizer/rasterizer_frame_statistics.c` is empty.
## Baseline and final gate
`python -B tools/campaign/gate.py source/rasterizer/rasterizer_frame_statistics --all --forbid-emitted-symbol _point_from_line3d`
| Function | Target | Candidate | Tag | Wave outcome |
| --- | ---: | ---: | --- | --- |
| `_eat_my_shorts` (parked) | 32 / 0 | 16 / 0 | size, sha | SKIPPED-EXHAUSTED (A42 refutes the last shape) |
| `_rasterizer_frame_statistics_count_static_vertices` (parked) | 64 / 0 | 64 / 0 | sha | NOT-LANDED (mechanism decoded) |
| `_rasterizer_frame_statistics_draw` | 4176 / 322 | 4176 / 322 | sha | SKIPPED-EXHAUSTED (C2 allocator tie) |
Baseline and final are both `== exact 7 residual 3 unwritten 0`, guard passed. `tinfo` confirms the object has
exactly these 10 functions, none unwritten and none a `_code_` placeholder, so this wave had no callee-first
work available. `scratch/parkcheck.py` reports parks 2 / drift 0; `tools/fake_match_scan.py` 0 leads; owner
census unchanged (no source change). Inherited exact and never re-touched:
`_rasterizer_frame_statistics_get_fps` (100K lane, 384/21).
Evidence read: all 10 prior object ledgers, `scratch/workers/rasterizer_frame_statistics.md` (w1),
`scratch/ghidra/out/rasterizer_frame_statistics.obj.decomp.c`, `scratch/atlas/rasterizer_frame_statistics.obj.txt`,
HCEA `blam/rasterizer/rasterizer_frame_statistics_count_static_vertices.c`, `scratch/gate4/c4013.txt`.
Two evidence cautions recorded for later waves: (1) the atlas records for this object are Halo-CE map entries
(`@rasterizer_frame_statistics_count_static_vertices@8`) — the `@N` decoration is the CE build's fastcall and
must not be read as a January calling convention, whose bytes are plain cdecl `[ebp+8]`/`[ebp+0xc]`;
(2) the HCEA body is a retail stub (`return 0;`) and carries no January topology.
## 1. `_rasterizer_frame_statistics_count_static_vertices` — mechanism decoded, still parked
January's complete stream (decoded this wave):
```
0 push ebp 14 mov cx,[edx] 26 test cx,cx
1 mov ebp,esp 17 cmp cx,1 29 jne 0x2e
3 mov edx,[ebp+8] 1b jne 0x26 2b mov eax,[esi+4]
6 xor eax,eax 1d mov eax,[edx+4] 2e pop esi
8 test edx,edx 20 add eax,2 2f nop
a je 0x30 23 pop esi 30 pop ebp
c push esi 24 pop ebp 31 ret
d mov esi,[ebp+0xc] 25 ret
10 test esi,esi
12 je 0x2e
```
January shrink-wraps `push esi` past the `triangle_buffer` test and splits ONE epilogue into two entry points
(0x2e for the paths that pushed esi, 0x30 for the `triangle_buffer == NULL` path); the `nop` at 0x2f is
jump-target alignment for 0x30. Detectors that confirm the current source is right in every other respect:
A42 (the entry `xor eax,eax` before the first test proves the declaration initializer `long vertex_count = 0;`),
A18/A34 (`mov cx,[edx]`, `cmp cx,1`, `test cx,cx` prove the 16-bit `type` field and the strip-then-triangles
order). Ghidra's `return *(int *)(param_1 + 2) + 2;` is the duplicated epilogue at 0x23, not a source return.
Shapes measured in scratch (`scratch/workers/w3c_rasterizer_frame_statistics/`, all gated with `--source`):
| Shape | Form | Result |
| --- | --- | --- |
| t1 | `if (!triangle_buffer) { return vertex_count; }` then `if (vertex_buffer) {...}` | 64/0; **push esi sinks exactly like January**, entry eax=0 reused (no remat); early exit laid out inline at 0xc (`jne 0xe; pop ebp; ret`) instead of jumping to the bottom tail — 1 hunk |
| t2 | two separate early returns | 64/0; two inline exit blocks, worse |
| t3 | nested `if (tb) { if (vb) {...} }` | v0 fixed point (push esi at 0xa) — re-confirms the park note |
| t4 | nested + `return vertex_count;` at the end of the tb block + final `return vertex_count;` | **22 of 23 code instructions identical incl. `je`→bottom and `push esi` at 0xc**; the bottom block rematerialises `xor eax,eax` instead of sharing January's tail — 1 hunk (control only: double return) |
| t5 | `if (!tb \|\| !vb) { return vertex_count; }` + flat if/else-if | sink lost, separate `xor eax,eax; pop esi` tail, worse |
| t6 | t4 with the inner return inside the `vertex_buffer` block | sink lost (vb-null path reaches the bottom with esi pushed), worse |
**Candidate law A46 (two clauses, measured here):**
(a) VC7 sinks a callee-save `push` past the first test only when that test's exit is a *separate return
statement* whose block never touches the register; with `&&` or a nested guard the exit is the shared epilogue
that pops the register, so the push can only sink to the end of the entry block.
(b) A return statement laid out at the BOTTOM whose value is a compile-time constant on that path
rematerialises the constant in its exit block; a return laid out immediately after the definition reuses the
entry definition.
January needs (a) while keeping the entry `xor eax,eax` live to 0x30 — one exit edge that is separate for
register-save purposes but is not a second `return` statement in the source. t1 satisfies the value half,
t4 satisfies the placement half, and nothing admissible satisfies both: the only bottom-placed forms are
double returns (R1/R12 class), and the park text already records the rejection of a same-size topology change
made "solely to steer code generation" (R13 binds it).
**Reopen criterion (sharpened, replaces "explain the delayed ESI save"):** an authentic January spelling that
gives the `triangle_buffer`-null path its own register-free exit edge without a second `return` statement
(January source/local records, or an authenticated guard idiom), or evidence that this TU's C2 state rather
than its source picks the sink. Re-measure `t1.c` and `t4.c` first — each is one hunk from exact.
## 2. `_eat_my_shorts` — exhausted, and the last candidate shape is now positively refuted
January: `mov ax,[ebp+8]; cmp ax,[ebp+0xc]; jbe 0x11; mov al,1; pop ebp; ret; 0x11: xor al,al; pop ebp; ret`.
`jbe` proves unsigned `word` operands and the `first > second` polarity with TRUE as the fall-through (the
current source is correct); the 8-bit constants prove the `boolean` return. VC7 if-converts every natural
spelling to `seta` (16 B).
The only 32-byte shape ever produced, w1's `boolean result = FALSE; if (first > second) result = TRUE;
return result;`, puts the zero at the entry and emits a single epilogue. **A42 refutes it from January's own
bytes**: VC7 does not hoist a constant into the entry, so January's `xor al,al` sitting in the branch target
proves there is no initializer at all. A38 gives the same conclusion (an initializer declared in the enclosing
block is emitted between the compare and the jcc). A3/A29 (single exit), A10 (conditional initializer),
A23/A39/A40 (loop/switch/inline-helper levers) and A43 (tail duplication has no source lever) do not fire —
this function has no call, loop, switch or helper. w1's k=1..46 declaration sweep already showed the row is
not TU-state dependent. The reachable natural set is {16 B `seta`, 16/32 B `sbb/neg`, 32 B entry-zero
single-epilogue}; January's form is in none of them.
Reopen criterion unchanged: authoritative January source/local records, or a natural same-compiler context
that suppresses the setcc if-conversion while keeping both epilogues and the late `xor al,al`.
## 3. `_rasterizer_frame_statistics_draw` — C2 allocator tie, donor match proven unreproducible
The residual is 3 sites / 6 instruction rows, all in the opening aggregate sums: 0x6e/0x7e/0x8d (statistics
`+0xB0`/`+0xA0`), 0xca/0xd3/0xd9 (`+0xA8`/`+0xB4`) and 0x10f/0x117/0x197 plus 0x19a/0x1a0/0x1a6/0x1a8/0x1b1
(`+0xE4`/`+0xD8`, `+0xDC`/`+0xE8`, `+0xE0`). In every case both builds issue the same two loads in the same two
instruction slots and the same semantic operand order in the following `lea`/`add`; only the physical register
each load lands in is swapped (ecx<->eax, edx<->ecx), which renames the destination of the `lea`/`add` and one
store. The other 1,172 instructions are identical, and the remaining alndiff rows are `symbol:` versus
`defined-noncode:.rdata:` descriptions of the same literal owners (a `--source` gating artifact).
Detectors run, all negative: A35 (leaf age / dot canonicalisation is x87; these are integer register
assignments), A12 (not a loop preheader), A20/A44 (no stores or calls in the hunks), A24 (no parameters),
A6 (frame identical — the `[ebp-0x24]` store matches), A11/A36 (no float constant), A7 (this TU has no implicit
declaration; the only frame-statistics C4013 in the whole build is `rasterizer_xbox_models.c(1723)`, which is
packet E4 and unlocks 0 B).
New evidence: the historical reconciled donor body (blob `6dac0962`, commit `5d3444f79`) gates
`exact 6 residual 4` at this HEAD — i.e. **the donor draw is residual now** — and the original donor blob
`4168c4a3` (commit `7841c6ac3`, the "exact draw") no longer compiles against the shared owner header. The
20260906 hold's donor match is unreproducible in any form at this HEAD, which confirms it was TU/C2 state and
not source topology, and closes the "import the donor source" avenue for good.
Classification: C2 register-allocation tie, definition-position driven (C2 POGO attribution: the allocator
record carries no spill-cost field; zero-register pinning residual). The only known lever is declaration
count/order, forbidden by the 20260906 hold and measured by w1 as a lottery with no k in 0..48 reaching zero
hunks. Reopen only with an authentic January include/declaration environment for this TU (a preprocessed
listing or the original header set) or a January source record — and re-measure whenever a predecessor body in
this TU changes, because the pair lottery is coupled to them.
## 4. Proposals
No header or config change is requested by this wave. (`E4` — putting `rasterizer_xbox_models.c` on this
object's owner header — remains an owner decision worth 0 B and is not re-proposed.) Candidate law A46 above is
offered for `scratch/w3/laws_w3.md`'s successor; it is measured only on this function and should be narrowed
accordingly.
@@ -0,0 +1,142 @@
# `rasterizer_xbox_environment.obj`: opus5 250K house-clean lane, wave w3c (2026-09-15)
## Scope and provenance
- Translation unit `source/rasterizer/xbox/rasterizer_xbox_environment.c`, target
`build/split/source/rasterizer/xbox/rasterizer_xbox_environment.obj` (the January split COFF is the byte authority).
- Lane `opus/250k-house-clean-20260915` (continues `opus/150k-house-clean-20260914`). Worker-only measurements with
`tools/campaign/gate.py`, `tools.campaign.alndiff`, `tools.campaign.tinfo`, `scratch/parkcheck.py`,
`tools/fake_match_scan.py`. No ninja, header, config or tool edits; no other source file touched.
- Prior ledgers read in full: `_codex_small_exact_20260902`, `_diffuse_texture_reconciliation_20260909`,
`_lightmap_draw_fuzzy_20260912`, `_opus_reflections_reconciliation_20260909`, `_opus5_100k_20260914` (wave B),
`_opus5_100k_waveC_20260914`, `_opus5_150k_w1_20260914`; worker notes
`scratch/workers/rasterizer_xbox_environment.md`; the w1 verifier verdict in `scratch/w1/w1-results.json`.
- Laws applied as detectors: WORKER_BRIEF section 9, `scratch/w2/laws_w2.md` (A1-A22, R1-R12, D) and
`scratch/w3/laws_w3.md` (A23-A45, R13-R19, C, D).
- Worker notes for this wave: `scratch/workers/w3c_rasterizer_xbox_environment.md`;
scratch dir `scratch/workers/w3c_rasterizer_xbox_environment/`.
## Baseline and final gate (identical; nothing landed)
`python -B tools/campaign/gate.py source/rasterizer/xbox/rasterizer_xbox_environment --all --forbid-emitted-symbol _point_from_line3d`
**exact 42, residual 2, unwritten 0 of 44** - point guard passed, `scratch/parkcheck.py` 1 park drift 0,
`fake_match_scan.py` 0 leads, `git diff --stat -- source/rasterizer/xbox/rasterizer_xbox_environment.c` empty.
| Row | Target size/relocs/sha16 | Real file | Status |
| --- | --- | --- | --- |
| `__rasterizer_environment_lightmap_draw` | 4016 / 248 / 7818e559325c1524 | 3984 / 246 / 02f716db92e8099f | residual [size, relocs, sha] |
| `_rasterizer_environment_specular_spot_light_begin` | 960 / 64 / e0331f6b94a74f9c | 944 / 64 / d103843ee5f01bad | residual, PARKED |
Context: `__rasterizer_environment_diffuse_light_begin` (w1 park reopen) is EXACT at HEAD and
`_IDirect3DDevice8_SetTexture@12` is inherited exact; neither was revisited. The w1 `lightmap_draw` landing was
rejected by its verifier and reverted, so the row is back at the 100K baseline.
## `__rasterizer_environment_lightmap_draw` - SKIPPED-EXHAUSTED (0 shapes spent)
**What is left.** Against the wave-B candidate (`scratch/workers/rasterizer_xbox_environment/v0.obj`, 4000/248) the
entire remaining 16-byte / 2-relocation gap is the `t` argument of the two `_point_from_line3d` calls:
```
January @b88 fld dword [ebp-4] ; add esp,0xc ; lea eax,[ebp-0x5c] ; push eax ; push ecx ;
lea ecx,[edi+0x19c] ; fstp dword [esp] ; push ecx ; lea edx,[ebp-0x5c] ; push edx ; call
ours @b88 mov ecx,[ebp-4] ; lea eax,[ebp-0x5c] ; push eax ; push ecx ; ... (and one merged add esp,0x44)
```
Everything else in the self-illumination block already matches byte for byte: the three
`periodic_function_evaluate` argument stages, both `fld __real@3f800000; fsub [ebp-N]` scale arguments, both plasma
`push 0x3f800000` constants, and - decisively - the **integer** push `mov eax,[ebp-0x50]` of `plasma_value` into
`real_alpha_to_pixel32` in the same function. Same declaration class, same block, integer-copied: the trigger is not
the declaration of the local.
**New evidence gathered this wave.**
1. *January-wide census* (re-using the 100K lane's `fldscan.py` over every `build/split` object): of the 71 pure
`fld dword [mem]` -> `fstp dword [esp]` argument stages in the whole January image, only three read a STACK slot -
these two sites and `_ai_test_line_of_fire @70` (`[ebp+eax-0x4e4]`, an indexed stack array element). The other 68
stage a pointer field (`[reg+off]`). `lightmap_draw` is therefore a member of the unresolved x87-staged-real-argument
family recorded in `laws_w3` C3 (`_object_test_vector`, `_player_examine_nearby_device`, `_ai_test_line_of_fire`,
`_biped_update_moving`), not an isolated puzzle. The family's only known reproduction - a parenthesised argument
produced by a genuine macro - is measured INERT on a stack-local leaf (w1 p1 = 4000), so the `_object_test_vector`
form does not transfer here.
2. *Donor re-check.* Ghidra `scratch/ghidra/out/rasterizer_xbox_environment.obj.decomp.c:1416-1430` shows a bare local
copy for the `t` argument (`local_264 = (undefined4 *)local_8;`). HCEA's later-build
`_rasterizer_environment_lightmap_draw_pp.c:156-213` computes `on*blend + off*(1-blend)` componentwise with **no**
intensity term and copies the plasma colours directly. Both corroborate the w1 verifier's rejection of the constant
factor; neither satisfies the reopen criterion. The punpckhdq and Stian trees contain no body for this object.
**Detectors run, none fires.** A23 (no loop), A24 (frame 0x218 and all three value slots already identical),
A25/A29 (single return, no join store), A31(a) (the `add esp` flush positions already match), A33 (block scoping
without the factor measured 4000: w1 f2/g2n), A35 (not a commutative product), A36 (the constant is exactly 1.0f),
A38 (inner-block declare+init temporaries measured 4000: w1 f2), A42 (no store to prove).
**Why no shape was spent.** Every exact form on record (w1 c1/e2/f1/g2 and waveC k16/k17/k22) requires the constant
1.0 identity factor or an explicit cast on a c2-folded expression. The w1 verifier rejected that tree as fake
arithmetic and required a full revert including the wave-B hunks; R13 binds that rejection, and no w2/w3 law or donor
supplies a genuine intensity/brightness term or a double intermediate. Wave B's four structural corrections alone
reach only 4000/248 and cannot land for an already-written residual (brief section 6).
**Classification.** Unresolved source form (x87 argument staging), not a register tie.
**Reopen criterion.** Unchanged from w1 - January or donor evidence of a real intensity/brightness term or a
double/cast intermediate - OR an owner/policy ruling on the `laws_w3` C3 x87-staged-argument family that also covers
stack-local leaves. Start from `scratch/workers/rasterizer_xbox_environment/v0.c` (4000/248).
## `_rasterizer_environment_specular_spot_light_begin` - NOT LANDED (park locked; 1 shape, 2 refutations)
w1 closed the structural half in scratch: the frame is a `real_matrix4x3 matrix` whose `scale` (-0x34) and `position`
(-0xc) are never written (forward -0x30, left -0x24, up -0x18), and `s3a.c`
(`matrix.forward = light->forward; matrix.up = light->up; normalize3d(cross_product3d(&light->forward, &light->up,
&matrix.left));`) reaches 960/64 with frame parity and 15 small blocks left.
**Shape p1 (new, evidence-led, refuted).** `source/math/matrix_math.c:337-346` shows the house idiom for building a
basis - `matrix->forward = *forward; cross_product3d(...); matrix->up = *up;` - i.e. the up copy AFTER the cross.
Under A35 that should make `up` the younger leaf and flip the j/k operand order towards January's.
Measured (`scratch/workers/w3c_rasterizer_xbox_environment/p1.c`, `p1.obj`): 960 [sha], but structurally worse than
s3a - the i-term flips to forward-first (`fld [esi+0x14]`), the up copy is pushed past the cross and loses January's
`lea ecx,[esi+0x1c]; mov edx,ecx` twin-pointer form, and the `push ebx` prologue register disappears. This **refutes**
the matrix_math ordering for this function: January's interleaved twin-pointer copies require both copies before the
cross, exactly as s3a spells it.
**Two controls that pin the source form (no shape spent).**
- Re-reading w1's `s3b.obj`: taking the cross operands from the matrix members makes VC7 read the LOCAL slots
(`fld [ebp-0x10]; fmul [ebp-0x2c]`), whereas January reads light-relative addresses
(`[eax+..]`, `[ecx+..]`, `[esi+0x20/0x24]`). VC7 does not forward the struct copy, so January's cross arguments are
`&light->forward, &light->up`; every mixed spelling (`&matrix.forward, &light->up` and friends) is excluded by the
same address evidence.
- Sibling control inside this object: the EXACT `__rasterizer_environment_diffuse_light_begin` inlines the same
`real_math.h` `cross_product3d` from local matrix members, and January loads operand b (up) first in **all six**
products. The spot light loads b first in 5 of 6 (the exception is the i-term subtrahend, whose up operand is read
through the light base ESI before `lea eax` exists); s3a loads b first in only 2 of 6. The order tracks leaf age and
pointer availability inside the shared inline; this TU cannot change it without moving the operand addresses away
from January's.
**Remaining 15 blocks in s3a:** four cross-product `fld`/`fmul` operand orders, one eax/ecx/edx rotation in the
`light->position` copy, one `fxch st(1)` before the last vertex constant, and the `rasterizer_set_pixel_shader` push
placement - the last three all downstream of the operand order (the two x87 stack residents at the tail are
`cone_scale` and `radius*0.5f`, swapped only because of the earlier product order).
**Classification.** x87 leaf-age / allocator tie inside the shared `real_math.h cross_product3d` inline; the source
spelling is pinned by January's addresses; no TU-local lever remains. Do not re-spend on cross-operand permutations
(9 shapes total across w1 and w3c).
**Reopen criterion (refined; supersedes w1's).** w1 asked for "a natural cross-product spelling that loads up.i/up.j
first in the j/k terms"; this wave shows no such spelling exists from this TU. Reopen only on (a) a measured VC7 law
explaining the `fld` order for pointer-read commutative operands, or (b) an owner-approved `real_math.h`
`cross_product3d` change measured across its consumers - noting that the current k,j,i body is REQUIRED by the exact
sibling `__rasterizer_environment_diffuse_light_begin`, so any such change must keep that row exact. Best scratch body
remains `scratch/workers/rasterizer_xbox_environment/s3a.c` (960/64, frame 0x84, sha16 9c8a4202366a9d91).
## Rejected / do-not-repeat (added by this wave)
- The matrix_math.c copy/cross/copy ordering in the spot light (p1): structurally worse; both copies precede the cross.
- Cross operands read from the matrix members or from a mixed member/pointer pair: wrong operand addresses (s3b proof
that VC7 does not forward the struct copy).
- Re-proposing the constant `intensity = 1.0f` factor (or any identity/cast wrapper) in `lightmap_draw`: rejected by
the w1 verifier, corroborated as absent by HCEA and Ghidra; R13 binds.
## Proposals
None. No header, config, symbols.json or parked.json need arises from this wave; the park stays locked and the real
file is unchanged.
@@ -0,0 +1,197 @@
# `sound_manager.obj`: opus5 250K house-clean lane, wave w3c (2026-09-15)
## 1. Scope and provenance
- Translation unit `source/sound/sound_manager.c`; target `build/split/source/sound/sound_manager.obj`.
- Lane worktree `C:\halo-worktrees\opus5-150k-house-clean-20260914`, branch `opus/250k-house-clean-20260915`,
HEAD `0483bde89`. Compiler XDK VC7 13.00.9254 with the repository flags; no flag was changed or passed.
- Nothing was written to `sound_manager.c`, to any header, or to `config/*.json`. No ninja, configure, pytest or
git write command was run. `git diff --stat -- source/sound/sound_manager.c` is empty.
- Worker notes `scratch/workers/w3c_sound_manager.md`; candidates and dumps in
`scratch/workers/w3c_sound_manager/` (`base.obj`, `d1.c/d2.c`, `rl1.c`..`rl3.c` with objects,
`rl_target.txt`, `rl_ours.txt`).
- Evidence: January split-object bytes, relocations and section order (authoritative); HCEA
`cache/sound_dispose_from_old_map.c`, `cache/sound_refresh_looping.c`,
`game/update_channel_for_impulse_sound.c` (later build; semantics and corroboration only);
`config/parked.json` park entries; all ten earlier `sound_manager_obj_*` ledgers and
`scratch/workers/sound_manager.md`; `scratch/w2/laws_w2.md` and `scratch/w3/laws_w3.md` applied as detectors.
## 2. Baseline (unchanged at the end of the wave)
`python -B tools/campaign/gate.py source/sound/sound_manager --all --forbid-emitted-symbol _point_from_line3d`
reports `== exact 58 residual 7 unwritten 0 (of 65 listed)`; the guard passed; `scratch/parkcheck.py`
reports `parks 5 drift 0`; `tools/fake_match_scan.py` reports 0 review leads.
| Function | Target padded / relocs | Base | Tag | Park |
|---|---:|---|---|---|
| `_refresh_listener` | 496 / 25 | 496 / 25 | sha | - |
| `_sound_dispose_from_old_map` | 240 / 21 | 272 / 23 | size, relocs, sha | - |
| `_sound_find_like_channel` | 272 / 16 | 272 / 16 | sha | P |
| `_sound_refresh_looping` | 1136 / 43 | 1088 / 42 | size, relocs, sha | P |
| `_sound_set_definition_end` | 208 / 9 | 208 / 9 | sha | P |
| `_update_channel_for_impulse_sound` | 528 / 29 | 528 / 29 | sha | P |
| `_update_channel_for_looping_sound` | 1360 / 61 | 1376 / 61 | size, sha | P |
## 3. Result
Nothing landed. Two of the seven rows are unparked and both are measured ties or provably spelling-inert; three
parks are ties whose known levers are already measured; two parks are blocked on one owner ruling. The wave's
substantive result is on `_sound_refresh_looping`: a new, byte-proven structural finding that fixes the park's own
recorded blocker (the missing relocation) in scratch and sharpens the residual to a single register-colouring fact.
## 4. `_sound_refresh_looping` - new structural finding (scratch only, park untouched)
### 4.1 The missing relocation is a source fact, not a merge accident
`relocdiff --count-by-target` shows January with **four** `_sound_start_fade` relocations and the parked body with
three. The park entry itself describes this as "a compiler-merged duplicate fade-call tail". The merge is visible in
our object: the alternate-fade call site ends `push ecx; jmp 0x3bf` and lands inside the fade-in site's push
sequence. Its cause is the parked source's `real fade_in_time;` local: an if / else-if / else phi that is homed at
`[ebp-0x18]` (the extra frame cell - frame 0x18 against January's 0x14) and lets both arms share one call.
January's bytes give the authentic shape directly (0x2d2-0x305):
```
2d2 cmp word ptr [ebp+0x14], 0 ; refresh_state != _looping_sound_refresh_start
2d7 jne 0x2e7 ; -> inaudible arm
2d9 test byte ptr [edi], 1 ; TEST_FLAG(track->flags, _fade_in_at_start_bit)
2dc je 0x2fb ; -> no fade, straight to the store
2de mov ecx, [edi+8] ; track->fade_in_duration
2e1 push -1 / push esi / push ecx / jmp 0x2f1
2e7 mov edx, [_sound_inaudible_fade_out_time]
2ed push -1 / push esi / push edx
2f1 push 0 / call _sound_start_fade
2fb mov [ebx+eax*4+0xd4], esi ; *playing_sound_index = new_sound_index
```
Each arm builds its own argument triple and the two merge only at `push 0; call`. That is two source-level calls,
no `fade_in_time` local and no `continue`; the store is the common statement after the if/else-if.
HCEA's later build refactored this into one call with a `fade` local, so HCEA is not evidence here - January's
relocation count is.
Rewriting the block that way (`scratch/workers/w3c_sound_manager/rl1.c`) gives **1120 / 43 /
`035c62df5f0f973d`** from 1088 / 42: the relocation identity is now exact (43/43, per-target counts equal) and the
frame is exactly January's 0x14. All 58 exact siblings are unchanged; only this park drifts; fakescan is clean.
### 4.2 Exit decode: the remaining 16 bytes are one colouring fact
January has four epilogues:
| Address | Form | Reached from |
|---|---|---|
| 0x134 | `mov al,1` | the `component_sound_count == 0` datum_delete path |
| 0x448 | `xor al,al` | the `looping_sound_new` failure **and** the fall-through from the bottom of the enabled block |
| 0x451 | `mov al,cl` (`mov cl,1` hoisted at 0x84, before the found test) | the stop + not-found path |
| 0x45a | `mov al,[ebp-1]` | both disabled tests (`initialized`, `enabled`) |
`[ebp-1]` carries `result` at entry (`sete byte [ebp-1]` at 0x10) and is reused for `new_looping_sound`
(`mov byte [ebp-1],0` at 0x80, `,1` at 0xa5), so `result` is dead inside the enabled block - only possible for
locals in different nested blocks (laws_w2 A6 side law). HCEA's tail `return 0;` corroborates that the bottom of
the enabled block is an explicit `return FALSE;`, which is what shares the `xor al,al` epilogue with the
new-failed return; and the register-carried TRUE at 0x451 (rather than a second `mov al,1`) indicates a returned
variable constant-folded on that path.
Our build colours `result` into `BL` instead of spilling it. That single decision produces every remaining
difference: `source` is pushed out of EBX into ESI, ESI is then re-used for `definition_index` so `[ebp+0x10]` has
to be reloaded before `looping_sound_new` (January pushes EBX at 0x93), and every `return` of a register-carried
boolean merges with the disabled-path `mov al,bl`, collapsing January's four epilogues into three (the 16 bytes).
### 4.3 Shapes measured this wave (5, the whole budget)
| id | shape | size / relocs | verdict |
|---|---|---|---|
| rl1 | two separate `sound_start_fade` calls, no `fade_in_time` local, no `continue`, common store after | 1120 / 43 | best; relocs + frame exact |
| rl2 | rl1 + early `return result` + bottom `return FALSE` | 1104 / 43 | epilogues merge further |
| rl2a | rl1 + early `return result` only | 1104 / 43 | merges with the disabled-path exit |
| rl2b | rl1 + bottom `return FALSE` only (HCEA-corroborated) | 1104 / 43 | merges with the early FALSE exit |
| rl3 | rl2 + split declaration/assignment of `result` (A38 stack-home probe) | 1104 / 43 | inert |
### 4.4 Reopen criterion (replaces the w1 criterion)
A source-level fact that gives `result` a frame home shared with `new_looping_sound` at `[ebp-1]` - that is,
`sete byte [ebp-1]` at entry with EBX left to the `source` parameter - applied on top of `rl1.c` together with
rl2's exits (`return result` in the stop + not-found arm, `return FALSE` at the bottom of the enabled block).
Everything else in `rl1.c` is byte-proven. Do not re-spend the five shapes above, the waveC R1-R10 fade/stop-arm
variants, or the w1 S1-S8 return-materialisation variants.
### 4.5 Proposal (orchestrator; zero strict credit)
Re-baseline the `config/parked.json` entry for `_sound_refresh_looping` from `1088 / 42 / 4820b25c...` to
`rl1.c`'s `1120 / 43 / 035c62df...` and land the `rl1.c` body with that edit. It is strictly closer (size +32
toward 1136, relocation identity exact, frame exact), it resolves the mechanism the park entry itself names, and
it deletes an unnecessary local rather than adding anything. This is not the R11 pattern: it is strictly closer
and it is tied to the sharpened reopen criterion above.
## 5. The other six rows
### `_sound_dispose_from_old_map` (active residual, 240 / 21 vs 272 / 23)
Target and candidate are byte-identical through 0xa6, including the entire ten-instruction wait-loop test
(`call _system_milliseconds; test eax,eax; mov [ebp-8],eax; fild; jge; fadd __real@4f800000; fcomp [ebp-4];
fnstsw; test ah,5; jp exit`). January closes the loop with one `jmp 0x82` back to that test; our build duplicates
the whole test into the latch (`jnp 0xa1`), which is the +12 instructions, +32 padded bytes and +2 relocations
(one `_system_milliseconds`, one `__real@4f800000`). The same function shows January rotating the preceding fade
loop into a guarded do-while, so the decision is per loop, not per function. HCEA spells the wait loop exactly as
we do.
New negatives this wave: `for (; cond; ) { sound_idle(); }` (d1) and the A23 for-increment probe
`for (; cond; sound_idle()) { }` (d2) are both byte-identical to the baseline. Together with the four earlier
lanes (while, while + continue, `while (TRUE)` + real local, `for(;;)` + break, inline deadline, HCEA `any_sounds`
flag, captured `paused`, definition position, whole-TU compile-order reorder) this proves the loop **spelling** is
not the lever; the header duplication is decided after the IL. Reopen: an exact January sibling whose
`while (call() < real)` loop keeps a single header copy, with a nameable source cause.
### `_refresh_listener` (active residual, 496 / 25, 178/178 instructions)
One transposition at the loop latch: January `mov edi,[ebp-4]; mov esi,[ebp-8]`, ours the reverse (the two loop
IVs reloaded after `matrix4x3_inverse_transform_vector`). Detector pass over laws_w2/laws_w3: A24 does not fire
(no parameter home is involved, both IVs own cells), A12 is about preheaders, A6 does not fire (frames are equal),
A20 needs stores. Declaration order, in-loop declaration, void single exit, the HCEA inverted arm and a whole-TU
compile-order reorder are already measured inert. No shape spent; criterion unchanged.
### `_update_channel_for_impulse_sound` (park, 528 / 29, 170/170 instructions)
Three ordering deltas remain inside one basic block: (a) January pre-pushes the
`sound_definition_get_minimum_distance` argument (`mov eax,[esi+8]; push eax`) into the gain product; (b)
`fld [esi+0x88]; fmul [edx+0x30]` against our `fld [edx+0x30]; fmul [esi+0x88]` for
`sound->pitch * pitch_range->playback_rate` (A35 leaf age); (c) January groups the three cone loads and wedges the
`FLT_MAX` store between the cone stores (the A4 "all loads then all stores" fingerprint). Both admissible levers
for (b) are already measured - a source operand swap is canonicalised away (waveC I1) and the named pitch local is
worse (waveC I2, 544) - and the only source form that would produce (c) is an aggregate copy or helper that does
not exist in January's tag layout (an invented owner, R14/R15). Exactness is therefore unreachable through (a)/(c)
alone, so no shape was spent.
### `_sound_set_definition_end` (park, 208 / 9) and `_update_channel_for_looping_sound` (park, 1360 vs 1376)
Both carry the same single mechanism, and laws_w3 A34 names it: January loads the `short` field
`sound->pitch_range_index` for a call argument as `xor eax,eax; mov ax,word [esi+0x8e]` (set_definition_end 0x3c;
looping 0x2ea), the fingerprint of a `short` prototype parameter, while `sound_definitions.h` publishes
`long pitch_range_index`, whose C semantics force our genuine conversion `movzx`. For `_sound_set_definition_end`
that load plus the resulting two-store shift is the *only* difference (72 vs 73 instructions);
`_update_channel_for_looping_sound` additionally shows a frame-cell permutation and one extra `xor eax,eax`, and
waveC measured it at exactly 1360/61 under an emulated `short` prototype. The owner ruled that prototype an ABI
lie (the `sound_definitions.c` definition is `long` and casts every use), so both rows stay blocked on that owner
decision; nothing in `sound_manager.c` can close them, and a mask or cast trick would be R7. When the ruling
unblocks the looping row, also fix the behavioural defect the w1 ledger recorded in the parked body (the
next-permutation test is nested, so the permutation advance is skipped).
### `_sound_find_like_channel` (park, 272 / 16, 91/91 instructions)
One callee-saved colouring swap (January `si`/`ebx` where we use `bx`/`esi`, including the `mov ax,si` return
copy). No law fires; declaration order and a named channel pointer are measured inert (waveC F1-F3). No shape
spent.
## 6. Checks
- Final real-file gate identical to baseline row for row: `== exact 58 residual 7 unwritten 0`;
`_point_from_line3d` guard passed.
- `scratch/parkcheck.py` on the real object: `parks 5 drift 0`.
- `tools/fake_match_scan.py source/sound/sound_manager.c`: 0 review leads (also 0 on `rl1.c`).
- `git diff --stat -- source/sound/sound_manager.c`: empty.
## 7. Disposition
`sound_manager.obj` stays at 58/65 strict exact; this wave claims no bytes. It leaves one actionable zero-credit
proposal (the `_sound_refresh_looping` park re-baseline to `rl1.c`), one owner ruling that would unlock 1,568
padded bytes across `_sound_set_definition_end` and `_update_channel_for_looping_sound`, and four rows classified
as measured ties with their levers exhausted.
@@ -0,0 +1,110 @@
# StructureLensFlares (opus5 250K house-clean lane, wave w3c, 2026-09-15): residual mechanism decoded, still owner-blocked
Worker lane `opus/250k-house-clean-20260915`. **No production source changed.**
`git diff --stat -- source/structures/structure_lens_flares.c` is empty; the final real-file gate equals the baseline.
## 1. Baseline and final (real file, whole-TU gate, `_point_from_line3d` guard passed)
`== exact 3 residual 1 unwritten 0 (of 4 listed)` — unchanged at the end of the wave.
| Row | January (padded / relocs / sha16) | Real file |
| --- | --- | --- |
| `_build_structure_lens_flares` (PARKED, `instruction-scheduling`) | 4336 / 156 / `40aa8e486e52fe25` | 4336 / 156 / `57d6f033f3793735`; 1327/1327 instructions, 13 differing aligned blocks |
| `_cluster_index_from_point` | 96 / 3 | EXACT |
| `_compare_temp_markers` | 32 / 0 | EXACT |
| `_structure_lens_flares_place` | 16 / 2 | EXACT |
## 2. Duplicate prevention
Read: the four canonical Jonas ledgers (grid topology 0826, policy 0829, Fable uniform boundary 0830, authenticated
fuzzy closeout 0901), the w2 ledger `structure_lens_flares_obj_opus5_150k_w2_20260914.md` and its worker notes
`scratch/workers/structure_lens_flares_breakable_surfaces.md`, `scratch/w2/laws_w2.md`, `scratch/w3/laws_w3.md`,
and the memory records (lens-flares 4-instruction witness, mechanism-proven parks, fast_ftol, no-fake-matching).
`git log --all -- source/structures/structure_lens_flares.c`: 21 commits. `branch_sweep.py`: 19 unique blobs,
14 compile-fail, the others 0-2 exact with 2-4 unwritten — **HEAD is the best blob in the corpus**. The Fable census
(ledger 0830) covered 1,562 worktrees and 903 distinct objects with zero strict-exact bodies.
## 3. Residual decomposition (alndiff vs `build/split`, re-measured at this HEAD)
Frame layout is identical to January's: `[ebp-0x34]/-0x30/-0x2c` = `s_temp.n.i/j/k`, `[ebp-0x24]/-0x20/-0x1c` =
`origin.x/y/z`, `[ebp-0x88]/-0x84/-0x80` = `t_plane.n.i/j/k`.
- **N1 @0xa65** — January `fstp [ebp-0x2c]`, then j*j, then a reload `fld [ebp-0x2c]; fmul [ebp-0x2c]`; ours forwards k
in st(0) (`fst` + `fmul`).
- **N2/N3/N4 @0xb05, @0xb3d, @0xbb0** — every s_temp/s_plane sum (magnitude_squared3d inside `normalize3d`,
`s_temp.d = dot_product3d(origin, n)`, and both `plane3d_distance_to_point` sites) is **j,k,i** in January and
**k,j,i** in ours. The t_plane sums are **k,j,i in both** and match; k is the youngest t leaf, so ours is the plain
laws_w3 A35(2) "youngest term first" order and January's s-sums are the tie-broken ones.
- **derivative @0xdee** — 2-byte `mov edi,edi` vs 3-byte `lea ecx,[ecx]` loop padding, a pure consequence of the 3-byte
shift from N1; it disappears whenever N is fixed.
- **tie A @0xe28** (`fld [ebp-0x84]` vs `mov [ebp-0x44],eax`, s-loop preheader) and **tie B @0xe6a** (`push ebx` vs
`fadd [ebp-0x24]`, inside project_point3d's argument pushes) — int-vs-FP interleave transpositions, Fable
dbg32b-certified DAG-creation-order tie-breaks after ~15k probes.
## 4. New evidence from this wave
1. **The marker-search statement is byte-insensitive to its spelling.** `alndiff base.obj vs f1.obj` (f1 = w2's lf_F1,
i.e. HEAD with `point_from_line3d(&test_point, &direction, offset, &test_point)` restored) shows the two objects are
**byte-identical from 0xdf0 to the end of the function**, with identical frame size and identical `[ebp-N]` offsets.
The genuine inline call and HEAD's hand expansion emit exactly the same local code; the call's whole effect is a
global IL/DAG tie-break perturbation ~1,000 bytes earlier (N1-N4 and the padding). January's bytes therefore cannot
discriminate the two spellings locally. This is the "per-basin lottery" the Fable ledger recorded, promoted here from
a hypothesis to a measurement, and it is the reason no COMDAT-free respelling can be argued from byte evidence.
2. **laws_w3 A35(4) is confirmed for this function** (the law file already names this group N as its example): the hand
expansion ages `direction`/`test_point` field names and flips the later s-sums.
3. **A31(b) / A35(1) pointer-write routing is refuted here.** `set_real_vector3d(&direction, ...)` — the lever that
closed breakable_surfaces' cross-product roles and `_lightning_offset_marker_position` — makes this function worse
(13 -> 16 differing blocks) and adds a candidate-only `_set_real_vector3d` COMDAT that the January object does not
own (census: `('code','_set_real_vector3d')` absent from target).
4. **Premise correction to the w2 ledger.** w2 recorded the d-only plane form as blocked by "a representation cast
(house rule)". That is void: laws_w2 section B and laws_w3 section B both ADMIT point-to-vector `(real_vector3d *)`
casts, and `source/math/real_math.h:1325` (`plane3d_from_point_and_normal`) itself writes
`dot_product3d((real_vector3d *)point, &plane->n)`. The d-only form is house-rule admissible; it is simply inert on
its own. The **sole** remaining blocker for group N is the `_point_from_line3d` COMDAT.
## 5. Law detector pass and shapes tried (3 of 5; scratch only, siblings 3/3 exact in every probe)
| Probe | Shape (law) | Result |
| --- | --- | --- |
| `scratch/workers/w3c_structure_lens_flares/p1.c` | marker update as `test_point.x += direction.i * offset;` x3 (natural-spelling control for A35(4)) | 4336/156, 13 blocks; **function bytes identical to base** |
| `.../p2.c` | `set_real_vector3d(&direction, ...)` initialisation (A31(b) + A35(1)) | 4336/156, **16 blocks — worse**; new candidate-only `_set_real_vector3d` owner |
| `.../p3.c` | `s_temp.d = dot_product3d((real_vector3d const *)&origin, &s_temp.n);` alone, no `point_from_line3d` (corrected cast premise, single-plane granularity; w2's F2 tested both planes together) | 4336/156, 13 blocks; **function bytes identical to base** — VC7 fully eliminates the `plane3d_from_point_and_normal` self-copy |
Detectors that did not fire: A12 touches tie A but w2's P* probes already spent the six `s_grid`/`s_count`/`t_distance`
decl-init orders in this basin (no flip); A31(a) does not apply (neither tie site is a post-call stack adjust — tie A is
a preheader integer store against a hoisted x87 invariant, tie B is one push inside a push sequence); A24 is inert (the
frame already equals January's); A23, A25-A30, A32-A34, A36-A45 have no hook (no unwritten row, no size/reloc delta, no
frame gap, no switch/loop-spelling question, no C4013 site in `scratch/gate4/c4013.txt`, no static-linkage candidate, no
`_code_` label, no alias class).
Not repeated (earlier waves): L1, LB1/LB2, L2/L2b, LS2-LS4, the 16-combination `POINT_DOT_VECTOR3D` lattice, F4-F6,
G1-G3, M1/M2, K1-K4, P*, and the Fable ~15k-probe tie search.
## 6. Outcome
**NOT LANDED — OWNER-BLOCKED (group N) + SKIPPED-EXHAUSTED (ties A/B). No proposal.**
Strict EXACT is unreachable without emitting `_point_from_line3d`, which WORKER_BRIEF sections 0 and 9b make a lane
rule and which laws_w3 R14 forbids re-proposing; and even with it the body stays two instruction pairs short (w2's
lf_F3/lf_F7). Brief section 6 allows an already-written residual to land only when it becomes strict EXACT, so no
body — however much closer — is landable here. Deliberately no orchestrator proposal: the w2 ledger already records
this function on the `point_from_line3d` owner-ruling list.
## 7. Reopen criterion (revised; replaces the w2 three-clause criterion)
Reopen only if **both**: (a) the owner lifts the `_point_from_line3d` no-emission rule; and (b) a source lever is found
for the two int-vs-FP transpositions at +0xe28 and +0xe6a. The w2 criterion's third clause ("a cast-free d-only plane
spelling") is **struck**: the cast is admitted policy and the d-only form is byte-inert on its own.
Do **not** spend further waves searching for COMDAT-free respellings of the marker-search update. This wave proved the
statement's local bytes are spelling-insensitive, so no byte evidence can select one, and any COMDAT-free spelling that
happened to win the global tie-break would be an unfalsifiable lottery pick barred by the no-fake-matching gate.
## 8. Verification
- `python -B tools/campaign/gate.py source/structures/structure_lens_flares --all --forbid-emitted-symbol _point_from_line3d`:
guard passed, `== exact 3 residual 1 unwritten 0` (equals baseline).
- `python -B scratch/parkcheck.py source/structures/structure_lens_flares <base.obj>`: parks 1, drift 0.
- owner census vs `build/base` and `build/split`: candidate-only `[]`, base-only `[]`.
- `python -B tools/fake_match_scan.py source/structures/structure_lens_flares.c`: 0 review leads.
- `git diff --stat -- source/structures/structure_lens_flares.c`: empty.
@@ -0,0 +1,142 @@
# `ui_widget_game_data_input_functions.obj` — opus5 250K house-clean lane, wave w3c (2026-09-15)
Worktree `C:\halo-worktrees\opus5-150k-house-clean-20260914`, branch `opus/250k-house-clean-20260915`.
Worker scope: `source/interface/ui_widget_game_data_input_functions.c` only. No header, config, build or git
operation was performed. Worker totals are not credit; only the orchestrator's full build counts.
**Outcome: nothing landed — honest early exit. The real file is byte-for-byte unchanged
(`git diff --stat` empty).** The unit's only strict-reachable non-exact row is a measured block-layout tie; the
other five rows are either accepted-semantic, csplit-alias-bound (strict exact unreachable), or a locked park whose
recorded blocker no w2/w3 law explains.
## Baseline and final
`gate.py source/interface/ui_widget_game_data_input_functions --all --forbid-emitted-symbol _point_from_line3d`
| | exact | residual | unwritten | guard |
|---|---:|---:|---:|---|
| baseline (HEAD) | 40 | 6 | 0 | passed |
| final (unchanged) | 40 | 6 | 0 | passed |
Parks: `_solo_level_select_list_update_displayed_items` — `scratch/parkcheck.py`: **parks 1, drift 0**.
`tools/fake_match_scan.py`: 0 review leads. Owner census: unchanged (no edit).
| function | padded | tag | w3c verdict |
|---|---:|---|---|
| `_multiplayer_game_directions` | 320 | sha | NOT-LANDED — block-layout tie (A43 family), 1 new shape + 8 lab spellings |
| `_player_profile_1wide_list_update` | 1,152 | sha | OWNER-BLOCKED — duplicate-store ruling, and reloc-identity even then (zero strict credit) |
| `_player_profile_3wide_list_update` | 1,232 | reloc-identity | SKIPPED — accepted_ledger (semantic tier) |
| `_player_profile_update_cache_for_nwide_list` | 272 | reloc-identity | SKIPPED-EXHAUSTED — bytes already equal; csplit alias (A45) |
| `_solo_level_select_list_update_displayed_items` | 704 | sha | SKIPPED-EXHAUSTED — parked two-reload transposition; no law fires |
| `_splitscreen_pregame_status_screen_update` | 1,216 | reloc-identity | SKIPPED-EXHAUSTED — bytes already equal; csplit alias (A45) |
There are no UNWRITTEN rows in this object, so the w3 work order started at the structural/residual rows.
Prior ledgers read in full: `*_obj_opus5_150k_w1_20260914.md`, `*_obj_fable_salvage_20260902.md`,
`ui_widget_game_data_profile_fuzzy_reconciliation_20260909.md`, the park text in `config/parked.json`, plus
`scratch/w2/laws_w2.md` and `scratch/w3/laws_w3.md` (applied as detectors to every row; see below).
## `_multiplayer_game_directions` (320) — the only strict-reachable row
w1 had already driven this to 122/122 instructions with equal size and relocations using
`scratch/workers/ui_widget_game_data_input_functions/mgd_a.c` (the real body plus the teams `if/else` join, i.e. one
`widget->visible = TRUE;` after the teams arms — itself the laws_w3 **A25** join-store form, confirmed by January's
tail-duplicated per-arm stores). The single remaining hunk is block placement:
```
January ours (mgd_a)
55 cmp word [esi+0x112],di 55 cmp word [esi+0x112],di
5c jl 0x89 <- machine arm 5c jge 0x6f <- skip over inline arm
5e call is_splitscreen 5e .. machine arm (0x22) + ret
.. 6f call is_splitscreen
78 player arm (0x23) + ret 89 player arm (0x23) + ret
89 machine arm (0x22) + ret
```
Flow graph, register allocation (widget in EBX, the shared `mov edi,2` constant), relocations and every other byte
are identical. January keeps the two test chains contiguous and emits both cold arms afterwards, player arm first.
### New work this wave
1. **f1 (A25 join-store applied to the server block)** — `scratch/workers/w3c_ui_widget_game_data_input_functions/f1.c`:
`short string_list_index = NONE;` assigned in the two arms, then one guarded store plus `visible = TRUE`.
Result **336 != 320 [size]**: VC7 does tail-duplicate the stores into both arms (A25 holds) but materialises the
value in a register (`mov eax,0x22 … mov word [ebx+0x40],ax`), and the arm order does not move. Reverted.
2. **Lab census** (`scratch/workers/w3c_ui_widget_game_data_input_functions/lab1.c`, `lab2.c`, runner `lab.py`,
compiled with this unit's ninja cflags). `h1` reproduces our real layout exactly, so the lab is faithful.
All of these leave the machine arm inline: else-if ladder (f2, h2 control), `while` instead of the for-increment
teams loop (f3 — laws_w3 **A23** frequency probe), the whole teams tail removed (f4), a `visible = FALSE` exit
inside the `if (server)` block (f5), and an extra nesting level on the splitscreen test (h3).
`h2` (the two ifs swapped in source order) swaps the **test** order in the emitted bytes, which positively proves
January's source order is machine-test-first — i.e. our source order is right and the difference is layout only.
Together with w1's five shapes (local join store, else-if, flat single-exit chain, global visible join, condition
boolean local) that is **14 measured spellings**. Classification: block-layout tie, laws_w3 **A43** family (no source
lever has ever moved late block/epilogue placement). laws_w3 A39's switch device does not apply (no switch; both arms
already end in an explicit `return`), and A25/A23/A16/A26 were each tested above.
**Reopen criterion:** a measured law that predicts which of two cold early-return arms C2 emits first (a real
block-frequency/placement decode), or January-side evidence that the machine arm is not a plain `if`-then in source.
Do not re-spend shapes on if/else-if, condition booleans, join stores, nesting or loop respellings.
## `_player_profile_1wide_list_update` (1,152) — owner-blocked and strict-unreachable
Re-measured w1's shape C (`scratch/workers/ui_widget_game_data_input_functions/p1_final.c`) at this HEAD:
**1,152/70, normalized bytes equal, tag [reloc-identity]** (the extra residual row in that gate is only because the
file predates the landed `_network_pregame_status_screen_update` unpark).
Two independent reasons it cannot land in this wave:
1. The body depends on January's byte-proven duplicated `text[0xFF] = 0` store (default-profile valid path stores at
+0x370 and again at +0x408). Brief section 5 prohibits duplicated stores; the w1 owner-ruling request is still open
(laws_w3 C3 "byte-proven redundant stores/branches", the A42 family) and the 2026-09-15 rulings do not cover it.
2. **Even with that ruling the row stays [reloc-identity]**: the remaining relocation differences are the csplit
one-past-the-end alias at +0x1a9 and the `L""` / `"\r\n"` literal COMDATs January references undefined
(laws_w3 **A45**). So it is worth **zero strict credit**, and brief section 6 forbids landing an already-written
residual that does not become strict EXACT.
For the orchestrator: `_player_profile_3wide_list_update`, `_player_profile_update_cache_for_nwide_list` and
`_splitscreen_pregame_status_screen_update` are all already in `build/semantic_report.json` accepted_ledger, so w1's
semantic-credit request for the latter two is satisfied; `_player_profile_1wide_list_update` is the only alias-class
row in this object that is uncredited, and it needs the duplicate-store ruling first.
## `_solo_level_select_list_update_displayed_items` (704, PARKED) — no law fires
Park class `instruction-scheduling`; target and parked base are both 704/45 with objdiff 99.89 %. Measured today:
214/214 instructions with **one** transposition — the loop back-edge block at +0x9a reloads
`mov eax,[ebp-0xc]` (item_index) then `mov edi,[ebp+8]` (list_widget) in January and the reverse in ours. The loop
bottom is `mov eax,[ebp-0xc]; inc eax; cmp eax,3; mov [ebp-0xc],eax; jl 0x9a`, so both reloads are allocator-redundant;
the frame (profile −0x54, index array −0x24, item_index −0xc, marker homes −0x10/−0x14/−0x18) and all 45 relocations
already match.
Detectors run with no hit: A6/A33 (frame layout, block scoping — the frame is already exact), A12 (preheader invariant
order — this is a back-edge reload block, not a preheader), A24 (parameter-home offer — no home is packed differently),
A5 (alias removal — there is no alias), A23/A25/A39 (layout/frequency — no block moves), A35 (x87 only).
The park's recorded cause is the shared `player_profile.h` ownership: the older exact body used a TU-local shadow
struct, which brief section 5 prohibits, and the park text forbids source-pressure tuning. No scratch candidate was
produced, because any edit here would be a pure two-load steering change.
**Reopen criterion:** a measured law predicting the order of two independent spill reloads in a loop back-edge block,
or January-side evidence that `struct player_profile` / the `player_ui_get_active_player_profile` signature differs
from the shared header in a way that changes allocation.
## Other rows
- `_player_profile_update_cache_for_nwide_list` (272) and `_splitscreen_pregame_status_screen_update` (1,216): landed
byte-identical in w1; the residual tag is purely the csplit one-past-the-end alias (+0x40/+0x79 and +0x4a1
respectively). laws_w3 A45 makes strict exact unreachable; no source work is possible or useful.
- `_player_profile_3wide_list_update` (1,232): accepted_ledger, semantic tier, untouched.
## C4013 note (no action)
`scratch/gate4/c4013.txt` reports one implicit declaration for this unit,
`ui_widget_game_data_input_functions.c(648) : warning C4013: 'error' undefined`. The site is inside
`_ui_widget_game_data_function_invoke`, which is **already strict EXACT**; laws_w3 A32 records that A7 includes whose
C4013 result is discarded or already exact are byte-inert, and E18 forbids landing byte-inert hygiene includes in a
unit where nothing else lands. No include was added.
## Proposals
None. No header, config or owner packet is needed for any row of this object beyond the two rulings already on the
orchestrator's list (the `_player_profile_1wide_list_update` duplicate-store ruling, which yields zero strict credit,
and the standing park criterion for `_solo_level_select_list_update_displayed_items`).
+87 -101
View File
@@ -1137,11 +1137,6 @@ static void game_engine_generate_title_string(
wchar_t *secondary_string;
wchar_t life_string[128];
wchar_t score_string[256];
union
{
wchar_t team_names[22];
struct postgame_statistic_entry entry;
} branch_storage;
long string_list_index;
wchar_t *format_string;
@@ -1212,41 +1207,41 @@ static void game_engine_generate_title_string(
{
long did_player_win = game_engine_did_player_win(player_index);
boolean has_teams = FALSE;
wchar_t *outcome_string;
if (game_engine)
has_teams = global_variant.has_teams;
if (did_player_win == NONE)
switch (did_player_win)
{
case NONE:
string_list_index =
tag_loaded('ustr', "ui\\multiplayer_game_text");
if (string_list_index != NONE)
{
ustrncpy(
title_string,
unicode_string_list_get_string(string_list_index, 0x37),
80);
title_string[79] = 0;
return;
outcome_string = unicode_string_list_get_string(
string_list_index,
0x37);
}
}
else if (did_player_win == FALSE)
{
else
outcome_string = L"";
ustrncpy(title_string, outcome_string, 80);
break;
case FALSE:
if (has_teams)
{
string_list_index =
tag_loaded('ustr', "ui\\multiplayer_game_text");
if (string_list_index != NONE)
{
ustrncpy(
title_string,
unicode_string_list_get_string(
string_list_index,
0x38),
80);
title_string[79] = 0;
return;
outcome_string = unicode_string_list_get_string(
string_list_index,
0x38);
}
else
outcome_string = L"";
ustrncpy(title_string, outcome_string, 80);
}
else
{
@@ -1254,37 +1249,30 @@ static void game_engine_generate_title_string(
tag_loaded('ustr', "ui\\multiplayer_game_text");
if (string_list_index != NONE)
{
ustrncpy(
title_string,
unicode_string_list_get_string(
string_list_index,
0x39),
80);
title_string[79] = 0;
return;
outcome_string = unicode_string_list_get_string(
string_list_index,
0x39);
}
else
outcome_string = L"";
ustrncpy(title_string, outcome_string, 80);
}
}
else if (did_player_win == TRUE)
{
break;
case TRUE:
if (has_teams)
{
string_list_index =
tag_loaded('ustr', "ui\\multiplayer_game_text");
if (string_list_index != NONE)
{
wchar_t *outcome_string =
unicode_string_list_get_string(
string_list_index,
0x3A);
ustrncpy(
title_string,
outcome_string,
80);
title_string[79] = 0;
return;
outcome_string = unicode_string_list_get_string(
string_list_index,
0x3A);
}
else
outcome_string = L"";
ustrncpy(title_string, outcome_string, 80);
}
else
{
@@ -1292,36 +1280,30 @@ static void game_engine_generate_title_string(
tag_loaded('ustr', "ui\\multiplayer_game_text");
if (string_list_index != NONE)
{
ustrncpy(
title_string,
unicode_string_list_get_string(
string_list_index,
0x3B),
80);
title_string[79] = 0;
return;
outcome_string = unicode_string_list_get_string(
string_list_index,
0x3B);
}
else
outcome_string = L"";
ustrncpy(title_string, outcome_string, 80);
}
break;
}
else
return;
ustrncpy(title_string, L"", 80);
title_string[79] = 0;
return;
}
if (game_engine && global_variant.has_teams)
else if (game_engine && global_variant.has_teams)
{
wchar_t team0_name[8];
wchar_t team1_name[8];
long team0_score;
long team1_score;
game_engine->format_team_name(
0,
&branch_storage.team_names[14]);
team0_name);
game_engine->format_team_name(
1,
&branch_storage.team_names[0]);
team1_name);
team0_score = game_engine_get_team_score(0);
team1_score = game_engine_get_team_score(1);
@@ -1341,8 +1323,8 @@ static void game_engine_generate_title_string(
title_string,
80,
format_string,
&branch_storage.team_names[14],
&branch_storage.team_names[0],
team0_name,
team1_name,
secondary_string);
}
else if (team0_score < team1_score)
@@ -1361,8 +1343,8 @@ static void game_engine_generate_title_string(
title_string,
80,
format_string,
&branch_storage.team_names[0],
&branch_storage.team_names[14],
team1_name,
team0_name,
secondary_string);
}
else
@@ -1381,50 +1363,54 @@ static void game_engine_generate_title_string(
title_string,
80,
format_string,
&branch_storage.team_names[0],
team1_name,
secondary_string);
}
title_string[79] = 0;
return;
}
branch_storage.entry =
*game_engine_get_player_place(&branch_storage.entry, player_index);
game_engine->format_player_score(player_index, score_string);
if (is_place_tied(&branch_storage.entry))
{
string_list_index = tag_loaded('ustr', "ui\\multiplayer_game_text");
if (string_list_index != NONE)
{
format_string = unicode_string_list_get_string(
string_list_index,
0x3F);
}
else
format_string = L"";
}
else
{
string_list_index = tag_loaded('ustr', "ui\\multiplayer_game_text");
if (string_list_index != NONE)
struct postgame_statistic_entry entry;
entry =
*game_engine_get_player_place(&entry, player_index);
game_engine->format_player_score(player_index, score_string);
if (is_place_tied(&entry))
{
format_string = unicode_string_list_get_string(
string_list_index,
0x40);
string_list_index =
tag_loaded('ustr', "ui\\multiplayer_game_text");
if (string_list_index != NONE)
{
format_string = unicode_string_list_get_string(
string_list_index,
0x3F);
}
else
format_string = L"";
}
else
format_string = L"";
{
string_list_index =
tag_loaded('ustr', "ui\\multiplayer_game_text");
if (string_list_index != NONE)
{
format_string = unicode_string_list_get_string(
string_list_index,
0x40);
}
else
format_string = L"";
}
usnprintf(
title_string,
80,
format_string,
get_place_string(&entry),
score_string,
secondary_string);
}
usnprintf(
title_string,
80,
format_string,
get_place_string(&branch_storage.entry),
score_string,
secondary_string);
title_string[79] = 0;
return;