Skip to content

Agents: exact colours, column code, textured maps, slab surface scripts - #1190

Merged
wass08 merged 1 commit into
mainfrom
feat/author-scene-fidelity
Oct 28, 2026
Merged

wass08 merged 1 commit into
mainfrom
feat/author-scene-fidelity

Conversation

@wass08

@wass08 wass08 commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

What does this PR do?

Lets author_scene and the MCP tools build more faithful finishes:

  • Columns in author_scene take code (the add_column module contract, mount floor), rotation, and a color that is now applied, as an exact material on every native surface (it was stored in metadata and never applied).
  • Same gap on other kinds: a slab's railing accepted a height but the slab renderer drew every run at 1.1 m in the slab's edge finish. Slab railings are now fences standing on the slab (supportSlabId) with their own height and a new color. Stairs now take railing (sides), railingStyle, color (flight), treads and railingColor.
  • exact: true on paint (with color: that colour as a matte scene material, not the nearest library colour) and on add_object (the module's slot colours with their roughness/metalness, not their library matches; glass and emissive slots keep theirs). One shared helper (exactColorMaterial / exactScriptSlots) now backs author_scene's exact slots too.
  • Native textures take offset, normalMap/normalScale, bumpMap/bumpScale; the viewer applies them (maps share the albedo's repeat and offset; normal/bump are non-colour, rendered shading only). New map URLs are inventoried as asset references; reference discovery now treats any AssetUrl field as a reference. paint documents the UV convention so an agent can line joints up (offset = frac(−c × repeat)).
  • Slab surface scripts: a standalone slab (not a room's floor plate, boundary !== 'auto') can carry surfaceScript, the same record as a room's floor.script: author_scene surfaceCode, setSlabSurfaceScript, refreshed by refreshFinishScripts when reshaped, drawn on the slab's top, owning the surface's colours (paint refused), items stand on its build, get_source reads it, clipboard carries its artifacts, the slab panel shows it (view / remove, like the room panel, via a shared ScriptedFinishRow).

Reviewer note: the slab kind now has a lazily loaded renderer (ParametricNodeRenderer + the script build beside the slab's group), like columns, doors and ceilings, instead of the default generic mount. ParametricNodeRenderer is exported from viewer for that.

Old scenes load unchanged: every new field is optional.

How to test

  1. bun run ci (run locally: green).
  2. author_scene a payload with a slab { polygon, top: 0.3, surfaceCode: <decking module> } and a column with code and another with color: the slab shows the decking on its top, the coded column its module, the coloured one that exact colour on shaft/base/capital.
  3. paint a wall with { color: '#3a5f8c', exact: true }: a scene material named #3a5f8c is created and reused on a second call.
  4. paint a floor with a native material { texture: { url, repeat: [2, 2], offset: [0.5, 0], normalMap } }: the pattern shifts half a tile and shows relief.

Screenshots / screen recording

Checked locally in apps/editor (next dev): a payload sent through the MCP author_scene tool, with real compiles and the app's artifact store, then a textured paint. It renders the terrace's script-built decking on the slab top, cut to its outline; a 0.9 m red railing standing on it; a native column in its exact green, turned 30°; a scripted post in its module's exact blue; and a brick wall face with its normal map, offset half a tile. The slab kind's new renderer path also renders an existing project's slabs unchanged. No new console errors; the two "synchronously unmount a root" warnings also show without this change. No recording attached.

Checklist

  • I've tested this locally with bun dev
  • My code follows the existing code style (run bun check to verify)
  • I've updated relevant documentation (if applicable)
  • This PR targets the main branch

🤖 Generated with Claude Code


Note

Medium Risk
Broad changes to agent paint/add_object, author_scene placement, finish-script refresh, and spatial elevation, but new schema fields are optional and heavily tested.

Overview
Adds exact: true on paint and add_object so hex colours become reusable scene materials instead of nearest library matches; scripted slots keep authored roughness/metalness while glass and emissive slots stay special. Shared exactColorMaterial / exactScriptSlots also drive author_scene exact slot mapping.

Native materials gain texture offset, normalMap/normalScale, and bumpMap/bumpScale (viewer applies shared placement; paint documents UV/joint alignment). Reference inventory and discovery cover the new map URLs.

Standalone slabs (not room floor plates) can carry surfaceScript via setSlabSurfaceScript and author_scene surfaceCode: compile on outline, refresh when reshaped, refuse surface paint, elevate placed items on the build, get_source / clipboard / slab panel parity with room floor scripts; slab kind gets a composed renderer.

author_scene also wires slab railings as height/coloured fences on the slab, columns with code, rotation, and applied color, and stairs with railing mode/style and body/tread/railing finishes.

Reviewed by Cursor Bugbot for commit 53bec51. Bugbot is set up for automated code reviews on this repo. Configure here.

- author_scene columns take code (mount floor), rotation, and a color applied
  as an exact material on every native surface (it was stored, never applied).
- author_scene slab railings are fences standing on the slab with their own
  height and color (the height was accepted but drawn at 1.1 m in the edge finish).
- author_scene stairs take railing sides and style, and flight, tread and railing finishes.
- paint color and add_object take exact: true to keep a colour as written
  instead of the nearest library finish; one shared exact-colour helper.
- Native textures take offset, normalMap/normalScale and bumpMap/bumpScale;
  paint documents the UV convention for lining joints up.
- Standalone slabs take a surface script (author_scene surfaceCode), as a room's
  floorCode: stored, rendered on the slab top, refreshed when reshaped, owning
  its colours, read back by get_source, shown in the slab panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 53bec51. Configure here.

),
} as AnyNode
place(fence)
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Slab railings decouple from the slab

Medium Severity

Slab railing runs are now separate level-parented fences linked only by supportSlabId. Deleting, duplicating, or translating the slab no longer takes those railings with it, so a balcony can vanish while its rails drop to the floor or stay behind in plan.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 53bec51. Configure here.

move: () => import('./move-tool'),
},

renderer: {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Script height skipped for slab hosts

Medium Severity

A slab surfaceScript raises the walking surface in floorFinishTopAt, but surfaces.top still returns the structural elevation and fence supportSlabId lift does too. Railings and anything hosted through that surface sit inside the decking instead of on it.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 53bec51. Configure here.

@wass08
wass08 merged commit 7e2abdf into main Oct 28, 2026
5 checks passed
wass08 added a commit that referenced this pull request Oct 28, 2026
…ocess (#1191)

A texture stamped before NEXT_PUBLIC_SUPABASE_URL is read (the native texture
tests from #1190, run first on Linux) pinned a null origin, so later storage
URLs resolved to no reference.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant