sots-re/ghidra/addresses.d
alex bebdee1ceb income-term: the output -> money chain read from the instruction stream; the BnkEl oracle goes 6/25 -> 25/25
`output-term.md` §6 said the verified output total did not unblock the budget
because a system's MONEY is a second chain. This is that chain, disassembled to
the next function start throughout.

The multiplier `formula-gaps.md` Q3 could not name is a three-row table the
executable BUILDS IN CODE from .rdata float literals -- no data-file key, no
GlobalConst slot, the same shape lane N found for the pop-type table.
ServerPlayer+0x36c is an unnamed, unsaved pointer to {int id; float ai[3];
float other[3]}, filled from that table by ServerPlayer::Read and selected per
player by `is-AI && !NPC`. Every corpus save carries aidf == 1, whose AI income
column is 1.1f. The record's other two columns are a fleet-maintenance DIVISOR
and a RESEARCH multiplier -- Q3 called the third a trade multiplier and it is not.

25/25 on the oracle, from 6/25. The prediction of WHERE the remaining misses were
was wrong and is written down as wrong: the twelve Zuul records were not missing
the suitability cost (every corpus colony sits at its species' ideal, so that
whole term is multiplied by zero and stays unexercised). They were missing
SpeciesDef +0x4c/+0x50, which are PER SPECIES and were carried as one global
pair -- 400 output points, 2000 money, per Zuul colony, and the observed 4400 and
5566 shortfalls fall out to the unit.

New wire fact: the Sim block's ISsp/ISsu pairs ARE server->IdealSuit[], the
float[7] CalcSuitMod indexes. The array is randomised per game by the map
generator and cross-checks against every ServerPlayer's own IdealSuit field in
all 11 saves, so the suitability cost needs no data file.

Also states plainly what this does NOT unblock: ComputeBudget's turn path takes
its per-system money from ComputeOutput with the system's OWN rate sliders, not
from ComputeMaxIncome, so P01/P02/P03/P05/P06 and the two research RNG words stay
blocked on a strictly larger function.
2026-09-08 13:49:48 -04:00
..
lane-a.json A: the AIAgent CD blocks - derivation, addresses, and what stays a hypothesis 2026-09-08 07:33:33 -04:00
lane-a2.json lane A2: the alliance mask read from the bytes, and every ModCount writer 2026-09-08 12:44:30 -04:00
lane-ai1.json board: lane AI1 - the AI is a StrategyClient running after the autosave; orders go through the TurnCommands we already own; P2 routed to the VM 2026-09-08 13:39:38 -04:00
lane-b5.json B5: the combat resolver's sub-dispatcher is RETREAT, and it is the largest 2026-09-08 12:00:14 -04:00
lane-d2.json lane D2: the ship-design catalogue -- how designs persist, hull size, and the 0x400 flag 2026-09-08 12:45:36 -04:00
lane-e1.json income-term: the output -> money chain read from the instruction stream; the BnkEl oracle goes 6/25 -> 25/25 2026-09-08 13:49:48 -04:00
lane-e3.json lane E3: ten addresses for the visibility record, and the standalone's new distance 2026-09-08 13:38:57 -04:00
lane-g2.json board: lane P2 nav classifier; type 2 is the Liir drive, a naming error not a gap 2026-09-08 12:45:27 -04:00
lane-i.json lane I: the complete inlined-draw inventory, and the seven RNG entry points 2026-09-08 10:03:33 -04:00
lane-j.json lane J: the combat resolver, read from the instruction stream 2026-09-08 09:37:02 -04:00
lane-k.json lane K: field offsets belong in the offset schema, and off_RNG was already right 2026-09-08 08:48:25 -04:00
lane-n.json lane N: the population -> base-output term, read and live-verified 2026-09-08 12:11:52 -04:00
lane-o.json lane O: 7 purpose-built saves - issued turn commands, node routes, research-roll-pending 2026-09-08 08:35:13 -04:00
lane-p2.json lane P2: the path solver read from the instruction stream, and OrderFleetMove's three failure bits 2026-09-08 12:43:34 -04:00
lane-q.json lane Q: TurnCommands_v5 reconciled and typed; SAVE_FORMAT section 11 corrected 2026-09-08 09:03:26 -04:00
lane-t.json T: read ServerPlayer::ProcessTurn and StrategyServer::ProcessTurn from the instruction stream 2026-09-08 08:08:36 -04:00
lane-u.json lane K: StrategyServer::OnAllCombatDone_Tail mapped, 36 phases from the instruction stream 2026-09-08 08:47:08 -04:00
lane-v2.json lane V2: vtable inversion — resolve indirect call edges image-wide 2026-09-08 12:05:05 -04:00
lane-w.json lane W: SvSctOb variant factories; fix the four save_reader.py defects openly 2026-09-08 07:05:09 -04:00
lane-z.json Z: the dominant RNG consumer is trade-raid generation, behind a virtual call 2026-09-08 10:57:12 -04:00
README.md gen_addresses: per-lane fragment dir; duplicate names are a hard error 2026-09-08 05:55:03 -04:00

Per-lane address fragments

addresses.json is a single shared file. When several lanes run concurrently they edit the same lines, and three times on 2026-09-08 one lane's git add swept another's in-flight entries into the wrong commit. Nothing was lost, but authorship and atomicity were.

A lane may instead drop its own file here:

{ "entries": [ { "name": "...", "addr": "0x...", "convention": "...",
                 "prototype": "...", "status": "verified", "source": "findings/..." } ] }

Name it after the lane (lane-d.json). tools/gen_addresses.py merges every fragment in sorted order after addresses.json. A duplicate name across files is a hard error, not last-wins — two lanes disagreeing about an address is exactly the thing we must not paper over.

The integrator folds fragments back into addresses.json once the lane's work is merged.