# when — cooperative event scripts [Syntax and values](README.md) Event scripts are top-level `when` statements: ```text when started(): say "Ready" broadcast("go") when after(1): say "One second later" when messageReceived("go"): say "Go!" when keyPressed("space"): say "Jump!" when pointerPressed("primary"): say "Pressed at", pointerX(), pointerY() when pointerReleased("primary"): say "Released at", pointerX(), pointerY() when pointerClicked("primary"): say "Clicked at", pointerX(), pointerY() ``` The trigger after `when` must be exactly `started()`, `after(seconds)`, `messageReceived("message")`, `keyPressed("key")`, `pointerPressed("primary")`, `pointerReleased("primary")`, or `pointerClicked("primary")`. `after` requires one direct finite Number literal from 0 through 10 seconds and starts its script exactly once. A positive value below one millisecond is represented as one millisecond. Message and key descriptors require one non-empty text literal written directly in the header. Message matching is exact and case-sensitive. Key names use the same portable normalization as `keyDown`; a handler starts only when the key changes from released to pressed, and operating-system repeats are ignored until key-up. `pointerPressed`, `pointerReleased`, and `pointerClicked` accept only the exact direct literal `"primary"`. A press runs when an eligible primary down occurs inside the logical scene and the host claims that pointer. It carries the [immutable](../concepts/mutation.md) bounded whole-number down point. A real up from the same claimed pointer next runs a release handler, even outside the scene, using a signed 32-bit logical-plane point. If the up is inside, it also runs a separate click handler with the existing bounded release point. Additional or duplicate downs do not start another press or release. `pointerX()` and `pointerY()` report the immutable point owned by that pointer-event task. Event descriptors are valid only directly after a top-level `when`; they are not ordinary callable functions. Periodic timers, pointer move/drag, GPIO-edge, and sprite event descriptors are not implemented yet. Ordinary top-level statements initialize shared globals before event scripts run. Started scripts are queued first. All `after` scripts are then armed once from one shared post-setup monotonic anchor; a zero-delay timer stays behind started work, and equal deadlines retain source order. Ready scripts use deterministic [FIFO](../concepts/event-loop.md) order, one script at a time. Every invocation has fresh local variables but may read and update shared globals. Inside a script, `wait` parks only that script and `broadcast` queues matching message scripts in source order before yielding. A run without persistent descriptors finishes after no ready or sleeping script remains. A `keyPressed`, `pointerPressed`, `pointerReleased`, or `pointerClicked` script keeps a capable run in state `running` while idle; Stop, `exitApp`, failure, or host closure ends it. A runtime without a required keyboard/pointer event capability fails with `E4019`. See [Section 17](../../../pliro-syntax.en.md#17-execution-input-exit-and-safety-limits). ## Related entries [Syntax and values](README.md) · [Built-ins](../builtins/README.md) · [Programming guides](../guides/README.md)