API Conventions
TL;DR: CVR-provided APIs use explicit Get*() / Set*() methods (signalling the interop marshalling cost); UnityEngine and library APIs keep idiomatic property access. The surface is still shifting — expect periodic breaking changes during closed testing, and read this page when an API that used to be a property is now a method.
Author-facing surface as of CCK 4.0.0-Preview.27-WASM.27
Section titled “Author-facing surface as of CCK 4.0.0-Preview.27-WASM.27”Methods, not properties, on CVR types
Section titled “Methods, not properties, on CVR types”Anything that returns a wrapped host object or crosses the VM boundary is a method:
// Playerstring userId = player.GetUserId();string name = player.GetUsername();short netId = player.GetNetworkId();GameObject rootGO = player.GetGameObject();AvatarPoint view = player.GetViewPoint();AvatarPoint voice = player.GetVoicePoint();Avatar avatar = player.GetWornAvatar();Prop[] spawned = player.GetSpawnedProps();
// AvatarPlayer wearer = avatar.GetWearer();string aName = avatar.GetName();string aId = avatar.GetContentId();GameObject aRoot = avatar.GetRootObject();Transform aT = avatar.GetRootTransform();avatar.SetCollisionExcludeLayers(someLayerMask);LayerMask exclude = avatar.GetCollisionExcludeLayers();avatar.ResetCollisionExcludeLayers();
// PropPlayer spawner = prop.GetSpawner();string pName = prop.GetName();string pId = prop.GetContentId();GameObject pRoot = prop.GetRootObject();Transform pT = prop.GetRootTransform();prop.Destroy();
// WorldWorld world = World.GetCurrentWorld();string wName = world.Name; // one of the few remaining property accessorsstring wId = world.ContentId;Why methods? Each call marshals across the host-guest boundary. Using methods rather than properties signals that work is being done — and prevents the common pitfall of reading player.Username in a tight loop without realising it’s a host round-trip.
Legacy properties that remain
Section titled “Legacy properties that remain”Not every CVR type has been migrated yet. CVR.Portal still exposes a few properties:
Player pSpawner = portal.Spawner; // still a propertyGameObject pRoot = portal.RootObject; // still a propertyTransform pT = portal.RootTransform; // still a propertyVector3 pos = portal.GetPosition(); // methodportal.SetPosition(newPos); // methodbool anchored = portal.IsAnchored(); // methodCVR.World also still exposes Name and ContentId as properties. These may move to Get*() methods in a future preview.
UnityEngine / TMPro — unchanged
Section titled “UnityEngine / TMPro — unchanged”Properties are idiomatic Unity. These stay:
transform.position // propertytransform.localPosition // propertyrigidbody.velocity // propertydisplay.text // property on TextMeshProUGUISetters on scope-sensitive Unity properties are scope-gated by the binder (writes typically require CVRScriptScopeContext.Self). See Permissions → Rules of thumb.
Static types in WasmScripting
Section titled “Static types in WasmScripting”Helper subsystems are static classes in the WasmScripting namespace (source: CVR.CCK.Wasm/Scripting/Links/APIs/CCKStubs/):
WasmScripting.Networking—SendMessage(Span<byte>, short[], SendType, bool),SendMessage(BufferReaderWriter, ...),WillMessageBeDropped(int),NetworkCloggedPercentage(),GetInstanceOwner(),Ping(property),GetServerStartTime(),GetServerUptime(),OnReceiveMessagedelegate.WasmScripting.FileStorage—ReadFile,WriteFile,DeleteFile,RenameFile,FileExists,GetFiles,GetFileSize,GetTotalSize,GetTotalCapacity. NoCanUseFileStorage/RequestUseFileStoragehelpers — callWorldPermissions.Requestdirectly.WasmScripting.WorldPermissions—Request(WorldPermissions),CurrentPermissionsstatic property.WasmScripting.WasmUtils—GetObjectContext()(returns the VM’sCVRScriptObjectContext, resolved guest-side),GetScopeContext(UnityEngine.Object)andGetOwnerContext()(both cross to the host).
Proposed — Api suffix (future)
Section titled “Proposed — Api suffix (future)”CVR.Avatar collides semantically with UnityEngine.Avatar (animation rig type). The team has discussed renaming the CVR-side types to carry an Api suffix:
CVR.Player -> CVR.PlayerApiCVR.Avatar -> CVR.AvatarApiCVR.Prop -> CVR.PropApiCVR.Portal -> CVR.PortalApiCVR.World -> CVR.WorldApiCVR.Clone -> CVR.CloneApi (not yet shipped)Not implemented yet. Write scripts against the current names; if the refactor lands, expect a rename-only breaking change.
Known removed surface
Section titled “Known removed surface”Usernameis no longer gated byAccessUserIdentity. OnlyGetUserId()requires that world permission.GetUsername()works without it. (Changelog: Preview.27-WASM.27.)
How to tell if a surface has moved
Section titled “How to tell if a surface has moved”If a call that used to compile now fails with error CS1061: 'Player' does not contain a definition for 'Username':
- Check this page for the migrated name (
GetUsername()). - Check the CCK stubs at
CVR.CCK.Wasm/Scripting/Links/APIs/CCKStubs/— they are the source of truth for what the guest sees. - If still unclear, grep the decompile at
CVR-GameFiles/WasmScripting/*Bindings.csfor the host function name; the shim mirror is usually adjacent in naming.
Related
Section titled “Related”- CVR Host Functions — the raw binder names (what the WASM module imports).
- Authoring — general workflow.
- Permissions — why a property read might throw.