Skip to content

drivasperez/dmars

Repository files navigation

dmars

A Redcode assembler and Core War simulator, written in Rust.

dmars.drpz.xyz · browser playground

Core War is the 1984 programming game in which warriors — self-modifying programs written in a pseudo-assembly language called Redcode — battle for control of a circular memory array called the core. The last warrior with a running process wins.

dmars is a reimplementation of pMARS, the canonical Core War toolchain. The assembler handles the full ICWS'94 preprocessor and produces load-file output byte-compatible with pmars -A. The simulator runs battles between assembled warriors, with ICWS'88 restrictions available behind a flag.

The same core compiles to WebAssembly, which powers the browser playground — write and fight your own warriors, or load any of the 503 classics from the bundled hill corpus.

The dmars playground: Cannonade vs Gamma Paper 3.0

Install

Shell installer (macOS and Linux):

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/drivasperez/dmars/releases/latest/download/dmars-installer.sh | sh

Cargo:

cargo install --locked --git https://github.com/drivasperez/dmars

Pre-built binaries are available on the latest GitHub release.

Usage

dmars assemble warrior.red            # assemble Redcode into an ICWS'94 load file on stdout
dmars assemble -o warrior.rc warrior.red   # write the load file to a path instead
dmars assemble -8 warrior.red         # enforce ICWS'88 restrictions (pMARS -8)
dmars run a.red b.red                 # run warriors against each other in the simulator
dmars run -f -r 100 a.red b.red       # fight 100 seeded rounds and report the score
dmars watch a.red b.red               # visualise a battle in an interactive terminal UI
dmars --help                          # full options

The CLI follows pMARS conventions throughout — core size, cycle and process limits, read/write windows, and fixed (--position, pMARS -F) or checksum-seeded (-f) positioning all behave identically, down to the round-by-round RNG sequence.

Performance

When running a single battle, dmars roughly matches pMARS's performance. It is significantly faster when running many battles: rounds that never read P-space are provably independent, so dmars run spreads them across every core (warriors using LDP/STP automatically run serially, preserving pMARS semantics).

500 rounds, Aeka vs Flash Paper, on an Apple M3 Pro — identical tallies both ways (7 11 482):

command time
pmars -b -f -r 500 aeka.red flashpaper.red 0.77 s
dmars run -f -r 500 aeka.red flashpaper.red 0.10 s (7.5×)

pMARS 0.9.4 compiled -O3; dmars single-threaded (-j 1) runs the same 500 rounds in 0.78 s.

Development

Build with cargo build; test with cargo t (an alias for cargo-nextest). Correctness is enforced by an oracle suite: the vendored pMARS 0.9.4 source (doc/pmars-0.9.4/) is compiled on demand and every battle outcome, listing, and RNG position sequence is diffed against it. Benchmarks run with cargo bench, and the website (including the wasm build of the assembler and simulator) lives in site/.

License

dmars is licenced with GPL-2.0-or-later, matching pMARS. dmars is mostly not a direct port of pMARS, but it was written with the pMARS source open on the other screen, and some of it (notably the positioning RNG) is a direct port, so it honours the license of the original by Albert Ma, Na'ndor Sieben, Stefan Strack, and Mintardjo Wangsawidjaja. The vendored pMARS source in doc/pmars-0.9.4/ retains its own notices. The warriors in warriors/ and warriors/corpus/ are historical community works by their respective authors, bundled for testing and for the playground. No copyright is claimed and if any of the authors request their warrior's removal, I will honour it. But I imagine nobody will mind.

About

Corewar

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors