Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/COMPONENT_DESIGN_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ Examples:
- `SteppedTier`
- `VerticalSetbackVolume`
- `SteppedDome`
- `EllipseRing`
- `PathRepeat`
- `ArcadeRun`
- `TreeCanopy`
- `OrganicPatch`
Expand All @@ -79,6 +81,8 @@ Examples:

Add a high-level component only when it captures a reusable pattern that agents otherwise express verbosely or incorrectly.

`EllipseRing` captures true bounded oval shells that cannot be represented by stadium caps without changing curvature. `PathRepeat` is deliberately limited to count-based ellipse sampling of a reusable assembly, reusing the existing arbitrary-angle instance rotation machinery. Keep the assembly Y local and apply global level offsets with non-negative integer `placement.y`; closed-loop `startAngle === endAngle` chooses a sampling phase without duplicating the seam. Keep the component semantics Minecraft-oriented; do not expand them into a general curve or CAD language.

## Component admission checklist

Before adding a new component, answer all questions below.
Expand Down
25 changes: 25 additions & 0 deletions docs/COMPONENT_PLAN_SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ Start with a small component vocabulary:
- `VerticalSetbackVolume`
- `SteppedDome`
- `RectRing`
- `EllipseRing`
- `PathRepeat`
- `RailingRun`
- `ArcadeRun`
- `SupportBracket`
Expand Down Expand Up @@ -243,6 +245,29 @@ Use `SteppedDome` for bounded Minecraft-style dome approximations, such as Taj-s

Use `RectRing` for rectangular ring bands around an open interior: eave bands on tiered towers and pagoda-style roofs, cornices, parapets, plinth bands, balcony fascias, and trim frames around courtyards or roof plates. It is the rectangular counterpart to `CircleRing` and expands into at most four axis-aligned band boxes (`ring_front`, `ring_back`, `ring_left`, `ring_right`) inside one anchored bounding box. Use `options.bandWidth` for the inward band thickness and `options.height` for the band height. The band must leave at least a one-block open interior; use `Platform` instead when the surface should be a full slab. Pair it with `SteppedDome` or `CircleRing` for curved caps.

Use `EllipseRing` for bounded oval shells, arenas, courtyards, and curved walls that need true ellipse curvature rather than a stadium approximation. Its integer `placement.center`, `radiusX`, and `radiusZ` define the ellipse on XZ; `placement.y` is the base layer. `options.height` and `options.thickness` default to 1, and `options.fill` defaults to `hollow`. Hollow rings subtract an inner ellipse inset by the thickness on both axes. Optional `startAngle`/`endAngle` select a partial ellipse using the same 0° (+X), increasing-toward-+Z convention as `CircleRing`. Bounds validation uses the full declared ellipse, including for a partial arc. Expansion emits deterministic single-block `SolidBox` nodes and keeps ordinary material, provenance, and support analysis behavior.

Use `PathRepeat` to place one reusable assembly at count-based samples along an ellipse, such as arcade bays or colonnade modules. The source is an assembly ID. `placement.y` is a non-negative logical height offset applied globally to every repeated sample as `y * grid.unitBlocks`; assembly member Y coordinates stay local and unchanged. The path point aligns with the XZ center of the assembly bounds, rounded to the nearest voxel when the pivot falls between blocks. `orientToTangent: true` rotates local +X onto the analytic ellipse tangent and uses the existing deterministic integer voxel rotation. It defaults to `false`. The schema is intentionally ellipse-only:

```json
{
"id": "arcade_bays",
"type": "PathRepeat",
"placement": {
"path": { "type": "ellipse", "center": { "x": 36, "z": 20 }, "radiusX": 25, "radiusZ": 13 },
"source": "bay_module",
"count": 24,
"y": 0,
"startAngle": 0,
"endAngle": 360,
"closed": true,
"orientToTangent": true
}
}
```

Closed paths emit `count` samples over one full turn without a duplicate seam endpoint. Use equal `startAngle` and `endAngle` values to choose a phase (for example, `7.5` to `7.5`); the legacy `0` to `360` form remains valid. Open paths require at least two samples over a non-zero sweep and include both endpoints. If `endAngle` is less than `startAngle` on an open path, sampling continues forward through 360°. Angles use the ellipse parameterization `x=cx+radiusX*cos(t)`, `z=cz+radiusZ*sin(t)`. The declared ellipse, Y-shifted rotated assembly envelope, and every emitted voxel must fit the plan bounds. Block budgeting conservatively sums each rotated source-assembly bounds envelope per sample without discounting overlap; vertical placement does not reduce that estimate. `PathRepeat` supports assemblies only; use `Instance` for one-off placements. It does not support arc-length spacing or general curves.

For stepped eave curvature, set `options.cornerRise` to a small non-negative integer: each corner column gains up to that many extra blocks above `options.height`, stepping down over `options.riseSpan` columns (defaults to `cornerRise`, one block per step) toward the middle of each edge. This approximates curved eave edges and corner uplift with deterministic integer segments named `ring_<side>_seg<n>`; keep the ring's inner hole aligned with the tower cross-section at that height so the band bears on the walls. The placement must declare vertical room (`options.height + options.cornerRise <= placement.size.height`) or validation rejects the plan. Flat rings without `cornerRise` expand exactly as before. Components that consume a cornerRise ring through `inputs` are connected to every emitted segment, preserving whole-ring bearing in the expanded graph.

Use `RailingRun` for repeated posts plus horizontal rails along bridges, decks, walls, balconies, and platforms. It is a bounded run, not a fence/pathfinding simulator. Use `postSpacing`, `includeTopRail`, and `includeMidRail` for controlled detail.
Expand Down
4 changes: 4 additions & 0 deletions docs/LLM_AUTHORING_CONTRACT.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ Use `RailingRun` for bounded posts and rails along decks, bridges, walls, and ba

Use `RectRing` for rectangular eave bands, cornices, parapets, plinth bands, and trim frames with an open interior. Set `options.bandWidth` for band thickness; keep at least a one-block open hole. Use `Platform` for full slabs and `CircleRing` for circular rings. For pagoda/temple eaves, set `options.cornerRise` (1-3) with `options.riseSpan` (defaults to `cornerRise`) so the band steps upward toward each corner, approximating curved eave edges and corner uplift; size the ring so its inner hole matches the wall cross-section at that height, and give the placement enough height for base + rise. Do not invent pagoda-eave or landmark-specific ring types. Components that declare `inputs` on a cornerRise ring are automatically attached to every emitted segment, so no per-segment refs are needed.

Use `EllipseRing` for true oval shells and curved walls. Set `placement.center`, `radiusX`, and `radiusZ`; use `options.height` and `options.thickness` for a hollow wall. It uses a deterministic voxel ellipse, not two circular caps and tangent walls. Partial `startAngle`/`endAngle` use the `CircleRing` angle convention, and bounds must contain the full declared ellipse.

Use `PathRepeat` for a reusable assembly repeated along an ellipse, such as a curved arcade. Set `placement.path` to `{ "type": "ellipse", "center": { "x": ..., "z": ... }, "radiusX": ..., "radiusZ": ... }`, then set `source`, `count`, non-negative integer `y`, `startAngle`, `endAngle`, and `closed`. `y` shifts every sample globally by `y * grid.unitBlocks`; keep Y coordinates in the reusable assembly local so the same module can be repeated at multiple levels. Closed paths use `count` samples without a duplicate seam endpoint; equal start/end angles set the phase of the full loop (legacy `0` to `360` is also accepted). Open paths include both endpoints and need at least two samples. Set `orientToTangent: true` to align assembly local +X to the ellipse tangent. The declared shifted assembly envelope and every rotated voxel must fit plan bounds. This is count-based ellipse sampling, not arc-length spacing or a generic curve language.

Use `ArcadeRun` for repeated stepped arch-like facade rhythms: colosseum bays, gothic arcades, palace cloisters, bridge arches, and monumental walls. Do not try to describe exact curves; use Minecraft-like blocky arches.

Use `SupportBracket` for visible support under overhangs, balconies, lifeboat shelves, awnings, and light bridge edges. Pair it with `structural.maxCantilever` when the bracket is intended to satisfy support diagnostics. Do not use it to silence unrelated floating structures.
Expand Down
4 changes: 3 additions & 1 deletion docs/llm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Authoring rules
10. If validation fails, repair the plan instead of loosening schema or validation.

Allowed ComponentPlan components
Foundation, Platform, Beam, RoomShell, Compartment, Corridor, StairRun, FloorStack, TaperedVolume, SteppedTier, VerticalSetbackVolume, SteppedDome, RailingRun, ArcadeRun, SupportBracket, TreeCanopy, OrganicPatch, PathRun, RockCluster, Light, Door, Window, Opening, Portal, GableRoof, FlatRoof, SupportPost, Repeat, Instance.
Foundation, Platform, Beam, RoomShell, Compartment, Corridor, StairRun, FloorStack, TaperedVolume, SteppedTier, VerticalSetbackVolume, SteppedDome, RectRing, EllipseRing, PathRepeat, RailingRun, ArcadeRun, SupportBracket, TreeCanopy, OrganicPatch, PathRun, RockCluster, Light, Door, Window, Opening, Portal, GableRoof, FlatRoof, SupportPost, Repeat, Instance.

When to use key components
- RoomShell: one exterior or interior hollow volume.
Expand All @@ -36,6 +36,8 @@ When to use key components
- SteppedTier: pyramids, amphitheater seating, podiums, terraces.
- VerticalSetbackVolume: tall towers, pagodas, skyscrapers, spires.
- SteppedDome: Minecraft-style dome roofs and caps.
- EllipseRing: true bounded oval shell using integer center and radii.
- PathRepeat: count-based ellipse path for a reusable assembly; non-negative integer `placement.y` globally offsets local assembly Y, closed paths omit the seam and allow phase with equal start/end angles, open paths include both endpoints, and orientToTangent aligns local +X.
- ArcadeRun: repeated blocky arches in facades or bridges.
- SupportBracket: visible supports under overhangs, balconies, lifeboat shelves.
- TreeCanopy, OrganicPatch, PathRun, RockCluster: landscape and garden detail.
Expand Down
Loading
Loading