`make bench` is one recipe over one run now. `IW4L_BENCH=1` arms an in-process recorder on the spans that already feed Perfetto, and at exit the run prints two independent reports and writes them to `iw4l-artifacts/bench/<stamp>.txt`: the waterfall from the shell command to a playable map, carrying the time each load stage held the pool alone, and frame time as a span tree whose nesting is recorded rather than declared. Neither needs a trace file or Trace Processor, and either can be MISS while the other stands. `bench-demo` and `bench-load` are gone — a goal after `bench` is a demo, `ZONE=` is a live map. A bot is no longer minted onto an id a real client already owns. The roster steps over the ids the authority and the local player hold, and a slot that still lands on the local player is retired, because `is_bot` would otherwise claim the player and nothing could drive the slot anyway. A stretch with no authority ack re-adopts the next snapshot and counts one stall; three of them still fail the link. Failing on the first turned every long frame into a permanent disconnect. The loading overlay comes down once the world is installed rather than waiting on the class-select hop, which a replay never makes — it was playing the whole demo behind `UiLayer::Loading`, with map ambience held back. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013bHwyKwUjaYmtVG1F3Ttku
2.9 KiB
Run and poke the live game
How to touch the live process. Observation is PERF.md.
set -a; . ./.env; set +a # IW4L_GAMES; DISPLAY=:0 if the session has none
make map mp_boneyard CMDS='spawn assault; wait 2s; quit'
cargo run --profile play -p launcher -- map iw5:mp_overwatch --cmds '…'
make passes no foreign flags through: in the Makefile it is CMDS, on the
binary --cmds. The colon is a GNU make pattern, so make map iw5:… fails —
write make map ZONE=iw5:mp_overwatch or use cargo run. Recipes: make scenario, chaos, bench (BENCH.md), bench-live, lifecycle-*
(*_CMDS in the Makefile). Live recipes use [profile.play]; LTO is PROFILE=release.
Controls are frozen until the match starts. sim::step allows movement only
in MatchPhase::Playing; hold +attack, +forward and move do nothing before
then. You wait out PLAYER_WAIT_MS 15 s + MATCH_START_MS 5 s
(crates/gamemode_iw4/src/prematch.rs) — bots (≥ 2 live players) cut the first
timer short, a single-player script waits the full 20 s. The verb is shorter:
wait world; spawn assault; force_match_start; wait 1s; …, and a script
involving firing, hits or decals lies with a zero without it.
Sync by default. Ritual waits are unnecessary: a command holds the FIFO
until its own fact — map/demo/play until the swap plus GPU-ready
WorldScene::spawned, spawn until AppScreen::InGame, move/look/tp
until a matching presented pose, force_match_start until Playing,
disconnect until the hold is torn down. wait Ns remains, for pacing and
observation windows. The & suffix is a loud refusal to wait (map mp_rust &),
! jumps the queue (in bash write disconnect !, or history expansion bites).
The 120 s gate timeout aborts the rest with an echo; parsing is
crates/console/src/. Hand-typed dump/clip/screenshot pass through any
wait while preserving the queue, which inside --cmds takes an explicit !.
Verbs and traps
map spawn class give attach name kill damage move tp look nudge press hold release bind bot wait mark record stoprecord clip demo dump screenshot ui disconnect quit
plus the debug force_match_start / showpos. bot is
add | hold | tp | give | fire; dump [name] writes the current snapshot into
dumps/. clip writes the last available 45 s into clips/<ULID>/ (demo + dump)
on host and clients — the host records authority, a client the snapshots it
received plus its own presented state; demo LATEST plays it back.
- ADS is
hold +speed_throw, not+speed; - bolt action (
fire_type=1):hold +attackis one shot, and a full magazine will not reload itself (press +attack×N, thenpress +reload); lookwithoutLookStateonly writesps.viewangles— no aiming;givetakes a namespace:give t5:weapon/psg1_acog,give iw5:weapon/msr.