Core

schema

Schema authoring, binding, and pre-bind feature composition.

This module is the bridge between raw descriptor declarations and the final bound Game API that systems, schedules, queries, commands, and runtimes actually use. It answers the question "what world is allowed to exist in this game?" before any runtime value is built.

The normal authoring flow is:

  1. declare descriptors with Descriptor.*
  2. group them into reusable Schema.fragment(...) values
  3. bind one Game with Schema.bind(...)
  4. build a runtime or composed project from that bound Game

Schema.Feature lives on the same pre-bind layer. Features contribute schema fragments and build schedules only after the final merged schema is known.

Reach for this module when a project grows beyond one file and needs schema composition that stays explicit, local, and type-safe instead of relying on mutable global registries.

Examples

// Declare the descriptor identities that define the allowed world contents.
const Position = Descriptor.Component<{ x: number; y: number }>()("Position")
const Velocity = Descriptor.Component<{ x: number; y: number }>()("Velocity")
const Score = Descriptor.Resource<number>()("Score")

// Package one gameplay slice as a reusable schema fragment.
const Core = Schema.fragment({
  components: { Position, Velocity },
  resources: { Score }
})

// Create one root brand so handles and bound APIs all agree on one world.
const Root = Schema.defineRoot("Game")

// Bind the final public ECS authoring surface for the project.
const Game = Schema.bind(Core, Root)

Variables

Functions

Public helpers for defining roots, creating fragments, binding Game, and composing features.

defineRoot

Source

Creates one explicit root token for schema-bound long-lived references.

Root tokens exist before schema construction so durable entity handles can be stored in descriptor payload types without widening to Schema.Any.

Use one root token for the whole application. Anything created from Schema.bind(Core, Root) will carry the same hidden root brand.

const Root = Schema.defineRoot("Game")

const Target = Descriptor.Component<{
  handle: Entity.Handle<typeof Root>
}>()("Target")

empty

Source

Creates an empty schema.

This is mostly useful as an implementation detail when folding fragments together into a final closed schema.

fragment

Source

Creates a schema fragment.

Fragments are the main composition unit for game modules. Use them to keep each gameplay slice local, exportable, and mergeable without introducing hidden registry mutation.

A fragment says "this subsystem contributes these components/resources/ events/states/relations", and nothing more. Binding and runtime assembly happen later once the final application shape is known.

// Keep combat schema local to the combat module.
const Combat = Schema.fragment({
  components: { Health, Damage },
  events: { Hit }
})

// Other modules can export their own fragments independently.
const Movement = Schema.fragment({
  components: { Position, Velocity }
})

merge

Source

Merges two schema fragments into a larger closed schema.

Duplicate keys are rejected both at the type level and at runtime so schema composition stays predictable.

bind

Source

Composes one or more fragments and returns one bound Game surface.

This is the canonical public schema entrypoint. Fragment composition and schema binding happen together so the common path does not need a separate intermediate built-schema value.

Use Game.schema when lower-level code still needs the final closed schema.

// Compose several independent gameplay fragments into one final API surface.
const Root = Schema.defineRoot("Game")
const Game = Schema.bind(Core, Combat, Root)

defineFeature

Source

Defines one pre-bind feature.

Features are pure typed values. They contribute a schema fragment, declare structural dependencies on other features, and build schedules only after the final merged schema has been bound.

Feature builders can only access descriptors from:

  • the feature's own fragment
  • the fragments of features listed in requires
const Combat = Schema.Feature.define("Combat", {
  schema: CombatSchema,
  requires: [Core],
  build: (Game) => ({
    update: [combatUpdate]
  })
})

composeFeatures

Source

No description provided yet.

Variables

Stable schema-level runtime markers used to brand bound roots and feature outputs.

Feature

Source

No description provided yet.