Source of truth. This page mirrors state-server/docs/JS/objects.md. The repo is canonical — update there first, then resync here.
Objects are the primary entities:
type: 'block') — leaf 3D object with model, transform, properties.type: 'group') — container holding child objects and a gallery of prototypes.type: 'brane') — root-level Group with is_brane: true representing a 3D scene.const block = await sdk.entities.createObject({
type: 'block',
name: 'Red Cube',
model: { uri: '/models/cube.glb', type: 'model/gltf-binary' },
transform: [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,1,0,1],
properties: { color: '#ff0000' },
parent_id: parentGroupId,
});
const group = await sdk.entities.createObject({
type: 'group',
name: { en: 'My Group', fr: 'Mon Groupe' },
});
const brane = await sdk.entities.createObject({
type: 'brane', // SDK converts to type:'group' + is_brane:true
name: 'My Scene',
});
const block2 = await sdk.createBlock({ name: 'Blue Sphere', model: { uri: '/models/sphere.glb', type: 'model/gltf-binary' } });
const group2 = await sdk.createGroup({ name: 'Container' });
Blocks require a model field. If omitted, the SDK supplies a default: { uri: '/models/default_block.glb', type: 'model/gltf-binary' }.
Input (CreateObjectRequest)
| Field | Type | Required | Description |
|---|---|---|---|
type |
'block' \| 'group' \| 'brane' |
yes | Entity type; 'brane' auto-converts to type:'group' + is_brane:true. |
name |
string \| LocalizedText |
no | Plain string auto-wraps to { en: value }. |
description |
string \| LocalizedText |
no | |
model |
{ uri, type?, size? } |
yes (blocks) | 3D model reference. |
transform |
number[16] |
no | 4×4 column-major matrix. |
properties |
object | no | Custom key-value props. |
parent_id |
ObjectID |
no | Parent group/brane ID. |
tags |
string[] |
no | |
icon_uri |
string | no | |
is_brane |
boolean | no | Set automatically when type='brane'. |
visibility |
'private' \| 'unlisted' \| 'public' |
no | Default 'private'. |
Response: the created Block or Group with server-assigned fields (id, creator_id, created, updated, version, ...).
const obj = await sdk.entities.getObject(objectId);
const full = await sdk.entities.getObjectFull(objectId);
const group = await sdk.entities.getGroupRecursive(groupId);
const shorts = await sdk.entities.getObjectsShort([id1, id2, id3], 'en');
getObjectsShort — input { object_ids: ObjectID[] (max 200), lang?: string }. Returns ObjectShort[]: id, name, description, tags, creator_id, is_brane, visibility, ....
const updated = await sdk.entities.updateObject(objectId, {
name: { en: 'Updated Name' },
properties: { color: '#00ff00' },
transform: newTransformMatrix,
});
System properties (keys starting with _) are filtered from properties. type is never sent on updates.
await sdk.entities.deleteObject(objectId); // 204 No Content
const entity = await sdk.getEntity(id); // tries object → prototype → user → interface
const updated = await sdk.updateEntity(id, { name: 'New Name' });
await sdk.deleteEntity(id);
const updated = await sdk.entities.setObjectVisibility(objectId, 'public');
// also: sdk.setObjectVisibility(objectId, 'public')
Options:
'private' — owner only.'unlisted' — accessible via direct ID, not discoverable.'public' — accessible and discoverable by anyone.Public and unlisted objects can be read via GET /api/v1/object/{id} without authentication.
const result = await sdk.entities.testObjectModification(objectId);
// result.can_modify, result.object_id, result.object_type, result.reason
Objects can be taken to a user's inventory (detached) and placed back into a brane.
const canTake = await sdk.entities.testTakeObject(objectId);
await sdk.entities.takeObject(objectId);
const canPut = await sdk.entities.testPutObject(objectId, { brane_id: braneId });
await sdk.entities.putObject(objectId, {
brane_id: braneId,
transform: [1,0,0,0, 0,1,0,0, 0,0,1,0, 5,0,0,1],
properties: { placed: true },
});
putObject input: objectId, brane_id (required), transform? (16 numbers), properties? (object).
const obj = await sdk.entities.instantiatePrototype(prototypeId, {
type: 'block',
parent_id: braneId,
name: { en: 'Spawned Instance' },
});
Overrides: type?, parent_id?, name?, transform?, properties?. Response is a Block | Group with prototype_id set.
| Field | Type | Description |
|---|---|---|
id |
ObjectID |
Entity ID. |
type |
'block' |
Discriminator. |
name |
LocalizedText |
Localized names. |
description |
LocalizedText |
Localized descriptions. |
icon_uri |
string | Icon URL. |
tags |
string[] |
Tags. |
transform |
Transform |
4×4 column-major matrix. |
properties |
object | Custom props. |
parent_id |
ObjectID |
Parent entity ID. |
inventory_id |
ObjectID |
User inventory ID (when in inventory). |
prototype |
Prototype |
Full prototype data (SDK-hydrated). |
prototype_id |
ObjectID |
Prototype ID. |
visibility |
ObjectVisibility |
'private' \| 'unlisted' \| 'public'. |
version |
number | Version (starts at 1). |
previous_version_id, next_version_id |
ObjectID |
Version chain. |
deprecated |
boolean | Superseded flag. |
creator_id |
ObjectID |
Creator user ID. |
created, updated |
UnixTimestamp |
Timestamps. |
model |
Metadata |
{ uri, type, size, counter }. |
block_cells |
BlockCellItem[] |
Block cell positions. |
Same as Block plus child_ids: ObjectID[], gallery_ids: ObjectID[], is_brane: boolean. Groups do NOT have model or block_cells.
id, prototype_id, is_brane, name, description, tags, creator_id, creator_display_name, created, updated, icon_uri, preview_uri: string[], visibility.
Real-Time WebSocket for live mutations. state-server/docs/JS/prototypes.md and state-server/docs/JS/types-reference.md in-repo (mirror pending).