docs: rewrite README to reflect actual implementation state

This commit is contained in:
2026-03-20 10:33:20 +00:00
parent d7cbbaa04b
commit 792a8981c1
+94 -98
View File
@@ -1,117 +1,113 @@
# Dorf
This project is my way of learning Rust by recreating key aspects of Dwarf Fortress in Bevy. The aim is to build a feature-rich, procedurally generated simulation game, combining colony management, world-building, etc.
A Dwarf Fortress-inspired simulation game built in Rust with Bevy. The focus is on a fully data-oriented chunk engine: procedural terrain, hierarchical pathfinding, GPU-baked sprite rendering, and dynamic chunk loading/unloading — all designed to scale to a full DF-style world with z-levels, entities, and simulation.
## Project Goals
- Learn Rust by implementing complex game systems.
- Explore procedural generation techniques.
- Develop an engaging simulation game inspired by Dwarf Fortress.
This is an **engine foundation**, not a complete game. Many features (crafting, needs, combat, world history) exist only as stubs or are entirely absent. The chunk rendering and pathfinding systems are production-quality; the simulation layer above them is early.
## Current Status
Work in progress.
## Architecture
## Features
```
src/
├── camera.rs # Panning camera, z-level control (Q/E, scroll)
├── config.rs # GameConfig resource
├── constants.rs # Tile size, pathfinding constants
├── entities/ # Dorfs, pigs, rabbits — ambulatory entities
│ ├── sentient/
│ ├── livestock/
│ └── shared_*/ # Ambulatory, pathfinding systems
├── game.rs # ZIndex resource, frame timing
├── main.rs # Bevy app bootstrap
└── world/
├── chunks/ # ChunkMap, chunk loading/unloading, connectivity
├── generation/ # Terrain blobs, forestry, foliage (stub), fauna (stub)
└── tiles/ # TileMap, TileRegistry, rendering, visibility
```
### Core Systems
### Chunk Architecture
#### Procedural World Generation
- [ ] Terrain generation
- [ ] Generate heightmaps and elevation
- [ ] Add water bodies and erosion effects
- [ ] Apply biome-specific textures
- **World chunks**: 8×8 tiles (`CHUNK_SIZE = 8`, `CHUNK_SIZE_TILE = 128px`)
- **Render chunks**: 32×32 tiles (`CHUNK_TILES = 32`, `512px`). One render chunk = 4×4 world chunks. This mismatch is intentional — a single GPU texture covers multiple world chunks, which means chunk unloading must mark the render chunk dirty (not the world chunk).
- **Z-levels**: 5 below, 15 above, 21 total (`Z_BELOW = 5`, `Z_ABOVE = 15`). Terrain is rendered as quilted sprites — one texture per z-level, all stacked in the shader.
- **Loading**: `setup_initial_chunks` runs at `Startup`, emits `GenerateChunkEvent` for all chunks in `initial_chunk_radius`. `handle_chunk_events` processes events and fires terrain/forestry/foliage/fauna generation events.
- **Unloading**: `unload_chunk(chunk_pos)` is the canonical function. Currently disabled — `dynamic_chunk_unloading_system` is a no-op stub. To enable: implement a system that diffs wanted chunks (player/NPC interest radius) against `ChunkMap.loaded_chunks` and calls `unload_chunk` for each evictable chunk.
- [ ] Biome distribution
- [ ] Define biome attributes (temperature, rainfall, etc.)
- [ ] Map biomes to regions based on attributes
- [ ] Add transitional zones between biomes
### Rendering Pipeline
- [ ] Rivers, caves, and mountain ranges
- [ ] Implement river pathfinding algorithms
- [ ] Procedurally carve cave networks
- [ ] Generate mountain chains with fractal noise
1. `handle_tile_occlusion_updates` — raycasts from each tile upward to compute `visible_range` bitmask (which z-levels can see it)
2. `build_quilted_terrain_sprites` — GPU bake: tiles bucketed by `(render_chunk, z_level)`, blitted into pooled pixel buffers, spawned as `TerrainSprite` entities
3. `update_tile_visibility` — toggles `Visibility` on sprites based on current `ZIndex` (camera z-level)
#### Resource Management
- [ ] Gathering raw materials
- [ ] Implement tree-cutting and stone-mining mechanics
- [ ] Add dynamic replenishment or exhaustion of resources
### Pathfinding
- [ ] Stockpile mechanics
- [ ] Create system for defining and assigning stockpiles
- [ ] Optimize pathfinding for resource transport
Three tiers, gated by distance:
- **Tier 1** (<4 chunks): synchronous A* on `TileMap`
- **Tier 2** (48 chunks): provisional path + full path via async queue
- **Tier 3** (>8 chunks): hierarchical chunk graph → async segmented A*
- [ ] Crafting items and tools
- [ ] Develop crafting recipes and progression
- [ ] Add tools with different qualities and effects
`PathfindingBenchmark` resource tracks sync vs async performance per frame.
#### Colony Simulation
- [ ] Individual dwarves with unique traits
- [ ] Generate personality traits and preferences
- [ ] Assign skill proficiencies and growth over time
### Entity Indexing
- [ ] Needs and mood systems
- [ ] Model basic needs (hunger, thirst, rest)
- [ ] Implement mood modifiers and stress responses
Static terrain entities (floor tiles, fixtures, trees) are indexed in `chunk_entity_index: HashMap<IVec2, Vec<Entity>>` at spawn time. When a chunk unloads, the index is retrieved and entities are despawned. This is **O(entities in chunk)**, not O(total entities).
Mobile entities (dorfs, pigs, rabbits) are **not** in `chunk_entity_index`. They are spawned once at game start and persist. They will need per-chunk lifecycle management once fauna generation is implemented.
## Controls
| Key | Action |
|-----|--------|
| Click + drag | Pan camera |
| Scroll | Pan camera |
| Q / E | Move camera z-level down / up |
| Mouse wheel | Pan camera |
## Configuration
`config.toml`:
- `initial_chunk_radius`: chunks loaded around origin at startup (default: 7 → 15×15 = 225 chunks)
- `spawn_counts`: dorfs, pigs, rabbits spawned at game start
`tiles.toml`: tile registry — floor tiles, fixture tiles. Each tile has `id`, `astar_weight`, `can_stand_in`, `can_stand_on`, `transparent` flags.
## Status
### Implemented
- [x] Procedural terrain (blob-based, simplex noise heightmap)
- [x] Tile registry (`tiles.toml`) with A* weights
- [x] Floor tiles, fixture tiles, item tiles
- [x] Z-levels with quilted GPU sprite rendering
- [x] Tile occlusion / visibility raycasting
- [x] Forestry: tree trunks + leaves spawned per chunk
- [x] Dorfs, pigs, rabbits spawning at startup
- [x] Hierarchical async pathfinding (3 tiers)
- [x] Chunk loading infrastructure
- [x] Chunk unloading infrastructure (`unload_chunk`, `dynamic_chunk_unloading_system` stub)
- [x] Camera panning + z-level control
- [x] GPU texture pooling (pixel buffer reuse across bakes)
- [x] Render chunk dirty-tracking for incremental rebakes
### Stubs (exist as empty functions, wired into schedules)
- [ ] Foliage generation per chunk (`generate_chunk_foliage`)
- [ ] Fauna spawning per chunk (`generate_chunk_fauna`)
- [ ] Weathering and precipitation (`generate_chunk_weathering_and_precipitation`)
### Not Started
- [ ] Crafting, stockpiles, resource gathering
- [ ] Needs, mood, stress systems
- [ ] Job assignment and task automation
- [ ] Create task queue and priority system
- [ ] Enable task reassignment dynamically
- [ ] Building and construction (digging/mining)
- [ ] Combat and squad management
- [ ] Item persistence and inventory
- [ ] Save/load world state
- [ ] World history and procedural storytelling
- [ ] UI (menus, z-level overlay, workshop assignment)
- [ ] Dynamic chunk loading (player/NPC-centered, not just radius-at-startup)
### Gameplay Mechanics
## Building
#### Building and Construction
- [ ] Rooms, workshops, and fortifications
- [ ] Design grid-based construction system
- [ ] Implement structural stability checks
```sh
cargo build # dev profile, ~1.2K warnings (pre-existing)
cargo run # dev mode
```
- [ ] Mining and digging mechanics
#### Combat and Defense
- [ ] Squad management
- [ ] Develop squad formation and control UI
- [ ] Assign weapons and defensive equipment
- [ ] Enemy invasions
- [ ] Generate enemy waves with scaling difficulty
- [ ] Simulate AI pathfinding and strategies
- [ ] Traps and defenses
- [ ] Add trap-building interface
- [ ] Implement trigger mechanisms and consequences
#### Economy and Trade (Possible)
- [ ] Trading with caravans
- [ ] Generate trading caravans based on world events
- [ ] Add barter or currency-based exchange
- [ ] Currency and wealth system
- [ ] Track wealth and its effects on game dynamics
- [ ] Introduce theft and economic threats
### Procedural Storytelling
#### Historical World-Building
- [ ] Generate civilizations, leaders, and conflicts
- [ ] Assign dynamic histories to regions and NPCs
- [ ] Model geopolitical relationships
- [ ] Persistent world history
- [ ] Save and load historical data across game sessions
- [ ] Link events and characters to history dynamically
#### Events and Narratives
- [ ] Random and scripted events
- [ ] Add contextual random events (e.g., resource scarcity, rival factions)
### User Interface
- [ ] Visual grid-based interface
- [ ] Add visual overlays for resources, paths, and zones
- [ ] Keyboard and mouse input
## Roadmap
1. Build procedural world generation prototype.
2. Implement basic colony simulation.
3. Add crafting and resource management mechanics.
4. Introduce combat and defense systems.
5. Polish user interface.
6. Expand procedural storytelling and events.
`[profile.dev.package."*"] opt-level = 3` gives near-release perf in dev builds.