Testing a new game against forty years of Core War warriors
How ZoreWars was built in a few days with an AI coding agent, checked against pMARS and more than a thousand historical warriors, and kept clear of GPL code with a clean-room process.

ZoreWars started on October 24, 2026. Four days later it had its own domain, zorewar.app. I built it with Claude Code as a working partner: 69 of its 86 commits so far carry its co-author line. Moving that fast only works if you can tell when something is wrong, so most of this project's design went into checking.
Core War has a gift for that. Its community has spent forty years writing warriors, publishing them, and running them in tournaments on one reference simulator, pMARS. Those warriors make a test suite nobody had to write.
pMARS as the referee
The rule for the classic game was simple: the same warriors go through ZoreWars and pMARS, and every difference is a bug. A comparison script builds pMARS from the Debian source package and checks four things:
- the assembled code, instruction by instruction, for every library warrior and 34 historical originals;
- the winner of single rounds at fixed positions, for every pair (2,550 rounds);
- win and tie totals for full matches with random placement (100 matches);
- matches between warriors that change strategy using P-space, memory that survives between rounds (42 matches).
All of them match. The library alone didn't find the hard bugs, though. Real warriors did.
Letting the archives find the bugs
I ran the 567 warriors of the public n1LS collection through both assemblers. 564 came out identical, and the differences exposed two gaps: a label on the END line, and an EQU that stands for a whole instruction. Then came 703 warriors from the public hills' benchmark collections, each under its own hill's rules. 676 matched at first. The rest traced back to five gaps in how ZoreWars read pMARS's preprocessor, most of them about EQU being plain text substitution rather than a value. After fixing them, all 703 match.
None of these warriors are stored in the project. The tests fetch them from their archives when they run, and the arena does the same when a player imports a classic. Imported files are only ever assembled as Redcode, never run as code.
A clean room for the preprocessor
pMARS is GPL-licensed and ZoreWars is Apache-2.0, so no pMARS code could be copied in. That made the preprocessor awkward: its exact behaviour lives in the source.
The answer was a clean room. One agent read pMARS's assembler and wrote a behaviour specification with no code in it, plus 81 small probe programs and their outputs from a real pMARS build. ZoreWars was then changed from the specification and the probes alone, without the source. 62 probes matched at first. Now 79 do, and the remaining two are deliberate differences, documented with the reasons.
Built for agents, too
Because an agent was doing much of the work, the command-line tool was designed for one. Every command can return JSON. A battle can return a post-mortem for each round: the instruction that killed the last process, who wrote it, process deaths by cause, and whether a warrior was converted into running its opponent's code. An agent can ask why a round was lost instead of guessing from a score.
The tuning tools follow the same idea. tune searches a warrior's constants, then re-checks the finalists on fresh seeds, opponent by opponent. A result only counts if the gain is larger than its noise margin. Without that rule, random search reliably finds settings that look better and aren't.
Studying the history before adding to it
Before adding new dimensions, I wanted to understand how the old one was played. I worked through original newsgroup posts, warrior sources and the Core Warrior newsletters, and kept four kinds of evidence apart: an author's own date, an archive's date, a confirmed lineage, and a source that was merely observed today. That caught real mistakes, such as a warrior our own encyclopedia dated 1995 although it appears in an October 1994 hill report.
The main lesson was that the big advances were rarely new instructions. They were better cooperation between the parts of a warrior: launchers, schedules, handoffs into an endgame. The summary is on the ZoreWars history page, with every claim linked to the original archive. Those archives belong to the people who kept them, so the page points there instead of copying them.
What I'd keep
The pattern that worked: pick an outside referee, feed it real data instead of examples you wrote yourself, and make every tool explain its answers. That's what made it possible to move quickly with an agent and still trust the result.
The project page has the links, and the companion post covers adding a Z axis to Core War.