Skip to content

feat(render): organic chamber walls with rounded corners (#97)#100

Merged
LightAxe merged 5 commits into
mainfrom
feat/97-organic-chamber-walls
May 5, 2026
Merged

feat(render): organic chamber walls with rounded corners (#97)#100
LightAxe merged 5 commits into
mainfrom
feat/97-organic-chamber-walls

Conversation

@LightAxe
Copy link
Copy Markdown
Owner

@LightAxe LightAxe commented May 5, 2026

Closes #97.

Summary

Chambers now render as rounded rectangles instead of crisp axis-aligned boxes. Each chamber's corner radius is deterministic on its identity (colonyId, chamberId, chamberType) so adjacent chambers don't all look identical and the visual is stable across frames and save/reload.

What changed

  • New src/render/chamber-shape.ts: pure helpers — chamberSeed() (Math.imul-based 32-bit hash) and chamberCornerRadius() (3..6 px nominal, capped at half the bounding extent, lower-bounded at 1).
  • src/render/draw-underground.ts chamber loop: replaces the single bounding-box fillRect with a rounded-rect built from 2 overlapping fillRect strips + 4 fillCircle corners. Queen-chamber gold outline (Phase 8.5 landmark) traces the new shape via 4 thin strips between the rounded corners.

What didn't change

  • Sim footprint stays rectangular. Collision, capacity, BFS, and chamber-tile checks all still operate on the rectangular CHAMBER_DIMENSIONS bounding box. Render-only change.
  • No save/replay impact. No new persisted state.
  • Determinism preserved. Same chamber identity → same shape every frame, every reload.

Why no strokeCircle for corner arcs?

GfxLike has only strokeCircle, which draws the full ring. Three of its four quadrants would overlap the chamber fill and draw visible gold curls inside the queen chamber — a visual regression. The rounded fillCircle underneath already conveys the rounded shape; the small gold-free arc at each corner reads as part of the hand-carved aesthetic. (Comment in code documents this.)

Test plan

  • Typecheck clean
  • 1842/1842 unit tests pass
  • UAT: chambers visibly less rectangular; queen-chamber gold trim still clearly readable as a landmark on a fresh underground tab
  • UAT: save → reload → queen chamber renders with the same corner radius as before save (determinism check)

Internal review loop ran 3 fresh-context passes; final pass was clean.

Closes #97.

Chambers now render as rounded rectangles instead of crisp axis-aligned
boxes. The shape is built from two overlapping fillRect strips plus four
fillCircle corners, with a per-chamber-deterministic radius (3..6 px)
derived from the chamber's identity (colonyId, chamberId, chamberType)
via a Math.imul-based 32-bit hash. Adjacent chambers vary so the layout
no longer looks tile-grid-perfect.

Queen-chamber gold outline (Phase 8.5 usability landmark) traces the
new shape via four axis-aligned strips between the rounded corners.
We deliberately do NOT use strokeCircle for the corner arcs because
GfxLike has no arc primitive — strokeCircle would draw the full ring,
and three of its four quadrants would overlap the chamber fill and
draw visible gold curls inside the chamber. The rounded fillCircle
underneath conveys the rounded shape; the small gold-free arc at each
corner reads as part of the hand-carved aesthetic.

Render-only change. The simulation footprint stays rectangular —
collision, capacity, BFS, and chamber-tile checks all still operate on
the rectangular CHAMBER_DIMENSIONS bounding box. No save/replay impact.

Tests cover: hash determinism, hash diversity by colonyId/chamberId/
chamberType, corner-radius cap at half the bounding extent, queen
outline = 4 thin strips with no strokeCircle, non-queen chambers don't
get the gold outline, and per-chamber position/radius determinism
across calls.
@LightAxe
Copy link
Copy Markdown
Owner Author

LightAxe commented May 5, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…smooth-wave polygon (#97)

UAT feedback on the rounded-rect approach: "I was expecting more of a wavy
line situation for the chamber walls, and I was expecting the yellow
queen's chamber outline to not be straight lines, but rather following
the organic wavy/inconsistent lines like a natural ant would have dug
out."

Redesign:

  • chamberPerimeterPoints() now generates 32 points walking the chamber
    bounding rectangle clockwise, each displaced along its outward normal
    by a deterministic per-chamber smooth wave: 8 wave-nodes hashed from
    the chamber's seed (Math.imul mixer), linearly interpolated around
    the perimeter at amplitude ±3 px. Half-step offsets keep samples off
    rectangle corners.

  • Chamber fill is now a fan triangulation from the chamber center (32
    fillTriangle calls per chamber). Bowtie overdraw from minor non-
    convexity is harmless under same-color additive draws.

  • Queen-chamber gold outline traces the SAME wavy perimeter via 32
    line-segment quads (each = 2 fillTriangle calls = 64 outline tris).
    Round-caps via fillCircle at each vertex hide the joint micro-over/
    under-lap that occurs at non-axis-aligned direction changes under
    alpha 0.7. drawOutlineSegment helper computes the perpendicular via
    Math.hypot — render layer, floats fine.

Drops the chamberCornerRadius helper and the rounded-rect rendering
path. Determinism story unchanged: chamber identity (colonyId, chamberId,
chamberType) → chamberSeed → wave nodes → polygon. Same perimeter every
frame and every reload.

Render-only — sim footprint stays rectangular (CHAMBER_DIMENSIONS).
Performance: ~96 fillTriangle + ~32 fillCircle per queen chamber, ~32
fillTriangle per non-queen — comfortable for ~10 chambers/colony.

Tests cover: hash determinism + diversity, perimeter point count, jitter
bounds, anchor translation invariance, non-trivial wave (regression
guard against amp=0), small-chamber amplitude clamp, degenerate 0×0
chamber, queen wavy fill + outline triangle counts, no axis-aligned
strips in outline pass, round-cap circle count + radius, non-queen
absence-of-gold-outline guard, and full-vertex determinism across calls.
@LightAxe
Copy link
Copy Markdown
Owner Author

LightAxe commented May 5, 2026

@codex review (chamber walls redesigned per UAT — now wavy polygon instead of rounded rect)

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…eed through (#97)

UAT feedback after the wavy-walls redesign: "I like it a lot but a small
amount of brown is bleeding through behind the nursing chamber."

Cause: chamberPerimeterPoints walked the chamber's bounding rectangle
directly, so the wave's inward swing (jitter -amp..0) pulled some
perimeter points INSIDE the rectangle. The fan-triangulated polygon
fell short of the rectangular CHAMBER_DIMENSIONS footprint in those
spots, exposing the open-floor substrate underneath.

Fix: walk an INFLATED rectangle (each side expanded by clamped wave
amplitude). Inward jitter now reaches exactly the original rectangle
edge, never crosses inside. Outward jitter extends up to 2 × amplitude
beyond into adjacent open-floor tiles, which reads as the chamber's
hand-carved boundary spilling slightly into the surrounding floor.

The polygon always fully covers the rectangular CHAMBER_DIMENSIONS
footprint by construction. Tests updated:
  • New: every perimeter point lies outside the original rectangle's
    open interior (the substrate-bleed guard).
  • Updated: outward bounds widened to 2 × amp.
  • Updated: deviation regression checks against the inflated edge.

Determinism unchanged. Sim footprint unchanged.
@LightAxe
Copy link
Copy Markdown
Owner Author

LightAxe commented May 5, 2026

@codex review (small fix: inflate wavy-perimeter base rect so the inward wave swing can't expose the substrate underneath)

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0198fde134

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/render/chamber-shape.ts Outdated
…dex P1 on #100)

Codex P1 on the prior bleed-through fix: the inflation guarantees every
VERTEX stays outside the original rectangle, but the chord BETWEEN
adjacent vertices can dip across a corner into the rectangle interior
with extreme jitter. Concrete repro from codex: seed=0, w=80, h=48
produces a segment passing through (~0.01, 0.79) — strictly inside
[0,80] × [0,48].

Fix: insert 4 fixed corner samples at the inflated rectangle's corners
during the perimeter walk, in clockwise order. Adjacent chords now wrap
around each corner externally — the chord from the last edge-sample
before a corner goes out to the inflated corner (always outside the
original rectangle), then from the corner to the first edge-sample
after, all stays outside.

Total perimeter point count: NUM_PERIMETER_POINTS (32 edge samples) +
NUM_CORNER_SAMPLES (4) = 36 points → 36 fan-fill triangles, 72 outline
segment-triangles, 36 round-cap circles per queen chamber. Cost: same
order of magnitude as before; perf still well within budget.

New test (chamber-shape.test.ts) explicitly samples 32 points along
each chord between adjacent perimeter vertices and asserts none fall
strictly inside the original rectangle. Reproduces the codex P1 case
(seed=0) as a regression guard.

Determinism unchanged. Sim footprint unchanged.
@LightAxe
Copy link
Copy Markdown
Owner Author

LightAxe commented May 5, 2026

@codex review (addressed P1: added 4 fixed corner samples at inflated-rectangle corners so adjacent chords wrap around corners externally — repro test for seed=0 now in chamber-shape.test.ts)

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…UAT)

UAT feedback: "I really like how the chambers are more dynamic, and
appreciate the color fill matching. The only piece I'd like to change
if it isn't terribly difficult is the corners: They are too sharp. A
natural chamber will tend towards being oval-shaped, and while that
doesn't translate well to a grid like we're using, I do wonder if we
could always have the corners rounded off to emulate or nod towards
ovals?"

Replace the 4 fixed sharp corner samples with 4 inscribed quarter-arcs:

  • Each arc has 5 samples (4 segments at 22.5° each), inscribed in the
    corresponding inflated rectangle's corner. Arc center sits R px
    inward diagonally from the inflated corner; arc midpoint stays
    outside the original rectangle for R ≤ 3 × amplitude (default
    R=6 px vs amp=3 px is well within margin).

  • Straight edges are now truncated by R on each end so they meet the
    arcs cleanly — no double-back at the joints.

  • Wave-driven edge samples are distributed across the truncated
    straight perimeter (~232 px for Queen 80×48 vs the prior 280 px
    inflated perimeter); per-sample spacing and wavelength land in the
    same range as before (~7 px between samples, ~29 px wavelength).

  • Arcs themselves are smooth fixed quarter-circles — no wave applied.
    This keeps the corner-rounding visually distinct from the edge
    wobble; edges undulate, corners are clean curves. Matches the
    user's "oval feel."

Total perimeter point count: 32 edge samples + 4 × 5 = 52 points per
chamber. Per queen chamber: 52 fan-fill triangles + 104 outline
segment-triangles + 52 round-cap circles. Still comfortably within
the render budget for ~10 chambers per colony.

Tests: chord-coverage guard (codex P1 repro on seed=0) still holds —
arc samples + straight-edge samples both stay outside the original
rectangle by construction. New test asserts exactly 4 × 5 = 20 points
sit at the expected arc radius from one of the four corner centers.
@LightAxe
Copy link
Copy Markdown
Owner Author

LightAxe commented May 5, 2026

@codex review (UAT polish: rounded corners — replaced sharp inflated-corner samples with inscribed quarter-arcs at 6-px radius, 5 samples per corner; straight edges truncated to meet arcs cleanly)

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@LightAxe LightAxe merged commit dd83c9a into main May 5, 2026
1 check passed
@LightAxe LightAxe deleted the feat/97-organic-chamber-walls branch May 5, 2026 19:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] Make chamber walls more organic/rounded, less rectangular

1 participant