---
name: godot-genre-roguelike
description: "Expert blueprint for roguelikes including procedural generation (Walker method, BSP rooms), permadeath with meta-progression (unlock persistence), run state vs meta state separation, seeded RNG (shareable runs), loot/relic systems (hook-based modifiers), and difficulty scaling (floor-based progression). Use for dungeon crawlers, action roguelikes, or roguelites. Trigger keywords: roguelike, procedural_generation, permadeath, meta_progression, seeded_RNG, relic_system, run_state."
---
## Godot 4.7 Baseline
- Expert patterns in this skill target **Godot 4.7+** (stable, 2026-06-18).
- Consult the [Godot 4.7 migration guide](https://docs.godotengine.org/en/4.7/tutorials/migrating/upgrading_to_godot_4.7.html) when upgrading projects from 4.6.
- **NEVER** assume 4.6 defaults (stretch mode, audio area_mask, RichTextLabel percent flags) without checking 4.7 migration notes.
# Genre: Roguelike
Expert blueprint for roguelikes balancing challenge, progression, and replayability.
## NEVER Do (Expert Anti-Patterns)
### Generation & RNG
- NEVER make runs dependent on pure RNG; strictly provide **mitigation** (rerolls, shops, pity timers) to ensure every run is winnable.
- NEVER use unseeded RNG for world generation; strictly initialize isolated `RandomNumberGenerator` with a predictable seed for daily runs/debugging.
- NEVER rely on `@GlobalScope.randi()` for critical logic; strictly use local RNG instances to prevent global state pollution.
- NEVER use `Array.pick_random()` for critical content drops; strictly use a **Shuffle Bag** to prevent statistically unfair streaks.
- NEVER generate massive dungeons on the main thread; strictly use **`WorkerThreadPool.add_task()`** or **`add_group_task()`** to distribute generation across cores and prevent frame freezes.
- NEVER interact with the SceneTree from a background thread; strictly generate dungeon data in a **thread-safe Array/PackedByteArray** before parsing on the main thread.
### Data & State
- NEVER allow **Save Scumming**; strictly delete mid-run save files immediately upon loading to enforce permadeath.
- NEVER allow the player to see the "Edge of the World"; strictly use **Fog of War** or limited vision cones to maintain the mystery of the unknown.
- NEVER evaluate complex "Director" heuristics every frame; strictly use **Frame-Slicing (`Engine.get_process_frames()`)** to run heavy pacing logic only once every 60-120 frames for CPU efficiency.
- NEVER move rooms individually by pixel values during procedural generation; strictly use **`Marker2D` Connection Points** in pre-authored scenes to calculate exact offsets for seamless room stitching.
- NEVER allow Run State to leak into Meta State; strictly use separate singletons or Resources for `RunManager` and `MetaManager`.
- NEVER scale meta-progression to be overpowered (+100% damage); strictly keep upgrades subtle (+5-15%) to maintain skill-based play.
- NEVER forget to call `duplicate(true)` on base stat Resources; failing to deep-duplicate causes all entities to share a single health instance.
- NEVER save run states to `.tscn` files; strictly serialize to JSON or binary in `user://` to prevent bloat.
- NEVER rely on the `SceneTree` as the source of truth for grid logic; strictly maintain grid data in a separate Dictionary or Array.
### Grid & Performance
- NEVER forget to handle **Navigation re-baking**; strictly rebake `NavigationRegion2D` AFTER procedural tiles are placed.
- NEVER use AStar2D for tile grids; strictly use **`AStarGrid2D`** with **`jumping_enabled = true`** (Jump Point Search) for O(1) queries and high-performance pathing across open areas.
- NEVER forget to call `update()` on `AStarGrid2D` after modifying states; strictly ensures pathfinding queries aren't stale.
- NEVER use floats (`Vector2`) for discrete grid coordinates; strictly use **Vector2i** to prevent precision drift.
- NEVER use Manhattan heuristics for 8-way movement; strictly use **`HEURISTIC_CHEBYSHEV`** or **`HEURISTIC_OCTILE`**.
- NEVER iterate over every cell coordinate (0 to W,H) in GDScript; strictly use `get_used_cells()` for optimized tile access.
- NEVER clear procedural levels using `free()`; strictly use `queue_free()` to avoid mid-frame segmentation faults.
- NEVER broadcast mass state changes to a grid immediately; strictly use `call_deferred()` or **`call_group_flags`** to avoid frame spikes during turn transitions.
- NEVER use heavy TileMapLayer nodes for high-resolution Fog of War; strictly use a **GPU Shader Mask** via `ColorRect` and an `ImageTexture` updated via **`RenderingServer.texture_2d_update()`**.
## 🛠 Expert Components (scripts/)
> **MANDATORY** before implementing generation, seed sharing, or meta unlocks — read these first (do not reinvent from inline samples):
> - [dungeon_generator_walker.gd](scripts/dungeon_generator_walker.gd) — Drunkard's Walk with **local** `RandomNumberGenerator` (`rng.randi() % n`, never `Array.pick_random()`).
> - [seeded_rng_resource.gd](scripts/seeded_rng_resource.gd) — seed persistence for shareable / daily runs.
> - [meta_progression_manager.gd](scripts/meta_progression_manager.gd) — permanent unlock currency + save boundaries vs run state.
>
> **Do NOT Load** the full scripts/ folder for a single task. Open only the script that matches the phase below.
### Original Expert Patterns
- [meta_progression_manager.gd](scripts/meta_progression_manager.gd) - Foundational meta-progression logic with secure data persistence and currency unlocks.
- [roguelike_patterns.gd](scripts/roguelike_patterns.gd) - 10 Essential Roguelike Expert Snippets (AStar, BSP, WorkerThreadPool, ShuffleBag, etc.).
### Modular Components
- [dungeon_generator_walker.gd](scripts/dungeon_generator_walker.gd) - Drunkard's Walk algorithm for carving procedural rooms and caves.
- [fov_raycast_calculator.gd](scripts/fov_raycast_calculator.gd) - High-performance LOS checking using physics server queries.
- [seeded_rng_resource.gd](scripts/seeded_rng_resource.gd) - RNG state persistence for deterministic and shareable replayability.
- [turn_manager_decoupled.gd](scripts/turn_manager_decoupled.gd) - Signal-driven turn coordination for decoupled entity logic.
- [astar_grid_handler.gd](scripts/astar_grid_handler.gd) - Specialised AStarGrid2D wrapper for optimized roguelike pathfinding.
- [weighted_loot_table.gd](scripts/weighted_loot_table.gd) - Native-optimized weighted random item drops with drop-rate controls.
- [json_state_serializer.gd](scripts/json_state_serializer.gd) - Persistent serialization for procedural entity data and run states.
- [fog_of_war_masker.gd](scripts/fog_of_war_masker.gd) - TileMapLayer-based visibility masking and discovery system.
- [meta_progression_resource.gd](scripts/meta_progression_resource.gd) - Data separation for permanent game unlocks and skill trees.
- [move_command_object.gd](scripts/move_command_object.gd) - Command pattern implementation for reversible turn-based actions.
- [dungeon_generator.gd](scripts/dungeon_generator.gd) - High-level procedural orchestrator for room-and-hallway layout generation.
- [run_manager.gd](scripts/run_manager.gd) - Autoload run seed/floor/inventory lifecycle (`start_run` / `end_run`).
- [director_ai.gd](scripts/director_ai.gd) - Pacing manager — spawn intensity from player power + time-in-run.
- [room_assembler.gd](scripts/room_assembler.gd) - Marker-based procedural room stitching from prefab scenes.
- [synergy_manager.gd](scripts/synergy_manager.gd) - Relic tag synergy detection and stacked modifier application.
- [example_relic_vampirism.gd](scripts/example_relic_vampirism.gd) - Sample `Relic` Resource hook (`on_damage_dealt`).
## Core Loop
1. **Preparation**: Select character, equip meta-upgrades (see `meta_progression_resource.gd`).
2. **The Run**: complete procedural levels (`dungeon_generator_walker.gd`), acquire temporary power-ups.
3. **The Challenge**: Survive increasingly difficult encounters using A* pathfinding (`astar_grid_handler.gd`).
4. **Death/Victory**: Run ends, resources calculated.
5. **Meta-Progression**: Spend resources on permanent unlocks (`meta_progression_resource.gd`).
6. **Repeat**: Start a new run with new capabilities.
## Skill Chain
| Phase | Skills | Purpose |
|-------|--------|---------|
| 1. Architecture | `godot-autoload-architecture`, `godot-state-machine-advanced` | Run State vs Meta State boundaries |
| 2. World Gen | `godot-procedural-generation`, `godot-tilemap-mastery` | Unique levels every run (walker/BSP/noise) |
| 3. Combat | `godot-combat-system`, `godot-ai-navigation` | High-stakes encounters + FOV/pathing |
| 4. Progression | `godot-inventory-system`, `godot-resource-data-patterns` | Run items/relics + typed Resources |
| 5. Persistence | `godot-save-load-systems` | Meta unlocks + anti-scum mid-run deletes |
| 6. Balance | `godot-monte-carlo-balancer` | Win% vs meta level; dead-item detection |
## Architecture Overview
Roguelikes require a strict separation between **Run State** (temporary) and **Meta State** (persistent).
- **Run lifespan / seed**: Own an AutoLoad that resets on death; seed via **MANDATORY** [seeded_rng_resource.gd](scripts/seeded_rng_resource.gd). Never leak run HP/gold into meta saves.
- **Meta unlocks**: **MANDATORY** [meta_progression_manager.gd](scripts/meta_progression_manager.gd) + [meta_progression_resource.gd](scripts/meta_progression_resource.gd) — subtle permanent bonuses only (+5–15%).
- **Serialize**: Prefer [json_state_serializer.gd](scripts/json_state_serializer.gd) / `user://` JSON-binary; never treat `.tscn` as a run save.
## Key Mechanics (route to scripts/)
### Procedural Dungeon Generation
- **Drunkard's Walk**: **MANDATORY** [dungeon_generator_walker.gd](scripts/dungeon_generator_walker.gd) — pass a local seeded `RandomNumberGenerator`; directions via `rng.randi() % directions.size()` (never `Array.pick_random()`).
- **Critical drops / fairness**: Use Shuffle Bag patterns in [roguelike_patterns.gd](scripts/roguelike_patterns.gd) or weights in [weighted_loot_table.gd](scripts/weighted_loot_table.gd).
- **BSP / room orchestrator**: [dungeon_generator.gd](scripts/dungeon_generator.gd); deeper WFC/noise → peer `godot-procedural-generation`.
- **Pathing after gen**: [astar_grid_handler.gd](scripts/astar_grid_handler.gd) — call `update()` after solid-cell edits; rebake `NavigationRegion2D` if using nav meshes.
### Relics, turns, fog, pacing
- Relic hooks / synergy tags: Resource subclasses + [weighted_loot_table.gd](scripts/weighted_loot_table.gd); inventory peer `godot-inventory-system`.
- Turns: [turn_manager_decoupled.gd](scripts/turn_manager_decoupled.gd) + [move_command_object.gd](scripts/move_command_object.gd).
- Fog / LOS: [fog_of_war_masker.gd](scripts/fog_of_war_masker.gd), [fov_raycast_calculator.gd](scripts/fov_raycast_calculator.gd).
- Director pacing: frame-slice with `Engine.get_process_frames() % N` (see NEVER); keep heuristics out of every-frame `_process` work.
## Common Pitfalls
1. **RNG Dependency**: Don't make runs entirely dependent on luck. Good roguelikes allow skill to mitigate bad RNG.
2. **Meta-progression Imbalance**: If meta-upgrades are too strong, the game becomes a "grind to win" rather than "learn to win".
3. **Lack of Variety**: Procedural generation is only as good as the content it arranges. You need *a lot* of content (rooms, enemies, items) to keep it fresh.
4. **Save Scumming**: Players will try to quit to avoid death. Save the state only on floor transition or quit, and delete the save on load (optional, but standard for strict roguelikes).
## Godot-Specific Tips
- **Seeded Runs**: Always initialize `RandomNumberGenerator` with a seed. This allows players to share specific run layouts.
- **ResourceSaver**: Use `ResourceSaver` for meta-progression, but be careful with cyclical references in deeply nested resources.
- **Scenes as Rooms**: Build your "rooms" as separate scenes (`Room1.tscn`, `Room2.tscn`) and instance them into the generated layout for handcrafted quality within procedural layouts.
- **Navigation**: Rebake `NavigationRegion2D` at runtime after generating the dungeon layout if using 2D navigation.
## Advanced Techniques
- **Synergy System**: Tag items (`fire`, `projectile`, `companion`) and check for tag combinations to create emergent power-ups.
- **Director AI**: An invisible "Director" system that tracks player health/stress and adjusts spawn rates dynamically (like *Left 4 Dead*).
> **MANDATORY** for depth beyond decision trees and script catalog: [roguelike-meta-systems-deep.md](references/roguelike-meta-systems-deep.md). **Do NOT Load** on first-pass wiring — use bundled `scripts/` first.
## Reference
> Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice.
### Official Documentation
- [Using TileMaps](https://docs.godotengine.org/en/stable/tutorials/2d/using_tilemaps.html) — TileMapLayer cells, sources, and runtime placement for procedural floors/walls.
- [TileMapLayer](https://docs.godotengine.org/en/stable/classes/class_tilemaplayer.html) — `set_cell` / `get_used_cells` APIs used after walker/BSP generation and fog clears.
- [AStarGrid2D](https://docs.godotengine.org/en/stable/classes/class_astargrid2d.html) — grid pathfinding with heuristics, diagonal modes, and `update()` after solid-cell edits.
- [RandomNumberGenerator](https://docs.godotengine.org/en/stable/classes/class_randomnumbergenerator.html) — seeded PCG32 for shareable runs; prefer local instances over global `randi()`.
- [WorkerThreadPool](https://docs.godotengine.org/en/stable/classes/class_workerthreadpool.html) — offload heavy dungeon generation without freezing the main thread.
- [Using multiple threads](https://docs.godotengine.org/en/stable/tutorials/performance/using_multiple_threads.html) — when WorkerThreadPool/tasks are safe versus SceneTree ownership rules.
- [Thread-safe APIs](https://docs.godotengine.org/en/stable/tutorials/performance/thread_safe_apis.html) — generate data off-thread, then apply tiles/nodes on the main thread only.
- [Saving games](https://docs.godotengine.org/en/stable/tutorials/io/saving_games.html) — `user://` persistence patterns for meta unlocks and anti-scum mid-run deletes.
- [Resources](https://docs.godotengine.org/en/stable/tutorials/scripting/resources.html) — Resource-backed meta/run data, `duplicate(true)`, and save/load of `.tres`/custom resources.
- [Singletons (AutoLoad)](https://docs.godotengine.org/en/stable/tutorials/scripting/singletons_autoload.html) — isolate RunManager vs MetaManager so run death cannot wipe permanent progress.
- [Ray-casting](https://docs.godotengine.org/en/stable/tutorials/physics/ray-casting.html) — PhysicsDirectSpaceState queries for FOV / line-of-sight without Area2D spam.
- [FastNoiseLite](https://docs.godotengine.org/en/stable/classes/class_fastnoiselite.html) — noise fields for cave-style maps before connectivity validation with AStarGrid2D.
### Related Skills
#### Prerequisites
- [godot-project-foundations](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-project-foundations/SKILL.md) — project layout, Autoloads, and Resource basics before run/meta split.
- [godot-tilemap-mastery](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-tilemap-mastery/SKILL.md) — TileMapLayer authorship and runtime cell edits that procedural generators write into.
- [godot-resource-data-patterns](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-resource-data-patterns/SKILL.md) — Resource duplication, typed data, and save-friendly schemas for relics/meta stats.
- [godot-autoload-architecture](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-autoload-architecture/SKILL.md) — singleton boundaries so Run state resets cleanly without touching Meta state.
#### Complements
- [godot-procedural-generation](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-procedural-generation/SKILL.md) — deeper Walker/BSP/WFC generators that feed this genre's dungeon loop.
- [godot-navigation-pathfinding](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-navigation-pathfinding/SKILL.md) — NavigationRegion rebake and agent pathing when not using pure AStarGrid2D.
- [godot-combat-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-combat-system/SKILL.md) — hit/hurt pipelines and turn-paced encounters inside generated floors.
- [godot-inventory-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-inventory-system/SKILL.md) — run bags, relic slots, and item Resources consumed by loot tables.
- [godot-save-load-systems](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-save-load-systems/SKILL.md) — JSON/binary persistence, floor-transition saves, and permadeath delete-on-load.
- [godot-signal-architecture](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-signal-architecture/SKILL.md) — decoupled turn/floor/run signals without SceneTree as grid source of truth.
- [godot-performance-optimization](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-performance-optimization/SKILL.md) — thread pools, fog GPU masks, and frame-sliced director heuristics at scale.
#### Downstream / consumers
- [godot-monte-carlo-balancer](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-monte-carlo-balancer/SKILL.md) — simulate win% vs meta level, pity timers, and dead-item detection across seeded runs.
- [godot-genre-action-rpg](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-genre-action-rpg/SKILL.md) — action-RPG combat/progression layers that often consume roguelike run/meta patterns.
#### Master
- [godot-master](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-master/SKILL.md) — library router and mirrored module entry for cross-skill discovery.