Skip to content

psoren/pwarf

Repository files navigation

pWarf

A Dwarf Fortress-inspired strategy sim with ASCII canvas rendering, procedural world generation, and a Supabase backend.

Play it live: https://psoren.github.io/pwarf/

Devlog: https://psoren.github.io/pwarf/blog/ — hourly digest of merged changes, auto-generated by GitHub Actions

What is this?

pWarf is a browser-based colony sim where you manage a group of dwarves, dig into mountains, build structures, and survive. The game features:

  • Procedural world generation — Simplex noise generates biomes (plains, mountains, forests, deserts, tundra, swamps, volcanoes) with smooth transitions
  • Fortress building — Mine stone, build walls/floors/beds/wells/mushroom gardens, create stockpiles
  • Dwarf AI — Dwarves autonomously eat, drink, sleep, and wander. They claim and execute player-designated tasks (mining, building, hauling)
  • Needs and stress — Dwarves have hunger, thirst, energy, social, purpose, and beauty needs. Unmet needs cause stress
  • Cave exploration — Discover cave entrances on the surface, explore underground caverns with ore and gem veins
  • Combat — Monsters spawn and attack your fortress. Dwarves fight back with skill-based combat
  • Sound engine — Procedural audio with ambient soundscapes and event-driven sound effects

Prerequisites

Quick Start

# 1. Install dependencies
npm install

# 2. Build all workspaces
npm run build

# 3. Set up environment variables (see below)

# 4. Start the frontend
npm run dev:app

Open the URL printed by Vite (usually http://localhost:5173).

Click Generate World, wait for the tiles to populate, then pan around with WASD or click-drag. Select a non-ocean tile and click Embark to create your fortress.

Environment Variables

Frontend (app/.env.local)

VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key

Copy from app/.env.example and fill in your Supabase project values.

Sim Engine (optional, for headless simulation)

Set these as shell environment variables or in a .env file:

SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_KEY=your-service-role-key
CIVILIZATION_ID=uuid-of-civilization
WORLD_ID=uuid-of-world

Then run:

npm run dev:sim

Project Structure

pwarf/
├── app/          React + Vite frontend (canvas ASCII renderer)
├── sim/          Node.js headless simulation engine
├── shared/       Shared TypeScript types and constants
├── supabase/     Database migrations
└── docs/         Documentation (design docs, brainstorming, system overviews)

Controls

Navigation

Key Action
WASD / Arrows Pan the map
Tab Toggle fortress/world view
< Go up one z-level
> Go down one z-level
[ Toggle left panel
] Toggle right panel
Click + drag Pan the map

Simulation

Key Action
Space Pause / unpause
1 Normal speed (1x)
2 Fast speed (2x)
5 Fastest speed (5x)

Designations

Key Action
m Mine / dig
b Open build menu
S (shift+s) Designate stockpile
D (shift+d) Deconstruct
O (shift+o) Smooth stone
E (shift+e) Engrave
f Farm (till soil)
p Task priorities
Escape Cancel current designation

Click and drag on the map to designate an area after selecting a mode.

Database Setup

Apply migrations to your Supabase project using the Supabase CLI:

supabase db push

Or run the SQL files in supabase/migrations/ manually in the Supabase SQL editor, in order.

Scripts

Command Description
npm install Install all workspace dependencies
npm run build Typecheck and build all workspaces
npm run dev:app Start the frontend dev server
npm run dev:sim Start the simulation engine
npm test Run all tests
npm test --workspace=sim Run sim tests only
npm test --workspace=shared Run shared tests only

Architecture

The sim engine runs as a fixed-timestep loop, executing phases in deterministic order each tick:

  1. Need decay — Hunger, thirst, energy decrease over time
  2. Deprivation — Stress increases when needs are critically low
  3. Task claiming — Idle dwarves claim pending player-designated tasks
  4. Task execution — Dwarves move to task targets and perform work
  5. Task completion — Finished tasks modify the world (mine tiles, build structures)
  6. Monster spawning — Periodic hostile creature generation
  7. Combat — Melee resolution between dwarves and monsters

All game state syncs to Supabase in periodic batches. The frontend receives live updates via the sim snapshot system.

Testing

Tests use Vitest and live next to source files as *.test.ts. The sim is fully headless — no browser dependencies, seeded RNG for deterministic results.

npm test                        # all tests
npm test --workspace=sim        # sim only
npm test --workspace=shared     # shared only

About

No description, website, or topics provided.

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors