feat(island): data-driven island + standalone Spline-like designer#74
Merged
Conversation
added 15 commits
June 15, 2026 15:23
…opy slice, const→slice swap
…rse-move drag (no gizmo)
…inspector, undo/redo, preview - Tree/Flowers/Fruits: ensureFromLayout reconciles live scene after addObject/removeObject - Tree: _teardownPlacements() for clean rebuild; ensureFromLayout calls _placeAll() + re-applies visibility - Flowers: diff by layoutId, disposes gone entries, _buildOne for new entries - Fruits: diff by layoutId, builds new bushes, defers via _pendingEnsure if not yet placed - editableViews: spawn/remove now call ensureFromLayout instead of no-op stubs - EditController: subscribes to objectAdded/objectRemoved/layoutReplaced; _reconcileAfterStructural delegates to correct view kind - IslandEditorPanel: dev-only hash-gated React panel (Add palette, Inspector, Undo/Redo, Diverged badge, Preview toggle) - EngineHost: mounts IslandEditorPanel under import.meta.env.DEV - Tests: 5 spawn/remove reconcile tests (all pass)
…landLayout.json - IslandEditorPanel: Export (↓) downloads island-layout-<stamp>.json; Import (↑) loads JSON via FileReader → setLayout (live update, no reload) - islandLayout.js: defaultIslandLayout() now loads from committed defaultIslandLayout.json (merged through mergeIslandLayout), falls back to defaultIslandLayoutFromConstants() if empty/invalid - defaultIslandLayout.json: 31-object seed committed from defaultIslandLayoutFromConstants() — replacing it with an exported edit changes the boot island with no other code change - Tests: serialize/setLayout round-trip, layoutReplaced event, invalid-input rejection, JSON validity guard (8 pass, 1 seed-parity skipped) - U3 (decorOffsets index→uuid re-key) deferred: high-touch change to Sprouts state + View/Sprouts; escape hatch invoked per plan 004 spec — will be its own plan
…te editor UI - speciesPalette.js: data model with defaultSpeciesPaletteFromConstants() (oak/cherry tree colors, 6 flower + 6 fruit species as #rrggbb) - defaultSpeciesPalette.json: committed default (seed from constants, visual no-op) - schema.js: mergeSpeciesPalette() — lenient merge with hex color validation per slot - SpeciesPalette.js: working-copy-over-committed-base slice (get/setColor/list/isDiverged/revertToDefault/subscribe/hydrate/serialize); fires paletteChanged / paletteReplaced - Persistence: speciesPalette added to KEY/SLICES/empty - State.js + Game.js: construct/hydrate speciesPalette, null singleton on dispose - Fruits.js: subscribes to paletteChanged → live _berryMats[species].color.set(); applies persisted overrides at boot - Tree.js: subscribes to paletteChanged → live uniforms.uColorA/uColorB.value.set(); applies after _loadAndBuild - Flowers: reload fallback (palette read at _buildOne; live re-skin deferred as U4 escape hatch) - IslandEditorPanel: Palette section with per-species color inputs, Export/Import palette JSON, diverged badge + Revert palette - Tests: 12 SpeciesPalette tests (model, setColor, paletteChanged, isDiverged, revert, serialize/hydrate round-trip)
Standalone, isolated workspace package (own three/r3f/drei + separate pnpm root) that does not touch the product app or its pinned three@0.149. Editable terrain: closed 2D coastline spline (point-in-polygon + distance-to-coast), analytic height profile, additive sculpt relief; seeded from today's island silhouette. Draggable coastline handles, hover-reveal tool panel, sculpt brush (raise/lower/smooth/flatten) with a cached base-field for fast strokes. Pure terrain/brush math unit-tested (9 tests); typecheck + build green.
… polish (P3 integration + P4)
The dedicated standalone designer (island-editor/, r3f + drei) replaces the in-product authoring overlay. Remove the editor surface and its dev-only engine wiring while keeping the load-bearing data model (islandLayout + speciesPalette slices and default*.json) that now drives live world rendering. - delete IslandEditorPanel + its EngineHost mount/import - delete Game/View/edit/ (EditController, editableViews, CommandStack, Selection) - unwire editController from View.js construction + dispose loop - delete editor-only tests (selection / spawn / transform) pnpm check passes; the 11 remaining test failures are pre-existing on main and unrelated to this change.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Turns the island from a hard-coded Three.js scene into a data-driven world, adds a standalone Spline-like island designer, and removes the experimental in-product editor overlay in favor of that dedicated tool.
Data-driven island (live app — load-bearing)
IslandLayout+SpeciesPalettestate slices with stable uuid object ids and a working-copy layered over committed defaultsdefaultIslandLayout.json+defaultSpeciesPalette.json— every user boots from these;Tree/Flowers/Fruits/Mailbox/Telescoperender from the slicesStandalone island designer (
island-editor/)@react-three/drei+ three — isolated from the product appRemoved: in-app editor overlay
IslandEditorPanel(the#editorhash overlay) and its dev-only engine wiring (Game/View/edit/:EditController,editableViews,CommandStack,Selection)Testing
pnpm checkpasses (tsc clean; 15 pre-existing Biome warnings in kept tests)pnpm test: 11 failures remain, all pre-existing onmainand unrelated to this branch (history/trajectory sheets, edupass login, dev pipeline, vips loader). Island data-model tests (IslandLayout,SpeciesPalette, defaults, export) pass.🤖 Generated with Claude Code