No description
Find a file
2026-08-02 16:25:00 +02:00
config Make all simulation constants configurable via world.toml 2026-07-20 18:14:10 +02:00
src improve panics 2026-08-02 16:25:00 +02:00
.gitignore Initial commit: fantasy world simulator with 3-level Voronoi generation, ratatui TUI, and deterministic turn-based simulation 2026-07-18 19:48:23 +02:00
AGENTS.md Make all simulation constants configurable via world.toml 2026-07-20 18:14:10 +02:00
Cargo.lock improve codebase 2026-07-31 07:55:32 +02:00
Cargo.toml improve panics 2026-08-02 16:25:00 +02:00
README.md Add headless log mode with --log and --verbose flags 2026-07-20 20:04:18 +02:00
UNLICENSE Add UNLICENSE and comprehensive README 2026-07-20 16:28:36 +02:00

terra-step

Fantasy world simulator — a terminal-based strategy game where procedurally generated worlds evolve through turn-based faction conflict.

Rust 2024 edition, ratatui TUI, deterministic simulation.

Features

  • Procedural world generation — 3-level Voronoi hierarchy (Continents → Provinces → Counties) with Perlin noise terrain (plains, forest, mountain, desert, swamp, water)
  • Turn-based simulation — deterministic AI factions gather income, build armies, construct buildings, and compete for territory
  • 6 species, 12 factions — Elves, Dwarves, Catfolk, Orcs, Merfolk, and Dragonkin, each with unique traits, terrain affinities, and AI behaviors
  • Building system — Farms, Lumbermills, Mines, Barracks, Mage Towers, and Forts, with terrain-specific production modifiers
  • Trait-driven AI — 17 traits (greedy, cruel, expansive, militaristic, etc.) that influence attack decisions and stat bonuses
  • Terminal UI — interactive map with zoom/pan, faction info panel, turn history scrubbing, county browser, and terrain legend
  • Deterministic — same seed always produces the same world and simulation results
  • Fully configurable — all species, factions, terrain, traits, buildings, and world parameters are defined in TOML files

Installation

git clone https://github.com/yourusername/terra-step
cd terra-step
cargo build --release

Requires Rust 2024 edition (Rust 1.85+).

Usage

# Run with default seed (42) for 100 turns
cargo run --release

# Custom seed and turn count
cargo run --release -- --seed 12345 --turns 200

# Headless log mode — print AI decisions to stdout (no TUI)
cargo run --release -- --log

# Verbose log output — full income/army/resource breakdown per faction
cargo run --release -- --log --verbose

# Pipe to a file for analysis
cargo run --release -- --seed 7 --turns 500 --log --verbose > run_7.log

# Show help
cargo run --release -- --help

Log output format

Simple (--log):

=== Turn 1 ===
  Abyssal Trench:  income=43.0  army=50→52  counties=5  stored=(F:71.7 W:43.9 S:23.8 I:10.0 G:49.5 M:12.5)
  Bloodfang Horde → Attack  #97 Laestock  [cost 24G]
  Bloodfang Horde → Build  Barracks in #17 Dark Forest  [cost {wood: 20, stone: 10}]
  Bloodfang Horde → Develop  #3 Blood Plains  [cost 20G, dev 10%→20%]
     Combat for Krofeworth: Sandswept Pride vs Abyssal Trench → Lost!  Losses: 13.2/4.8

Verbose (--log --verbose):

======================================================================
                              Turn 1
======================================================================
--- Abyssal Trench (id=0) ---
  Counties: 5    Army: 50.0
  Income:   +22.8F +13.9W +3.8S +2.5M  (total: 43.0)
  Building army: +0.0   Regen: +2.2   Upkeep: -0.5G  -1.0F
  Army: 50.0 → 52.2
  Stored: Before: F:50.0 W:30.0 S:20.0 I:10.0 G:50.0 M:10.0
          After:  F:71.7 W:43.9 S:23.8 I:10.0 G:49.5 M:12.5
  >> Attack  #97 Laestock  [cost 24G]
  >< Combat for Laestock: Bloodfang Horde (atk) vs Abyssal Trench (def)
     Attack roll: 48.2  Defense roll: 42.1  → Won!
     Losses: atk -4.5  def -7.2

Controls

Key Action
+/- Zoom in/out
Arrow keys Navigate zoom items (map) / scroll faction list (info)
W A S D Pan the viewport
[/] Step back/forward through turn history
Tab Toggle focus between map and info panel
Enter Expand/collapse selected faction (info focus)
n/p Next/previous county (county zoom level)
c Toggle county browser
l Toggle terrain legend overlay
? Toggle help dialog
Space Pause/resume auto-advance
Ctrl+U/Ctrl+D Scroll info panel by 10 lines
Mouse click Zoom to county (map) / select faction (info)
Mouse scroll Zoom in/out
q Quit

Configuration

All game data is defined in TOML files under config/:

File Purpose
world.toml Map dimensions, generation parameters, army regen rate
terrain.toml Terrain types, colors, passability, base resources
species.toml Playable species, stat modifiers, terrain affinities
factions.toml Named factions, species assignment, traits, starting counties
traits.toml Trait definitions with stat bonuses
buildings.toml Buildable structures, costs, production, terrain modifiers

Customization: place config files in ~/.config/terra-step/ to override the bundled defaults. Items are merged by name — project entries override home entries with the same name.

Architecture

src/
├── main.rs              # CLI entry point (clap argument parsing)
├── app.rs               # Application state, turn management, view scrubbing
├── config/
│   ├── mod.rs           # Config loading and merging (home + project)
│   └── types.rs         # Deserialization DTOs (TOML shapes)
├── world/
│   ├── generator.rs     # Voronoi world generation, faction placement
│   ├── types.rs         # Runtime types (World, Continent, County, Faction, etc.)
│   ├── names.rs         # Procedural name generation (syllable-based)
│   └── faction.rs       # (stub)
├── simulation/
│   ├── turn.rs          # Turn loop: income → army regen → AI decisions → combat → snapshot
│   ├── economy.rs       # Income calculation, building production
│   └── combat.rs        # Attack resolution, defense bonuses
├── tui/
│   ├── mod.rs           # Event loop, input handling, layout
│   ├── renderer.rs      # Map rendering, faction borders, labels
│   ├── screens/         # (stub)
│   └── widgets/         # (stub)
└── persistence/
    ├── mod.rs           # (stub)
    └── save.rs          # (stub)

The world is generated as a 3-level Voronoi diagram: continents are seeded from random points, subdivided into provinces, then into counties. Terrain is sampled from 2D Perlin noise (elevation + moisture).

Each turn: factions receive income → regenerate armies → make AI decisions (attack, build, or develop) → contested counties are resolved → a snapshot is recorded. The RNG is seeded from world.seed + turn * 7919 for full determinism.

Testing

cargo test          # 57 tests, all deterministic
cargo check         # 0 warnings expected
cargo clippy        # run before pushing

License

This is free and unencumbered software released into the public domain. See UNLICENSE for details.