The editor is a component, not an application. Drop it on a page, give it a library and an ensemble, and it edits — the doc site's /editor/ is one such page and has no privileged access to anything.

<tosi-ensemble-editor
  library-url="https://cdn.tosijs.net/enemies.glb"
  library="enemies"
  src="/ensembles/ocean-rig.json"
  backdrop="aquatic"
></tosi-ensemble-editor>
import { ensembleEditor, registerSceneFeatures } from 'tosijs-3d-ensemble'

registerSceneFeatures()
document.body.append(
  ensembleEditor({
    library: 'enemies',
    libraryUrl: '/enemies.glb',
    backdrop: 'aquatic',
    handleSave: async (data) => localStorage.setItem('draft', JSON.stringify(data)),
  })
)

The chrome is tosijs-3d's SVG UI, not DOM widgets

One implementation renders as a DOM overlay and as an in-scene texture, so the same editor runs in a browser and in a headset. Editing a 3D arrangement is a spatial task performed at arm's length: judging whether a fortress reads, whether a turret covers the approach, whether a gap is flyable are exactly the questions a flat viewport answers badly.

The backdrop is not part of the ensemble

backdrop mounts a sample world — ground or sea, sky, and the ambient conditions — for the ensemble to be judged against. It is authoring context: it is never saved, and dragging the ensemble over it is the point. An ensemble that carries its OWN landform does so as a piece with a terrain feature, which is a different thing and does get saved.

Both planes are pinned to the origin. A bench looks at one thing from many angles, so the world holds still and the camera moves.

What is not here yet

No manipulator. tosijs-3d has no gizmo — b3d-panel's coloured axes are a debug READOUT that looks exactly like one — so pieces are currently placed by editing numbers. That is the editor's single most important interaction and it is an upstream build; see UPSTREAM.md.