Skip to content

World Permissions

TL;DR: World scripts can request elevated capabilities (read the local player’s user ID, make HTTPS calls to a domain whitelist, increase the file-storage quota). The user sees a prompt and either approves, denies, or adjusts before the world continues. Decisions are stored per-world at %APPDATA%/ChilloutVR/WorldData/{worldId}/WasmPermissions.json.

Source: CVR-GameFiles/WasmScripting/WasmWorldPermissions.cs.

public class WasmWorldPermissions {
public string WorldId; // CVR world content ID
public bool AccessUserIdentity; // UserId only (Username is un-gated)
public bool FileStorageApiAllowed; // persistent KV store
public bool FileStorageReadRawFiles; // read user-provided files, no quota
public long FileStorageStorageLimit; // bytes (default 4 MB)
public bool HttpApiAllowed; // HTTPS outbound
public string[] HttpAllowedDomains; // host allow-list
}

Detail per flag (behaviour verified from CVR-GameFiles/WasmScripting/PlayerBindings.cs and FileStorageManager.cs):

  • AccessUserIdentity — Without it, CVR_Player_GetUserId returns Guid.Empty.ToString() (the decompiled shipped version also walks a per-session counter to stand in for usernames; the CCK source released GetUsername from the gate entirely in Preview.27-WASM.27). A world that depends on canonical user IDs (scoreboards, role gates, ban lists) still needs this flag.
  • FileStorageApiAllowed — Turns on the FileStorage_* binding family for this world. Without it, FileStorageManager.CheckAPIAccess throws WasmAccessDeniedException on every read/write/list call.
  • FileStorageReadRawFiles — Lets FileStorageManager.GetInfo fall through to user-placed raw files in LocalStorage/. These files are read-only from the script (writes still go through the encrypted path) and don’t count toward the quota.
  • FileStorageStorageLimit — Bytes. Default 4_194_304 (4 MB). User-adjustable via a 46-value palette running 1 KB → 16 GB in WasmPermissionsPage.
  • HttpApiAllowed — Enables outbound HTTPS once a future binding lands. The permission is persisted and surfaced through OnWorldPermissionsChanged today; no HTTP host binding is live yet.
  • HttpAllowedDomains — Each entry is required to start with https:// (WorldPermissionsMarshalStruct.ToPermissions throws otherwise). HTTPS only; no raw TCP, no cleartext HTTP.

Source: CVR-GameFiles/WasmScripting/WorldPermissionsManager.cs.

  1. At world loadCVRGameEventSystem.World.OnLoad fires, LoadPermissions(worldId) reads WasmPermissions.json (or falls back to the defaults), and OnPermissionsChanged(CurrentPermissions) is invoked. World-VM scripts with OnWorldPermissionsChanged receive the initial state through WasmVM.CallOnWorldPermissionsChanged.
  2. Guest requests — the script calls the host binding WorldPermissions_RequestPermissions(marshalStructPtr). The marshal struct is a flattened WasmWorldPermissions with pointer+length arrays for the domain list; see WorldPermissionsMarshalStruct.cs. The binding first calls CheckAccess(World, Any) — non-world scripts throw WasmAccessDeniedException.
  3. Compare — the manager only prompts _promptedThisSession == false && !CurrentPermissions.IsContentsSame(requested). A matching set short-circuits silently. _promptedThisSession is reset each world load, so one prompt per session per world is the upper bound.
  4. Prompt — otherwise WasmPermissionsPage.RequestPermissions opens a confirm dialog (“Review” / “Ignore”). On “Review” the user sees:
    • toggle for each flag,
    • the storage-limit slider (46 steps),
    • the domain list as read-only text (user can’t add domains; they either accept the list as-is or deny HttpApiAllowed),
    • “Open Storage Folder” shortcut,
    • “Apply” button (disabled until the pending set differs from the saved set).
  5. Save — on Apply, AcceptPermissions writes WasmPermissions.json in %LocalAppData%/ChilloutVR/WorldData/{worldId}/ and overwrites CurrentPermissions iff the saved permissions’ WorldId matches Instances.CurrentWorldId.
  6. BroadcastOnPermissionsChanged fires; the host calls the guest export CVR_WorldPermissions_OnWorldPermissionsChanged(marshalStructPtr) with the accepted permissions, and the guest-side dispatcher fans it out to every behaviour that defined OnWorldPermissionsChanged. Non-world VMs never receive this event.
%APPDATA%/ChilloutVR/WorldData/{worldId}/
├── WasmPermissions.json # permission decisions
└── {hash}.part.wasmdata # FileStorage data, XOR-encrypted

{worldId} is the published CVR world ID.

Source: CVR-GameFiles/ABI_RC.Systems.WasmScripting/WasmPermissionsPage.cs.

  • Toggle buttons per flag.
  • Storage quota slider with a 46-value palette from 1 KB to ~17 TB.
  • Domain list viewer — read-only; the world requested them, the user either accepts the list as-is or denies the HTTP permission entirely.
  • “Open Storage Folder” — reveals {WorldData}/{worldId}/ in the OS file browser.
  • “Apply” — commits to disk and fires the change event.

World permissions do not widen the three-axis ObjectContext/OwnerContext/ScopeContext check. For example, enabling FileStorageApiAllowed on an avatar has no effect — the binding is gated to ObjectContext.World. World permissions layer on top of that to gate world-scoped features that are otherwise dangerous (user identity, HTTP).

From a guest script:

// Pseudocode against the intended high-level wrapper exposed by CCKWasmModule:
var current = WorldPermissions.Current;
if (current.HttpApiAllowed && current.HttpAllowedDomains.Contains("api.example.com"))
{
// safe to do an HTTP call
}

Exact API name depends on the CCKWasmModule version. From the binding side the only request function is WorldPermissions_RequestPermissions; query happens via the OnWorldPermissionsChanged event (which fires once on startup with the current state).

  • CVR-GameFiles/WasmScripting/WasmWorldPermissions.cs — the six-flag shape stored per world.
  • CVR-GameFiles/WasmScripting/WorldPermissionsManager.cs — load/save + prompt-once-per-session gate.
  • CVR-GameFiles/WasmScripting/WorldPermissionsBindings.cs — host binding for WorldPermissions_RequestPermissions.
  • CVR-GameFiles/WasmScripting/WorldPermissionsMarshalStruct.cs — guest↔host serialization, enforces https:// prefix.
  • CVR-GameFiles/ABI_RC.Systems.WasmScripting/WasmPermissionsPage.cs — CVR UI wiring (Init, OpenPage, 46-step storage slider).
  • Permissions — the lower, always-on access control.
  • File Storage — the API this unlocks.
  • Networking — CVR’s in-instance networking is unaffected; HTTP is the flag for external calls.