Model or dataset
mshumer/Claude-of-Duty avatar
mshumer/Claude-of-Duty

Claude of Duty: a procedural browser FPS and the agent harness behind it

A Call of Duty-quality FPS in Three.js, built from a single prompt.

3,422 stars519 forksJavaScriptMIT

At a glance

What is it?
Claude of Duty is a Three.js first-person shooter with no art assets, roughly 55k lines across 11 subsystems, and a toolchain for reproducible screenshots and hitch attribution. The README is explicit that it does not reach its Call of Duty target.
Who is it for?
Adopt Claude of Duty if you are studying procedural rendering, Three.js r180 pipelines, or how a multi-agent build was orchestrated and measured; the tooling under tools/ is the part worth reading first.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 55 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 18, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What Claude of Duty actually is, and who it is for

Claude of Duty is a browser first-person shooter written in JavaScript on Three.js r180 and WebGL2. The README describes roughly 55k lines across 11 subsystems, produced by a fleet of AI agents under orchestration. The repository is MIT licensed and not archived; the last push was on 2026-07-25.

The defining constraint is that there are no art assets. Every texture, mesh, animation and sound is generated procedurally at load time from code. No models, no HDRIs, no image files, no audio files. The only runtime dependency is three.

That constraint is also the audience filter. If you want a game to play, the README's own assessment is blunt: the goal was to match a modern Call of Duty, and it does not. If you want to read a rendering pipeline, a from-scratch physics engine, a Web Audio synthesis layer, and a screenshot-diffing harness that enforces pixel neutrality, the repository is dense with material. The eleven subsystems are named and scoped in the README table, and ARCHITECTURE.md is described as the contract the agents worked against: subsystem interfaces, directory ownership, a cross-subsystem event vocabulary, and shared surface types.

The rendering and materials pipeline, subsystem by subsystem

The render subsystem is where most of the engineering sits. The README lists an HDR pipeline, cascaded shadow maps stored in a sampler2DArray with texel snapping and PCSS contact hardening, an MRT depth/normal/velocity prepass, GTAO, TAA with YCoCg variance clipping, tile-dilated motion blur, a Karis bloom pyramid, GPU EV100 metering, a procedural 33-cubed grade LUT, and an AgX composite. That is a modern deferred-ish stack assembled in WebGL2, not a toy forward renderer.

The materials subsystem is the answer to the no-assets rule. It is described as a GPU texture forge producing 19 procedural surfaces (concrete, brick, plaster, asphalt, sand, rusted, painted and brushed metal, wood, fabric, burlap, glass, and others). Periodic noise is used so the results tile, a Sobel pass converts height to normals, and parallax occlusion mapping, triplanar projection and curvature-driven edge wear fill in the rest. The README names the ceiling of this approach directly: surfaces read as procedural noise rather than photographed reality at close range.

Physics is written from scratch with no library. The README gives a binned-SAH BVH built from 29k triangles into 14k nodes in 22 ms at 0.25 microseconds per raycast, a swept-capsule character controller with a five-plane crease stack, impulse rigid bodies with CCD, PBD ragdolls, and multi-layer bullet penetration. Audio is Web Audio synthesis with no sound files: layered weapon fire, convolution reverb, HRTF spatialisation, occlusion.

One design detail is worth flagging as a trade-off rather than a win. The world is a roughly 120 by 120 metre market street with a modular building kit, real wall thickness, enterable interiors and several hundred instanced props. That is a deliberately small footprint, which is what makes procedural generation tractable at all. It also means the project is not evidence that this approach scales to an open world.

Installing Claude of Duty and running your first capture

The README gives two commands. The only runtime dependency is three, and the dev server binds to 127.0.0.1 on port 5173.

bash
npm install
npm run dev          # http://127.0.0.1:5173

Open that address, then click the canvas to lock the cursor. The README lists the controls: WASD move, mouse aim, LMB fire, RMB ADS, R reload, Shift sprint, Ctrl crouch, Space jump, Q/E lean, Esc release. If the canvas does not take input, the pointer lock was not engaged, which is the usual first-run confusion.

For a production build there are two more scripts in package.json: npm run build runs vite build, and npm run preview serves the result on port 4173.

bash
npm run build
npm run preview --port 4173

The more interesting first use is the harness. package.json exposes npm run shot, which runs node tools/capture.mjs, and the README documents tools/shotset.mjs as all 11 shots in one session and tools/baseline.mjs as the reproducible variant with each shot in an isolated page and a fixed frame budget. The capture tools depend on Playwright and pngjs, both listed as devDependencies.

bash
node tools/baseline.mjs
node tools/imagediff.mjs

imagediff.mjs is a per-pixel gate that exits non-zero if any pixel moved, and the README states baseline.mjs is bit-identical across runs, which is what makes the gate usable. If you are evaluating this repository for its harness rather than its game, that pair is the thing to run.

Where Claude of Duty fails, by its own measurements

The README does not hide the result. Eleven independent adversarial critics scored frames against a modern Call of Duty bar, and the scores went 3.59, 4.14, 4.05, then 5.05 out of 10. Two shots reached CLOSE; the rest remain AMATEUR. In a blind A/B, every critic in every round picked the real Call of Duty frame.

The named shortfalls are specific: blocky finger slabs that do not convincingly grip the weapon, material richness that reads as procedural noise at close range, enemies that read as mannequins at distance, indirect light that is an approximation rather than real GI, and frame rate. The art passes tripled geometry cost from 5.9M to 11.3M triangles, and optimization recovered about half of that.

A root cause remains unfixed. The README states the viewmodel light rig in render/index.js delivers roughly 20 times the irradiance per unit albedo that the world does, so a plain black material in the view scene renders at L=110 against a background of 91 purely from F0=0.04. Every weapon albedo is cheated to a third of physical to compensate, which caps material separation on the most-looked-at object in the game. That is a structural limitation, not a tuning miss, and it explains why the weapon reads as untextured even though it is specular-dominated.

The performance picture is the other hard boundary. Measured on an Apple silicon laptop at 1512x982 with DPR 2, the ultra preset, three runs, gameplay in motion with AI and firing active: fps p50 went from 12 to 17 before optimization to 28 to 30 after, p99 from 4 to 9 to 14 to 17, worst frame from 728 to 1236 ms down to 66 to 82 ms, shader compiles during play from 34 to 35 down to 0, and boot from roughly 9 to 12 seconds down to 3.7 to 4.6 seconds. Those are the project's own numbers on one machine, and 28 to 30 fps at Retina is not a comfortable target. If you need a browser shooter that holds 60 fps on integrated graphics, this is the wrong tool.

The harness is the real contribution, and it found two measurement errors

The README says the interesting part of the repository is arguably the harness, not the game. The evidence supports that. Two findings recorded there invalidated earlier measurements, and both are general lessons.

The first: median frame time hides the actual problem. A static-camera benchmark reported 94 fps while the game was unplayable. Real gameplay at Retina DPR, internal 3.34 MP rather than 2.07, ran 12 to 17 fps with 728 to 1236 ms stalls caused by 34 or more WebGL programs compiling lazily mid-frame. tools/profile.mjs reports p50, p95 and p99 and attributes each hitch via per-frame WebGL program counts, which is what surfaced it. Shader pre-warm in src/core/prewarm.js is what removed the stalls.

The second: captures were not reproducible. tools/shotset.mjs reuses one page across all 11 shots, so particle age, decal buffers and exposure state leak forward, and two identical runs differed on 10 of 11 shots. tools/baseline.mjs isolates each shot in a fresh page, which is bit-identical and is what makes tools/imagediff.mjs a usable gate.

There is a subtlety worth noting. Making shader pre-warm provably pixel-neutral required first fixing subsystems that animated off performance.now() instead of the engine clock, because any change to boot duration otherwise shifted output. That is the kind of coupling that a screenshot gate exposes and a code review does not.

The optimization pass itself was constrained to produce zero visual change, enforced by imagediff.mjs rather than by assertion. If you take one idea from this repository, take that one: a per-pixel gate turns "this refactor should not change anything" from a claim into a check.

Alternatives and how the approach differs

The obvious alternative is a conventional Three.js game built from downloaded assets. The difference is not stylistic. With glTF models, HDRI environments and recorded audio, you get photographic material fidelity and real character silhouettes at the cost of an asset pipeline, licensing, and load size. Claude of Duty trades all of that away for a code-only repository where every surface is a shader and every sound is a Web Audio graph. The README's own critique, that materials read as procedural noise rather than photographed reality, is precisely the price of that trade.

