Core War is a game in which the players never touch the game. Each player writes a small program, a warrior, in an assembly language called Redcode. Two warriors are loaded into the same circular block of memory, the core, and take turns executing one instruction each. A warrior loses when all of its processes have tried to execute a DAT instruction and died. Nothing else exists in the game: no screen, no input, just two programs overwriting each other’s memory.
Below is a full ICWS'94 simulator (a MARS, Memory Array Redcode Simulator) written for this page: an 8000-cell core, up to 8000 processes per warrior and a tie after 80,000 cycles. These are the standard “94nop” hill settings.
How to read the arena#
Every square is one memory cell. Cells are numbered from left to right and top to bottom, and the last cell is next to the first one, so the core has no edges.
- Colour shows which warrior last wrote the cell. Bright means recently written, and the colour fades as the cell gets older. Cells holding a
DATare drawn darker, so you can tell bombs apart from live code. - White dots are processes, the program counters waiting to run.
- White flashes are the instructions that just ran.
- Hover over a cell, or tap it on a phone, to see the instruction inside it.
- Turn on Show code to see the instructions around each warrior’s last executed line, a one-sentence description of what that line did, and arrows on the core pointing to where it wrote, jumped or split. This works best at low speed or with Step (keyboard: →, and Space to pause).
- Finish runs the current battle to the end at once. Tournament plays every warrior against every other one in a background thread and scores them the way King-of-the-Hill servers do: 3 points for a win, 1 for a tie.
- Edit warriors lets you change a warrior or paste your own and send it to fight straight away.
A short history#
1961, Darwin. At Bell Labs, Victor Vyssotsky, Robert Morris and Doug McIlroy wrote Darwin, a game for the IBM 7090 in which programs tried to find and destroy each other in memory. Core War is a descendant of that idea.
1984, the article. In March 1984, D. G. Jones and A. K. Dewdney published the Core War Guidelines. In May 1984, Dewdney’s Computer Recreations column in Scientific American introduced the game to the public with the title “In the game called Core War hostile programs engage in a battle of bits”. The name comes from core memory, the magnetic-core RAM of older computers. The article included the first two famous warriors: Imp and Dwarf.
1986, the first tournament. The International Core War Society (ICWS) was founded in 1985, and the first standard, ICWS'86, appeared in 1986. The first tournament was held the same year. It was won by Mice, a self-copying program by Chip Wendell.
1988 and 1994, the standards. ICWS'88 fixed the instruction set used for years afterwards. The 1994 draft added instruction modifiers (.A, .B, .AB, .F, .I…), new addressing modes and new opcodes. It was never formally ratified, but it became the de facto standard, and this page implements it.
1990s, the Usenet era. The newsgroup rec.games.corewar and the automatic King of the Hill servers turned Core War into a continuous competition. You mailed your warrior to the hill, it fought every warrior already there, and it stayed only if it scored high enough. The reference simulator pMARS dates from this time. Most classic strategies, such as imp spirals, paper (Silk), quick-scanners and core clears, were refined on those hills. A few hills still run today, and the community collects history and warriors at corewar.co.uk.
Redcode in two minutes#
For a visual, instruction-by-instruction guide to the language and a step-by-step debugger, see Redcode, instruction by instruction.
Every cell holds one instruction: an opcode, a modifier and two operands, A and B. Each operand has an addressing mode and a number. All addresses are relative: 1 means “the next cell” and -1 means “the previous cell”. No program knows where it is in the core.
| Opcode | What it does |
|---|---|
DAT | Data. A process that executes it dies. |
MOV | Copy a field, or with .I the whole instruction, from A to B. |
ADD SUB MUL DIV MOD | Arithmetic on fields. Dividing by zero kills the process. |
JMP | Jump to A. |
JMZ / JMN | Jump to A if B is zero / is not zero. |
DJN | Decrement B, then jump to A if it is not zero. |
SEQ (CMP) SNE SLT | Compare A with B and skip the next instruction if the test holds. |
SPL | Start a new process at A. Its own process carries on with the next instruction. |
NOP | Do nothing. |
| Mode | Meaning |
|---|---|
#5 | Immediate: the number itself |
$5 or 5 | Direct: the cell 5 ahead |
@5 | B-indirect: go to cell 5 ahead, then follow its B-field |
*5 | A-indirect: the same, following the A-field |
<5 {5 | Like @ / *, but first decrement the pointer field |
>5 }5 | Like @ / *, but increment the pointer field afterwards |
Processes take turns: warrior 1 runs one instruction, then warrior 2, and so on. A warrior with many processes doesn’t get more CPU time. Its single turn just rotates through the processes in its queue. That is why SPL makes a warrior harder to kill but also slower.
The warriors#
Strategies in Core War form a rock-paper-scissors triangle: stones (bombers) tend to beat scissors (scanners), scanners beat paper (replicators), and paper beats stones. Imps are a fourth element that is hard to kill but rarely kills anything. They are mostly used to force a tie. The simple warriors here follow the triangle only roughly. Run the tournament and watch where they break it.
Imp#
imp MOV.I 0, 1One instruction: copy this cell to the next one. The process then moves to the next cell and finds the same instruction there. The Imp crawls through the core at one cell per turn and leaves a trail of copies behind it. It is almost impossible to kill, because a bomb has to land exactly on the cell it is about to execute. It also almost never wins: when an imp runs into the enemy’s code, it turns that code into imps, so the enemy keeps running too and the battle ends in a tie.
Dwarf, a stone#
dwarf ADD.AB #4, bomb
MOV.I bomb, @bomb
JMP dwarf
bomb DAT #0, #0The first real bomber. Each loop adds 4 to the B-field of bomb and copies the DAT to the address that B-field points to (@bomb). Because 8000 is divisible by 4, the bombs land on every fourth cell. The only part of the Dwarf they ever hit is bomb itself, and overwriting a DAT with a DAT does no harm. Any enemy longer than 3 instructions gets hit sooner or later. When that happens, the enemy process that steps on the bomb dies.
Mice, a replicator#
Mice copies its 8 instructions to a new place (MOV @ptr, <dest in a DJN loop), starts the copy with SPL @dest and moves its target 653 cells further. Each copy does the same. Within a few thousand cycles the core is full of mice, and a bomber can’t kill all of them. This is the strategy that won the first tournament.
Imp Spiral#
Three imps placed 2667 cells apart. Because 3 × 2667 = 8001, the third imp writes the cell right after the first one. The processes move in lock-step, and each imp keeps rewriting the cell the next imp is about to execute. A single DAT bomb can’t stop the spiral, because the next imp in line repairs the damage. The launcher uses SPL to create several processes at each point, so the spiral can also survive losing a few of them.
Paper (Silk-style)#
The modern version of Mice. Three SPL 1 instructions create 8 processes. All 8 run SPL 3620 and then MOV >-1, }-1. Each process copies one line, because the post-increment modes advance both pointers. The new copy starts running before it is even finished, so a paper spreads extremely fast. After copying, the old processes stay behind in a bombing loop. Killing paper means killing every copy, and there can be hundreds of them.
Scanner, scissors#
scan ADD.AB #7, ptr
ptr JMZ.F scan, trap+7Instead of bombing blindly, a scanner looks. It checks every 7th cell and skips the empty ones (JMZ.F jumps back while both fields are zero). When it finds something, it plants a SPL #0 trap there. A process that steps on the trap only creates more stuck processes, which slows the enemy almost to a stop. After one lap around the core, the scanner kills everything that is stuck with a DAT core clear. Scanners are deadly against slow, large targets like paper, but bombers are small and hard to find.
Vampire#
A bomber with a twist. Instead of DAT, it throws fangs: JMP instructions whose offsets always point back into its own pit. ADD.F changes both fields of the fang at once, so the fang’s target stays the pit wherever it lands. An enemy process that executes a fang jumps into the pit and becomes a prisoner. Prisoners run a two-line loop, MOV kill, <pit-10 and SPL -1, that clears the core backwards with DAT while keeping their number constant. When the clear goes all the way around and erases the SPL, every prisoner dies. The step is a multiple of 4, so a fang can only land on the fang itself or on kill, and the pit still works when that happens. That makes the Vampire as regular as the Dwarf. Against the Dwarf it is the bigger target, though, and the tournament shows what that costs.
Write your own#
Open Edit warriors, change a number and press Load & fight. Good first experiments:
- Change the Dwarf’s step from
#4to#3. It will eventually bomb itself. Why? - Give the Imp a partner: put
SPL 1before it. - Change
stepin the Scanner and see how the tournament ranking changes.
The parser supports labels, EQU, ORG/END, arithmetic in operands and the ;name / ;author / ;strategy comments. Write the modifiers explicitly, as in the examples above. If you leave one out, the ICWS'94 default is used.