The world state file

A world's scene definition: placed objects, planner configuration, and its sidecar files.

A world is a folder at worlds/<id>/. The required file is world_state.json; worlds built from a camera scan carry sidecar files beside it.

You author worlds in the World Builder, not by hand. This page is for reading the file and understanding what the fields mean.

⚠️

Hand-authoring an entry in objects is the one edit to avoid. The loader reads most of an object's fields by direct key access, so an entry missing any one of them fails with a KeyError rather than a helpful message. Add objects through the World Builder and edit the result.

Minimal example

A fresh world from zeon new world my_world:

{
  "version": "2.0",
  "config": {
    "tensor_device": "cuda",
    "enable_blox": false,
    "create_workspace_boundaries": false
  },
  "objects": {},
  "metadata": {
    "name": "my_world",
    "description": "",
    "source": "manual"
  }
}

Top-level fields

FieldTypeRequiredDescription
versionstringyesWorld schema version. See the note below; "2.0" and "3.0" are both in circulation.
configobjectyesPlanner and simulator configuration.
objectsmapyesObjects placed in the scene, keyed by instance name.
metadataobjectnoDisplay metadata. Read by the world list to label the world; the scene loader ignores it.
📝

Two schema versions are in circulation. Worlds created by zeon new world, and older worlds generally, carry "2.0". A World Builder save writes "3.0". The two differ in how object geometry is serialized. See the note under geometry. Loading a world during normal use does not check the version, so both work; you mainly need to know which shape you are looking at when reading a file.

config

Set by the World Builder. You rarely edit these by hand.

FieldTypeDescription
tensor_devicestringWhere the planner runs its computations. "cuda" on GPU-equipped installs.
collision_cacheobjectPlanner cache sizing, as {"obb": 20, "mesh": 10}.
enable_bloxbooleanWhether the world carries a voxelized geometry layer, typically from a camera scan.
blox_layer_namestringName of the voxel layer. "world" in practice.
blox_voxel_sizefloatVoxel size in metres.
blox_integratorstringVoxel integration algorithm. "tsdf" in practice.
create_workspace_boundariesbooleanWhether the planner treats the workspace AABB as invisible walls.
workspace_aabb_min[x, y, z]Workspace AABB minimum corner.
workspace_aabb_max[x, y, z]Workspace AABB maximum corner.
map_savedbooleantrue once a voxel grid has been persisted to .npz.
mesh_savedbooleantrue if a visualization mesh has been persisted to blox_mesh.ply.
tsdf_savedbooleantrue once the block-sparse TSDF has been persisted to blox_tsdf.npz. Written by newer exports; the shipped 2.0 worlds omit it.
voxel_countintegerNumber of occupied voxels in the saved grid.
voxel_export_regionobjectThe exported region, as {"aabb_min": [...], "aabb_max": [...]}.
include_objects_in_voxelsbooleanWhether placed objects were baked into the voxel grid.
voxel_specobject | nullVoxel reconstruction spec. null when unused.

objects

A map of the objects placed in the scene. Each key is the instance name. Objects the World Builder places are keyed <type>_<uuid>, so the same object type can appear several times in one scene. Fixtures added by hand tend to keep plain names like table.

A placed project object. The pose values are shortened for readability. Real files carry full double precision, and the instance key carries a full UUID:

"fixture_plate_9e3b532c-…": {
  "geometry": {
    "type": "articulated",
    "yaml_path": "objects/fixture_plate/fixture_plate.object_model.yaml"
  },
  "mount": {
    "type": "FixedMount",
    "world_P_body_fixed": {
      "xyz": [0.605, 0.403, 0.0],
      "wxyz": [1.0, 0.0, 0.0, 0.0],
      "stamp_s": null
    }
  },
  "enabled": true,
  "filter_from_depth": true,
  "collide_in_planner": true,
  "attachment_spec": {
    "fit_type": "voxel_volume_sample_surface",
    "surface_sphere_radius": 0.001,
    "voxelize_method": "ray"
  },
  "metadata": {
    "name": "fixture_plate",
    "location": "fixture_plate",
    "type": "fixture_plate"
  },
  "joint_config": {}
}

