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
1 change: 1 addition & 0 deletions docs/BUILD_COVERAGE_MATRIX.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Observed support diagnostics on the current samples:
| `temple-palace-dome-study` | pass | pass | 58 | 828 | 0 | Assembly authoring works; dome diagnostics remain noisy |
| `xi-an-bell-tower-study` | pass | pass | 20 | 108 | 728 | Good visual landmark probe; broad eaves create intentional span/cantilever review points |
| `giant-wild-goose-pagoda-study` | pass | pass | 20 | 0 | 24 | Walkable pagoda is structurally connected; repeated levels are verbose and need authoring support |
| `pagoda-eave-flare-study` | pass | pass | 20 | 0 | 0 | Multi-level pagoda with `RectRing` cornerRise eaves on default strict policy; overhang review warnings are expected and no decorative suppression is needed |
| `ship-bow-shape` | pass | pass | 38 | 1996 | 0 | Ship bow taper is useful visually but support diagnostics need clearer intent |
| `arcade-bracket-study` | pass | pass | 60 | 1328 | 0 | Arch/bracket sample exposes span semantics and diagnostic noise |

Expand Down
2 changes: 1 addition & 1 deletion docs/COMPONENT_DESIGN_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ If an existing component plus clearer docs solves the problem, do not add a new
- `SteppedTier`: horizontal stepped tiers
- `VerticalSetbackVolume`: vertical setback segments
- `SteppedDome`: bounded stepped dome approximation
- `RectRing`: rectangular ring band (eaves, cornices, parapets) around an open interior
- `RectRing`: rectangular ring band (eaves, cornices, parapets) around an open interior, with optional stepped `cornerRise` toward corners for curved-eave/corner-uplift silhouettes
- `GableRoof`: pitched roof volume
- `FlatRoof`: flat cover/cap/canopy

Expand Down
11 changes: 9 additions & 2 deletions docs/COMPONENT_PLAN_SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ The expander translates semantic dependencies into low-level CraftDAG inputs and

For attached and covering components, `placement.target` and `placement.over` are implicit dependencies. Agents may include them in `inputs` for readability, but the expander must add the low-level CraftDAG dependency even when they are omitted.

When a dependency resolves to a multi-segment source component, the expander connects the consumer to every emitted segment instead of one canonical part: a `RectRing` with `cornerRise` bears through all of its `ring_<side>_seg<n>` nodes, so anything resting on a flared eave depends on the whole ring. Flat `RectRing`s keep the legacy single `ring_front` attachment.

## v0.1 Component Set

Start with a small component vocabulary:
Expand Down Expand Up @@ -239,7 +241,9 @@ Use `VerticalSetbackVolume` for tall landmark massing with discrete setbacks, su

Use `SteppedDome` for bounded Minecraft-style dome approximations, such as Taj-style central domes, temple or mosque roofs, observatories, rotundas, and fantasy tower caps. It expands into stacked shrinking tiers inside one anchored box. Use it when the authoring intent is a dome-like roof or cap; use `SteppedTier` for horizontal terraces and `VerticalSetbackVolume` for tall setback towers. Do not add landmark-specific dome component types.

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. Corner flares and curved profiles are intentionally out of scope; pair it with `SteppedDome` or `CircleRing` for curved caps.
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.

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 Expand Up @@ -690,6 +694,7 @@ The analyzer reports:
- `DISCONNECTED_COMPONENT`: blocks are not connected to configured support roots.
- `FLOATING_SOURCE_NODE`: a source node contributes disconnected blocks.
- `LARGE_CANTILEVER`: connected blocks exceed the configured `maxCantilever` distance from nearby vertical support.
- `MINIMAL_ATTACHMENT`: a component that declares `inputs` and uses `must_connect_to_input` or `must_connect_to_ground` connects to the rest of the build through fewer than `minAttachmentContacts` (default 2) shared faces, such as an eave ring resting on a single corner block.
- `NOT_VERTICALLY_SUPPORTED_BUT_CONNECTED`: blocks have air below but remain connected through adjacent blocks, such as bridge spans or rails.
- `ALLOWED_*`: the same condition is allowed by `structural.supportPolicy` when `includeAllowed: true`.

Expand Down Expand Up @@ -719,9 +724,11 @@ The result includes a `summary` field for agent and product quality gates:
Quality gate status is conservative:

- `block`: at least one unallowed `DISCONNECTED_COMPONENT` or `FLOATING_SOURCE_NODE`.
- `review`: no blocking diagnostics, but at least one `LARGE_CANTILEVER` or `NOT_VERTICALLY_SUPPORTED_BUT_CONNECTED`.
- `review`: no blocking diagnostics, but at least one `LARGE_CANTILEVER`, `MINIMAL_ATTACHMENT`, or `NOT_VERTICALLY_SUPPORTED_BUT_CONNECTED`.
- `pass`: no blocking or review diagnostics. Allowed diagnostics do not downgrade the status.

Components without declared `inputs`, and components using `decorative` or `may_float` policies, are exempt from `MINIMAL_ATTACHMENT`; standalone foundations and intentional decorations stay quiet.

The result also includes `sourceSummaries`, which aggregate total blocks, bounds, disconnected block counts, vertical unsupported counts, and large cantilever counts by `sourceNodeId`.

By default, diagnostics for `decorative` and `may_float` components are filtered out. Use `includeAllowed: true` when a UI or repair loop wants to show allowed floating elements for inspection.
Expand Down
4 changes: 2 additions & 2 deletions docs/LLM_AUTHORING_CONTRACT.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ Use `SteppedDome` for bounded Minecraft-style dome roofs and caps: Taj-style dom

Use `RailingRun` for bounded posts and rails along decks, bridges, walls, and balconies. Prefer it over manually listing many posts. Use `postSpacing` for rhythm and `includeMidRail` for extra detail.

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. Do not invent pagoda-eave or landmark-specific ring types.
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 `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.

Expand Down Expand Up @@ -455,7 +455,7 @@ Agents should use structured diagnostics when available. Prefer `diagnosticsFrom

For support warnings after successful compilation, use `analyzeComponentPlanSupport(plan)`. For preview/export tools that already have compiled voxels, use `analyzeVoxelSupport(voxelPlan)`.

Support diagnostics are warnings, not validation failures. Repair unexpected `DISCONNECTED_COMPONENT` or `FLOATING_SOURCE_NODE` warnings by adding foundations, posts, brackets, shelves connected to inputs, or by moving the component onto a supporting surface. Treat `NOT_VERTICALLY_SUPPORTED_BUT_CONNECTED` as a review signal for bridges, roofs, rails, and spans. Treat `LARGE_CANTILEVER` as a stronger span warning: add nearby posts, arches, cables, brackets, or explicit structural intent.
Support diagnostics are warnings, not validation failures. Repair unexpected `DISCONNECTED_COMPONENT` or `FLOATING_SOURCE_NODE` warnings by adding foundations, posts, brackets, shelves connected to inputs, or by moving the component onto a supporting surface. Treat `NOT_VERTICALLY_SUPPORTED_BUT_CONNECTED` as a review signal for bridges, roofs, rails, and spans. Treat `LARGE_CANTILEVER` as a stronger span warning: add nearby posts, arches, cables, brackets, or explicit structural intent. Treat `MINIMAL_ATTACHMENT` as a roof-frame review signal: a component you connected with `inputs` rests on very few shared faces; widen the bearing surface or add brackets instead of silencing it with `decorative`.

Use `sourceSummaries` to identify the noisiest source nodes before editing. Prefer repairing the largest unexpected source groups first instead of making broad random changes.

Expand Down
149 changes: 149 additions & 0 deletions examples/component-plans/pagoda-eave-flare-study.componentplan.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
{
"version": "0.1",
"name": "Pagoda Eave Flare Study",
"grid": {
"unitBlocks": 1
},
"policy": {
"sizeTier": "large"
},
"bounds": {
"width": 40,
"height": 44,
"length": 40
},
"palette": {
"foundation": "minecraft:stone_bricks",
"wall": "minecraft:sandstone",
"floor": "minecraft:cut_sandstone",
"roof": "minecraft:cyan_terracotta",
"trim": "minecraft:gold_block"
},
"components": [
{
"id": "plinth",
"type": "Foundation",
"role": "temple_plinth",
"placement": {
"anchor": { "x": 4, "y": 0, "z": 4 },
"size": { "width": 32, "height": 1, "length": 32 }
}
},
{
"id": "podium",
"type": "SteppedTier",
"role": "tiered_temple_podium",
"inputs": [{ "ref": "plinth" }],
"placement": {
"anchor": { "x": 8, "y": 1, "z": 8 },
"size": { "width": 24, "height": 4, "length": 24 }
},
"options": {
"axis": "both",
"levels": 2,
"stepHeight": 2,
"insetPerLevel": 1
}
},
{
"id": "pagoda_body",
"type": "FloorStack",
"role": "multi_level_pagoda_levels",
"inputs": [{ "ref": "podium" }],
"placement": {
"anchor": { "x": 10, "y": 5, "z": 10 },
"size": { "width": 20, "height": 30, "length": 20 }
},
"options": {
"levels": 5,
"levelHeight": 6,
"setbackPerLevel": 1,
"stairStyle": "ladder",
"includeDoorways": true,
"includeWindows": true
}
},
{
"id": "eave_1",
"type": "RectRing",
"role": "flared_eave_level_1",
"inputs": [{ "ref": "pagoda_body" }],
"placement": {
"anchor": { "x": 8, "y": 10, "z": 8 },
"size": { "width": 24, "height": 4, "length": 24 }
},
"options": {
"bandWidth": 2,
"height": 1,
"cornerRise": 2,
"riseSpan": 3
}
},
{
"id": "eave_2",
"type": "RectRing",
"role": "flared_eave_level_2",
"inputs": [{ "ref": "pagoda_body" }],
"placement": {
"anchor": { "x": 9, "y": 16, "z": 9 },
"size": { "width": 22, "height": 4, "length": 22 }
},
"options": {
"bandWidth": 2,
"height": 1,
"cornerRise": 2,
"riseSpan": 3
}
},
{
"id": "eave_3",
"type": "RectRing",
"role": "flared_eave_level_3",
"inputs": [{ "ref": "pagoda_body" }],
"placement": {
"anchor": { "x": 10, "y": 22, "z": 10 },
"size": { "width": 20, "height": 4, "length": 20 }
},
"options": {
"bandWidth": 2,
"height": 1,
"cornerRise": 3,
"riseSpan": 3
}
},
{
"id": "roof_cap",
"type": "SteppedDome",
"role": "pagoda_roof_cap",
"inputs": [{ "ref": "pagoda_body" }],
"placement": {
"anchor": { "x": 13, "y": 35, "z": 13 },
"size": { "width": 14, "height": 6, "length": 14 }
},
"materials": {
"main": "roof"
},
"options": {
"levels": 3,
"insetPerLevel": 2,
"hollow": false
}
},
{
"id": "roof_finial",
"type": "SupportPost",
"role": "pagoda_roof_finial",
"inputs": [{ "ref": "roof_cap" }],
"placement": {
"anchor": { "x": 19, "y": 41, "z": 19 },
"size": { "width": 2, "height": 3, "length": 2 }
},
"materials": {
"main": "trim"
},
"structural": {
"supportPolicy": "decorative"
}
}
]
}
Loading
Loading