← All posts
7 min read

MechAssault v2: side by side with the original

A week of MechAssault v2, played clip for clip against the original game: what 150 changes got right, what's still off, and the Claude Code settings that burned through a $200 plan's weekly limit in a day and a half.

Project: MechAssault v2TypeScriptThree.jsWebGPUAI AgentsReverse EngineeringClaude Code

The last post showed the port on its own. This one puts it next to the real thing.

Every clip below plays the original MechAssault 2: Lone Wolf on the left and the browser port on the right: the same map, the same machine, the same button presses, lined up to the frame. Where the port is still off, the caption says so.

An Owens empties its missiles and machine guns into a burning Summoner until it goes up. The blast, the debris, the fires on the wreck and the smoke all come from the original's own effect files. The original's flash still washes out the whole screen; the port's is about a third dimmer at its peak.

Making that clip turned up a real bug. The first takes fired from exactly where the original's Owens stands, and in the port every missile burst on a VTOL parked between the two machines. In the original, the same volley flies straight over it. Until that's fixed, the port's Owens fires from a clear line a short walk away.

The other difference is paint. The original dresses the machine you drive in your team's red. The port does that for the Summoner so far, but not yet for the Owens or the VTOL.

How the clips are made

The original runs in an Xbox emulator on my machine, from the same disc image the port reads all of its data from. A script restores a saved moment of a Deliverance match, puts the machine at an exact spot and heading, and then presses the controller's buttons on a timer while it records.

The port runs in headless Chrome on WebGPU under a recorder that advances the game exactly two simulation ticks per frame and screenshots each one, so the same inputs always produce the same clip. The two recordings are lined up on the frame where the motion starts and cut to the same length.

The agents have used this rig for weeks to check their work against the original. It also lets them read the running game's memory, so a number like a missile's speed off the rail is measured rather than guessed. This is the first time the comparisons have been put together as video.

Jumping, flying, wading

A Summoner fires its jump jets and lands. The flame swells and shrinks on the original's own rhythm, the side plumes come from the jets' settings on the disc, and the smoke column rides with the jets. The original's landing still kicks up more smoke.
Red's VTOL leaves its bay and heads out over the swamp, with the original's engine glow, ground dust and a contrail off each side. The port's VTOL still climbs too slowly, so it skims treetops the original clears.
A Summoner wades into the swamp and backs out again, throwing the original's splash from wherever each foot lands. The port's water is still too light and too yellow, and its spray is fainter.

What landed this week

In the eight days from October 5th, 150 changes landed. Each one was built by an agent, attacked by a second agent whose only job is to break it, fixed where it broke, and merged once the pipeline passed. Most of them show up somewhere in the clips above:

  • Light. Energy weapons get the original's bloom, drawn the same way the Xbox drew it. The ground now uses the original terrain shader's math, which took Deliverance from up to 1.7 times too dark to within about 15 percent. Lights cast pools on the ground, slopes catch the sun from the correct side, and flames pulse and flicker.
  • Hits and wrecks. Hits leave glows and scorch marks, and rounds that miss blast the ground, raise dust and splash water. A destroyed 'Mech falls away from the shot that killed it, anything killed in the air keeps flying until it crashes, and wrecks burn for 13 seconds before they shrink away.
  • Weapons. Guns scatter more as they heat up, then overheat and wait to cool. Missiles leave at the firing machine's speed and build up from there. Each arm fires from its own barrel, and hits wear down the legs as well as the torso.
  • New systems. Defenses: anti-missile fire, a glass-like cloak, jamming and shields, with the HUD's DEFENSE gauge. Wrecks drop glowing salvage that repairs you or upgrades a weapon, and the VTOL can load power-ups at a pad and drop them anywhere on the map.
  • The AI. Computer pilots strafe, dodge, back off and hop with their jets the way the original's do. They aim their torsos, lead their shots, miss like the original's, and fight an actual war: every third pilot pushes for the enemy generator.
  • Sound. Deliverance's music, the menu sounds, the announcer calling out each generator's damage, and the generators' hum.
  • Feel. The camera's view narrowed from 44 degrees tall to the original's 33, so the 'Mech fills the screen the way it should. On a gamepad, turning eases up to speed and aiming slows as the sights cross an enemy, both as in the original.
  • On foot. The pilot climbs into and out of the power armour, which raises its cannon, flinches when hit and backpedals instead of turning around.
  • Behind the scenes. A second build machine takes the heaviest jobs, and every deploy boots the game in Firefox before it goes out.

