---
title: "Script Effect Contracts"
description: "Sources: `packages/script-codegen/src/scriptEffectContracts.ts`, `packages/script-nodes/src/index.ts`."
engineVersion: v1.0.234
date: 2026-09-28
license: "(c) Gessa, proprietary. Cite with attribution to https://gessa.ai/docs/. Terms: https://gessa.ai/terms/."
canonical: https://gessa.ai/docs/spec/generated/script-effect-contracts/
---
<!-- GENERATED FILE: do not edit by hand. -->
<!-- Regenerate with `npm run gen-docs`. -->

Sources: `packages/script-codegen/src/scriptEffectContracts.ts`, `packages/script-nodes/src/index.ts`.

# Script Effect Contracts

This generated snapshot is derived from the canonical Script IR node catalog and the Script Effect Contract builder. It describes host effects, runtime pending-op receipt mappings, and the typed gameplay state scopes projected to AI, MCP, SDK, frontend, and Platform Catalog surfaces.

Contract version: `script-effect-contract.v1`.
Typed gameplay state version: `typed-gameplay-state.v1`.
Catalog hash: `sha256:cb70a0c39411cee3f013d8366510880a50cbd937a3ef2040ec68be11e2a10240`.
Host effect contracts: `112`.
Runtime pending-op mappings: `43`.
Effect tags: `pure`, `readWorld`, `writeWorld`, `readState`, `writeState`, `emitEvent`, `spawnEntity`, `despawnEntity`, `physicsCommand`, `uiEffect`, `audioEffect`, `platformRequest`, `networked`, `durable`, `nonRollbackable`, `requiresAuthority`.
Typed gameplay state scopes: `entity`, `script_instance`, `room`, `match`, `player`, `team`, `global`, `persisted_player`, `persisted_project`.

## Host Effects

| Host | Node | Effect | Effect tags | Authority | State scope | Persistence | Replication | Runtime receipts | Approval |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `Audio.play` | `host.audio.play` | runtime_command | `audioEffect`<br>`networked`<br>`nonRollbackable` | runtime_room | player | ephemeral | public_projection | `RuntimeAudioCueQueued`<br>`RuntimeAudioStopped`<br>`RuntimeAudioVolumeSet`<br>`RuntimeBackgroundMusicSet` | no |
| `Audio.playSpatial` | `host.audio.play_spatial` | runtime_command | `audioEffect`<br>`networked`<br>`nonRollbackable` | runtime_room | player | ephemeral | public_projection | `RuntimeAudioCueQueued`<br>`RuntimeAudioStopped`<br>`RuntimeAudioVolumeSet`<br>`RuntimeBackgroundMusicSet` | no |
| `Audio.setBackgroundMusic` | `host.audio.set_background_music` | runtime_command | `audioEffect`<br>`nonRollbackable` | runtime_room | player | ephemeral | public_projection | `RuntimeAudioCueQueued`<br>`RuntimeAudioStopped`<br>`RuntimeAudioVolumeSet`<br>`RuntimeBackgroundMusicSet` | no |
| `Audio.setVolume` | `host.audio.set_volume` | runtime_command | `audioEffect` | runtime_room | player | ephemeral | public_projection | `RuntimeAudioCueQueued`<br>`RuntimeAudioStopped`<br>`RuntimeAudioVolumeSet`<br>`RuntimeBackgroundMusicSet` | no |
| `Audio.stop` | `host.audio.stop` | runtime_command | `audioEffect` | runtime_room | player | ephemeral | public_projection | `RuntimeAudioCueQueued`<br>`RuntimeAudioStopped`<br>`RuntimeAudioVolumeSet`<br>`RuntimeBackgroundMusicSet` | no |
| `Camera.addLookInput` | `host.camera.add_look_input` | runtime_command | `platformRequest`<br>`nonRollbackable`<br>`requiresAuthority` | runtime_room | player | ephemeral | public_projection | `RuntimePlatformRequestQueued` | yes |
| `Camera.setLookSensitivity` | `host.camera.set_look_sensitivity` | runtime_command | `platformRequest`<br>`nonRollbackable`<br>`requiresAuthority` | runtime_room | player | ephemeral | public_projection | `RuntimePlatformRequestQueued` | yes |
| `Camera.setPitchClamp` | `host.camera.set_pitch_clamp` | runtime_command | `platformRequest`<br>`nonRollbackable`<br>`requiresAuthority` | runtime_room | player | ephemeral | public_projection | `RuntimePlatformRequestQueued` | yes |
| `Camera.setViewTarget` | `host.camera.set_view_target` | runtime_command | `platformRequest`<br>`nonRollbackable`<br>`requiresAuthority` | runtime_room | player | ephemeral | public_projection | `RuntimePlatformRequestQueued` | yes |
| `Commerce.owns` | `host.commerce.owns` | read | `readState` | runtime_room | player | backward_compatible | owner |  | no |
| `Commerce.promptPurchase` | `host.commerce.prompt_purchase` | runtime_command | `platformRequest`<br>`nonRollbackable`<br>`requiresAuthority` | runtime_room | player | ephemeral | owner | `RuntimeScriptCommercePromptRequested` | yes |
| `Debug.log` | `host.debug.log` | runtime_command | `emitEvent` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptLog` | no |
| `Entity.addComponent` | `host.entity.add_component` | state_write | `writeWorld`<br>`writeState`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.ancestors` | `host.entity.ancestors` | read | `readWorld`<br>`readState` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.children` | `host.entity.children` | read | `readWorld`<br>`readState` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.descendants` | `host.entity.descendants` | read | `readWorld`<br>`readState` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.detach` | `host.entity.detach` | state_write | `writeWorld`<br>`writeState`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.hasTag` | `host.entity.has_tag` | read | `readWorld`<br>`readState` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.parent` | `host.entity.parent` | read | `readWorld`<br>`readState` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.patchComponent` | `host.entity.patch_component` | state_write | `writeWorld`<br>`writeState`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.readComponent` | `host.entity.read_component` | read | `readWorld`<br>`readState` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.removeComponent` | `host.entity.remove_component` | state_write | `writeWorld`<br>`writeState`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.removeTag` | `host.entity.remove_tag` | state_write | `writeWorld`<br>`writeState`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.replaceComponent` | `host.entity.replace_component` | state_write | `writeWorld`<br>`writeState`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.setName` | `host.entity.set_name` | state_write | `writeWorld`<br>`writeState`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.setOwner` | `host.entity.set_owner` | state_write | `writeWorld`<br>`writeState`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.setParent` | `host.entity.set_parent` | state_write | `writeWorld`<br>`writeState`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.setTag` | `host.entity.set_tag` | state_write | `writeWorld`<br>`writeState`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.worldPosition` | `host.entity.world_position` | read | `readWorld`<br>`readState` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Entity.worldRotation` | `host.entity.world_rotation` | read | `readWorld`<br>`readState` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Events.emit` | `host.events.emit` | runtime_command | `emitEvent` | runtime_room | room | ephemeral | room | `RuntimeCustomEventEmitted` | no |
| `Fx.decal` | `host.fx.decal` | runtime_command | `networked`<br>`nonRollbackable` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Fx.particleBurst` | `host.fx.particle_burst` | runtime_command | `networked`<br>`nonRollbackable` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Inventory.grant` | `host.inventory.grant` | state_write | `writeState`<br>`emitEvent`<br>`durable`<br>`requiresAuthority` | runtime_room | persisted_player | durable | owner | `RuntimeScriptInventoryGrantRequested` | no |
| `Match.addScore` | `host.match.add_score` | runtime_command | `writeState`<br>`emitEvent`<br>`requiresAuthority` | runtime_room | match | session | room | `RuntimeScriptScoreAddRequested` | no |
| `Match.getScore` | `host.match.get_score` | read | `readState` | runtime_room | match | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Match.getState` | `host.match.get_state` | read | `readState` | runtime_room | match | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Match.patchObjective` | `host.match.patch_objective` | runtime_command | `writeState`<br>`emitEvent`<br>`requiresAuthority` | runtime_room | match | session | room | `RuntimeScriptObjectivePatchRequested` | no |
| `Match.setPhase` | `host.match.set_phase` | runtime_command | `writeState`<br>`emitEvent`<br>`requiresAuthority` | runtime_room | match | session | room | `RuntimeScriptMatchPhaseRequested`<br>`RuntimeScriptWinStateSet` | no |
| `Navigation.findPath` | `host.navigation.find_path` | read | `readWorld` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Navigation.isReachable` | `host.navigation.is_reachable` | read | `readWorld` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Navigation.nearestPoint` | `host.navigation.nearest_point` | read | `readWorld` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Navigation.raycast` | `host.navigation.raycast` | read | `readWorld` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Navigation.steerToward` | `host.navigation.steer_toward` | read | `readWorld` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Network.sendMessage` | `host.network.send_message` | runtime_command | `emitEvent`<br>`networked`<br>`nonRollbackable` | runtime_room | room | ephemeral | room | `RuntimeNetworkMessageSent` | no |
| `Physics.command` | `host.physics.command` | runtime_command | `writeWorld`<br>`physicsCommand`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimePhysicsForceQueued`<br>`RuntimePhysicsImpulseQueued`<br>`RuntimePhysicsVelocityQueued` | no |
| `Physics.occupancyQuery` | `host.physics.occupancy_query` | read | `readWorld` | runtime_room | entity | session | room | `RuntimePhysicsForceQueued`<br>`RuntimePhysicsImpulseQueued`<br>`RuntimePhysicsVelocityQueued` | no |
| `Physics.overlapTest` | `host.physics.overlap_test` | read | `readWorld` | runtime_room | entity | session | room | `RuntimePhysicsForceQueued`<br>`RuntimePhysicsImpulseQueued`<br>`RuntimePhysicsVelocityQueued` | no |
| `Physics.raycast` | `host.physics.raycast` | read | `readWorld` | runtime_room | entity | session | room | `RuntimePhysicsForceQueued`<br>`RuntimePhysicsImpulseQueued`<br>`RuntimePhysicsVelocityQueued` | no |
| `Physics.shapecast` | `host.physics.shapecast` | read | `readWorld` | runtime_room | entity | session | room | `RuntimePhysicsForceQueued`<br>`RuntimePhysicsImpulseQueued`<br>`RuntimePhysicsVelocityQueued` | no |
| `Platform.exitFullscreen` | `host.platform.exit_fullscreen` | runtime_command | `platformRequest`<br>`nonRollbackable`<br>`requiresAuthority` | runtime_room | player | ephemeral | public_projection | `RuntimePlatformRequestQueued` | yes |
| `Platform.exitPointerLock` | `host.platform.exit_pointer_lock` | runtime_command | `platformRequest`<br>`nonRollbackable`<br>`requiresAuthority` | runtime_room | player | ephemeral | public_projection | `RuntimePlatformRequestQueued` | yes |
| `Platform.requestFullscreen` | `host.platform.request_fullscreen` | runtime_command | `platformRequest`<br>`nonRollbackable`<br>`requiresAuthority` | runtime_room | player | ephemeral | public_projection | `RuntimePlatformRequestQueued` | yes |
| `Platform.requestPointerLock` | `host.platform.request_pointer_lock` | runtime_command | `platformRequest`<br>`nonRollbackable`<br>`requiresAuthority` | runtime_room | player | ephemeral | public_projection | `RuntimePlatformRequestQueued` | yes |
| `Player.eliminate` | `host.player.eliminate` | runtime_command | `writeWorld`<br>`requiresAuthority` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Player.possess` | `host.player.possess` | runtime_command | `writeWorld`<br>`requiresAuthority` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Player.release` | `host.player.release` | runtime_command | `writeWorld`<br>`requiresAuthority` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Player.spawnCharacter` | `host.player.spawn_character` | runtime_command | `writeWorld`<br>`spawnEntity`<br>`requiresAuthority` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Players.get` | `host.players.get` | read | `readWorld` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Players.list` | `host.players.list` | read | `readWorld` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Program.inputActions` | `host.program.input_actions` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Program.inputBundle` | `host.program.input_bundle` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Program.inputFlags` | `host.program.input_flags` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Program.param` | `host.program.param` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Program.paramCount` | `host.program.param_count` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Random.bool` | `host.random.bool` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Random.gaussian` | `host.random.gaussian` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Random.int` | `host.random.int` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Random.next` | `host.random.next` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Random.pick` | `host.random.pick` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Random.pointInCircle` | `host.random.point_in_circle` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Random.pointInSphere` | `host.random.point_in_sphere` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Random.range` | `host.random.range` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Random.seeded` | `host.random.seeded` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Random.shuffle` | `host.random.shuffle` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Random.sign` | `host.random.sign` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Random.unitVector` | `host.random.unit_vector` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Random.weightedPick` | `host.random.weighted_pick` | read | `pure` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Room.getPlayers` | `host.room.get_players` | read | `readWorld`<br>`readState` | runtime_room | room | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Room.getState` | `host.room.get_state` | read | `readWorld`<br>`readState` | runtime_room | room | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Team.getAssignment` | `host.team.get_assignment` | read | `readWorld`<br>`readState` | runtime_room | team | session | team | `RuntimeScriptPendingOpDrained` | no |
| `Terrain.heightAt` | `host.terrain.height_at` | read | `readWorld` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Terrain.normalAt` | `host.terrain.normal_at` | read | `readWorld` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Terrain.raycastDown` | `host.terrain.raycast_down` | read | `readWorld` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Terrain.sampleLayerWeights` | `host.terrain.sample_layer_weights` | read | `readWorld` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Terrain.slopeAt` | `host.terrain.slope_at` | read | `readWorld` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Tween.cancel` | `host.tween.cancel` | runtime_command | `writeWorld`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `Tween.start` | `host.tween.start` | runtime_command | `writeWorld`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `UI.closePanel` | `host.ui.close_panel` | runtime_command | `uiEffect`<br>`nonRollbackable` | runtime_room | player | ephemeral | owner | `RuntimeScriptUiProjectionPatched` | no |
| `UI.openPanel` | `host.ui.open_panel` | runtime_command | `uiEffect`<br>`nonRollbackable` | runtime_room | player | ephemeral | owner | `RuntimeScriptUiProjectionPatched` | no |
| `UI.setWidgetValue` | `host.ui.set_widget_value` | runtime_command | `uiEffect`<br>`nonRollbackable` | runtime_room | player | ephemeral | owner | `RuntimeScriptUiProjectionPatched` | no |
| `Warehouse.append` | `host.warehouse.append` | state_write | `writeState`<br>`durable`<br>`requiresAuthority` | warehouse | persisted_project | durable | server_only | `RuntimeWarehouseRecordUpdated` | no |
| `Warehouse.create` | `host.warehouse.create` | state_write | `writeState`<br>`durable`<br>`requiresAuthority` | warehouse | persisted_project | durable | server_only | `RuntimeWarehouseRecordCreated` | no |
| `Warehouse.delete` | `host.warehouse.delete` | state_write | `writeState`<br>`durable`<br>`requiresAuthority` | warehouse | persisted_project | durable | server_only | `RuntimeWarehouseRecordDeleted` | no |
| `Warehouse.get` | `host.warehouse.get` | read | `readState`<br>`durable` | warehouse | persisted_project | backward_compatible | server_only | `RuntimeWarehousePrefetchCompleted` | no |
| `Warehouse.increment` | `host.warehouse.increment` | state_write | `writeState`<br>`durable`<br>`requiresAuthority` | warehouse | persisted_project | durable | server_only | `RuntimeWarehouseRecordUpdated` | no |
| `Warehouse.query` | `host.warehouse.query` | read | `readState`<br>`durable` | warehouse | persisted_project | backward_compatible | server_only | `RuntimeWarehousePrefetchCompleted` | no |
| `Warehouse.set` | `host.warehouse.set` | state_write | `writeState`<br>`durable`<br>`requiresAuthority` | warehouse | persisted_project | durable | server_only | `RuntimeWarehouseRecordUpdated` | no |
| `Warehouse.transform` | `host.warehouse.transform` | state_write | `writeState`<br>`durable`<br>`requiresAuthority` | warehouse | persisted_project | durable | server_only | `RuntimeWarehouseRecordUpdated` | no |
| `Warehouse.update` | `host.warehouse.update` | state_write | `writeState`<br>`durable`<br>`requiresAuthority` | warehouse | persisted_project | durable | server_only | `RuntimeWarehouseRecordUpdated` | no |
| `Water.isSubmerged` | `host.water.is_submerged` | read | `readWorld` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `Water.surfaceLevelAt` | `host.water.surface_level_at` | read | `readWorld` | script_runtime | script_instance | ephemeral | server_only | `RuntimeScriptPendingOpDrained` | no |
| `World.despawn` | `host.world.despawn` | world_mutation | `writeWorld`<br>`despawnEntity`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `World.entityHasTag` | `host.world.entity_has_tag` | read | `readWorld`<br>`readState` | runtime_room | entity | session | room |  | no |
| `World.find` | `host.world.find` | read | `readWorld` | runtime_room | entity | session | room |  | no |
| `World.query` | `host.world.query` | read | `readWorld` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `World.setEntityOwner` | `host.world.set_entity_owner` | world_mutation | `writeWorld`<br>`writeState`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `World.setEntityTag` | `host.world.set_entity_tag` | world_mutation | `writeWorld`<br>`writeState`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `World.spawn` | `host.world.spawn` | world_mutation | `writeWorld`<br>`spawnEntity`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimePrefabInstantiated`<br>`RuntimeScriptPendingOpDrained` | no |
| `World.spawnMany` | `host.world.spawn_many` | world_mutation | `writeWorld`<br>`spawnEntity`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimeScriptPendingOpDrained` | no |
| `World.spawnPrefab` | `host.world.spawn_prefab` | world_mutation | `writeWorld`<br>`spawnEntity`<br>`requiresAuthority` | runtime_room | entity | session | room | `RuntimePrefabInstantiated`<br>`RuntimeScriptPendingOpDrained` | no |
| `World.teleportPlayer` | `host.world.teleport_player` | world_mutation | `writeWorld`<br>`networked`<br>`nonRollbackable`<br>`requiresAuthority` | runtime_room | player | session | room | `RuntimeTeleportRequested` | no |

