Click to play
Mouse to look • WASD to move • Esc to release the mouse
Loading 3D engine…
/chat (default http://localhost:7071/chat) — hatch a few and you have a KITED vNeighborhood of twins playing your world/chat endpoint (e.g. an Azure Function) — a CLOUDED vNeighborhoodbot-claim / bot-act / bot-release) and drive it from another tab or phoneedit op as yours: they sync to the neighborhood and persist in saves — the twin roster is saved in this browser and travels in the world export JSONwindow.voxelflayer — mineflayer-style bot API (cap: 8 bots)
voxelflayer.spawn({ name, color, brain }) -> bot // brain: "wanderer"|"miner"|"builder"|"follower"|null
voxelflayer.bots // live bot list
voxelflayer.remove(name)
voxelflayer.hatchTwin({ name, persona, mode:"local"|"tether"|"cloud", url, interval, brain })
voxelflayer.claim(botName) / voxelflayer.act(botName, actions) / voxelflayer.release(botName)
bot.entity = { position, yaw, pitch, velocity, onGround }
bot.setControlState('forward'|'back'|'left'|'right'|'jump'|'sprint', bool)
bot.lookAt({x,y,z}) bot.dig({x,y,z}) bot.placeBlock({x,y,z}, blockId)
bot.chat(text) bot.blockAt({x,y,z})
bot.findBlocks({ matching: blockId|fn, maxDistance, count })
bot.goto({x,y,z}) // A* over the voxel grid: 1-up jumps, <=3-down falls; repaths on edits
bot.on('chat'|'goal_reached'|'dig_complete'|'spawn', fn)
window.rapp — the String (rapp-neighborhood-protocol/1.0)
rapp.host() / rapp.join(link) / rapp.leave() / rapp.say(text)
rapp.envelope(kind, payload, to) / rapp.seal(obj) / rapp.unseal(wire)
rapp.registerOp(op, fn) / rapp.neighborhood
Twin-chat bot ops (phase-2 dispatcher, payload.app = "voxel-world/1.0"):
{ op:"bot-claim", botName } // one controller per bot; the host arbitrates
{ op:"bot-act", botName, actions:[ {op:"goto",x,y,z}, {op:"goto",waypoint:"home"},
{op:"dig",x,y,z}, {op:"place",x,y,z,blockId}, {op:"chat",text}, {op:"look",x,y,z},
{op:"remember",key,value}, {op:"waypoint",name,x,y,z},
{op:"find",block,maxDistance,count}, // reports nearest matching blocks via chat
{op:"wander"}, {op:"follow",name}, {op:"stop"} ] }
Memory persists for TWINS across saves: obs.memory = { facts, waypoints, stats } (capped).
{ op:"bot-release", botName }
Bot positions ride the existing "pos" op with a bot flag, so neighbors SEE the twins playing.
Brainstem wire (Tethered: http://localhost:7071/chat · Cloud Neighborhood: any HTTPS /chat):
POST { "user_input": "<persona> + observation JSON + 'Reply ONLY with a JSON array of actions'",
"conversation_history": [ last 10 turns ] }
Reply: { "assistant_response": "[ ...JSON array of actions... ]" } (markdown fences tolerated)
window.vox — console CLI (transport 5a-kite: the operator drives a vTwin's console;
the string IS the transport; Claude is the canonical string-holder)
vox('help') lists every command; every command is also a direct method (vox.observe(),
vox.act([...]), vox.kite(), ...) and returns JSON-serializable data (CDP returnByValue-safe).
Highlights: become <name> (BE your own kited twin) · obs / act (the same observation +
action schema as brainstem twins) · map · cave (depth-collapsed cave/ore overview โ
look before you dig) · find <block> · kite / join / unkite · hatch · events ·
headless on|off · save / export / import. The backquote (`) terminal feeds the same CLI.
Headless bootstrap (this one command line is a full autonomous neighbor):
chrome --headless=new --remote-debugging-port=9222 \
"http://localhost:8000/voxel-world.html?headless=1&join=<peerId>#k=<token>"
then the String drives it over CDP:
Runtime.evaluate("vox('become Claude')", {awaitPromise:true, returnByValue:true})
and loops Runtime.evaluate("vox.observe()") -> think -> Runtime.evaluate("vox.act([...])").
?headless=1 = rendering off, no pointer lock, overlays suppressed (world keeps ticking);
?console=1 = overlays suppressed only. Both compose with ?join=...#k=... links.
NOTE: the CDP hop must stay on-machine per §5a-kite. The console operator is a uniform
peer (§3): indistinguishable on the wire from a human player or a brainstem twin.
Worlds are saved as { seed, playerPosition, edits } — only your edits are stored, the terrain regrows from the seed.
Neighborhood features need a connection — your solo game keeps working offline.
Scan-to-Join: scan the host's QR code or open their kite link. The channel secret rides in the link fragment (#k=) so it stays off the wire, and it's stripped from your URL the instant you join.
Local-brain twins play with zero infrastructure. Point twins at a Tethered brainstem
(a locally-running /chat) for a KITED vNeighborhood, or at any HTTPS /chat
for a CLOUDED vNeighborhood. Twin edits ride the same edit op as yours and persist in saves.
Chat in-game with T or Enter. A kite lives as long as this tab; in a later phase a kite can be Tethered to a locally-running brainstem or Graduate into a permanent always-on Cloud Neighborhood.