Image decode takes the pool it runs on as a parameter and every lane hands it the loader's. `ComputeTaskPool` is the frame's pool, with its own thread count and its own affinity, so a load stage that decoded on it ran on the frame's threads and competed with the frame for them. Material compile chunks move onto the same load pool instead of raw `std::thread::scope` threads: the pool's workers set their affinity to the process CPUs when they spawn, while a thread spawned from an `AsyncComputeTaskPool` worker inherits that pool's narrower set. The compile scope is explicitly non-cooperative, so the calling thread waits for its chunks rather than ticking the pool's queue. The `common_mp` FPV plan is held rather than enqueued, and decodes once the donor plans have merged. `prune_to` drops every demand whose rows the merge would not fill — the same predicate `apply` uses, so pruning changes when the question is asked and not what the catalog ends up holding — and `release_claims` hands the rows back when nothing survives, which is otherwise `apply`'s job and would leave later stages skipping every name the plan had claimed. The census counts `pruned_variants` and `pruned_rows` on their own, apart from duplicate claims and from discards, and the report line carries what was cut, what is left and what asking cost. `presented_state_age` and `presented_frames_behind` measure from a render frame's extract to the render graph's Finish set: how old the state a frame drew was, and how many main frames had opened since it was taken. They get their own table in the counter report, because an age divided by a frame is not a share of one, and a line in the frames section beside main/render overlap — what pipelining costs, next to what it buys. Both say where they stop: bevy presents after the graph schedule returns, so the present, the compositor and the panel are outside, and neither is an input-to-photon latency. `IW4L_FRAME_LATENCY` sets the surface's `desired_maximum_frame_latency` without a rebuild. The backend may clamp it, so the manifest records the number asked for and never a grant this process cannot read back. Env switches now read through one rule in `perf::switch`: absent, empty, `0`, `false` and `off` are off. `IW4L_MULTI_DRAW=0` therefore turns the indirect path off instead of enabling it, which is what a paired run across it needs. A lightmap page counts the bytes of all six of its images in `handed_bytes`, `bytes_total` and against the budget pacing the overlay frames, and a slot that takes another slot's handle no longer counts as having handed anything over. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.





