Replaces the 2D-only demo pipeline with a 3D cell-based blobber generator. Per-cell face walls, per-material mesh emission, and a GDExtension binding that returns a Dictionary with ArrayMesh surfaces the demo consumes directly. - src/blobber/: cell3d_t data model, dungeon container, pipeline that wraps the 2D generator per level and materializes into cell3d - src/mesh/: face-quad emitter with per-material groups + .obj dump - src/genesis3d_main.c: new CLI driving the blobber + mesh - godot/: BrogueGen.generate_dungeon(seed, num_levels, depth) binding with dungeon_to_dict packing cells + mesh surfaces - demo/: demo_blobber.tscn + dungeon_builder.gd, func_godot addon for the .map export path, point/entity templates, TrenchBroom docs - Retired: old arcade/FPS demo scenes and their scripts, unused meshlib Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.6 KiB
TrenchBroom round-trip
Generate a dungeon procedurally → edit it by hand in TrenchBroom → load the edited map back into Godot with typed entities wired up via FuncGodot.
BrogueGen / Blobber
│
▼
export_map.gd ──► demo/maps/generated.map ◄──► TrenchBroom
│
▼
demo/scenes/dungeon_from_map.tscn
│
▼
FuncGodotMap
(instantiates entity scenes)
Prerequisites
- Godot 4.6+ on PATH as
godot. - FuncGodot addon installed under demo/addons/func_godot/ and enabled in Project Settings → Plugins (already wired up in demo/project.godot).
- Brogue-Genesis GDExtension built:
make godotfrom the repo root. This produces demo/addons/brogue_gen/bin/libbrogue_gen.linux.template_debug.x86_64.so and exposes theBrogueGenclass to GDScript. - TrenchBroom installed (
flatpak install com.kristianduske.TrenchBroomor distro package).
One-time setup
Install the TrenchBroom game config + FGD:
make tb-sync
This writes GameConfig.cfg and FuncGodot.fgd into ~/.TrenchBroom/games/brogue-genesis/. In TrenchBroom, open Preferences → Games → brogue-genesis → set the "Game Path" to this repo's demo/ directory (anywhere works, but demo/ lets TB find maps/ relative paths).
Re-run make tb-sync any time you:
- Add or remove an entity under data/entities/.
- Edit data/fgd/brogue_fgd.tres.
- Change the GameConfig template in scripts/export_tb_config.gd.
Day-to-day workflow
1. Generate a map
make map # defaults: brogue, seed=42, depth=20, 1 level
make map SEED=77 DEPTH=30 LEVELS=4 # override
make map GENERATOR=blobber LEVELS=3 # use the 3D blobber path
Output lands at demo/maps/generated.map (MAP_OUT= overrides the path).
2. Edit in TrenchBroom
Launch TrenchBroom → New Map → pick the brogue-genesis game → File → Open demo/maps/generated.map. Move brushes, place entities, save back to the same path.
Entities visible in TB's entity browser:
| Classname | Type | Purpose |
|---|---|---|
point_player_start |
point | Party spawn. Emitted once per map at level-0 stairs-up. |
point_stair_up |
point | Interact marker to climb a level. |
point_stair_down |
point | Interact marker to descend a level. |
point_door |
point | Door marker (angle property controls orientation). |
func_water |
solid | Water volume — slow movement, extinguish fire. |
func_lava |
solid | Lava volume — damage on entry + burn debuff. |
worldspawn |
solid | Default static geometry (floors, walls, ceilings). |
3. Rebuild in Godot
Open demo/scenes/dungeon_from_map.tscn → select the FuncGodotMap node → click Build Map in the Inspector. Brushes become MeshInstance3Ds, entity brushes become Area3Ds, point entities instantiate their scene files from data/entities/{name}/.
Save the scene to persist the built nodes.
Makefile targets
| Target | What it does | Variables |
|---|---|---|
make map |
Run export_map.gd → writes .map file |
GENERATOR, SEED, DEPTH, LEVELS, MAP_OUT |
make tb-sync |
Run export_tb_config.gd → writes GameConfig.cfg + FuncGodot.fgd |
TB_GAME_DIR (default: ~/.TrenchBroom/games/brogue-genesis) |
make godot |
Build the GDExtension | — |
Raw CLI (if Make isn't available)
# Generate a .map
godot --headless --path demo --script scripts/export_map.gd -- \
--generator brogue --seed 42 --depth 20 --levels 2 \
--out /abs/path/demo/maps/generated.map
# Sync TrenchBroom config
godot --headless --path demo --script scripts/export_tb_config.gd -- \
/home/$USER/.TrenchBroom/games/brogue-genesis
Legacy positional form for export_map.gd (still supported, brogue only): SEED DEPTH [LEVELS] OUT.map.
Adding a new entity type
- Create
demo/data/entities/<classname>/<classname>.tres(aFuncGodotFGDPointClassorFuncGodotFGDSolidClass) and a<classname>.tscnscene for it to instantiate. - Add the
.tresto theentity_definitionsarray in data/fgd/brogue_fgd.tres. - If the exporter needs to emit it, teach scripts/export_map.gd to recognize whatever terrain/liquid tag drives it — see the
_emit_point_entities/_emit_liquid_entitieshelpers. make tb-syncso TrenchBroom picks up the new class.
Troubleshooting
TrenchBroom says "Unknown game: brogue-genesis" — Preferences → Games → make sure brogue-genesis appears. If not, ~/.TrenchBroom/games/brogue-genesis/GameConfig.cfg is missing. Run make tb-sync.
FuncGodot "Build Map" does nothing / errors about missing class — brogue_fgd.tres references a .tres that doesn't exist, or the addon isn't enabled. Check Project Settings → Plugins.
BrogueGen.new() crashes with "class not found" in headless — The GDExtension wasn't built, or only the template_debug variant is present and Godot is launched against template_release. Run make godot. For editor-time tool scripts, the extension needs a linux.editor.x86_64 entry in addons/brogue_gen/brogue_gen.gdextension (already wired).
Player spawn ends up inside a wall — Exporter picks level-0's first T_STAIRS_UP cell, else first walkable. If neither yields a good spawn, move the point_player_start entity by hand in TrenchBroom; next rebuild in Godot preserves it.
Lots of point_door entities from the blobber generator — Blobber treats every FT_DOOR_SILL cell as a door, so multi-cell doorways emit multiple entities. A future pass can merge adjacent door cells into one entity with an extent property.