sots-engine/src/shim/shim.cfg.zledger
alex 2a9b97dcee Z: per-call-site draw ledger -- seven entry points, keyed by return address
The boundary ledger says which phase spends a turn's words; this says which
call site. Each entry point is detoured with its verified prototype and records
__builtin_return_address(0) plus the word cost from left before/after -- two
4-byte reads, no record per draw, since NextFloat alone has 109 call sites.

Each draw is tagged with WHICH generator it came from. That is not a detail:
the first build counted every Mars::RNG instance in the process and reported 44
words against a bracket of 18. The StrategyClient's generator at +0x134 draws 8
times a turn and must not be in the strategic total.

Also hooks EncounterDetect::AssignContacts, lane I's one inlined-draw site in
ProcessTurn's closure -- invisible to both a call-graph sweep and to the entry-
point detours, so only a boundary hook can see it. It did not fire on this
workload, which is consistent with the site sums reconciling exactly.
2026-09-08 10:42:05 -04:00

41 lines
1.9 KiB
Text

# Lane Z -- the per-turn RNG ledger, TRACE. Copy over C:\SOTS\shim.cfg.
#
# Every other hook is off so the log holds nothing but the ledger: six records per End Turn
# instead of ~40 per player. Read `side.rng.before.words` and `side.rng.after.words` on each
# record -- the difference is the number of 32-bit words the strategic generator consumed inside
# that call. Because the hooks nest, subtracting the inner subtotals from the outer one
# attributes the turn.
#
# fpu.sample_turn=off is REQUIRED: the fpu module samples the control word at
# StrategyServer::ProcessTurn, MinHook allows one hook per target, and this config needs that
# address for the ledger. With it left on, shim.log records which of the two failed to install.
hooks=trace
hook.Shim::SelfTest::Fill=off
hook.Mars::GlobalConsts::LoadFile=off
hook.Game::WeaponDictionary::Init=off
hook.Game::SectionDictionary::SectionDictionary=off
hook.Game::ServerPlayer::ComputeBudget=off
hook.Game::TechTree::ProcessResearch=off
hook.Game::ServerPlayer::OnTechResearched=off
hook.Game::ServerSystem::ProcessTurn=off
hook.Game::ServerPlayer::ProcessTurn=off
hook.Game::StrategyServer::MoveFleet=off
hook.Game::StrategyServer::ProcessFleetMovement=off
hook.Game::StrategyHost::Autosave=trace
hook.Game::StrategyServer::ProcessTurn=trace
hook.Game::StrategyServer::OnAllCombatDone_Tail=trace
hook.Game::StrategyServer::ApplyEncounterResult=trace
hook.Game::StrategyServer::NodeLineDecay=trace
hook.Game::StrategyServer::ProcessNodeSpaceTravel=trace
fpu.sample_turn=off
fpu.sample_ticks=off
# The generator is 0x9cc bytes and every record carries it twice. Inlining it as hex would make
# each record ~5 kB of state nobody reads -- the `describe` already reduces it to
# {left, index, block, words, block_hash}, and the raw bytes are only ever a sha256 line.
trace.inline_max=64
trace.path=C:\SOTS\shim.trace.jsonl
trace.flush=always
hook.Game::EncounterDetect::AssignContacts=trace