{"slug": "show-hn-a-self-running-space-economy-sim-in-rust-and-bevy", "title": "Show HN: A self-running space economy SIM in Rust and Bevy", "summary": "The Space Project, an agent-driven space economy simulation built in Rust and Bevy, is now open-source under MIT. The simulation runs hundreds of autonomous ships, facilities, populations, and factions in a single native binary with no runtime dependencies, featuring a GOAP planner for ship AI and a coverage-model market system. Creator 'kettlecorn' released the code after rewriting it from Elixir/Phoenix to Rust, aiming for others to build upon the simulation engine.", "body_md": "**A self-running space-economy simulator, in Rust + Bevy.**\n\nHundreds of autonomous ships trade, mine, haul cargo, take out contracts, run out of fuel, and occasionally go bankrupt across a living solar economy — markets find their own prices, factions tax and subsidize, populations migrate when they're unhappy, and abandoned stations rot. It all runs in one native binary with no runtime dependencies.\n\nThe Space Project is an **agent-driven economic simulation** wrapped in a\nnative 3D client. There's no scripted storyline and no player objective —\nyou're an observer (and god-mode admin) watching an economy run itself.\n\nEvery ship is an autonomous agent with its own credits, crew, fuel, cargo\nhold, and a **GOAP planner** that decides what to do next: chase the\nhighest-margin trade route, accept a delivery contract, seek out a\nshipyard to retrofit, or dock and let its crew rest before morale\ncollapses. Facilities run production recipes, degrade and self-repair,\nlevel up, and get abandoned when they go broke. Factions collect taxes\nand post subsidies. Populations consume food, produce labor, and pack up\nand leave when sentiment craters. Markets price everything off a coverage\nmodel with shortage urgency multipliers — no fixed prices anywhere.\n\nIt started as an Elixir/Phoenix prototype and was rewritten in Rust\nbecause the BEAM scheduler struggled on Windows gaming PCs. The engine\n(`sim_core`\n\n) is pure, synchronous, IO-free Rust; the Bevy client embeds\nit directly as a library, so the simulation and the renderer share the\nsame ECS world with zero marshalling between them.\n\n**Scale today:** ~485 live agents (282 ships · 93 facilities · 27\npopulations · 8 factions · 60 celestial bodies), ticking at p50 ≈ 10–20 ms\ninside a 125 ms budget. The architecture is built to push toward 100k+.\n\nNowhere, on its own — and that's kind of the point.This started as a fun idea: a from-scratch space economy that actually simulates itself instead of faking it. It grew\n\nwaypast what I expected, mostly in late-night sessions pairing with Claude. But I'm not pretending it's a game with a roadmap, and I'm not actively pushing it toward \"shippable.\"I'm putting it out under MIT because the bones are genuinely good and I'd rather someone do something with it than let it sit in a private repo. So:\n\nfork it, gut it, rename it, bolt a game on top of it, rip the economy engine out and use it somewhere else entirely.Build the thing I didn't.PRs and issues are welcome and I'll look at them, but I can't promise a cadence. If you want to take it somewhere real, see\n\n[CONTRIBUTING.md]— there's a \"directions you could take this\" section written exactly for you.\n\n| System | What happens |\n|---|---|\nShip AI (GOAP) |\nA forward planner scores every goal — trade, deliver, refuel, retrofit, rest, explore — over an abstract world state, then builds a behavior tree to execute the cheapest plan. Ships replan mid-flight when a better option appears. |\nEconomy |\nAn order-book market per station prices 13 commodities off a coverage model with shortage-urgency multipliers. Ships move real supply between markets as they trade. |\nContracts |\nSix kinds — Delivery, Courier, Passenger, Subsidy, Supply, CrewMission — with a full posted → accepted → paid lifecycle, reputation gating, auto-renewal, and age-escalating payments. |\nFacilities |\nRun production recipes (smelting, refining, manufacturing, farming, mining), degrade over time, self-repair with tools, level up 1–10, restock from local markets, and get abandoned when chronically broke. |\nFactions |\nCollect taxes on member facilities, post subsidy contracts for chronic shortages, fund construction of new facilities where demand is unmet, and hold pairwise relations. |\nPopulations |\nConsume food and fuel, produce labor, post food and passenger contracts under stress, and physically migrate to happier systems when sentiment collapses. |\nCrew |\nAggregate hunger / fatigue / morale with derived tasks (piloting, engineering, trading, eating, resting), skill progression, wages, and a morale death-spiral guard. |\nConstruction |\nChronic shortages spawn construction sites that accrete delivered cargo 0 → 1.0, then materialize into a real, persistent facility. |\nPersistence |\nEverything flushes to SQLite; a sim resumes from the exact tick it left off. A per-universe `world_seed` keeps the nebula backdrop and landmarks stable across restarts. |\nSpatial LOD |\nDistant ships tick less often (with rate-scaled state changes) so the frame budget goes where you're looking. |\n\nFor the deep dive — tick phase ordering, the AI stack, the economic\nfeedback loop, runtime ownership — see\n[docs/ARCHITECTURE.md](/Kalcode/spaceprojectsim/blob/main/docs/ARCHITECTURE.md), which has mermaid diagrams\nfor all of it.\n\nYou need a [Rust toolchain](https://rustup.rs/) (stable). Then:\n\n```\nmake run\n# equivalent to: cargo run -p client_bevy\n```\n\nThat boots the Bevy app into the main menu. **Start** opens a fresh\nuniverse (name it, or take the default); **Load Game** lists every save\nin the binary's directory. Saves live next to the binary as\n`<universe-name>.db`\n\n— default `sim.db`\n\n.\n\nOther entry points:\n\n| Goal | Command |\n|---|---|\n| Windowed client (debug) | `make run` |\n| Release build | `make build` → binary at `target/release/client_bevy` |\nHeadless (no window, for CI / smoke tests) |\n`cargo run -p client_bevy -- --headless` |\n| Verify (build + test + clippy, strict) | `make verify` |\n| Smoke test (boot headless, print DB counts) | `scripts/smoke.sh [secs]` |\n\nOne binary, one process.`client_bevy`\n\nisthe whole thing — the simulation runs in-process. Headless mode spins up the HTTP/WebSocket server (from the`sim_server`\n\nlibrary crate) for scripted and CI use; there is no separate server binary to run.\n\n| Input | Action |\n|---|---|\nLeft-drag |\nOrbit camera |\nRight-drag / WASD |\nPan |\nScroll |\nZoom |\nLeft-click |\nSelect ship or facility → opens its details panel |\nRight-click |\nContext menu (Inspect / Follow / POV / Destroy) |\nSpace |\nPause / resume |\nEsc |\nClose top panel · clear selection · open pause menu |\nP |\nPause menu |\nF12 |\nScreenshot |\n| Top bar | Toggle panels (Ships, Markets, Factions, Contracts, Events, …), set speed (1× / 2× / 5× / 10×), spawn ships/facilities |\n\nEvery panel reads the ECS world live — the inspector is effectively a real-time debugger with full component access. Click a ship to see its credits, crew, fuel, current goal, fitting, route memory, and its last few AI commands.\n\nFive crates in one Cargo workspace:\n\n```\nsim_core     Pure simulation logic — hecs ECS, GOAP planner, economy,\n             contracts. No async, no IO, no framework. Trivially testable.\nsim_db       SQLite persistence (sqlx) — pool, seeder, ECS loader,\n             persistence worker, migrations.\nsim_server   Library crate — HTTP/WebSocket handlers + engine apply\n             helpers. Drives headless mode; embedded by the client.\nsim_protocol WebSocket wire types (headless / CI only).\nclient_bevy  The binary. Bevy 0.18 + egui. Embeds sim_core as a Bevy\n             Resource; the renderer queries the hecs world directly.\n```\n\nThree rules keep it honest:\n\nPure logic only, so the whole simulation is reasoned about and unit-tested without async.`sim_core`\n\nnever imports tokio, sqlx, or axum.**hecs is the source of truth during a tick.** The tick loop holds exclusive mutable access — no per-agent locks.**Cross-entity effects go through a command buffer**(`SimCommand`\n\n). A phase reads world state and writes commands; the next phase applies them. Deterministic, no mid-phase write conflicts.\n\nThe full tick phase order, ownership model, and feedback loops are\ndiagrammed in [docs/ARCHITECTURE.md](/Kalcode/spaceprojectsim/blob/main/docs/ARCHITECTURE.md).\n\nThe original\n\nGodotclient lives on in history as a parity reference, but it's no longer the front end — the pivot to an embedded Bevy client removed the socket boundary entirely, and every feature now lands in`client_bevy`\n\n.\n\nThe `Makefile`\n\nwraps cargo + rustup + codesign + packaging:\n\n```\nmake build              # release binary (host target)\nmake build-mac          # arm64 macOS  (also: build-mac-intel, build-mac-universal)\nmake build-win          # Windows MSVC (run on a Windows host)\nmake build-linux        # Linux        (best on a Linux host)\n\nmake package-mac        # .app bundle + ad-hoc codesign + Info.plist\nmake dmg                # macOS .dmg\nmake package-win        # Windows .zip\nmake package-linux      # Linux .tar.gz\n```\n\nThe workspace version in the root `Cargo.toml`\n\nis the single source of\ntruth — the binary reads it via `env!(\"CARGO_PKG_VERSION\")`\n\nand the\n`Makefile`\n\ngreps the same field for `Info.plist`\n\nand archive names, so\npackaged builds never drift.\n\n(edition 2021) — the whole thing[Rust](https://www.rust-lang.org/)— renderer, ECS-driven main loop, custom WGSL shaders (procedural planets, sun corona, nebulae, starfield)[Bevy 0.18](https://bevyengine.org/)— the simulation's own ECS (separate from Bevy's, deliberately)[hecs](https://github.com/Ralith/hecs)(via[egui](https://github.com/emilk/egui)`bevy_egui`\n\n) — every inspector panel— GPU particle trails and explosions[bevy_hanabi](https://github.com/djeedai/bevy_hanabi)+ SQLite — persistence, bundled so there's no runtime dependency[sqlx](https://github.com/launchbadge/sqlx)+ tokio — the headless HTTP/WebSocket harness[axum](https://github.com/tokio-rs/axum)\n\nContributions are welcome — see [CONTRIBUTING.md](/Kalcode/spaceprojectsim/blob/main/CONTRIBUTING.md) for dev\nsetup, the conventions that keep the codebase clean, and a list of\nconcrete directions if you want to take this somewhere real.\n\nThe fastest sanity check before any PR:\n\n```\nmake verify   # build + ~250 tests + clippy, strict\n```\n\n[MIT](/Kalcode/spaceprojectsim/blob/main/LICENSE) © 2026 Kalcode (David Clausen). Do whatever you like with it.\n\nBuilt for fun in Rust & Bevy · By Kalcode & Claude · Made with ❤️ in Illinois", "url": "https://wpnews.pro/news/show-hn-a-self-running-space-economy-sim-in-rust-and-bevy", "canonical_source": "https://github.com/Kalcode/spaceprojectsim", "published_at": "2026-07-21 18:29:57+00:00", "updated_at": "2026-07-21 18:55:21.674015+00:00", "lang": "en", "topics": ["ai-agents", "artificial-intelligence", "ai-research", "developer-tools"], "entities": ["The Space Project", "Rust", "Bevy", "kettlecorn", "GOAP", "Elixir", "Phoenix", "MIT"], "alternates": {"html": "https://wpnews.pro/news/show-hn-a-self-running-space-economy-sim-in-rust-and-bevy", "markdown": "https://wpnews.pro/news/show-hn-a-self-running-space-economy-sim-in-rust-and-bevy.md", "text": "https://wpnews.pro/news/show-hn-a-self-running-space-economy-sim-in-rust-and-bevy.txt", "jsonld": "https://wpnews.pro/news/show-hn-a-self-running-space-economy-sim-in-rust-and-bevy.jsonld"}}