Tests, packages, and the debugger
Authored tests
[Test] public bool is the fast synchronous author-test mode.
[Test] public async Task<bool> runs in a disposable gameplay fixture with real components, lifecycle, shared frame stepping, seeded random, and explicit test services. Fixtures can spawn prepared prefabs, remove owners, switch scenes, and advance bounded frames. Physics is explicit injection. Exported-player tests also exercise real Rapier, rendering, and both shipped composition paths.
Write tests next to the component in Script Studio. The Tests panel runs them in the editor.
The fireball and locked chest pages are complete sources for definition capture, SpawnConfigured, cancellation, and a saved GameState transaction. They are the same APIs your project scripts use.
Packages
Asset-bearing gameplay packages reuse the normal .opal format. They close over source, component, and asset dependencies, validate before import, and remap fresh asset ids.
Source-only libraries use .opal-script for code without assets.
Frame budgets
The host meters 250,000 world operations, 20,000 native work units, and 65,536 allocation work units per active frame, plus per-call and task bounds. A script cannot raise these limits. Shared exhaustion stops subsequent script work for the frame; cleanup keeps its allowance.
Allocation units count tracked collections, data, and query entries — not JavaScript heap bytes or total retained memory. Native subsystems also keep their own limits. Seeded Script and Flow random share an injected world stream; that alone does not make physics replay portable.
Loops and nested component calls share a 10,000-operation limit per callback. See language.
Debugger
The debugger inspects live instances, field changes, task outcomes, and bounded Script / Flow / native causal traces. Source links return to the operation that produced a change. Reload reports explain which values were preserved or reset.
The Tasks panel shows waits, parent/task identity, owned resources, applied source revision, and recent terminal reasons. See Tasks.
Reviewing changes made in Play
Play tuning edits exposed [Property] fields, previews them against authoring values, and lets you select fields to keep. Apply selected and Stop ends Play and applies the reviewed values as one undoable authoring command. It rejects stale sources, schemas, entities, and changed preview values. Private fields, runtime transforms, and unselected Properties are not copied back.
Input / frame recording
Recording runs a fresh isolated Play session. Replay reports the first state divergence and does not write saved gameplay data.
Pointer gestures, media, network traffic, prefab spawning, scene changes, and asynchronous definition loads currently lack an outcome journal and are explicitly refused. Replay is not a portable physics or general network debugging guarantee.