Examples

Look at what is in the scene

{"command": "scene.info"}
{"command": "entity.list"}
{"command": "entity.get", "entity": "Player"}
{"command": "asset.list", "type": "Material"}

Make a project from nothing

{"command": "project.create", "directory": "/path/to/MyGame", "name": "My Game"}
{"command": "project.open", "path": "/path/to/MyGame/MyGame.cairnproject"}

Or start from a template:

{"command": "template.list"}
{"command": "template.apply", "template": "ThirdPerson"}

Add a lit object, then change it

{"command": "entity.create", "name": "Beacon", "mesh": "Sphere", "data": {"Transform": {"Translation": [0, 3, 0]}, "PointLight": {"Range": 9, "Color": [1, 0.6, 0.3]}}}
{"command": "entity.update", "entity": "Beacon", "data": {"Transform": {"Translation": [2, 3, 0]}, "PointLight": null, "SpotLight": {"OuterAngle": 60}}}

The second command moves it, removes its point light and adds a spot light.

Make a material and use it

{"command": "material.create", "path": "Assets/Materials/Gold.cairnmat", "data": {"BaseColor": [1, 0.78, 0.2, 1], "Metallic": 1, "Roughness": 0.25}}
{"command": "entity.update", "entity": "Beacon", "data": {"MeshRenderer": {"Materials": ["Assets/Materials/Gold.cairnmat"]}}}

Write a script and put it on an entity

{"command": "script.write", "path": "Assets/Scripts/Spin.lua", "text": "local Spin = {}\nSpin.Fields = { Speed = 90 }\nfunction Spin:OnUpdate(dt)\n\tlocal r = self.Entity.Rotation\n\tr.y = r.y + self.Speed * dt\n\tself.Entity.Rotation = r\nend\nreturn Spin\n"}
{"command": "entity.update", "entity": "Beacon", "data": {"Scripts": [{"Script": "Assets/Scripts/Spin.lua", "Fields": {"Speed": 180}}]}}

script.fields lists the fields a script exposes, with their defaults.

A field that points at an entity takes its name or ID, and one that points at an asset takes its path:

{"command": "entity.update", "entity": "Player", "data": {"Scripts": [{"Script": "Assets/Scripts/Player.lua", "Fields": {"Camera": {"Entity": "Main Camera"}, "Bullet": {"Asset": "Assets/Prefabs/Bullet.cairnprefab"}}}]}}

Build a physics object

{"command": "entity.create", "name": "Floor", "mesh": "Cube", "data": {"Transform": {"Translation": [0, -0.5, 0], "Scale": [20, 1, 20]}, "BoxCollider": {}}}
{"command": "entity.create", "name": "Crate", "mesh": "Cube", "data": {"Transform": {"Translation": [0, 5, 0]}, "BoxCollider": {}, "Rigidbody": {"Type": "Dynamic", "Mass": 5}}}

An empty object, {}, adds a component with its default values.

Make a prefab and place copies

{"command": "prefab.create", "entity": "Crate", "path": "Assets/Prefabs/Crate.cairnprefab"}
{"command": "prefab.instantiate", "prefab": "Assets/Prefabs/Crate.cairnprefab", "data": {"Name": "Crate 2", "Transform": {"Translation": [3, 5, 0]}}}

Build a HUD

{"command": "entity.create", "name": "HUD", "data": {"UICanvas": {"ReferenceSize": [1280, 720]}}}
{"command": "entity.create", "name": "Score Text", "parent": "HUD", "data": {"UIElement": {"Type": "Text", "Text": "Score 0", "FontSize": 40, "Position": [28, 20], "Size": [360, 46]}}}

Play, look, stop

{"command": "play.run", "seconds": 2}
{"command": "lua.run", "code": "print(Scene.FindByName('Crate').Position)"}
{"command": "screenshot", "path": "/tmp/after.png", "position": [0, 6, 12], "look_at": [0, 0, 0]}
{"command": "play.stop"}

lua.run runs Lua with the full scripting API. What it prints comes back in the answer's log.

screenshot with nothing else is the game's own view. position and look_at give a view from anywhere, which is the way to check on something from several sides. Add "physics": true to outline the colliders.

Save, undo, export

{"command": "scene.save"}
{"command": "edit.undo"}
{"command": "export", "output": "/path/to/Builds"}

Whole games

Samples/CoinRun/Build.jsonl, Samples/Tetris3D/Build.jsonl and Samples/FeatureTour/Build.jsonl in the repository are complete games, each built from an empty folder by commands alone. Read them as worked examples. Feature Tour's is nearly a thousand commands, written by Samples/FeatureTour/Build.py: a script that writes commands is a good way to build a large level.

Samples/ZombieSurvival goes one step further: its models were made by an agent too, in Blockbench through the Blockbench MCP plugin. Samples/ZombieSurvival/Models/Models.py describes each model as cubes, builds it in Blockbench, exports it as glTF and merges its cubes into one mesh per moving part. asset.import then brings each .gltf into the project, and its parts are named like any model's: Assets/Models/Zombie.gltf#Mesh/2.