-
world[x][z] is intent and cellMeshes['x,z'] is render state.
-
New asset edits must flow through setCell(x, z, opts) or helpers that call it.
-
Selection state is exposed through window.__tinyworldSelection; use worldCoords(), materialize(), and replaceWorldCoords(). Do not parse raw selectedCells keys in new code.
-
Select-tool dragging of an already-selected cell/object should be preview-first: clone the current rendered object/extras into a separate hologram group, update only that virtual offset during pointermove, and commit the real cut/paste once on pointerup. Do not call shiftSelectedCellIntent() repeatedly from pointermove, because intermediate cut/paste steps can wipe cells along the drag path.
-
The dedicated Build Brush dock is intentionally top-centered under the world selector/top chrome, not near the bottom toolbar, so users can find it before painting.
-
Brush shape modes should keep the same safety contract: Single may use the existing live freehand draw path, but Line/Rectangle/Fill/Scatter must render a holographic footprint first and commit through applyToolToCell() only on pointer-up. Fill previews a bounded flood fill of matching connected cells; Scatter previews a deterministic organic subset inside the dragged rectangle. Keep the current brush mode in window.__tinyworldBrushModes so the mode indicator and UI stay in sync. Non-single brush modes should still feel like paint: selecting one from Select/Island/non-drawable tools (and pressing the canvas while one is active) must switch to a safe drawable fallback, the brush pointer path must win over editable-island widgets and orbit fallback, the ground footprint should update during pointermove before the drag threshold, and release should apply the paint without requiring a second click.
-
Duplicate, paste, and latest-template placement should be preview-first: copy/normalize the payload into a pending placement state, show a holographic representation following hover (clone live meshes when available; otherwise use a lightweight clipboard footprint), and commit only on the next board click. Keep Escape as a cancel path and keep any immediate helper explicitly opt-in/fallback-only.
-
Radial color changes should be preview-first: swatches should arm a tinted hologram for the selected object/cells and commit through updateSelectedBoardObjects() only on the next board click; Escape cancels.
-
Radial Generate should be contextual: summarize the current selection/selected object into the generator prompt/status instead of opening a blank generic modal. Do not imply a scoped apply unless the generator actually supports one; phrase it as context for the preview.
-
Generate should be preview-first: after the model returns validated world JSON, stage it as a holographic diff overlay with Apply / Regenerate / Discard controls. Do not call applyState() until the user applies the preview; discard must dispose preview geometries/materials.
-
Selected-cell rotation should be preview-first too: radial/keyboard rotate arms a holographic rotated clone, commits the real sel.rotate() on the next board click, and cancels with Escape. Keep immediate rotation as an explicit fallback only.