sots-engine/tests
alex 3ca010978c game/ai: the order block, the turn's phase spine, and what a command costs
Adds the half of the AI's turn that is arithmetic rather than judgement: what an
order looks like in the command block, which orders advance the save's
modification counter and by how much, and the phase/pass skeleton the decisions
hang in.

The counter's per-command cost turns out to have a sharp boundary. Applying an
element of command lists 1..16 advances it; applying an element of lists 17..27
does not, and one of the six flag-gated single commands is free as well. So a
uniform per-element cost model is wrong on any turn that touches the free half.

Two behaviours here are not conveniences and change the output:

  * every submitted block costs at least one, because the send-buffer build sets
    the research-rate gate unconditionally whatever the player did. On a quiet
    board that is the largest term in the turn's delta -- four of the ten command
    bumps on the reference turn are exactly this, and one of the four is the
    human's;
  * an AI fleet order costs three where the interface's costs two, because the
    AI's bridge issues the fleet-task command twice, mode 0 then mode 1, and the
    adder keys on (fleet, mode).

The phase spine records the one thing a literal port gets wrong: the turn submits
at phase 28 of 34, the submit latches the client closed before it builds the send
buffer, and every order the last five phases issue -- one of which is a colonize
order -- is refused. Tested through the client rather than by asserting a flag.

The task walk reproduces the two passes: rank once, walk twice, and refuse every
write in the first pass at the client rather than trusting the caller to check.

Nothing here decides anything. Which tasks exist and what each one wants are
questions about the board, and no part of this models the board; the module
supplies the order API, the pass gate and the cost function, and a caller
supplies the decisions.

game/ai tests 233 -> 423 checks; ctest 51/51 -> 53/53. Not linked into the
standalone driver, whose divergence on the reference pair is unchanged at 128.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARBgSooAfokKUy6wKUKEyZ
2026-09-08 16:27:38 -04:00
..
app P11: post the no-research event into the save's turn bucket 2026-09-08 15:39:42 -04:00
game_ai game/ai: the order block, the turn's phase spine, and what a command costs 2026-09-08 16:27:38 -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 S11 civilian growth; fix ComputeBudget's interest literals 2026-09-08 15:52:38 -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