## Runtime Pending Ops

| Pending op | Host refs | Receipt kind |
| --- | --- | --- |
| `audio_background_music` | `Audio.setBackgroundMusic` | `RuntimeScriptPendingOpDrained` |
| `audio_play` | `Audio.play`<br>`Audio.playSpatial` | `RuntimeScriptPendingOpDrained` |
| `audio_set_volume` | `Audio.setVolume` | `RuntimeScriptPendingOpDrained` |
| `audio_stop` | `Audio.stop` | `RuntimeScriptPendingOpDrained` |
| `camera_add_look_input` | `Camera.addLookInput` | `RuntimeScriptPendingOpDrained` |
| `camera_set_look_sensitivity` | `Camera.setLookSensitivity` | `RuntimeScriptPendingOpDrained` |
| `camera_set_pitch_clamp` | `Camera.setPitchClamp` | `RuntimeScriptPendingOpDrained` |
| `camera_set_view_target` | `Camera.setViewTarget` | `RuntimeScriptPendingOpDrained` |
| `commerce_prompt_purchase` | `Commerce.promptPurchase` | `RuntimeScriptCommercePromptRequested` |
| `component_patch` | `Entity.addComponent`<br>`Entity.patchComponent` | `RuntimeScriptPendingOpDrained` |
| `component_remove` | `Entity.removeComponent` | `RuntimeScriptPendingOpDrained` |
| `component_replace` | `Entity.replaceComponent` | `RuntimeScriptPendingOpDrained` |
| `custom_event_emit` | `Events.emit` | `RuntimeCustomEventEmitted` |
| `data_store_write` | `Warehouse.append`<br>`Warehouse.create`<br>`Warehouse.delete`<br>`Warehouse.increment`<br>`Warehouse.set`<br>`Warehouse.transform`<br>`Warehouse.update` | `RuntimeWarehouseRecordUpdated` |
| `entity_despawn_target` | `World.despawn` | `RuntimeScriptPendingOpDrained` |
| `entity_detach` | `Entity.detach` | `RuntimeScriptPendingOpDrained` |
| `entity_name_set` | `Entity.setName` | `RuntimeScriptPendingOpDrained` |
| `entity_reparent` | `Entity.setParent` | `RuntimeScriptPendingOpDrained` |
| `entity_spawn` | `World.spawn`<br>`World.spawnMany` | `RuntimeScriptPendingOpDrained` |
| `entity_tag_add` | `Entity.setTag`<br>`World.setEntityTag` | `RuntimeScriptPendingOpDrained` |
| `entity_tag_remove` | `Entity.removeTag` | `RuntimeScriptPendingOpDrained` |
| `fx_decal` | `Fx.decal` | `RuntimeScriptPendingOpDrained` |
| `fx_particle_burst` | `Fx.particleBurst` | `RuntimeScriptPendingOpDrained` |
| `inventory_grant` | `Inventory.grant` | `RuntimeScriptInventoryGrantRequested` |
| `latent_cancel` |  | `RuntimeScriptPendingOpDrained` |
| `latent_schedule` |  | `RuntimeScriptPendingOpDrained` |
| `log` | `Debug.log` | `RuntimeScriptLog` |
| `match_phase_transition` | `Match.setPhase` | `RuntimeScriptWinStateSet` |
| `network_message_send` | `Network.sendMessage` | `RuntimeNetworkMessageSent` |
| `objective_state_patch` | `Match.patchObjective` | `RuntimeScriptObjectivePatchRequested` |
| `physics_command` | `Physics.command` | `RuntimeScriptPendingOpDrained` |
| `platform_exit_fullscreen` | `Platform.exitFullscreen` | `RuntimeScriptPendingOpDrained` |
| `platform_exit_pointer_lock` | `Platform.exitPointerLock` | `RuntimeScriptPendingOpDrained` |
| `platform_request_fullscreen` | `Platform.requestFullscreen` | `RuntimeScriptPendingOpDrained` |
| `platform_request_pointer_lock` | `Platform.requestPointerLock` | `RuntimeScriptPendingOpDrained` |
| `prefab_instantiate` | `World.spawn`<br>`World.spawnMany`<br>`World.spawnPrefab` | `RuntimeScriptPendingOpDrained` |
| `score_add` | `Match.addScore` | `RuntimeScriptScoreAddRequested` |
| `teleport_player` | `World.teleportPlayer` | `RuntimeScriptPendingOpDrained` |
| `tween_cancel` | `Tween.cancel` | `RuntimeScriptPendingOpDrained` |
| `tween_start` | `Tween.start` | `RuntimeScriptPendingOpDrained` |
| `ui_close_panel` | `UI.closePanel` | `RuntimeScriptPendingOpDrained` |
| `ui_open_panel` | `UI.openPanel` | `RuntimeScriptPendingOpDrained` |
| `ui_set_widget_value` | `UI.setWidgetValue` | `RuntimeScriptPendingOpDrained` |

## Projection Rules

- Canonical Script IR is the only source for per-script effect contracts.
- Semantic Patch is the normal authoring path for creator/AI gameplay behavior.
- Generated TypeScript and visual graph layouts are projections, not contract authority.
- Runtime draining refuses pending ops that cannot be matched to a declared script effect contract.
