sots-engine/tests
alex 2d93404c67 SV: the script-object event bus, and what it writes in a turn
`SvSctOb` is not written by direct calls. Every update goes through an event bus: a
driver notifies the root object with an integer id, the root fans the delivery out to
every child, and each delivery is two steps -- a generic handler that takes the id, then
one event-specific vtable slot that does not. The id -> slot map is a 33-entry jump table
in the image, so which class reacts to which event is recovered and exhaustive rather than
inferred from what the saves happen to show. Five of the 33 rows are not in slot order,
including two the tail sends.

Three handlers write the eight leaves that diverged:

  * the slavers' difficulty tier, on the tail's end-of-turn delivery -- a three-record
    stack table scanned against the frame, boundaries 1/50/100, stored only on a change,
    and at frame 100 and above the scan runs off the end and stores nothing, so the tier
    can never reach 2;
  * the refugees' one-shot latch, on the turn-begin delivery, with a design instantiation
    behind the same latch that nothing here can do;
  * the swarm queen's hives, also at turn begin, registered on the systems carrying the
    SWARM's scenario tag (the queen's constructor stores 3 for that and 10 for its own
    encounter id) and then ticked -- and the tick is the whole explanation of a target
    turn that reads 31 after one turn and 32 after the next. It is not re-rolled; it slips
    forward by one every turn the spawn gates stay shut.

New host phase H03 for the turn-begin delivery, run right after the frame counter where
the original sends it, and tail phase T20 implemented. Rules are pure in game/sim.

Measured on CT111, closed and regressed stated separately:

  default                 turn1->turn2  209 -> 126 (was 128)  closed 83, regressed 0
                          turn2->turn3  108 ->  67 (was  69)  closed 41, regressed 0
  --commit-blocked=H03    turn1->turn2  209 -> 124            closed 87, regressed 2
                          turn2->turn3  108 ->  67            closed 41, regressed 0

Registering a hive closes the four leaves that say which systems have hives and that they
have no queens, and opens two carrying a target turn known to be wrong: the original draws
it from the strategic generator inside the turn-begin step, outside both turn drivers, and
neither the two data-file constants nor the generator's position there is settled. That
trade is a flag, not a default.

The prediction in docs/SV-script-objects.md was committed before the build, and P5 was
wrong: it called the second pair a null control, and the second pair is where the slip
rule is tested EXACTLY -- two hives, two target turns, both landing on the oracle with no
draw and no fitting.

Gates run separately: clean-room OK, host ctest 51/51, CT111 shim cross-build clean.
2026-09-08 16:46:25 -04:00
..
app SV: the script-object event bus, and what it writes in a turn 2026-09-08 16:46:25 -04:00
game_ai merge lane W2: watchpoints + multiplayer Tier 0 (CMake list and main.cpp union-resolved to keep both instruments; header regenerated) 2026-09-08 15:28:28 -04:00
game_combat B5: the post-battle retreat rules as a pure planner (game/combat) 2026-09-08 11:52:57 -04:00
game_config m2: manifest/id dictionary hooks + manifest_loader; thiscall support in Hook template; struct sizes pinned (+0x14 word) 2026-09-07 22:41:42 -04:00
game_data tests: restore test_catalog fixture text (rename only member accesses) 2026-09-07 22:15:20 -04:00
game_design lane D2: aggregate hull size in the record's MEMORY slot order, not its wire order 2026-09-08 12:47:14 -04:00
game_effects b2: OnTechResearched hook + 10 effects-table corrections (float32, xenotech block size, no already-researched guard, sticky mask, AI bonus values) 2026-09-08 00:01:04 -04:00
game_events lane P: post the research events from ours (count-only), declare ObservedTech 2026-09-08 04:16:22 -04:00
game_nav lane P2: fleet path planning (game/nav) 2026-09-08 12:43:11 -04:00
game_sim SV: the script-object event bus, and what it writes in a turn 2026-09-08 16:46:25 -04:00
mars_parse mars/parse + mars/text: engine parity (Mars::Script tokenizer, first-wins keys, trailing-pair drop); oracles 1531/1531, 64/64 2026-09-07 18:10:18 -04:00
mars_stream mars::rng: the seven draw entry points, with their word costs 2026-09-08 09:59:05 -04:00
mars_text mars/parse + mars/text: engine parity (Mars::Script tokenizer, first-wins keys, trailing-pair drop); oracles 1531/1531, 64/64 2026-09-07 18:10:18 -04:00
mars_vfs mars/vfs: gob ZIP reader + native override, miniz 3.1.2; oracle-verified 8352+2035 entries 2026-09-07 17:40:51 -04:00
shim_budget b1: ComputeBudget hook + adapter; fix researchMoneyKept to be charged only with a research target; budget out-param is int[22] 2026-09-07 23:24:10 -04:00
shim_colony b4: colony + movement hooks; 22 formula corrections (growth curve has no capacity term, range margin +0.05f, ties-to-even rounding); 3 verified signatures 2026-09-08 00:57:55 -04:00
shim_events lane P: post the research events from ours (count-only), declare ObservedTech 2026-09-08 04:16:22 -04:00
shim_movement b4: colony + movement hooks; 22 formula corrections (growth curve has no capacity term, range margin +0.05f, ties-to-even rounding); 3 verified signatures 2026-09-08 00:57:55 -04:00
shim_player_turn T: hook for Game::ServerPlayer::ProcessTurn, with the prediction committed first 2026-09-08 08:08:47 -04:00
shim_rng_ledger Z: measure the strategic RNG, do not assume it 2026-09-08 09:16:24 -04:00
shim_techfx b2 live: 3 completions compared 0 divergences; float32 confirmed on the game; RollResearchEvent RNG region added; xenotech block size bug fixed 2026-09-08 01:18:39 -04:00
shim_trace harness: compile-time Coverage on every descriptor, guard regions, replace-mode records; audit of 23 undeclared side effects 2026-09-08 01:28:35 -04:00
addr_smoke.cpp m0: binkw32 proxy shim, minhook, trace hook on Application::Initialize; build/deploy tooling 2026-09-07 17:22:15 -04:00