Go to file
Steve Biedermann a4eb181154 fix(sim): prevent starvation before population can recover
Use terrain-aware pathfinding for travel toward home and resources so settlers do not get stranded against blocked terrain. Add a startup food reserve, slow hunger accumulation, let villagers return for food sooner, ensure available food is consumed before starvation, and make the first birth check available at the first weekly boundary.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-11 18:39:50 +02:00
src fix(sim): prevent starvation before population can recover 2026-10-11 18:39:50 +02:00
ui fix(ui): fall back to polling when websocket is unavailable 2026-10-11 18:28:47 +02:00
.dockerignore feat: add database persistence and Docker setup 2026-10-08 09:10:42 +02:00
.gitignore feat: add database persistence and Docker setup 2026-10-08 09:10:42 +02:00
Cargo.lock feat(sim): integrate Picard actors for living entities 2026-10-11 17:30:28 +02:00
Cargo.toml feat(sim): integrate Picard actors for living entities 2026-10-11 17:30:28 +02:00
Dockerfile feat: add database persistence and Docker setup 2026-10-08 09:10:42 +02:00
Justfile build: update Just workflows for Compose and SQLite development 2026-10-08 09:24:14 +02:00
README.md fix(sim): prevent starvation before population can recover 2026-10-11 18:39:50 +02:00
build.rs build: bundle the Leptos UI during Cargo builds 2026-10-08 09:10:42 +02:00
compose.yaml feat: add database persistence and Docker setup 2026-10-08 09:10:42 +02:00

README.md

World Simulation

A browser-based world simulation with a Rust server and a Leptos/Wasm UI. The server runs the simulation and exposes its state over HTTP and WebSockets. You can edit terrain and resources, manage people and animals, and customize agent behavior with the included Rune script.

Living simulation entities (people, rabbits, and wolves) run as Picard actors. The world coordinates terrain, shared resources, and actor messages; Rune behavior scripts remain on the simulation thread because Rune's VM is not Send.

The Calendar and life-stage durations panel configures ticks per day and the number of days, weeks, and months in larger calendar units. Each human life stage has an inclusive minimum/maximum duration in in-game days; the world samples within that range when a person enters the stage. These settings are stored with the world snapshot.

New people, including babies, start as toddlers and age through child, teen, young adult, adult, older adult, elderly, and death. The starting village is seeded with young and mature adults and a reserve of 60 food so the simulation can work and form the first partnerships immediately. People pathfind around blocked terrain when travelling home for food. Unpartnered people from young adulthood onward can form a single partnership with a nearby eligible person. Each partnership can have one toddler per calendar week when both partners are in stages marked fertile, the stockpile has enough food, and housing capacity permits it. The starting village has capacity for 12 people, with each additional house increasing capacity by three. Young adult and adult stages are fertile by default; fertility can be changed per stage in the calendar panel. Partnerships are Picard actors as well as people and animals.

The UI is built automatically as part of cargo run and embedded in the server binary. There is no separate manual UI build step.

Getting Started

Local run with SQLite

Install Rust with rustup. The build script installs the wasm32-unknown-unknown target if it is missing. Start locally with SQLite using:

just dev

Open http://127.0.0.1:7878. The database is SQLite at sim.db in the current directory, and the initial seed is 42. You can also run directly with cargo run.

To choose a seed on the first run:

cargo run -- 123

An existing database snapshot takes precedence on later runs, including over a new command-line seed. Use the UI's Reset button to start a fresh world with its current seed, or Regenerate to choose a different seed.

Run with Just

Install Just, then list the project recipes:

just

Useful recipes:

just run  # Stop Compose services, then build and start the app with Postgres
just stop # Stop Compose services; keep the database volume
just dev  # Run locally with SQLite

Run with Docker Compose and Postgres

Install Docker with the Compose plugin, then run just run. This stops any existing Compose stack before rebuilding and starting the app with Postgres. You can also use the equivalent Docker command directly:

docker compose up --build -d

Open http://localhost:7878. Compose waits for Postgres to become healthy before starting the app. Postgres data is stored in the postgres_data volume and survives container restarts, just stop, and docker compose down.

To remove the database volume and all saved simulation data as well:

docker compose down -v

The Compose file uses development-only database credentials. Change them before exposing the service beyond a trusted local environment.

Database Configuration

The server selects its database through DATABASE_URL:

Backend Example URL
SQLite (default) sqlite://sim.db?mode=rwc
Postgres postgres://sim:sim@localhost:5432/sim

For example, run locally against a reachable Postgres server with:

DATABASE_URL=postgres://sim:sim@localhost:5432/sim cargo run

The simulation is saved as a snapshot about once per second and restored at startup. SQLite is convenient for local testing; Compose configures the app to use Postgres.

SIM_ADDR sets the listen address. It defaults to 127.0.0.1:7878; containers set it to 0.0.0.0:7878.

Project Layout

  • src/world.rs contains the simulation and snapshot serialization.
  • src/main.rs runs the Axum server, simulation thread, and HTTP/WebSocket API.
  • src/storage.rs provides SQLite and Postgres snapshot storage.
  • src/behavior.rn is the default Rune behavior script.
  • ui/ contains the Leptos frontend, compiled to Wasm by build.rs.
  • Dockerfile, compose.yaml, and Justfile provide container and developer workflows.

Tests

Run the server tests with:

cargo test --bin sim