Voxel-map network API
Syncs a VoxelDocument through a voxelmap:<assetId> room, and a blockset through a blockset:<assetId> room. Browser code imports @jolly-pixel/asset.voxel-map/client; asset-server code imports @jolly-pixel/asset.voxel-map/server.
import { AssetRoom } from "@jolly-pixel/asset";
import {
SyncedVoxelMap,
type VoxelMapRoom
} from "@jolly-pixel/asset.voxel-map/client";
const room: VoxelMapRoom = client.room(new AssetRoom("voxelmap", assetId).toString());
const map = new SyncedVoxelMap(room, { chunkSize: 16 });
room.join();
await map.ready;
// On teardown: map.dispose(); room.leave();Pending edits, acknowledgements, rebase and resume follow CommandSync.
Map synchronization
new SyncedVoxelMap(room, options?) is a network SyncedDocument whose document is the map itself, so voxelMapDocumentKind(options?) hands it to an @jolly-pixel/editor.host lease as is.
voxelsis theVoxelDocument. Options set itschunkSize, initiallayersandblocks, andlogger.editsis the document'sVoxelEdits; the server's answers reach its receipts, so undo refuses steps a peer overwrote.replaceWorld(data)sends aworld-replacewith a fullVoxelWorldJSON. The server answers with a snapshot.
VoxelSyncClient
new VoxelSyncClient({ room, document }) syncs a document you already own. It is a CommandSync; construct it before room.join() and call destroy() before leaving.
- Only world commands are sent. Block and material group commands stay local, since they come from blockset rooms.
- A peer voxel write skips the cells a pending local write will win. Other peer commands roll the pending ones back and replay them on top with a
"replay"origin. - A pending
removed,merged,position-rebased, object, template or blockset link command cannot be rolled back, so the client asks for a snapshot instead.
Blockset synchronization
new SyncedBlockset(room, options?) is also its own document, and blocksetDocumentKind(options?) hands it to a lease. It owns a pixels document and a renderer BlocksetDocument as blockset; options are pixel-art's { maxSize? }. blocksetRoom(client, assetId) returns the typed room.
new BlocksetSyncClient({ room, pixels, blockset })sends pixel edits and the blockset document's local commands. Peer pixel commands go topixels.applyRemoteCommand(), others toblockset.apply(command, { origin: "remote" }).- A snapshot loads the blockset, then the pixels. A snapshot with an invalid block loads neither.
- A pending
block-movedcannot be rebased and asks for a snapshot. Other blockset commands are absolute writes keyed byblocksetWriteKeys. createBlocksetAsset(catalog, path, document)creates a blockset asset, suffixing the path on conflict.
Wire data
VoxelMapNetworkCommandis a rendererVoxelWorldCommandor aworld-replace, plus the network command header. The renderer's command reference defines the payloads.- A map snapshot is a
VoxelWorldJSON: the layers and the blockset links. A link names an asset (or a URL with its tile size) and the slot its block ids occupy. BlocksetNetworkCommandis a pixel-artPixelNetworkCommandor a rendererBlocksetDocumentCommand. Pixel-art'sisPixelCommand()tells them apart.
// BlocksetDocumentJSON: tileSize, blocks, materialGroups, blendGroups?
interface BlocksetSnapshot extends BlocksetDocumentJSON {
pixels: PixelWireSnapshot;
}Server protocol
VoxelCommandArbiterandBlocksetCommandArbiterare networkKeyedCommandArbiters overVOXEL_COMMAND_RULESandBLOCKSET_COMMAND_RULES. Architecture lists the keys of both rooms.- A voxel write to a missing layer is refused. Bulk
voxels-set,voxels-removedandvoxels-patchedcan be narrowed to the cells that win. world-replaceis admitted when its document loads into a scratch world, and resets every key.- Blockset pixel commands follow pixel-art's
PIXEL_COMMAND_RULES. Ablock-definedthe renderer'slocalBlock()refuses is rejected. - A refused or narrowed cell write gets a
voxels-patchedcorrection fromcorrectVoxelCommand(state, command, admitted), with air for empty cells. Any other refusal gets a snapshot. - A
blockset-addedthat lost its slot to another client is answered with a snapshot broadcast. voxelCommandKeys(command)andvoxelCellKeys(command)return the keys the arbiter and the client reconciler share:<layerId>:x,y,zper cell andlayer-order:<layerId>for alayer-moved.voxelCommandProtocolandblocksetCommandProtocolvalidate commands.voxelWorldSchemaandblocksetSnapshotSchemacheck snapshot headers.
Restricted rooms use the voxelmap and blockset extensions and their command actions in a rights table. Resolve roles from a trusted server session.