diff options
Diffstat (limited to 'docs/building.md')
| -rw-r--r-- | docs/building.md | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/docs/building.md b/docs/building.md new file mode 100644 index 0000000..9c9609b --- /dev/null +++ b/docs/building.md @@ -0,0 +1,114 @@ +# Building + +## Quick start + +```bash +nix develop # or let direnv do it: the repo's .envrc says `use flake` +cargo run --release # play a game (computer against computer by default) +cargo test +``` + +Without Nix, any stable Rust toolchain from **1.87** on works (the code uses +`unsigned::is_multiple_of`, stabilised in 1.87). The flake currently pins rustc 1.95. + +```bash +rustup toolchain install stable +cargo run --release +``` + +Always use `--release` (or the `profiling` profile) for anything that searches or trains. A debug +build searches many times slower, so the computer players reach much shallower depths in the same +time limit and training takes hours longer. + +## The toolchain: Nix + +| File | Purpose | +|------|---------| +| `flake.nix` | The real definition: the package and the dev shell | +| `flake.lock` | Pins the exact revisions of the flake's inputs | +| `.envrc` | `use flake`, so [direnv](https://direnv.net) enters the dev shell when you `cd` in | +| `shell.nix`, `default.nix` | flake-compat shims, so `nix-shell` and `nix-build` work without flakes | + +### Flake inputs + +| Input | Used for | +|-------|----------| +| `nixpkgs` (26.05) | Everything: rustc, cargo and the dev tools | +| `naersk` | Builds the crate as a Nix package (`defaultPackage = naersk-lib.buildPackage ./.`), reading `Cargo.lock` so dependencies are fetched reproducibly | +| `flake-utils` | `eachDefaultSystem`, so the package and shell exist for every common platform | + +### What the dev shell provides + +| Tool | Why it's there | +|------|----------------| +| `cargo`, `rustc` | Building and testing | +| `rustfmt` | Formatting (but see the note on style below) | +| `clippy` | Lints: `cargo clippy` | +| `rust-analyzer` | Editor support; the shell sets `RUST_SRC_PATH` so it can find the standard library's source | +| `pre-commit` | Git hook runner, for anyone who sets up hooks | +| `perf`, `samply` | Profiling the search (see [Benchmarking and profiling](benchmarking.md)) | + +`nix build` builds the release binary into `./result/bin/tigers-and-sheep-rs`. This is also what +the GitHub workflow in `.github/workflows/build_nix.yml` runs on every push. Note that `.github` is +currently listed in `.gitignore`, so that workflow only exists locally and isn't committed. + +## Crate dependencies + +The crate keeps its dependencies few. Everything else (the board, the search, the neural network, +its optimiser, the random number generator, the weights file format) is written by hand. + +| Crate | Version | What it does here | +|-------|---------|-------------------| +| [`ratatui`](https://ratatui.rs) | 0.30 | The terminal UI: layout, bordered panes, paragraphs and the `Widget` trait that `BoardView` and every `Player` implement. It re-exports `crossterm`, which the game uses through `ratatui::crossterm` for raw mode, mouse capture and reading key and mouse events. Don't add `crossterm` as a direct dependency: the re-export keeps the two versions in step. | +| [`clap`](https://docs.rs/clap) | 4.6, feature `derive` | The command line (`Cli`, `Command`, `PlayArgs`, `TrainArgs` in `main.rs`), including `--help` text taken from the doc comments | +| [`rayon`](https://docs.rs/rayon) | 1.12 | Parallelism for training only: self-play games and matches run across all cores, and the network's gradient and loss are computed in parallel chunks. The game itself is single-threaded. | + +## Cargo profiles + +| Profile | Command | Use | +|---------|---------|-----| +| `dev` | `cargo build`, `cargo test` | Day-to-day development and tests | +| `release` | `cargo run --release` | Playing and training | +| `profiling` | `cargo build --profile profiling` | Release optimisations plus debug info, so profilers can show function names and source lines. The binary lands in `target/profiling/`. | + +## Cargo features + +| Feature | Effect | +|---------|--------| +| `search-stats` | Counts nodes, leaves, cache probes and hits, cutoffs and more during the search, and makes `bench` print them. Without it the `count!` macro compiles to nothing, so it costs nothing. | + +Run the tests both with and without it when touching the search, since some code only exists in +one configuration: + +```bash +cargo test +cargo test --features search-stats +``` + +## Running + +```bash +cargo run --release -- --help +cargo run --release -- -S human -T claude --time 5 # you play sheep against ClaudePlayer +cargo run --release -- -S weights/latest.bin -T human # a trained network plays sheep +cargo run --release -- train 50 500 weights # train a network +cargo run --profile profiling -- bench 9 # time the search +``` + +The game needs a terminal that supports mouse reporting and Unicode box-drawing characters; any +modern terminal emulator does. The board grows to fill whatever space the window gives it. + +## Generated files + +| Path | What | In git? | +|------|------|---------| +| `target/` | Cargo's build output | No | +| `result` | Symlink to the `nix build` output | No | +| `weights/` | Trained networks, `gen-NNN.bin` and `latest.bin` | No | +| `.direnv/` | direnv's cache of the dev shell | No | + +## Code style + +Tabs for indentation and braces on their own line (Allman style). A few trait-impl blocks use +4-space indentation. `cargo fmt` would reformat the whole crate to a different style, so only run it +on a file you're happy to see restyled, never across the crate. |
