@domecs/scene
v2.0.0
Published
DOMECS scene: parent-child entity hierarchy, ancestor/descendant queries, tree despawn, and transform composition (M4).
Downloads
239
Readme
@domecs/scene
Parent-child entity hierarchy for DOMECS (M4): a Parent component plus
tree-shaped queries, a despawn-orphan policy plugin, and parent-before-child
transform composition.
Install
npm install @domecs/sceneQuick start
import { createWorld, defineComponent, entry } from '@domecs/core'
import {
Parent,
setParent,
childrenOf,
ancestorsOf,
rootsOf,
despawnTree,
installHierarchy,
composeTransforms,
} from '@domecs/scene'
// A group needs a persistent component of its own: snapshot pruning
// (persist's pruneTransientOnlyEntities) drops bare entities, which would
// orphan their children on save, load and every history undo.
const Group = defineComponent<{ name: string }>('Group')
const world = createWorld()
world.use(installHierarchy()) // reparent-to-root on plain despawn()
const root = world.spawn([entry(Group, { name: 'squad' })])
const child = world.spawn()
setParent(world, child, root) // { ok: true }
childrenOf(world, root) // [child]
ancestorsOf(world, child) // [root]
rootsOf(world) // every entity with no Parent, or Parent.entity === null
despawnTree(world, root) // despawns root AND childMain API
Parent—defineComponent<{ entity: Entity | null }>('Parent', ...). Ordinary (non-transient) component data: it round-trips throughworld.snapshot()/world.restore()for free.setParent(world, child, parent)— never throws; rejects ({ ok: false, reason }, no component touched) a parent that is not alive, self-parenting and cycles (parenting an ancestor under its own descendant). A parent with no persistent component is dropped by snapshot pruning — give groups one (see Quick start).childrenOf(world, entity)— direct children in ascending id order, recomputed every call (no cache:WorldSignalshas no per-component "changed" event).ancestorsOf(world, entity)—[parent, grandparent, ..., root], not includingentityitself; terminates even over a corrupted/cyclicParentgraph.rootsOf(world)— every entity with noParent, orParent.entity === null.despawnTree(world, entity)— despawnsentityand every descendant (descendants before ancestors). Linear in the number ofParentholders, and terminates on a corrupted/cyclicParentgraph.installHierarchy()—Plugin; on a plainworld.despawn(), reparents any live children of the despawned entity tonull(root). Does not fire fordespawnTree's own cascade (descendants are already gone by the time an ancestor's despawn signal reaches this handler).composeTransforms(Local, WorldT, compose, options?)—Plugin; installs a'tick'system derivingWorldTfromLocaldown theParenthierarchy, always composing a parent before its children regardless of query/spawn order, at any chain depth.WorldTis marked changed only when a value moved (a field holding an object always counts as moved); an entity that losesLocallosesWorldT; disposing the plugin removes its systems.options.priorityplaces the system (default 0 — run what movesLocalbefore it and what readsWorldTafter it);options.nameoverrides the defaultdomecs-scene:compose-transforms:<Local>><WorldT>, so one instance per component pair can be installed.compose(parentWorld, local)receivesparentWorld = nullat hierarchy roots and whenever the directParenttarget does not itself carryLocal.
Related packages
@domecs/core— providesWorld,defineComponent,definePlugin,world.snapshot()/world.restore().
License
MIT
