mirror of
https://github.com/vladtrc/iw4L
synced 2026-10-26 02:11:39 -04:00
2f71d93b3a
`make bench` printed two reports and left nothing behind but a text file, so a number could be compared with another number from the same afternoon and not much else. It now prints three and writes the run's own directory: `report.txt`, `manifest.json` and `summary.json` beside the `trace.pftrace`. Section [3/3] is the counters — the render stages, the GPU passes, and the per-frame work census. A counter nobody sampled prints MISS rather than `0.00`, and the counters and spans this build declares but this run never reached are named at the end, so a hole in the instrumentation cannot read as a fact about the workload. GPU passes overlap and resolve late, so they are never summed. `manifest.json` says what produced the number: the revision, the dirty flag, the toolchain, the profile cargo actually built under, the locked `bevy` and `wgpu`, the adapter and whether its device can time a pass, the window, the pools, the env toggles and the cache state. The build half is baked in at compile time, because asking `git` at runtime names the tree the process is standing in rather than the build. A fact nobody could read is `null`, never a plausible default. Reading that report, `preparing match audio` was the largest stage of every load — one row holding one number, which cannot tell a thousand cheap byte loops from five hundred external processes. It is the second. Section [1/3] now splits the stage by the decoder each clip took, in worker time, and counts what each one prepared, failed, held and left resident. The T5 XWMA decode goes through the artifact cache under `xwma_pcm`, keyed on every input the decode reads, so a clip is decoded once per machine rather than once per launch. A cold load still had to pay the first time: 515 `ffmpeg` processes, 18.9 s of worker time, almost none of it decoding. A worker now takes the jobs already queued and answers up to 64 clips through one process — every clip its own input and its own output, nothing concatenated — which is 1.3 s for the same bytes. Failure stays per clip: a batch `ffmpeg` refuses is re-asked one clip at a time, leaving the bad clip as the only failure. `make bench-overhead` can point at either recorder, `VAR=IW4L_PERF` or `VAR=IW4L_BENCH`; they are separate costs and each needs its own pairs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2.5 KiB
2.5 KiB
docs/ — the one-page map
Short files (each ≤50 lines) on what lives where and how to poke the live game. Keep them this short: nobody opens a long file twice.
| file | about | when to read |
|---|---|---|
RUN.md |
running (make map, --cmds), controls frozen until Playing, force_match_start, sync-by-default, the verb list and the traps |
before your first live run |
WINDOWS.md |
portable iw4launcher.exe: .env, shortcuts into CoD, writable iw4l-artifacts/ |
building and running on Windows |
DEPLOY.md |
make release / publish / deploy: the play profile, hashed .zst, master by SHA, provision kept separate |
shipping a release, "why is the player on an old version" |
MASTER.md |
your own master over ssh from the machine with the clone: cargo xtask master install, a self-signed certificate with no domain, what to hand players |
standing up a relay for yourself or your friends |
PERF.md |
native .pftrace — the only runtime truth; picking a UUID, the manifest, IW4L_PERF, SQL |
traces, scenario SQL, why a frame took 80 ms |
BENCH.md |
make bench: the map-load waterfall and stage exclusive time, frame time as a span tree, the render/GPU/work counters, and the run package (manifest.json, summary.json); in-process, no trace needed |
"where did this run spend its time" |
RENDER.md |
the nine crates of the island, the frame path IR → cull → one drawsurf list → tess → material → SM3 → wgpu, GPU-side ownership, the d3d9_* border |
touching the picture, techsets, lighting |
ANIM.md |
three floors: anim_iw4 (facts and curves), xmodel_runtime (tree and pose), who picks the clip (sim / render_frontend/adapters/anim/) |
viewmodel, skeleton, bone hits |
MAP-LOAD.md |
map load: the session → assets → install transaction, the load_prepared_match walk, the lane by ZoneGame, the artifact cache |
a zone won't load, an asset went missing, "why didn't the match come up" |
ENTITIES.md |
the TickInput → sim::step → Snapshot funnel, the entity_iw4 taxonomy (EntityState / Centity / ET_* / trajectories), what sits where in sim |
gameplay, networking, replay |
SIM-STEP.md |
sim::step: one TickInput → Snapshot funnel for authority, prediction and replay; StepReason; what makes a step deterministic |
touching the step, prediction or replay |