Skip to main content

Grids (world ownership)

client.gameApps wraps the Game API grid administration surface — the spatial permission layer that decides what a player may do in a given 3D region of your world. It is a studio-admin surface that runs on the Game API, so every call needs an app-scoped token for the target app (mint one with identity.portal.mintAppToken(appId); there is still no separate "admin token" type — it is the same app/gameplay token) and a logged-in user who holds the manage_apps permission on the app's organization. A studio admin can mintAppToken for their own app even without player entitlement. Drive it from a trusted admin context — a studio backend or your own admin-only / authenticated web tool (a browser is fine) — and just keep that privileged token out of the untrusted game client you ship to end users. It is also reachable as client.admin.grids. See Portals & app-scoped tokens; the examples below assume client holds that app's app-scoped token.

For the underlying concepts (how grids layer on top of app access, the open-by-default world grid, nesting vs. straddling, and effective-permission math) see Game API → Grids and permissions.

Create and delete grids

A grid is an axis-aligned box of chunks. createGrid and deleteGrid both return a hybrid result — inspect error first (it is a UDP-style error code; NO_ERROR means success), rather than relying on a thrown exception.

const created = await client.gameApps.createGrid({
appId: '1',
corner1: { x: '0', y: '0', z: '0' },
corner2: { x: '15', y: '7', z: '15' },
});
if (created.error === 'NO_ERROR') {
console.log('grid', created.grid?.grid_id);
}
// Remove a studio-created peer grid (e.g. to unblock GRID_OVERLAPS_EXISTING).
const removed = await client.gameApps.deleteGrid({ appId: '1', gridId: '10' });
if (removed.error !== 'NO_ERROR') {
// GRID_NOT_FOUND | CANNOT_DELETE_DEFAULT_WORLD_GRID | GRID_HAS_NESTED_CHILDREN | UNKNOWN_ERROR
console.warn('delete failed:', removed.error);
}

deleteGrid refuses to remove the open-by-default world grid or a grid that still has nested child grids (delete the children first). It removes only the grid definition and its permission rows — chunks, voxels, actors, and game-model data in that region are untouched. Requires cks-game-api >= v0.12.3 (release v0.1.33+).

Grant and limit permissions

// Per player:
await client.gameApps.grantPermissions({
appId: '1', gridId: '10', userId: '42',
permissionKeys: ['access', 'update_voxel_data'],
});

// Per team/group (every member, or only members holding groupRoleId):
await client.gameApps.assignGroup({
appId: '1', gridId: '10', groupId: '7',
permissionKeys: ['access', 'update_voxel_data'],
});

// Cap what the grid can ever allow (build a safe zone — movement, no building):
await client.gameApps.setPermissionLimits({
appId: '1', gridId: '10',
permissionKeys: ['access', 'use_voice_chat'],
});

Use revokePermissions / revokeGroup to remove grants (omit permissionKeys to remove all), and the read helpers to inspect the effective ACL:

await client.gameApps.userPermissions('1', '10', '42'); // one player's keys on a grid
await client.gameApps.permissionLimits('1', '10'); // the grid's whitelist
await client.gameApps.groupGrants('1', '10', '7'); // a group's grants
await client.gameApps.nearbyPermissions({ // grids overlapping a box + a user's keys
appId: '1', userId: '42',
corner1: { x: '0', y: '0', z: '0' },
corner2: { x: '63', y: '15', z: '63' },
});

Methods

MethodGame API field
createGrid(input)createGrid
deleteGrid(input)deleteGrid
grantPermissions(input) / revokePermissions(input)grantGridPermissions / revokeGridPermissions
assignGroup(input) / revokeGroup(input)assignGroupToGrid / revokeGroupFromGrid
setPermissionLimits(input)setGridPermissionLimits
userPermissions(appId, gridId, userId)gridUserPermissions
nearbyPermissions(input)nearbyGridPermissions
permissionLimits(appId, gridId)gridGroupGrants-adjacent gridPermissionLimits
groupGrants(appId, gridId, groupId)gridGroupGrants

All take/return the generated GraphQL input/output types. A grant or revoke takes effect immediately for connected players.