Building
This page explains how to build each part of Un-Banished from source: the game, the viewer, the command-line tools, the mod manager, the multiplayer relay, the browser versions and this website. The setup guide explains how to install Rust and Git on Windows, macOS and Linux.
What you need
| Tool | Needed for | Install |
|---|---|---|
| Rust (stable) | everything | https://rustup.rs |
| Git | getting the code, the build id | your system's package manager |
| ALSA headers (Linux only) | sound | sudo apt install libasound2-dev pkg-config |
The wasm32-unknown-unknown target | the browser versions | rustup target add wasm32-unknown-unknown |
| Trunk | the browser versions | cargo install trunk |
| Python 3 | the scripts in tools/ | your system's package manager |
| Node.js 22 | this website | https://nodejs.org |
| A copy of Banished 1.0.7 | running anything, and most tests | Steam or GOG |
Copy your game data into the project
Most tools and tests read the game data from game-data/ in the project folder. Git ignores this folder. Copy your data into it once:
tools/extract-assets.sh # looks in the usual Steam folders
BANISHED_DIR="/path/to/Banished" tools/extract-assets.shBANISHED_DIR is the folder that contains WinData. The script copies the four .pkg files to game-data/original/WinData/. For the research tools, it also does these things:
- it copies the original program files (
.exe,.dll) togame-data/original/; - it extracts every resource to
game-data/extracted/; - it writes the checksums of the copied files to
game-data/MANIFEST.sha256; - if FFmpeg is installed, it decodes every sound to MP3 in
game-data/derived/audio/.
In a second checkout (git worktree)
A git worktree (AI coding agents often work in one) has none of the ignored folders. Link them to the main checkout instead of copying them, and tell Git to ignore the links. A link is a file to Git, so the /game-data/ rule in .gitignore does not match it:
main=/path/to/main/checkout
for d in game-data save-game analysis; do ln -s "$main/$d" "$d"; done
exclude="$(git rev-parse --git-common-dir)/info/exclude"
for d in game-data save-game analysis; do grep -qx "/$d" "$exclude" || echo "/$d" >> "$exclude"; done
git status --short # the links must not appearinfo/exclude is shared by every worktree of the repository and is never committed.
The game
cargo build -p banished-app --release
target/release/banished # reads game-data/original/WinData
target/release/banished /path/to/WinData # or any other WinData folderThe package is called banished-app; the program is called banished. Always build with --release to play: a debug build is too slow. The workspace builds its dependencies with optimisation even in debug builds ([profile.dev.package."*"] in Cargo.toml), so a debug build of the game is usable for stepping through code.
The game's README lists every command-line option.
The viewer, the command-line tools, the mod manager and the relay
cargo run -p banished-viewer --release # browse models, textures, sounds, dialogs
cargo run -p banished-cli --release -- export-audio # decode every sound to MP3 (needs FFmpeg)
cargo run -p banished-cli --release -- nexus search terrain # mods from Nexus Mods
cargo run -p banished-modmanager --release -- path/to/WinData # the mod manager, banished-mods
cargo run -p banished-relay --release # the multiplayer relay, on 0.0.0.0:7780See the READMEs of the viewer, the command-line tools, the mod manager and the relay. The mod manager's Play starts banished from beside itself (or from the PATH), so build both into the same target/release folder.
The browser versions
The game and the viewer also build for WebAssembly. Trunk builds the program, writes the HTML page next to it and serves both.
rustup target add wasm32-unknown-unknown # once
cargo install trunk # once
tools/dev-web.sh --app game --release # the game: http://127.0.0.1:8733/?data=/game-data/
tools/dev-web.sh --release # the viewer: http://127.0.0.1:8731/?data=/game-data/tools/dev-web.sh also serves your game-data/ folder on port 8732, so ?data=/game-data/ loads your game data without the file chooser. Without ?data=, the page asks you to choose the four .pkg files. The script uses its own target folder, target/web, so it does not block other Cargo builds. Do not make this server available on the internet: it serves your game files.
To check that the browser version compiles without starting a server:
cargo build --release -p banished-app --target wasm32-unknown-unknownThis build must finish with no warnings.
The build id
The version of a build looks like 0.2.0-93be55d. The first part is the workspace version, from [workspace.package] in Cargo.toml. The second part is the build id. apps/game/build.rs chooses it, in this order:
- the
UNBANISHED_BUILDenvironment variable, if it is set; - the short git commit hash (7 characters), with
-dirtywhen tracked files have changes; - the
GITHUB_SHAenvironment variable; unknown.
banished --version prints it.
This website
The website is in site/. It uses VitePress. Most pages are made from files in the repository by site/scripts/prepare.mjs, so the site and the repository say the same thing. Edit the file in the repository, not the generated page in site/.
npm --prefix site ci # once
npm --prefix site run dev # a local preview with live reload
npm --prefix site run build # the full build; it fails on a dead linkTwo parts of the site are built separately, because they take longer:
site/scripts/build-game.sh # the browser game, for the Play page (site/public/game/)
site/scripts/build-api.sh # the Rust API documentation (site/public/api/)The GitHub workflow .github/workflows/site.yml runs all three steps and publishes the site to GitHub Pages after each push to main.
Separate target folders
Several builds can run at the same time if each one uses its own target folder. The project uses these:
| Folder | Used by |
|---|---|
target/ | normal builds |
target/web | tools/dev-web.sh |
target/compat | tools/compat/build.sh (builds of other revisions) |
target/profiling | profiling builds with line tables (see Performance) |
target/api | site/scripts/build-api.sh |