Object fields

FieldRequiredDescription
geometryyesWhat this object is (see below).
mountyesHow it is anchored.
enabledyesfalse leaves the object defined but out of the scene.
filter_from_depthyestrue excludes the object from depth-based perception, and is used for objects whose pose is already known.
collide_in_planneryestrue makes the planner avoid it.
attachment_specyesHow the object is fitted when picked up.
metadatayesFree-form per-object metadata. May be {}.
joint_configfor articulatedJoint name → value. Present on articulated geometry.

Every field above except joint_config is read by direct key access. Omitting one is a load error, not a defaulted value.

geometry

Two shapes appear, distinguished by the type tag:

A project object, from your objects/ folder or the mesh database:

{ "type": "articulated", "yaml_path": "objects/fixture_plate/fixture_plate.object_model.yaml" }

The yaml_path points at the object's object_model.yaml. It is stored in this portable, project-relative form on purpose; the absolute path is worked out at load time and never written back to the file, so a world stays valid on another machine. Older worlds instead have an absolute container path baked in, like /app/storage/mesh_database/<name>/<name>.object_model.yaml. Both resolve.

A primitive, a synthetic shape used for tables, filters, and workspace walls:

{ "type": "Cuboid", "name": "x_min", "pose": { "xyz": [-1.36, -0.36, 0.35], "wxyz": [1, 0, 0, 0], "stamp_s": null }, "dims": [0.02, 2.9, 1.7] }

The registered primitive types are Cuboid, Sphere, Cylinder, Capsule, Mesh, and VoxelGrid. An unrecognized type is a load error.

📝

This flat, type-tagged form is the "3.0" shape. A "2.0" world serializes its primitives the older way, as {"class": "Cuboid", "kwargs": {...}}. If you open an existing world and see class/kwargs, that is what you are looking at.

mount

FixedMount is the only mount type a saved world may contain. Any other value raises an error on load. It carries world_P_body_fixed with three keys: xyz (metres), wxyz (quaternion, scalar first), and stamp_s (null in every saved world).

Workspace boundaries

When create_workspace_boundaries is on, the World Builder adds six primitives named x_min, x_max, y_min, y_max, z_min, and z_max, invisible cuboids at the AABB faces. Those six names are reserved and special-cased by the loader, which can skip them on request. Don't edit them by hand; they're regenerated when the AABB changes.

metadata

FieldTypeDescription
namestringDisplay name. Usually matches the folder name.
descriptionstringFree text.
created_atstring (ISO 8601)When the world was created.
sourcestring"manual" or "execution".

source is shown in the world list as Created manually or From execution.

Sidecar files

A world built from a camera scan carries binary sidecars beside world_state.json:

FilePurpose
blox_voxels.npzThe voxel grid from the scan. Loaded when enable_blox is true.
blox_tsdf.npzA block-sparse TSDF snapshot. Preferred over blox_voxels.npz when present, because it lets depth integration resume rather than start over.
blox_mesh.plyA visualization mesh. Written only when the export asks for one; mesh_saved records whether it exists.
nvblox_map.binNVBlox map data.

One more sidecar appears on any world, scanned or not:

FilePurpose
live_state.yamlA text file holding what genuinely changes at run time and so does not belong in a frozen scene export: per-object calibration offsets and the tipbox tip pointer, keyed by object UUID.

Commit all of them like any other file. Don't edit the binaries: they are written by the platform and have no hand-editable form.

live_state.yaml is the exception: it is meant to be hand-edited during calibration. A YAML typo there fails with a clear error naming the file rather than an opaque parser error inside a skill.

When the file is wrong

Malformed JSON does not surface as a clean "this world is broken" message. The world list swallows the parse error and still shows the world, labelled with a title-cased version of the folder name (my_world appears as "My World") and an object count of 0. The raw folder name survives as the world's id. The failure surfaces when you load it: the path resolver logs a warning and hands the file to the loader, which fails on the same malformed JSON.

A referenced object that doesn't exist is more forgiving: the path resolver catches per-object failures and logs a warning, so one missing mesh doesn't fail the whole world load. The world opens without that object.

See also


Did this page help you?