Commit graph

17 commits

Author SHA1 Message Date
a1d2a63937 feat(core): polygonal room shapes (rect/octagon/ellipse/plus)
RoomCarver now rolls a per-room shape within its chosen rectangle, weighted by
a new RoomConfig.shapes (ShapeWeights). The rect is still picked first and
unchanged, so room centers — and the corridors wired between them — are
identical to before; only the carved interior differs.

- Shapes built from per-row contiguous spans → guaranteed 4-connected and
  convex, so flood-fill never strands a cell.
- Hard invariant: every shape contains rect.center() (the corridor target),
  with a fallback to a full rect for tiny rooms or any non-covering shape —
  keeps MstConnect/CorridorCarver correct.
- ShapeWeights::default() is rect-only (preserves old behavior + existing
  tests); the dungeon recipe opts into ShapeWeights::varied().
- Configs lose Eq (now carry f64 weights); serde unaffected.

Core: 116 tests green (new forced-shape invariants test: in-bounds, center
carved, non-rectangular, 4-connected); connectivity + determinism + door tests
all pass with varied shapes active. Surfaced as 4 shape-weight sliders in the
web playground.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 00:16:45 -06:00
f849d82d31 feat(wasm+web): live browser dungeon playground (WASM core + atmospheric renderer)
Phase 0+1 of the browser viz effort:
- core: drop unused `rand` dep (removes getrandom/libc → clean wasm32 build);
  derive serde on DungeonConfig + 5 sub-configs so the bridge can (de)serialize
- reikhelm-wasm: thin wasm-bindgen cdylib exposing generate(seed, config_json)
  -> JSON envelope (tiles as int codes, regions, edges, per-pass snapshots) and
  default_config_json(); holds no generation logic
- workspace: add reikhelm-wasm member; default-members keeps host cargo
  test/clippy on core+viz only
- reikhelm-web: vanilla-JS + Canvas 2D renderer running the real core live in
  the browser. Atmospheric look — lit stone floor, raised stone walls with
  rim-lit carved edges + top bevel, room light-pooling, amber door thresholds,
  vignette. Controls: seed/reroll, 9 config sliders, stage scrubber, semantic
  overlays (region outlines / graph / grid). window.reikhelm hooks for
  Playwright-driven iteration.

Core stays 115 tests green. Driven + screenshotted via Playwright MCP.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 00:07:24 -06:00
ab195306a5 feat(core): richer default dungeon — denser rooms + loop edges
Default was a pure MST (extra_edge_ratio 0.0), which reads as a linear
chain of rooms. Retune DungeonConfig::default to min_leaf 8 / max_depth 5,
rooms 5..=11, and extra_edge_ratio 0.30 — ~17 interconnected rooms with
loops. Validation inequality still holds (8 - 2 >= 5); boundary test now
uses an explicit edge-case config since the default no longer sits on it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 22:53:03 -06:00
4e54d3b7ba feat(core): dungeon recipe + end-to-end integration tests
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 22:24:53 -06:00
93c32a652f fix(core): pierce-aware DoorPlacer with configurable door_chance
Corridors carve center-to-center and pierce room walls, so the old
wall-threshold rule placed almost no doors. Detect the pierced-wall
threshold (corridor floor outside a room, room on one side, corridor on
the opposite) and mark it Door with probability door_chance (default
0.5), else leave it an open archway. Connectivity is via corridor floor,
independent of doors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 22:19:59 -06:00
61aedfa0c7 feat(core): DoorPlacer pass
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 21:39:02 -06:00
42fda84eaa feat(core): CorridorCarver pass
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 21:36:04 -06:00
d3e389d7f8 feat(core): MstConnect pass
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 21:33:16 -06:00
d2d5fa1a8b feat(core): RoomCarver pass
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 21:30:28 -06:00
f95a562927 feat(core): BspPartition pass
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 21:27:44 -06:00
e0a20f7fd1 feat(core): generation engine — GenContext, Pass, Pipeline, Blackboard
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 21:20:29 -06:00
8c4ef2ed4d feat(core): derive PartialEq/Eq on Grid<T> and Map
Lets downstream determinism tests compare maps with `assert_eq!` instead
of a serde-string workaround. Auto-gated on T (Grid<f32> gets only
PartialEq); Map has no float fields so Eq is sound.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 21:14:12 -06:00
659ef00017 feat(core): data model + Map output contract + ASCII renderer
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 21:10:47 -06:00
6ffe0cc68c feat(core): deterministic ChaCha8 RNG with order-independent fork
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 21:07:43 -06:00
dbfd44a014 feat(core): generic bounds-safe Grid<T>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 21:04:44 -06:00
f707bd13be feat(core): geometry primitives (Point, Rect, Line)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 21:02:36 -06:00
08e99e38a3 chore: scaffold reikhelm cargo workspace (core + viz crates)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 20:56:24 -06:00