Skip to main content

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 toRuns whileDies when
An objectthat object is on screenit is hidden, disabled or deleted
A scenethat scene is activethe scene is left
A spacethe visitor is in that spacethey move to another space
The projectalways, in every spacethey 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.

This is what "space-level" means technically

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 inA scene changeA space changeA reload
a variable in initif the script livesif the script livesno
ctx.storeyesnono
a globalyesyesno
a @space: globalyesno — deliberately isolatedno
Nothing survives closing the tab

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