Zappy Runner¶
The Zappy Runner is a command-line orchestrator that builds and launches the full Zappy server/AI/GUI suite for development or testing. It uses nix (or nom) to build binaries (from local or remote sources) and spawns the server, multiple AIs, and the GUI with consistent configuration.
It is designed to simplify:
Building derivations with custom settings (branches, local sources, debug modes)
Managing multiple team AI clients
Logging output for debugging
Coordinating the launch of all components
This document explains how to use the runner, its options, and how it works internally.
Running the tool¶
You can invoke the runner via Nix:
nix run github:Sigmapitech/zappy/zappy-runner -- --help
Or to launch a full local game with defaults:
nix run github:Sigmapitech/zappy/zappy-runner
Basic Usage¶
By default, this will:
Build the Zappy server, AI, and GUI derivations
Launch the server on port 4242 with a 10x10 map
Start 2 AI clients per team (3 teams)
Start the GUI
Connect all clients automatically
You can customize almost every parameter with CLI flags.
Example invocations¶
Use local server and GUI sources (without pulling from GitHub):
nix run github:Sigmapitech/zappy/zappy-runner -- --local-server --local-gui
Pin server and GUI to specific branches:
nix run github:Sigmapitech/zappy/zappy-runner -- --branch-server fix-map-bug --branch-gui new-theme
Run with debug server build:
nix run github:Sigmapitech/zappy/zappy-runner -- --debug-server
Full CLI reference¶
These are all available command-line options:
Option |
Description |
Default |
|---|---|---|
|
Map width in tiles |
10 |
|
Map height in tiles |
10 |
|
Number of teams |
3 |
|
Number of AI clients per team |
2 |
|
Initial capacity of players per team on the server |
200 |
|
Server frequency (game ticks per second) |
100 |
|
Server port |
4242 |
|
Server host address for AI and GUI connections |
0.0.0.0 |
|
Force using reference GUI derivation |
|
|
Force using reference server derivation |
|
|
Use |
|
|
Build GUI, server, and AI from independent branches |
|
|
Override GUI branch |
None |
|
Override server branch |
None |
|
Override AI branch |
None |
|
Use local source for AI |
|
|
Use local source for GUI |
|
|
Use local source for server |
|
|
Use server build with debug instrumentation |
|
|
Use simple team names like team1, team2, team3 instead of generated names |
|
|
Don’t launch the server process |
|
|
Don’t launch the GUI process |
|
|
Don’t launch any AI clients |
|
|
Write separate log files in |
|
|
Wait for Enter before starting AI and GUI |
Log files¶
If you use --split-logs, the runner will create a logs/ directory and save separate log files for:
Server output
Each AI client
GUI
It also writes a .gitignore to exclude logs from version control.
Team names¶
By default, the runner generates unique, random, pronounceable team names (like Zavria or Plouvenek). Use --basic-team-names to get deterministic names: team1, team2, etc.
Branches and Sources¶
You can control precisely which code is built:
By default, all components build from the
zappy-runnerflake input (same branch).--respective-brancheslets you specify different branches for server, GUI, AI.You can also force use of local sources (no branch) or official reference derivations.
How it works¶
When you run the runner:
It parses CLI options and computes build settings (bitmask flags).
It resolves source derivations (with branches, local overrides, or reference builds).
It runs
nix buildornom buildfor the required derivations.It extracts the binaries from the Nix build outputs.
It launches: - The server process (if not disabled) - Multiple AI processes (per team and init count) - The GUI process (if not disabled)
It manages their lifecycles and shuts them down cleanly on interrupt.
Nix Build System¶
All building is done via Nix (or Nom if specified). The runner supports:
Selecting branches (for testing specific changes)
Local development builds (no GitHub fetch)
Reference derivations (stable baseline)
This ensures reproducible builds and simplifies testing multiple configurations.
Interrupt Handling¶
If you interrupt the runner (Ctrl+C), it gracefully terminates all subprocesses to avoid zombie processes.