An open API service indexing awesome lists of open source software.

https://github.com/lewster32/chaos-disassembly

Annotated dissasembly of Chaos: The Battle of Wizards (1985)
https://github.com/lewster32/chaos-disassembly

gamedev sinclair-zx-spectrum z80-assembly

Last synced: about 2 months ago
JSON representation

Annotated dissasembly of Chaos: The Battle of Wizards (1985)

Awesome Lists containing this project

README

          

# Chaos Disassembly

An annotated disassembly of [Chaos: The Battle of Wizards](https://en.wikipedia.org/wiki/Chaos_(1985_video_game)) (Julian Gollop, 1985) for the ZX Spectrum 48K, produced with [SkoolKit 10.0](https://skoolkit.ca/).

**Browse the rendered site:** [archaos.co.uk/chaos-disassembly](https://www.archaos.co.uk/chaos-disassembly/)

The output is a browsable HTML site with labelled routines, annotated data tables, creature sprites, sound-effect previews, and cross-referenced spell and creature stats. Custom memory-map pages group the engine into thematic chunks (Spell selection and casting, Movement and combat, Computer AI).

## AI disclaimer

_The following paragraph has been written by a real person; everything else is probably AI-generated._

While this project has been supervised by a knowledgeable human (me, [Lewis Lane](https://www.rotates.org)) the immense amount of heavy lifting has been performed tirelessly by [Claude Code](https://claude.ai/). Its accuracy can therefore not be guaranteed; I don't know Z80 assembly, nor have I spoken to Julian Gollop at any length about the original game's development. Everything presented here is a mixture of research and reference materials from others who have almost certainly done things the old fashioned way, my own knowledge of the game, and a lot of LLM magic.

## Layout

```
sources/ everything the build consumes
chaos.ctl primary annotation file (this is what you edit)
chaos.ref SkoolKit config (paths, custom pages, page index)
pages.ref [Page:*] definitions for the custom HTML pages
bugs.ref [Bug:*] entries
glossary.ref [Glossary:*] entries
chaos.py ChaosHtmlWriter subclass that renders the live tables
chaos.css site stylesheet (overlays skoolkit.css + dark theme)
chaos.js sortable tables and the custom audio player
chaos.woff/.woff2 Chaos web font
chaos.z80 game snapshot (input to sna2skool)
chaos.rzx game recording (input to the trace harnesses)
chaossounds.json beeper-effect parameter table

tools/ build, generation and research scripts
gen_sounds.py beeper WAV synthesiser, run by update.sh
trace_beams.py capture beam-flight sounds via the trace harness
encode_sounds.py WAV -> Opus/OGG converter (needs ffmpeg, falls back to WAV)
gen_beams.py beam GIFs, run by update.sh
gen_favicon.py favicon.ico from the Blob sprite, run by update.sh
trace_magic_wood.py Magic Wood placement trace (research)
serve.py local dev server with browser auto-reload
*.py archived one-shot research / patch scripts

reference/ read-only reference material
chaos-manual.md, chaos-rules.md, creatures.md
chaos-mapped-utf8.ctl, chaos-guesser.ctl, chaos-guesser.skool
zxs48rom.asm, ZXS48.ROM
alignment.ts TS reference for the spell-alignment math

chaos/ generated HTML site (gitignored)
```

## Prerequisites

- Python 3.x
- [Pillow](https://pillow.readthedocs.io/) (for the favicon and beam GIFs)
- SkoolKit 10.0 - either checked out into `skoolkit-src/` or installed via pip:

```
pip install -r requirements.txt
```

- [ffmpeg](https://ffmpeg.org/) - used by `tools/encode_sounds.py` to compress the synthesised beeper WAVs into Opus/OGG (~95% smaller). The build falls back to shipping uncompressed `.wav` if ffmpeg isn't on `PATH`, so this is technically optional, but the rendered site is much lighter with it. Windows install:

```
winget install --id=Gyan.FFmpeg -e
```

(or `choco install ffmpeg` / `scoop install ffmpeg`). On macOS use `brew install ffmpeg`; on Debian/Ubuntu `sudo apt install ffmpeg`.

## Building

```
bash update.sh
```

The script runs from the project root:

1. `sna2skool` reads `sources/chaos.z80` + `sources/chaos.ctl` and writes `sources/chaos.skool`.
2. `tools/gen_sounds.py` synthesises beeper WAVs into `chaos/audio/sounds/`.
3. `tools/trace_beams.py` captures the beam-flight sounds that need the trace harness.
4. `tools/encode_sounds.py` compresses the WAVs to Opus/OGG via ffmpeg (skipped with a notice if ffmpeg is missing).
5. `tools/gen_beams.py` renders beam-animation GIFs into `chaos/images/beams/`.
6. `skool2html` renders `sources/chaos.skool` + the ref files into `chaos/`. SkoolKit's `[Game] AudioFormats` default makes it auto-prefer the `.ogg` siblings of any `#AUDIO0(...wav)` macro, so no source edits are needed when the encode step runs.
7. `tools/gen_favicon.py` writes `chaos/favicon.ico` from the Blob sprite.

Open `chaos/index.html` to browse the result, or use the dev server:

```
python tools/serve.py # http://localhost:8080
python tools/serve.py 9000 # custom port
```

The dev server auto-reloads any open browser tabs after each `update.sh` run.

## What's annotated

- **Spells** - all 65 records at `$7D60` with casting chance, range, alignment bias, sort key, and dispatch routine.
- **Creature stats** - 38-byte records for every creature and structure, with sprite UDGs and live casting-chance lookup from the spell table.
- **Sound effects** - 10-byte beeper records with embedded WAV preview and a custom audio player.
- **Beams** - the six beam types rendered by the Bresenham line routine at `$B626`, each with a per-beam GIF preview.
- **Sprites** - creature, wizard, font, and effects/UI blocks rendered as UDG arrays.
- **Custom memory maps** - `Spell selection and casting` (`$9168-$97CD`), `Movement and combat` (`$AC36-$B60A`), `Computer AI` (`$C63D-$CDD2` + `$D3F0`).

## Editing tips

- Edit `sources/chaos.ctl` only. `sources/chaos.skool` is generated and overwritten on every build.
- All addresses in `chaos.ctl` use `$XXXX` hex (uppercase).
- Stick to ASCII in `sources/*.ctl` and `sources/*.ref` - SkoolKit decodes them as ASCII. Use HTML entities (`×`, `✓`, etc) for symbols.
- See `CLAUDE.md` for the full annotation conventions.