How a line is built
A typical line looks like this:
ADD.F source target
ADD is the opcode, .F is the modifier, source is operand A, and target is operand B.
This guide explains the instruction set in your visualizer in plain English. It is written for somebody new to Core War, so the goal is not just to list the commands, but to explain what each one is for, when you would use it, and what common beginner mistakes to avoid.
A and write to B.
DAT, that process dies.
MOV, JMP, DJN, SEQ, and SPL first. That gets you very far.
A typical line looks like this:
ADD.F source target
ADD is the opcode, .F is the modifier, source is operand A, and target is operand B.
Every cell has two numeric fields: an A-field and a B-field. Modifiers decide whether the opcode uses A, B, or both.
DAT 3 5
A B
Example: with ADD.AB, the source A-field is added into the destination B-field.
# ImmediateUse the number itself. Do not treat it as an address.
MOV #5 10
This uses the literal value 5.
A plain number or label points to a memory cell.
MOV bomb target
In this visualizer, bare numeric operands are relative to the current instruction.
* RelativeExplicit relative addressing from the current instruction.
JMP *-3
Good when you want to make “relative” intent obvious.
@ IndirectGo to a cell, read its B-field, then use that as an extra offset.
MOV bomb @ptr
Very common in pointers and scanners.
< PredecrementFirst decrement the referenced cell’s B-field, then use it.
MOV bomb <ptr
Useful for stepping backward through memory.
> PostincrementUse the referenced cell first, then increment its B-field.
MOV bomb >ptr
Useful for stepping forward through memory.
# means “this is a value,” while bare operands, *, @, <, and > all lead to memory addresses in different ways.
Modifiers decide which fields an instruction touches. This is where a lot of Core War power comes from.
Use source A-field and destination A-field.
ADD.A src dst
Use source B-field and destination B-field.
ADD.B src dst
Take source A-field and apply it to destination B-field.
ADD.AB src dst
Take source B-field and apply it to destination A-field.
ADD.BA src dst
Work on both fields pairwise: A→A and B→B.
ADD.F src dst
Cross the fields: A→B and B→A.
ADD.X src dst
Treat the full instruction as the thing being compared or copied.
MOV.I src dst
MOV → .I
ADD SUB MUL DIV MOD → .F
SEQ SNE → .I
SLT JMZ JMN DJN → .B
If a process executes DAT, that process dies immediately.
DAT 0 0
Mostly used as bombs or as data storage, not as a live instruction.
Important: DAT is not the only thing that kills a process. In your visualizer, any invalid instruction execution is also death. If a process steps onto garbage, malformed code, or even a plain 0 that does not decode into a valid instruction, that process dies too.
Copy from operand A to operand B.
MOV.I source target
This is the heart of replicators, bombers, and many scanners.
Add values from A into B.
ADD.F step ptr
Often used to move a pointer through memory.
Subtract values from A out of B.
SUB.F step ptr
Useful for walking backward or counting down.
Multiply B by A.
MUL.B factor target
Less common, but can build unusual stepping patterns.
Divide B by A using integer division.
DIV.B divisor target
Division by zero kills the process with an error.
Replace B with the remainder from B divided by A.
MOD.B divisor target
Modulo by zero is also fatal.
Always jump to operand A.
JMP loop
The simplest loop instruction.
If the tested part of B is zero, jump to A. Otherwise continue normally.
JMZ.B target check
Good for branching on counters or empty-looking data.
If the tested part of B is not zero, jump to A.
JMN.B loop counter
Think of this as the opposite of JMZ.
If the tested part of B is greater than zero, jump to A.
JMG.B alive value
This is a custom instruction in your visualizer, useful for positive-only tests.
First decrement B, then test it. If it is still not zero, jump to A.
DJN.B loop counter
One of the best loop-building instructions in Core War.
First decrement B, then jump only if the result is exactly zero.
DJZ.B done counter
Custom to your visualizer. Great for “jump when the countdown reaches zero.”
If A and B are equal, skip the next instruction.
SEQ.I probe target
Usually used in scanners. Equal means the next line is skipped.
If A and B are different, skip the next instruction.
SNE.I probe target
Useful when you want to react to “something changed here.”
If A is less than B, skip the next instruction.
SLT.B a b
A comparison tool rather than a movement tool.
If A is greater than B, execution continues normally. Otherwise it skips the next instruction.
CMG.B a b
Custom to your visualizer. It behaves like a “greater than” test with skip logic.
Generate a random number and write it into operand B.
RAN #-40 target
In your visualizer, the range is 0..max(0, (CORE-1)+A). So operand A changes the maximum range.
Swap the entire instruction at A with the entire instruction at B.
SWI ref1 ref2
This swaps whole cells, not just a single number.
Pause the current process for A cycles, then resume later.
SLP #5
Useful for timing tricks or slowing part of a warrior down.
Do nothing and move to the next instruction.
NOP
Helpful as a placeholder while testing.
Create a new process at operand A, while the current process keeps going.
SPL child
This is how papers and process-heavy warriors multiply their activity.
| Directive | What it does | Simple example |
|---|---|---|
ORG |
Sets the starting execution point of the program. | ORG start |
EQU |
Defines a constant or reusable expression. | STEP EQU 5 |
| Labels | Name a location so you can jump to it or reference it later. | loop: MOV bomb, @ptr |
EQU, so something like boot+41 can resolve as a numeric expression.
loop JMP loop
start MOV.I source target
JMP start
source DAT 0 0
target DAT 0 0
loop MOV.I bomb @ptr
DJN.B loop count
ptr DAT 0 0
count DAT 0 5
bomb DAT 0 0
Using # when you meant an address. Immediate values are not memory locations.
Forgetting what gets written. Most opcodes change operand B, not operand A.
Using the wrong modifier. .AB and .F are very different.
Jumping into a DAT. That kills the process instantly.
Assuming only DAT kills. In your visualizer, any non-valid instruction is fatal when executed. That means corrupted code, malformed instructions, and simple bombs like 0 can all work as killers.
Spawning too much with SPL. A process explosion can help, but it can also make your own warrior chaotic.
| Opcode | Plain-English meaning | Typical use |
|---|---|---|
DAT | Process dies if it lands here | Bombs, data |
MOV | Copy A into B | Replication, bombing |
ADD | Add A into B | Pointer stepping |
SUB | Subtract A from B | Reverse stepping |
MUL | Multiply B by A | Pattern tricks |
DIV | Divide B by A | Math / niche tricks |
MOD | Remainder of B by A | Range / cycle tricks |
JMP | Always jump | Loops |
JMZ | Jump if B is zero | Branching |
JMN | Jump if B is not zero | Branching |
JMG | Jump if B is greater than zero | Positive-only test |
DJN | Decrement B, jump if non-zero | Countdown loops |
DJZ | Decrement B, jump if zero | “Jump on final tick” loops |
SEQ | Skip next if equal | Scanners |
SNE | Skip next if not equal | Scanners |
SLT | Skip next if A < B | Comparisons |
CMG | Do not skip only when A > B | Custom compare-flow control |
RAN | Write a random value into B | Chaos, experiments |
SWI | Swap two whole cells | Weird control tricks |
SLP | Sleep for A cycles | Timing |
NOP | Do nothing | Padding |
SPL | Spawn a new process | Multi-process warriors |