Skip to main content

Entity catalog and swatches

The editor Add palette and swatch drag-and-drop need serializable descriptors on the game side while factories stay in game-lib. @zylem/game-lib/catalog registers entity types and swatch sources; GameBridge publishes descriptors and applies entity:apply-swatch commands against live entities.

Entity catalog​

Each placeable type is an EntityTypeRegistration:

  • Descriptor fields from EntityTypeDescriptor (id, label, optional icon SVG markup, tags, group, description, defaultProps)
  • create(context) — factory receiving snapped position, optional surface normal, and merged props

API:

FunctionRole
registerEntityType / registerEntityTypesAdd or replace types; returns unregister
registerBuiltInEntityTypesPrimitives (box, sphere, zone, light, …)
getEntityType, listEntityTypesIntrospection
buildCatalogDescriptorsSerializable list for catalog:snapshot
onEntityRegistryChangedRefresh palette when hosts register late
clearEntityRegistryTests

Built-in types only include shapes placeable without external assets (no actors/sprites in the default set). Hosts register configured entities after loading models or spritesheets.

import { registerEntityType, registerBuiltInEntityTypes } from '@zylem/game-lib/catalog';
import { createSphere } from '@zylem/game-lib/entity';

registerBuiltInEntityTypes();
registerEntityType({
id: 'hero',
label: 'Hero',
group: 'Characters',
defaultProps: { radius: 0.5 },
create: ({ position, props }) =>
createSphere({ name: 'hero', position, radius: (props.radius as number) ?? 0.5 }),
});

When the game starts, GameBridge.publishCatalog(buildCatalogDescriptors()) sends the palette to the editor.

Swatch registry​

Swatches cross the bridge as SwatchSpec:

  • kind: 'shader' or 'behavior'
  • source: export name (createLava, ThrusterBehavior, …)
  • props: factory options or behavior overrides

Register sources so entity:apply-swatch can resolve names:

FunctionRole
registerSwatchSource / registerSwatchSourcesRegister one or many
registerSwatchSourcesFromModuleWalk a module namespace for exports
registerBuiltInBehaviorSwatchSourcesgame-lib behavior descriptors
getSwatchSource, listSwatchSourcesLookup
onSwatchRegistryChangedNotify on changes
isBehaviorDescriptorType guard helper

Shader swatches call a SwatchShaderFactory; behavior swatches attach a BehaviorDescriptor (replacing same-key behaviors on the entity).

Bridge batching: one message can target many uuids × many swatches; the game applies in order, last shader wins per entity, behaviors replace matching keys. Results return on entity:swatch-applied with per-target success/failure reasons (entity-not-found, unknown-source, no-material, invalid-props).

Helper: applySwatchesToSelection from @zylem/game-lib/bridge for game-side tooling.

Pitfalls​

  • Icons are inline SVG — not icon font names; ship markup in the descriptor.
  • Override ids — registering the same id replaces a built-in type.
  • Unknown swatch source — apply fails for that target; register sources at boot before editor connects.

API reference​

See Bridge for catalog:snapshot, entity:apply-swatch, and entity:swatch-applied.