Skip to content

World Context Examples

TL;DR: World scripts get the full API surface — LocalPlayer, FileStorage (with permission), WorldPermissions, WorldSettings, Networking — and their writes to scene objects pass the scope check as long as the target is inside the loaded world scene. Most “games” belong here because they need cross-player networking, persistent storage, and authoritative state.

  • Everything avatar and prop scripts can do.
  • Call LocalPlayer.* — teleport, velocity, rotation, immobilize, IgnoreCollision, Respawn, SetPositionAndRotation.
  • Use FileStorage.* for per-world save data (needs FileStorageApiAllowed).
  • Use WorldPermissions.Request(...) to ask the user for identity / HTTP / storage access.
  • Use WorldSettings.SetPropVisibility / SetPlayerVisibility to toggle visibility locally (shim exists; host binding pending).
  • Read / write transforms inside the world hierarchy (scope = Self because the world is your content root).
  • Destroy props via Prop.Destroy().
  • Spawn and manipulate portals via the portal API.
  • Mutate a remote avatar’s hierarchy (scope check fails; avatars are external content).
  • Force-write another player’s input — they’re the owner of their own input; you can only write local player’s input on their own client.
  • Access the raw filesystem or network outside the sandboxed FileStorage / Networking / HTTP-allowed-domains surface.
  • Change when your scripts run relative to Unity or CVR systems ([DefaultExecutionOrder] only orders within one VM).
  • Request permissions in Start, once, guarded by _permissionRequested. Re-check on OnWorldPermissionsChanged.
  • Make the instance owner authoritative for shared state (score, turn, game phase). Compare Networking.GetInstanceOwner() == LocalPlayer.PlayerObject.
  • Save on meaningful events, not every frame. FileStorage.WriteFile is a full-rewrite host call.
  • Pack network messages with BufferReaderWriter. A 1-byte tag + a handful of primitives beats JSON for size and determinism.
  • Use PostLateUpdate when sampling the player’s final pose — Avatar IK and Network IK land only by then.
  • Debounce HUD updates — throttle TMP text writes to 10 Hz or on state change, not every frame.
  • Don’t write state every frame to FileStorage. Wear the disk. Save on discrete events or on a debounced timer.
  • Don’t accept network messages blindly. Verify the sender matches expected authority (instance owner, specific player ID).
  • Don’t build unbounded per-frame work (searching player lists, instantiating temporary objects). The 20 ms epoch deadline will trap you eventually.
  • Don’t call Application.Quit / OnApplicationQuit or any disallowed event — stubbed.
  • Don’t rely on [RuntimeInitializeOnLoadMethod] — Unity’s attribute doesn’t run in WASM. Use Start.
  • Don’t assume Time.time is monotonic across scene reloads — it resets. Use DateTime.UtcNow (via the WASI clock stub) for cross-session timing.

Six game examples, each under world context:

  • Clicker — one-button incremental with upgrade thresholds.
  • Idle — time-based resource generation including offline progress.
  • Visual Novel — branching dialog tree with text reveal.
  • Turn-based — two-player grid game with owner-authoritative move validation.
  • RPG — single-player stats, inventory, quests, save/load.
  • Networked RPG — multi-player version with owner-authoritative world state.