What a consumer imports

The ensemble format, its instantiator, and the editor that authors them — one package, so that the editor writes exactly what the runtime reads because it is the same code.

It is not a combat format. It describes an arrangement — a fortification, a botanical garden, or tosijs-3d's own standard scene (sun, sky, shadows, ground) — and a consumer loads it in one line:

import { registerSceneFeatures, loadEnsemble } from 'tosijs-3d-ensemble'

registerSceneFeatures()
await loadEnsemble('/ensembles/standard-scene.json', { scene })

Hit points, turrets and shields live in an opt-in preset, because most things in most scenes can never be shot:

import { registerCombatPreset } from 'tosijs-3d-ensemble/presets/combat'

An author imports the tool as well:

import { ensembleEditor } from 'tosijs-3d-ensemble'

The split is enforced by a test rather than by packaging (src/tree-shaking.test.ts), which is the only way it stays true: a stray import from the format layer into the editor is exactly how this rots, and nothing else would notice.