Commit graph

4 commits

Author SHA1 Message Date
alex
3a3513b5cc Z: S+0x8 is 12-44 per turn, not 12-14 -- it scales with the game state
The second save's numbers were not in the first draft's table. Correcting my
own correction: on a turn-19 Zuul game the counter moves 16, 21 and 44 times
between ProcessTurn entries, against 12-14 on an early two-colony game. So it
is not a driver-invocation counter and not a constant either.
2026-09-08 09:49:17 -04:00
alex
9af2d0c6f4 Z: state the absent safety net -- no Guard region, so undeclared=0 is vacuous 2026-09-08 09:48:20 -04:00
alex
c24bf6e7e0 Z: reconcile with lane J's rules 16/17, add the Zuul ledger table
Lane J landed rule 16 (inlined draws are invisible to call-graph sweeps) while
this run was in flight, and it bears directly on three claims here that rested
on direct-call sweeps. Those claims now rest on the behavioural measurement
instead, which is immune to it: ProcessNodeSpaceTravel moved the generator by
0 words on 16 observations and node-line decay on 8. The instrument does not
ask which function drew, only whether the generator moved.

Lane J's resolver map and this ledger pair up: the resolver has no
unconditional draw, so its prediction -- a plain fleet battle costs the same
18-22 words as a peaceful turn -- is testable with these hooks as soon as
someone builds a save where two hostile fleets meet.
2026-09-08 09:47:11 -04:00
alex
1d50f1edda lane Z: the RNG ledger for one strategic turn, measured end to end
We consume 18-22 generator words per turn and model none of them as a count.
All of it is inside StrategyServer::ProcessTurn; OnAllCombatDone_Tail costs 0
on every turn observed; the residual outside the two drivers is exactly 0. The
generator does not move between turns at all, so the interval a standalone has
to reproduce is closed at both ends.

The instrument reads generator STATE, not calls, and that choice paid: the
image has four draw entry points, not three (NextUInt 0x004f7670 is in no
lane's primitive set) plus inlined draws in twelve functions, two reachable
from the turn roots. A primitive-counting hook would have undercounted
silently.

Checked against the save files independently: the turn-6 autosave pair gives
18 words read from the two Sim.RNG blobs, and with twists == 0 that number
never passes through a twist implementation -- so the two instruments do not
share the hidden assumption they could have.

Corrections to combat-done-tail.md, in place:
  * the node-line 0x20000-fleet check runs AFTER the Chance(0.5f) call and
    cannot gate the draw; the expiry test is NodePath::RemainingLife 0x006e2130
    and is now a formula rather than a description
  * StrategyHost::Autosave is ret 8 and returns the std::string* in EAX
  * SNMAllCombatDone IS delivered every End Turn (8 of 8) -- lane K's inference
    was right; the stronger no-encounter reading is narrowed, not closed
  * S+0x8 advances 12-14 times per turn, not twice

Node-line decay still has not fired. The hook reports the distance instead of
the absence: 51 of 53 lines are permanent, the mortal ones are dug ~1/turn by
the Zuul, each ~40 turns from expiry. It stays a labelled hypothesis.
2026-09-08 09:45:06 -04:00