Skip to main content

Crate banished_game

Crate banished_game 

Source
Expand description

§banished-game

The rules of Banished 1.0.7, ported to Rust: citizens and their lives, jobs and professions, construction, production, farming, trade, wildlife, the weather, and disasters. Each ported function names the original function it came from, keeps the original’s order of arithmetic and its float precision, and draws random numbers in the same order. Tests compare the results with output from the original functions in the emulator, and with real save files.

The crate has no graphics, windows or sound, and it is deterministic: the same inputs and the same seed always give the same results. The game program (apps/game) owns the town’s state and calls these rules every simulation step.

§Modules

The modules are grouped by domain. Each folder’s mod.rs says what it holds.

FolderWhat it contains
peopleCitizens: ages and lives, households, names, needs, health, happiness, services, status counters, immigration, burial
behaviourHow characters act: the citizen AI and its activities, the agents that run citizens and animals, action stacks, animation, commuting
workThe work economy: the job manager, professions, construction and demolition, production recipes, storage, building controls, roads
productionWorkplaces that gather or grow resources: quarries and mines, foresters, herbalists, hunters, fishing docks, crop fields, orchards, pastures
commerceMarkets, the trading post and the trader boats
natureResource seeding and spawning, growth, wildlife, and the environment (temperature and weather)
worldThe gameplay map and its cells, bridges, building placement, terraforming
disastersFire, crop blight, tornadoes
town.rs, town/The simulation context that jobs and construction run in (Sim), with its methods split by topic: geometry, orders, construction sites, buildings, clearing, piles, storage, the state callbacks and the job manager’s work slots
events.rsThe event log and stock warnings

It also re-exports the crates it builds on, so that one dependency is enough:

PathIs the same as
banished_game::{calendar, crt, math, noise, picking, random, scheduler}the modules of banished-core
banished_game::terrainthe banished-terrain crate
banished_game::{pathfind, sectors}the modules of banished-path

§Use it

[dependencies]
banished-game = { path = "crates/game" }
banished-formats = { path = "crates/formats" }

§Name a citizen

Names come from the game’s name databases (Game/Names/Male, Female and Cities). The same seed gives the same names as the original.

use banished_formats::names::NameDatabase;
use banished_formats::pkg::Archive;
use banished_game::people::names::generate;
use banished_game::random::Random;

fn three_names(archive: &Archive) -> banished_formats::Result<Vec<String>> {
    let db = NameDatabase::read(&archive.read_ref("Game/Names/Male.rsc:resource")?)?;
    let mut rng = Random::new(7);
    // A first name has 3 to 10 letters; a town name has 5 to 20.
    Ok((0..3).map(|_| generate(&db, &mut rng, 3, 10)).collect())
}

§Find the start of a new town

world::map::Map classifies every cell of a generated terrain. find_start finds the town’s start cell as the original does: in rings outward from the centre of the map, the first place where every cell within radius is buildable ground. The start condition profile gives the radius (map_generator(...).start_radius).

use banished_game::terrain::{Generator, HeightGrid};
use banished_game::world::map::Map;

fn start_cell(generator: &Generator, radius: i32) -> (i32, i32) {
    let heights = generator.heights();
    let terrain = HeightGrid { width: generator.width(), heights: &heights };
    // The gameplay map is the central n × n cells of the 2n-cell terrain.
    let map = Map::new(generator.record.half_size() as usize, &terrain);
    map.find_start(radius)
}

banished-terrain shows how to make the Generator.

§More

The rest of the crate is the simulation itself. The best way to learn it is to read the topic documents, then the module that ports the part you are interested in:

§Tests

cargo test --release -p banished-game

The unit tests run without game data. The tests in tests/ compare with emulator output or with real saves. Each one names the generator in tools/emu/ that makes its data, and skips when the data is missing. For example:

TestWhat it checks
terrain_emuEach terrain generation stage, the cell types, the mesh and the start point
savesThe terrain of real saves, regenerated from their seed and settings
names_emuCitizen and town names
astar_emu, regions_emu, sectors_emuPath finding
game_loop_emu, time_emuThe simulation step and game time
growth_emu, storage_emu, equipment_emuGrowth, storage and equipment
crt_math, transform, picking_emuThe exact maths of banished-core

§Example programs

examples/ has helpers for animation work: clips (the clips of an animation group), pose_bones, pose_scan and skin_bounds. rng_trace_names records the random draws of name generation, for comparison with the original (see Emulate for exact numbers).

§The API

The full API documentation is at https://tanepiper.github.io/unbanished/api/banished_game/index.html.

Re-exports§

pub use banished_terrain as terrain;

Modules§

behaviour
How characters act: the citizen AI and its activities, the agents that run citizens and animals, characters and their action stacks, animation and commuting.
calendar
The bit-exact foundations, from their own crate (banished-core). The game’s calendar: the year, and the time since the year began.
commerce
Trade: markets, the trading post and the trader boats.
crt
The bit-exact foundations, from their own crate (banished-core). The float functions of the Microsoft C runtime, as the game calls them: sinf, cosf, acosf and atan2f.
disasters
Disasters: fire, crop blight and tornadoes.
events
The town event log (Game) and the stock warnings that post to it. See docs/EVENT-LOG.md.
math
The bit-exact foundations, from their own crate (banished-core). Engine math helpers (Runtime-steam-x64.dll Math::Scalar, Math::Vector2/3) with the original’s precision: the C runtime’s sinf/cosf/atan2f (crate::crt), sqrtf (correctly rounded), and the operations in the original’s order.
nature
The natural world: resource seeding and spawning, growth, wildlife and the climate.
noise
The bit-exact foundations, from their own crate (banished-core). The engine’s Perlin noise, which the terrain generator uses.
pathfind
Path finding (banished-path) and the terrain (banished-terrain), from their own crates. Path finding over the map’s cells: the walkable regions and the A* pathfinder.
people
The citizens themselves: ages and lives, households and names, needs, health and happiness, services they use, status icons, immigration and burial.
picking
The bit-exact foundations, from their own crate (banished-core). Picking: which triangle a ray hits, as the engine finds the object under the pointer.
production
Workplaces that gather or grow resources: quarries and mines, foresters, herbalists, hunters, fishing docks, crop fields, orchards and pastures.
random
The bit-exact foundations, from their own crate (banished-core). The game’s random number generator: a Mersenne Twister (MT19937).
scheduler
The bit-exact foundations, from their own crate (banished-core). Game time, and the entity manager’s update buckets.
sectors
Path finding (banished-path) and the terrain (banished-terrain), from their own crates. The sector graph, and the “path rank” distance that storage, job and resource searches use.
town
The simulation context jobs and construction run in: Sim implements the job manager’s work slots (WorkHost) and the building state callbacks (Callbacks), over the citizens, the map, the storages and the construction state. See docs/JOBS.md.
work
The work economy: jobs and professions, construction and demolition, production recipes, stock and storage, building controls, trackers and roads.
world
The map: its cells, floors (bridges), building placement and terraforming.