Reference: ECS Model and Contracts
Last verified 2026-09-03 against engine v1.0.232.
This is the behavioral-tier reference for the ECS unit: the surfaces it exposes, the invariants that hold, the checks and tests that prove them, and the version-pinned numbers, each bound to a source symbol. It is a companion to the model in the ECS explanation. The canonical per-component inventory, every field, pack, consumer, and replication policy, is the generated Component Type Definitions reference; this page links down to it and does not restate its tables.
Canonical source
The Tier-1 source of truth is code. The built-in registry is COMPONENT_TYPE_DEFINITIONS and the value union is ComponentSchema, both in packages/ecs/src/index.ts. The generated reference is produced from them by scripts/gen-component-docs.ts (run through npm run gen-docs) and verified by gen-docs:check, which fails the build if the committed projection drifts from the code. The generator writes two byte-identical files, docs/spec/generated/component-types.md and its companion docs/spec/COMPONENT_TYPE_DEFINITIONS.md.
Surfaces
Each surface is a code symbol, cited by name and file. This is the ECS API that the rest of the engine, the generators, and the gates read.
- Registry and value schema.
COMPONENT_TYPE_DEFINITIONS,ComponentSchema, and the by-type lookupCOMPONENT_SCHEMAS_BY_TYPE(packages/ecs/src/index.ts). - Internal set.
INTERNAL_ENGINE_COMPONENT_TYPESand the public authorable narrowingPublicAuthorableBuiltInComponentType(packages/ecs/src/index.ts). - Field contracts.
currentComponentFieldContracts,componentFieldContractsForType,componentJsonSchemaForType, and the pinning constantsCOMPONENT_FIELD_CONTRACT_VERSIONandCOMPONENT_FIELD_CONTRACT_HASH(packages/ecs/src/index.ts). - Authoring.
ComponentAddMode,componentFieldAuthoringContractsForType,applyComponentAuthoringIntent, andconditionAndValidateAuthoredComponent(packages/ecs/src/index.ts). - Custom components.
CustomComponentContract,compileComponentValueSchema,validateAuthoredComponentDefinition, andcanonicalizeAuthoredComponentDefinition(packages/ecs/src/index.ts). - Replication and relevance.
ComponentReplicationDeclaration,projectComponentReplicationValueForType,componentReplicationDeclarations, andcomponentSceneRelevanceDeclarations(packages/ecs/src/index.ts). - Ordering, dependencies, removed contracts.
COMPONENT_DISPLAY_RANK,COMPONENT_DEPENDENCIES,REMOVED_COMPONENT_CONTRACTS, and the catalog hashCOMPONENT_CATALOG_CONTRACT_HASH(packages/ecs/src/index.ts). - Data vocabulary.
VOCABULARY_PRIMITIVE_NAMES(packages/ecs/src/primitives.ts). - Field semantics.
COMPONENT_FIELD_SEMANTICS(packages/ecs/src/fieldSemantics.ts), merged byapplyFieldSemantics(packages/ecs/src/index.ts). - Artifact vocabulary.
Artifact,ArtifactKind,ConsumerSubsystem, andMaterializedComponentArtifact(packages/component-artifacts/src/index.ts). - Module contract.
ComponentKind,DeclaredConsumer, andMaterializeCtx(packages/component-intents/src/index.ts). - Modules and registry.
COMPONENT_MODULES,portedComponentTypes,unportedComponentTypes(packages/component-modules/src/registry.ts), the conformance runnerrunModuleConformance(packages/component-modules/src/conformance.ts), and the inline binderinlineFieldModule(packages/component-modules/src/inlineModule.ts). - Field-consumer manifest.
FIELD_CONSUMER_MANIFEST(packages/ecs/src/generated/fieldConsumerManifest.ts). - World-transform composition.
RuntimeHierarchyTransformSystem(server/src/modules/runtime/runtimeSystems.ts).
Invariants
Every invariant is bound to the check or test that proves it. These are the gates that fail the build when the property breaks.
- Materialize-mandatory (no Potemkin). Each registered module proves that a declared effectful field changes only its own coordinate and changes the emitted artifacts, and that each effectful verb changes the artifacts; a vacuous module fails. Proved by
runModuleConformance(packages/component-modules/src/conformance.ts) driven over every module incomponentModuleConformance.test.ts, which includes a Potemkin negative control. - Materialization determinism.
materialize()is twin-run byte-equal. Proved by the twin-run assertion inrunModuleConformanceand byproductionMaterializationSpine.test.ts. - Registry coherence. The registered module set equals the ECS component surface exactly, with nothing unported; inline modules accept the ECS default and resource-backed modules bind through an ECS resource reference. Proved by
registryCoherence.test.ts. - Field-consumer closure. Every top-level authored field maps to a manifest entry naming a resolvable reader, or to a non-expired, time-boxed exemption; dead keys, dangling evidence, expired exemptions, and stale baseline entries all fail. Proved by
check:component-field-consumer-closure(scripts/check-component-field-consumer-closure.ts). - Contract completeness. Every definition declares a positive-integer
contractVersionand a validaddMode, and internal visibility and internal-runtime-only admission imply each other. Proved bycheck:component-contract-completeness(scripts/check-component-contract-completeness.ts). - Contract-surface closure. Field-contract rows are unique per type and path, every schema property has a contract, frontend-exposed fields exist in the canonical schema, fully hidden fields carry a non-exposure reason, and
CameraComponent.firstPersonis forbidden. Proved bycheck:ecs-contract-surface-closure(scripts/check-ecs-contract-surface-closure.ts). - Source-not-dist authority. Contract gates read through the source adapter
scripts/component-contract-source.ts, and a source-versus-dist fingerprint parity keeps a stale build from greening a source regression. Proved bycheck:component-materialization. - Data-vocabulary singularity. Authored payloads use only the sanctioned primitive constructors; a second encoding of a concept fails at the syntax level. Proved by
check:data-vocabularyoverVOCABULARY_PRIMITIVE_NAMES. - Display-order source of truth.
COMPONENT_DISPLAY_RANKis complete by construction and is presentation metadata only, excluded from the catalog contract manifest and hash. Proved bycomponentDisplayRank.test.ts.
Numbers
No count on this page is typed; the generated projection owns those and the count tag reads them live.
- Catalog counts and hashes. The generated projection's header prints the built-in component count, the canonical field count, the count of fields that carry no authored Description, a component catalog contract hash, a field contract version, and a field contract hash. They are recomputed and byte-checked by
gen-docs:check; the field contract hash is additionally checked bycheck:ecs-contract-surface-closure. Read them in the generated reference. Live counts: components built-in components across fields canonical fields. - Field-consumer baseline. The unmapped-field baseline is a single, shrink-only exemption,
ParticleEmitterComponent:schemaVersion. Receipt:check:component-field-consumer-closure(scripts/check-component-field-consumer-closure.ts). - Representation-only exemption.
NetworkProfileComponentcarries an inert ownership field admitted through one time-boxed exemption inFIELD_CONSUMER_MANIFEST(packages/ecs/src/generated/fieldConsumerManifest.ts), separate from the unmapped baseline. Receipt:check:component-field-consumer-closure.
Proof surfaces
The ECS invariants stand on these checks and tests. Each runs in the check chain or the package test suite.
runModuleConformance(packages/component-modules/src/conformance.ts) andcomponentModuleConformance.test.ts, with its Potemkin negative control.registryCoherence.test.tsandproductionMaterializationSpine.test.ts.check:component-field-consumer-closure,check:component-contract-completeness,check:ecs-contract-surface-closure,check:component-materialization, andcheck:data-vocabulary.componentDisplayRank.test.ts.gen-docs:check, which byte-verifies the generated projection against the registry.
Limits and non-features
- Two structural module kinds only; no hybrid dual-source module (
ComponentKind,packages/component-intents/src/index.ts). ForceComponentandVelocityComponentare internal and palette-hidden (INTERNAL_ENGINE_COMPONENT_TYPES); Force is not creation-map authorable, velocity is.- Custom project components are validated project-local data, never engine atomics, and are not exposed to the in-product AI (
scripts/check-ecs-contract-surface-closure.ts). CameraComponent.firstPersonis forbidden; there are no first-class camera modes.- Gameplay patterns (health, damage, spawn pools) are script patterns under ADR 0020, not ECS atomics; the generated reference lists the stripped pattern names.
HierarchyComponentandStateMachineComponentpersist only as removed-contract migration metadata (REMOVED_COMPONENT_CONTRACTS).- World-space pose is emitted only for hierarchical entities; a non-hierarchical entity keeps its local pose as its world pose (
RuntimeHierarchyTransformSystem,server/src/modules/runtime/runtimeSystems.ts).
See also
- Explanation: Entity Component System for the model and its reasoning.
- Reference: ECS Components for a reader's guide to the generated catalog.
- Component Type Definitions reference for the canonical inventory.