Where a script lives
The same script behaves differently depending on what you attach it to. Choosing the level is usually more important than the code.
| Attached to | Runs while | Dies when |
|---|---|---|
| An object | that object is on screen | it is hidden, disabled or deleted |
| A scene | that scene is active | the scene is left |
| A space | the visitor is in that space | they move to another space |
| The project | always, in every space | they leave |
On an object
The default, and the right choice for behaviour that belongs to a thing: a door that opens, an enemy that chases, a button that reacts.
Its ctx.entity is that object, and it stops the moment the object does — which is a feature.
You never clean up a script for an object that no longer exists.
On a scene
Added in the scene's Scripts section. Use it for logic about the scene as a whole: sequencing an intro, counting how many collectables are left, deciding when the visitor may move on.
It starts when the scene becomes active and stops when it does — so in an AR project, it starts on detection.
On a space
Added in the space's Scripts section. This one survives scene changes, which is the whole point: a score that carries across three scenes, a timer for the whole visit, a controller deciding which scene comes next.
An entity with behaviour and no parent belongs to no scene. It keeps running as scenes come and go, and every addressed event eventually reaches it — the route is object, then scene, then space.
On the project
Added in project settings. Injected into every space, so it is there no matter where the visitor goes.
Reach for it when something must outlive a space transition: the visitor's choices, an overall progress counter, analytics.
What survives what
| Stored in | A scene change | A space change | A reload |
|---|---|---|---|
a variable in init | if the script lives | if the script lives | no |
ctx.store | yes | no | no |
| a global | yes | yes | no |
a @space: global | yes | no — deliberately isolated | no |
Not store, not globals, not anything. If a value has to be there next time, send it somewhere
of your own while the visitor is still on the page.
Choosing, in one question
What is the smallest thing this logic is about?
- about one object → put it on the object;
- about this scene → put it on the scene;
- about the whole visit → put it on the space, or the project if there are several spaces.
Putting everything at project level "to be safe" works and then stops working: a project script cannot assume any particular scene is loaded, so it ends up full of existence checks that an object-level script would never need.
Patches follow the same rule
A patch can be attached at any of these levels too, with identical lifetimes. A project-level patch is the usual way to build a global controller without writing code.
Next: The ctx API