Measure a function that walks the game's data structures under the emulator
What to know
A function that reads pointers into loaded data (a graph, lists, tables) can still be measured under Unicorn without running the game's loader: lay the structures out in scratch memory exactly as the loader does, and point the game's globals at them. POD's path tracker and order update (measure/race_paths.py) were measured this way on Beltane's whole path graph, 20,000 cases each, and the port matched every one.
- Read the loader first for the run-time layout, which differs from the file: POD's links point at nodes and at a run of section points chosen by an index, its section entries overlap a 16-bit field with a pointer, and the "first list" of a node is the one the game walks as its links out.
- Set the guard globals. A function can return at once on a global the loader sets. POD's tracker does nothing while
DAT_00539280(the first link's points) is 0, and the first 2,000 cases all came back unchanged until it was set. - Make side effects harmless where the case does not test them: the tracker calls the order update, which returns at once when the car stands first.
- Stop before library calls that need the C runtime's thread data: POD's
format_timecalls Watcom'ssprintf, which faults under Unicorn (UC_ERR_WRITE_UNMAPPED). Stopping at the call and reading its arguments from the stack measures the function's own work:emu.call(addr, args, until=CALL_SITE)['stack']. - Load a control word before the call when the code uses the FPU (
emu.call(..., fpu_cw=0x037f); x87-magic-add-rounding). - Bias the random cases towards the branches: points near a gate's plane, trackers at a link's last point, cars on the same lap.
Keep each case as a JSON line with the original's answer; the port's test reads the file and checks every line (crates/pod-race/tests/measured.rs).