The project also stepped past Deliverance for the first time. The title screen now opens a hub with Campaign and Multiplayer. RushHour, a city map from the original's multiplayer list, became the second map you can play Base War on. And multiplayer has a plan: one player's browser hosts the match and the others join it directly with a room code or an invite code, with no server of mine in between. Two browsers can already link up that way, though the game doesn't use the link yet.

An Atlas seen from behind at the edge of RushHour, looking out over a city of dark spired towers lit from below, with the HUD's gauges, radar and weapon card around it
RushHour, the second Base War map: an Atlas walking out of Red's base toward the towers.

By the numbers

Measured the same way as last time:

Oct 3Oct 12
Hand-written game code~30,000 lines~45,900 lines
Source files241369
Largest file499 lines499 lines
Test code~86,000 lines~125,000 lines
Commits~3,300~5,100

About half again as much game code in nine days, and the largest file still sits one line under the 500-line limit.

A week's usage in a day and a half

Not everything went well. Right around the last post, the project burned through the entire weekly usage limit of a $200-a-month Claude Max plan in a day and a half.

In that post I mentioned moving the implementers to Claude Sonnet 5.5 to keep costs down. That was part of the problem. Most of it was how Claude Code was configured.

I had Claude go through its own logs for the week: 64,230 model calls from 435 sub-agents and two orchestrators, about 3.4 billion tokens once cache reads, cache writes and output are weighted by roughly what they cost. Where it went:

  • 55%: agents re-reading their own context. Every step an agent takes sends everything it has seen so far, and these contexts typically ran 200,000 to 400,000 tokens a step, the biggest close to a million.
  • 33%: rewriting that context into the cache. Claude Code caches a conversation for five minutes by default, and the sub-agents were on that default. But they spent much of their time waiting on 13-to-20-minute test runs, so nearly every time one woke up, its cache had expired and the whole context was written to the cache again, which costs more than ten times as much as reading it back.
  • 2%: the actual output. The code and reports the agents wrote barely registered.

Sonnet at extra-high effort made it worse. It took up to twice as many steps as Opus and carried bigger contexts (about 410,000 tokens a step against 270,000), burning roughly 840 million weighted tokens a day to Opus's 590 million.

The fix was three lines of local settings:

.claude/settings.local.json
{
  "subagentPromptCacheTtl": "1h",
  "autoCompactWindow": 300000,
  "bashOutputMaxChars": 10000
}

A one-hour cache means an agent comes back from a test run to a warm cache. Compacting against a 300,000-token window keeps contexts from growing toward a million. Capping shell output at 10,000 characters stops one noisy test log from flooding an agent's context.

The process changed too. Implementers and fixers went back to Opus 5.5 at medium effort. No agent runs the full test suite anymore; the merge pipeline does. A change gets at most two adversarial reviews, after one had gone through 13 agents. And each fix pass starts a fresh agent with a short brief, instead of resuming one that drags 400,000 tokens of history into every step.

With those changes, the same plan carried up to six agents working in parallel this week, and the 150 changes above. I'd still rather burn through a week's usage fast than make it last, but now it buys a lot more.

What's next

The gaps these clips found go on the list: the VTOL that eats missiles, the team paint, the water's colour and the dimmer explosion. After that comes the first step of the multiplayer plan, a match that holds more than one player.

More to come as it develops.