Clamp effective_min to DISK_TWIST_MAX in randomize_disk() so gen_range never receives an empty range. Also guard all params.disks.len() - 1 subtractions with saturating_sub to prevent overflow if disks is empty.
VOID::NAV
A single-player open-world space exploration RPG — trade, quest, fight, or simply drift and enjoy the ambiance. Inspired by the charm and freedom of Windward Horizon, set in a procedurally generated galaxy with FTL-style tactical combat.
You are a young, unaffiliated captain with an entire galaxy open for exploration. Every campaign features a unique, procedurally generated sector map. Trade goods between stations, take on quests for various factions, mine asteroid belts, or simply cruise and enjoy the void. Prefer a quieter life? You can simply sail the stars.
Combat is FTL-style tactical resource management — no dogfighting or direct piloting. Click a hostile, your ship auto-engages, and you manage reactor power between Weapons / Shields / Engines / Auxiliary. The skill is in what you power and when, not how fast you click.
VOID::NAV is a pnpm workspace monorepo for the game website, living design docs, browser game shell, and SpacetimeDB backend module. The architecture supports optional co-op servers in the future, but the core experience is designed as a solo adventure.
Core Pillars
| Pillar | Description |
|---|---|
| Open-World Exploration | Procedurally generated galaxy with unique sectors, anomalies, and hidden treasures every campaign |
| Trade & Commerce | Regional price differences, supply/demand, and trade routes between stations and factions |
| FTL-Style Combat | Tactical power management (not action). Auto-engage with reactor allocation decisions |
| Ship Customization | Build the ship that suits your style — tough juggernaut, nimble scout, or cargo hauler |
| Dynamic World Impact | Faction leaders, world events, and player actions shape the galaxy without firing a shot |
| Solo Adventure | A personal galaxy to explore at your own pace. The architecture supports optional co-op servers later. |
Layout
apps/docs Existing docs, interactive demos, and vertical slice
apps/site Public landing page / game website
apps/game Playable game shell connected to SpacetimeDB bindings
packages/ui Small shared UI primitives and CSS tokens
services/spacetimedb TypeScript SpacetimeDB module
archive/legacy-static Legacy static prototype files kept for reference
Prerequisites
- Node.js 24+
- pnpm 9+
- SpacetimeDB CLI (
spacetime) v2.3.0+
The SpacetimeDB CLI is not vendored. Frontend builds use the committed placeholder bindings in apps/game/src/module_bindings; run pnpm generate:bindings after installing the CLI to replace them with generated bindings.
Quick Start
pnpm install
pnpm dev
This single command starts a fresh SpacetimeDB instance (ephemeral, in-memory), publishes the module, generates bindings, and launches the game dev server.
Open http://localhost:5175 to play.
Press Ctrl+C to stop everything.
Development
pnpm dev # Full stack: SpacetimeDB + game (port 5175)
pnpm dev:docs # Docs only (port 5173)
pnpm dev:site # Site only (port 5174)
pnpm dev:game # Game frontend only (requires running SpacetimeDB)
Default ports:
- docs:
http://localhost:5173/docs - site:
http://localhost:5174 - game:
http://localhost:5175 - SpacetimeDB:
http://127.0.0.1:3000
Builds
pnpm build # Build all apps
pnpm check # Typecheck all packages
pnpm generate:bindings # Regenerate SpacetimeDB TypeScript bindings
SpacetimeDB
Root spacetime.json points at services/spacetimedb and generates TypeScript bindings into apps/game/src/module_bindings.
The pnpm dev script uses an isolated ephemeral data directory (.spacetime-dev/) so it starts clean every time. No stale database or auth issues.
Reducers: connectPlayer, renamePlayer, seedWorld, ping, undock, selectTarget, startApproach, completeApproach, dock, startMining, completeMiningCycle, sellOreToNpcMarket