Runtime Context
ctx is the Tissue Preview Runtime context passed into script lifecycle methods.
It is the entry point for scripts to access the current GameObject, project data, shared state, and supported runtime capabilities.
export default {
start(ctx) {
ctx.transform.setPosition(100, 200)
},
update(ctx, dt) {
// dt is seconds
}
}ctx is not Phaser
ctx is not a raw Phaser object and is not a Phaser Scene.
Do not guess APIs from Phaser, Cocos, Godot, or other engines. Only APIs listed in the Runtime Manifest are supported.
Unsupported examples:
ctx.now()
ctx.time
ctx.clock
ctx.scene.time
ctx.gameObject.list
ctx.parentContainer
ctx.physicsIf a capability is missing, use the supported Tissue API or report the missing capability.
Lifecycle
Recommended script shape:
export default {
awake(ctx) {},
start(ctx) {},
update(ctx, dt) {},
onPointerDown(ctx) {},
onDestroy(ctx) {}
}awake(ctx)
Called when the script instance is created. Use it for local fields.
awake(ctx) {
this.vy = 0
this.elapsed = 0
}start(ctx)
Called once when the script starts. Use it for input registration and shared state initialization.
start(ctx) {
ctx.state.score = 0
ctx.input.onKeyDown('SPACE', () => {
this.vy = -320
})
}update(ctx, dt)
Called every frame. dt is already in seconds.
update(ctx, dt) {
this.elapsed += dt
ctx.transform.setPosition(ctx.self.x, ctx.self.y + 100 * dt)
}onPointerDown(ctx)
Called when the current object is clicked.
onPointerDown(ctx) {
ctx.state.started = true
ctx.node.hide()
}Core rules
Use only APIs listed in the manifest
Wrong:
const t = ctx.now()Correct:
this.elapsed += dtdt is seconds
Wrong:
this.y += speed * (dt / 1000)Correct:
this.y += speed * dtUse ctx.state for shared state
// StartButton.js
onPointerDown(ctx) {
ctx.state.started = true
ctx.node.hide()
}// Bird.js
update(ctx, dt) {
if (!ctx.state.started) return
}Use this for local script state
awake(ctx) {
this.elapsed = 0
}
update(ctx, dt) {
this.elapsed += dt
}Common properties
ctx.self
Current editor GameObject data.
const startX = ctx.self.x
const width = ctx.self.widthctx.gameObject
Current Phaser GameObject.
Avoid relying on Phaser internals. Prefabs in Tissue are GameObject hierarchies, not Phaser Containers.
Do not use:
ctx.gameObject.list
ctx.gameObject.parentContainerctx.project
Current project data.
const width = ctx.project.width
const height = ctx.project.heightctx.state
Shared state for the current preview scene.
start(ctx) {
if (typeof ctx.state.score !== 'number') {
ctx.state.score = 0
}
}Alternatives to unsupported APIs
| Unsupported | Use instead |
|---|---|
ctx.now() | this.elapsed += dt |
ctx.time | Accumulate time in update(ctx, dt) |
ctx.scene.time | Future Tissue ctx.time wrapper if needed |
ctx.gameObject.list | instance.objects or instance.find(name) from ctx.instantiatePrefab() |
ctx.parentContainer | Tissue GameObject hierarchy or prefab instance handle |
ctx.physics | ctx.transform + ctx.collider until a Physics component exists |
AI rules
AI-generated scripts must:
- Treat
ctxas Tissue Runtime Context, not Phaser. - Never guess APIs.
- Use only APIs listed in the Runtime Manifest.
- Treat
dtas seconds. - Use
this.elapsed += dtfor timers. - Use
ctx.statefor shared state. - Use the prefab instance handle returned by
ctx.instantiatePrefab(). - Report missing capabilities instead of silently falling back.