- Body region impacts are scaled by retail's centre-of-mass speed curve (x1 at rest up to x5 from ~0.95 m/s, read from the vault; no clamp after the multiply), so bails reach the tier-1 / tier-2 body and concrete hits. Setup exports the curve; older installs get the identical default. SKATE_AEMS_BODY_CURVE=0 = old. - Region impacts take |Δv·n| as retail does (matches 12,054 of 12,054 recomp region lines). - The body and deck posters' cooldowns count console frames (0.5 s / 0.2 s at any frame rate). SKATE_AEMS_BODY_CONSOLE=0 / SKATE_AEMS_DECK_CONSOLE=0 = old. - Second grain bed for the NPC skater (retail's per-instance SkateBoard update; inert until the engine has NPC skaters). The local player's renders are byte-identical. - The state log records the COM speed; the e2e harness replays it. - Docs: doc 11 (bail density: the missing speed curve, not the ragdoll; the hooks' local test), PR plan, docs index; the published recomp trace reader knows the new line kinds.
Recomp trace analysis
For use with the Skate 3 recomp's research hooks:
Hailey-Ross/skate3recomp, branch research-hooks
(described in docs/hails-additions/13-recomp-research-hooks.md).
Reference only. These scripts read traces written by that branch's hooks. You must build the recomp yourself (from your own legally owned copy of the game), apply its SDK patch, and set up the trace paths and the paths below for your machine. The recompilation is not a perfect copy of the console game: it runs uncapped, and its timing and threading differ. Treat logged values, data and program logic as evidence; treat timings and per-frame rates as specific to the recomp.
The hooks write a tab-separated trace.tsv (KIND <tab> <ms> <tab> fields…, all on one time base),
optionally a float32 stereo capture of the mixed output, and screenshots. A session folder holds
trace.tsv (and trace.f32 / audio.f32, shots/).
| Script | What it does |
|---|---|
trace.py |
Shared reader (from trace import Trace): lines per kind, MARK stops, screenshot nearest a time, capture windows. Run alone: line counts per kind, malformed fixed-layout lines (should be zero), stops. |
first_pass.py |
Summarises first-pass raw-register hook lines per kind: call counts and the distinct values of each register, so constant fields (pointers, flags) stand apart from data. |
resolve_trace.py |
Finds each played sample's payload in your own disc's audio archives and names the bank member and stream. Used by retail_voices.py. |
retail_voices.py |
Joins each voice's PLAY with its MOD (pitch, filters), GAIN and SEND lines: per bank, voices, pitch / rate quantiles, filter cutoffs and level. --csv per voice; --modules lists the buses. Caches resolutions in the session folder. |
retail_relay.py |
How one emitter bank's voices follow each other: starts, slots, pitch, gaps, overlaps, repeats and the most voices at once. Needs play_resolve.json from retail_voices.py. |
grec_level.py |
Grain-bed (rolling) levels from GREC lines per speed band: straight rolling and carving. |
grec_clean.py |
Grain-bed gain on clean straight rolling only (settled, no brake / push / balance / trick), per speed band and truck. |
grec_material.py |
Wheel material against wheel count from GREC lines: how often the material changes while rolling, and how often it reads the "no contact" value. |
send_vectors.py |
Per-channel send gains from SEND lines: power sums, LFE share, most common pan shapes. |
grain_trace_stats.py |
Grain voice starts (PLAY lines matching a .grain member of your disc): starts per member, per second and inter-start intervals. |
retail_windows.py |
Straight four-wheel rolling windows of the session's capture per 5 km/h band (level, octave bands), next to the engine's e2e renders folded the same way (tools/audio-e2e). |
veh_trace.py |
Traffic summary from the traffic hook lines: per vehicle speed, target speed, manoeuvre and lane changes, stops, plus the horn / skid / engine lines. |
Inputs
- A session folder or
trace.tsvfrom the research-hooks build. - Your extracted disc for
resolve_trace.py,retail_voices.py,grain_trace_stats.py:--disc DIR(the folder holdingdata/), default$SKATE3_DISCor.local/skate3-disc. - An installation's decoded banks for
retail_relay.py(--assets, defaultassets). - Hook-specific values that depend on your build are inputs, not built in: e.g.
retail_windows.py --contact-callers(the caller prefixes of the board-contact SPLC lines in your trace).
Usage
py -3.13 tools/recomp-trace/trace.py sessions/my_session/trace.tsv
py -3.13 tools/recomp-trace/retail_voices.py sessions/my_session --bank SomeBank --csv voices.csv
py -3.13 tools/recomp-trace/retail_relay.py sessions/my_session SomeBank --from 60000 --to 120000
py -3.13 tools/recomp-trace/grec_level.py sessions/my_session/trace.tsv
py -3.13 tools/recomp-trace/retail_windows.py sessions/my_session .local/audio-e2e --contact-callers 82AAAA,82BBBB
py -3.13 tools/recomp-trace/first_pass.py sessions/my_session/trace.tsv SOMEKIND
Example output
trace.py (made-up counts):
{'MARK': 12, 'PLAY': 5400, 'MOD': 31000, 'GAIN': 18000, 'CAPTURE': 900}
malformed (fixed-layout kinds): {'TREAT': 0, 'SEAMPAT': 0, 'SEAMHIT': 0, 'GRECX': 0, 'FIRSTHIT': 0, 'SKID': 0, 'EMITSLOT': 0}
stop_a 12.0 .. 95.5 s
Requirements
Python 3.13; numpy for retail_windows.py and Trace.capture. The repository's tools/owned_game
and tools/asset_pipeline/audio_formats.py for the resolvers.