vtroc 2f71d93b3a Package what each run measured, and decode the match's audio once.
`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>
2026-09-15 19:43:47 +03:00
2026-09-13 13:52:33 +03:00
2026-09-13 13:52:33 +03:00
2026-09-13 13:52:33 +03:00
2026-09-13 13:52:33 +03:00
2026-09-13 13:52:33 +03:00
2026-09-13 13:52:33 +03:00
2026-09-13 15:09:39 +03:00
2026-09-13 13:52:33 +03:00
2026-09-13 13:52:33 +03:00
2026-09-13 13:52:33 +03:00
2026-09-13 13:52:33 +03:00
2026-09-13 13:52:33 +03:00

IW4L

IW4L is a Call of Duty runtime written from scratch in Rust, on bevy and wgpu. Point it at a copy of MW2 you already own and it loads that install's data into its own engine.

The on-disk layouts came out of reverse engineering the original binaries and reading public technical references.

This whole project is written by an LLM.

Status

No releases yet: you build it from this tree. Nothing here is stable either — the API, the config format, caches and the wire protocol all change between commits, so everyone in a session needs to be on the same one. Expect bugs and desyncs.

The network side is for arranged playtests among people who already agreed to play; it has never been vetted for lobbies full of strangers. IW4L sends nothing home, and diagnostic files sit on your disk until you attach them to a report.

Architecture

assets MW2 zones read natively; MW3 and Black Ops land in the same asset_iw4 IR.
shaders Retail D3D9 SM3 tokens translated to WGSL, so no DirectX at runtime.
rendering One sorted drawsurf list; only the tess emitters fork per surface type.
physics Fixed 17 ms step on its own accumulator. Framerate changes nothing about how a body falls.
simulation One TickInput → sim::step → Snapshot funnel for server, prediction, replay and the determinism test.
network Custom p2p wire over UDP: deltas, reliability, reconciliation. A QUIC master only introduces peers.
platforms Linux and a portable Windows build.

Retail protocols, the original ABI and patched executables are out of scope. IW4L clients talk to IW4L clients.

Game data

IW4L_GAMES points at the folder holding your game trees. No assets ship in this repository or in any release, and IW4L is unaffiliated with the rights holders of the original games.

Those trees are read only. IW4L never patches them, swaps files in them or writes anything back; caches, settings, demos and logs land in iw4l-artifacts/ next to the IW4L binary.

Build and run

cp .env.example .env          # IW4L_GAMES — folder containing the game trees
make map mp_boneyard          # run a map
make map mp_boneyard CMDS='spawn assault; wait 2s; quit'
make help                     # every recipe

Live runs use [profile.play], a development build with optimizations turned on. PROFILE=release builds the real release binary. docs/WINDOWS.md covers Windows.

Documentation

Implementation notes live under docs/, one short file per area. Start at docs/INDEX.md.

file about
docs/RUN.md running the game, console scripts, commands and traps
docs/PERF.md Perfetto tracing and performance analysis
docs/RENDER.md rendering pipeline
docs/MAP-LOAD.md map loading and asset installation
docs/ENTITIES.md simulation data flow and entity taxonomy
docs/SIM-STEP.md simulation step architecture
docs/ANIM.md animation system
docs/WINDOWS.md portable Windows build
docs/DEPLOY.md release, publishing and deployment
docs/MASTER.md running your own master server

Contributing and support

A personal, experimental project. Bug reports are welcome and get no promised fix date. CONTRIBUTING.md says what a useful report contains and how changes get reviewed; security reports go to SECURITY.md.

Acknowledgements

IW4L ships none of the code below. It was read against all of it.

  • OpenAssetTools and its iw4x-x64 fork — modding tools whose asset-structure headers document the on-disk layouts IW4L reads.
  • IW4x — a custom client for MW2 (2009), a cross-reference for asset and protocol behaviour.
  • KisakCOD — an open-source CoD4 reimplementation, a cross-reference for engine structure one generation over in the same family.
  • Ghidra — the framework the original binaries were read with.

License

IW4L is licensed under the Apache License 2.0, and NOTICE holds the copyright notices, the licences of the projects above and the bundled fonts. That licence covers IW4L's own source code. Call of Duty, Modern Warfare, Black Ops and the related assets, trademarks and intellectual property belong to their respective owners.

S
Description
No description provided
Readme Apache-2.0 21 MiB
Languages
Rust 99.3%
Common Lisp 0.5%
Makefile 0.1%