A second comparison is against engines like Unity or Unreal, or against a WebGL engine such as Babylon.js. Those give you a physics engine, an editor, an asset importer and a profiler as products. This project instead writes its own binned-SAH BVH and its own swept-capsule character controller, and builds its own capture and diff tooling in tools/. That is more code to own and more places to be wrong, but it means the repository is fully self-describing: no engine version to match, no editor project files, and no binary assets to review in a pull request.

The third comparison is the one the README invites by implication, against a human-authored game of the same scope. A 55k-line codebase with 11 subsystems is not a weekend project, and the process note reports what the agent orchestration actually cost. Three rounds of six agents each owning one directory moved the critic score by +0.46 and left frame-ruining defects higher than they started, going 60 to 47 to 66, because tonemapping, sky and indirect light are one coupled system and isolated agents kept breaking each other's assumptions. One sequential pass with a single owner per coupled concern moved it +1.00 and cut defects from 66 to 26. If you are evaluating agent orchestration rather than rendering, that paragraph is the most transferable result in the repository.

Maintenance, upgrade cost and licence

The repository is not archived and the last push was on 2026-07-25. There are no releases retrieved, so there is no versioned artifact to pin against; you would be tracking the main branch. The README points to a newsletter for updates, and there is no homepage listed.

The dependency surface is small, which keeps upgrade cost low in one sense and high in another. Runtime is three at ^0.180.0. Development adds playwright ^1.61.1, pngjs ^7.0.0 and vite ^7.3.6. Three.js has a history of breaking changes across minor versions, and the render subsystem here uses WebGL2 features, MRT prepasses and a sampler2DArray for cascaded shadow maps, so a three upgrade is not a drop-in. The screenshot gate is your safety net: run node tools/baseline.mjs, then node tools/imagediff.mjs, and you get a non-zero exit if any pixel moved.

One inconsistency is worth noting because it affects anyone redistributing or vendoring the code. The README states the project is MIT licensed, and the LICENSE file is present at the top level, but package.json declares "license": "ISC". Both are permissive and both permit commercial use, modification and redistribution with attribution, so the practical difference is small, but the two files disagree and you should read LICENSE rather than trusting the package.json field. This is not legal advice; if the distinction matters to your organisation, have counsel read the actual LICENSE file.

Editorial conclusion

Adopt Claude of Duty if you are studying procedural rendering, Three.js r180 pipelines, or how a multi-agent build was orchestrated and measured; the tooling under tools/ is the part worth reading first. Do not adopt it as a game to play or as a foundation for a shippable shooter: the README states it does not match a modern Call of Duty, and 28 to 30 fps at Retina with a known viewmodel light rig defect (roughly 20x irradiance per unit albedo versus the world) is not a shipping baseline. Before anything else, run npm install, npm run dev, and then node tools/profile.mjs at your real device pixel ratio, because the README records a static-camera benchmark reporting 94 fps while gameplay ran at 12 to 17 fps. Verify frame time distribution on your own hardware rather than trusting the median.

Frequently asked questions

What is Claude of Duty used for?

It is a browser first-person shooter built with Three.js r180 and WebGL2, and the README frames its main value as a study of procedural rendering and of the agent harness that built it. Every texture, mesh, animation and sound is generated at load time from code, so there are no art assets to download.

How do I install and run Claude of Duty?

The README gives two commands: npm install followed by npm run dev, which serves the game at http://127.0.0.1:5173. Click the canvas to lock the cursor, then use WASD to move and LMB to fire.

What frame rate does Claude of Duty reach?

The README reports measurements on an Apple silicon laptop at 1512x982 with DPR 2 on the ultra preset: fps p50 of 28 to 30 and p99 of 14 to 17 after optimization, with a worst frame of 66 to 82 ms. Shader compiles during play went from 34 to 35 down to 0.

Does Claude of Duty match Call of Duty visually?

No. The README states the goal was to match a modern Call of Duty and that it does not, with critic scores ending at 5.05 out of 10 and every critic in a blind A/B picking the real Call of Duty frame. Named gaps include blocky hands, procedural-looking materials at close range, and mannequin-like enemies at distance.

Official sources

  1. Issues
  2. License: MIT
  3. mshumer/Claude-of-Duty on GitHub
  4. README
Community notes

Community notes