ScriptBehaviourSystem
Loads user-authored Behaviour scripts via dynamic import(), instantiates their classes, and drives the full Behaviour lifecycle (init, onUpdate, onDestroy) each frame.
Overview
ScriptBehaviourSystem runs every frame and is responsible for:
- Discovering entities with a
ScriptComponentand iterating theirentriesarray. - Dynamically importing each script's compiled URL the first time it is seen (or when the URL changes).
- Resolving the exported
Behavioursubclass by name (or falling back to the default export). - Instantiating the class and calling
init()once. - Calling
onUpdate(deltaTime)on every active script instance each frame. - Detecting stale instances (removed entries, changed URLs, destroyed entities) and calling
onDestroy()before discarding them.
Queried components
| Component | Access |
|---|---|
ScriptComponent | Read (entries, defaultData, runtimeData) |
Behaviour resolution
The system resolves the Behaviour constructor from the imported module using:
- Named export matching
ScriptEntry.className. defaultexport as a fallback.- A
__reluBehaviourClassstatic marker check to handle cases where esbuild bundles a second copy of@relu-interactives/spatial-ecsinto the script blob (breaking theinstanceofidentity check).
If no valid Behaviour subclass is found the entry is skipped and an error is written to the console.
Behavior notes
- Instance keying — each script instance is keyed by
entityId + scriptUrl + className. A new instance is created only when any of these three values changes. - Error isolation — errors thrown inside
init()oronUpdate()are caught per-instance and logged to the console. A failing script does not crash the frame loop or affect other scripts. - Destroyed entity cleanup — when an entity is removed from the world, all of its script instances are destroyed and removed from the registry on the next update.
- Editor vs preview — Behaviours execute only at preview/runtime. In an editor world (
isEditorMode()), everyScriptComponententry stays inidlestate andinit()/onUpdate()never run. For visuals that must render in the editor, useScriptObjectSystem+ScriptObject.
API reference
- Class:
ScriptComponent - Base class:
Behaviour - Source:
core/systems/ScriptBehaviourSystem.ts

