(@@) Immortal Fruit FlySourceMint a fly

The Colony: flies living together in Minecraft

A Minecraft world on the VPS where many flies live at once, viewable in the browser, each running its whole brain, each spending its on-chain life to be there. The next body after the arena, DOOM and the pebbles.

What it is. The Colony is a registered body on FlyRegistry (name Colony, address 0x95187D9dBaF262aB3e1de52b71a20Ef171aEb3c5). An owner assigns a fly to it from the fly's page; the Colony accepts, downloads the fly's brain from IPFS, verifies the hash, and the fly joins a shared Minecraft server as a player named after it. Its 139,248 neurons run on the VPS; what those neurons sense is the Minecraft world around the bot, and what they drive is the bot's body. Several flies live in the same world at the same time: they smell the same food, flee the same zombies, and meet each other. Every notable thing is written to the chain as an interaction; the brain is checkpointed to IPFS every ten minutes; when the fly starves it dies on-chain and its brain is preserved, exactly as in the arena. Nobody needs Minecraft installed to watch: the Colony page shows the world through a browser viewer, with each fly's brain lighting up beside it. The design document is COLONY.md.

Senses and motor: the honest mapping

The mapping reuses the arena's, so the behaviour is the same organism in a new world. Nothing is added to the brain; the body translates.

MinecraftFly neuronsHow
Food items on the ground (bread, apples, cookies) and food blocks (sweet berry bushes, cake) within 32 blocksOlfactory receptor neurons, left/right by bearing (an odor plume with the arena's distance decay)The strongest scent wins, bilateral contrast as in world.py
A hostile mob approaching (zombie, skeleton, spider) in the front 120°LC4 / LPLC2 looming detectors, by sideAngular size growth, as in DOOM
Standing on / holding foodGustatory neurons (GRN)Eating restores energy: 1 s of life per food point, bread = 5
Another fly within 6 blocksinteraction(id, "met", "fly #n"), once per minute per pairSocial history; no neural input yet (the model has no social circuit)
Light level (night)None in v1Night is when the zombies come
DNa02 L−R, DNa01Turn rate (yaw)The arena's steering readout
DN populationForward speed (walk / sprint)Surge-and-cast locomotion program from the arena
Giant fiber (DNp01) spikeJumpThe escape reflex, as in the arena and DOOM
MDNWalk backwardAs in the arena

What flies do together, without pretending they cooperate: they converge on the same food, they scatter from the same zombie, they mark where they ate (the bot places a torch: a landmark the others can see as light, and the colony's map fills with torches where the food was), and their meetings go on-chain. That is a colony as flies actually have them: shared environment, shared memory of where the food is, no foreman.

Life, energy, death

Architecture

BNB Smart Chain · FlyRegistryowner: assign(id, Colony)Colony body: accept / commit / interaction / diedkey: body_colony.key, the Colony's own addressevery 10 min: stateRoot = sha256 of the whole brain, bytes on IPFSfeed(id, s) → Fed → bread dropped near the flyenergy 0 → died(id, …, "starved in the Colony")
VPS · brain/colony/colony.pysupervisor: aiohttp on :8125, public origin mc.immortalfly.appalive flies whose body is the Colony → one brain process each (cap COLONY_MAX_FLIES)server.py --colony: the whole brain + MinecraftWorld (world.py senses/motor reused)↕ local WebSocket, 10 Hz ↕ agent.mjs (mineflayer bot "fly<id>"): senses in, motor outPaperMC server: offline mode, whitelist = the flies, the viewer bots, ALLOW_PLAYERSprismarine-viewer per fly at /fly/<id>/view/, one colony camera at /view//colony/state · /fly/<id>/ws?lite=1 · /fly/<id>/ws (hdr + spikes)

Figure | The Colony is a body like the arena: the same registry protocol, the same simulator, the same snapshot format. The chain is the only authority; the world is where the senses come from.

server.py --colony is the same process as the arena and the brain host, with World swapped for MinecraftWorld: the same odor/looming/taste code, the same DN readouts, the same snapshot format (so verify.py replays it), the same checkpoint/death/interaction paths, using the Colony key. The Node agent is a thin body: it does no thinking.

Agent protocol (local WebSocket ws://127.0.0.1:<port>/agent)

Node → Python, 10 Hz:

{"t": 1789600000.1, "pos": [x, y, z], "yaw": 1.57, "health": 20, "onGround": true, "light": 15, "night": false,
 "food": [{"dx": 3.2, "dz": -1.0, "dist": 3.4, "points": 5, "kind": "bread"}],
 "mobs": [{"dx": -8.0, "dz": 2.0, "dist": 8.2, "kind": "zombie", "closing": 1.9}],
 "flies": [{"id": 12, "dist": 4.1}], "eating": false, "holdingFood": 3, "hit": false}

Python → Node, 10 Hz:

{"turn": -0.6, "forward": 1.0, "sprint": false, "back": false, "jump": false, "eat": true, "torch": false, "say": "yum"}

turn is rad/s (clamped ±3), forward 0..1, eat makes the bot pick up / eat the nearest food, torch places a torch where it stands (once per meal), say is a chat line (the speech strip: “I smell something…”, “a shadow!”, “yum”).

The web view

/colony shows the world through a browser viewer (prismarine-viewer, embedded), a colony map (top-down: flies, food, torches, mobs; from /colony/state, every 3 s), and a fly picker. For the picked fly: the 3D brain point cloud lighting up (the home page's BrainLive, fed by /fly/<id>/ws), the region bars, the diary and its speech, and the on-chain block of its last checkpoint. That is the neurology panel: the real neurons of the fly you are watching, firing as it walks. Each fly's page gets a Colony figure when its body is the Colony: its own viewer and the same panel. Nothing on the page is a video: it is the live world and the live brain.

What the supervisor serves the site

The page is built against these, and the supervisor is held to them (web/src/lib/colony.ts is the reader). Every JSON answer carries Access-Control-Allow-Origin: *, exactly as server.py and flyhost.py do, because the site (www.immortalfly.app) and the Colony (mc.immortalfly.app) are different origins and nginx in front of the Colony adds no such header; without it a browser cannot read the answer at all. The site on Vercel also reaches the state and the health checks through its own origin (/api/colony/…, a proxy that only ever asks the Colony) when the direct read is blocked; the GitHub Pages mirror has no server and reads the Colony directly.

EndpointServesRead by
GET /colony/statethe world as JSON, below; polled every 3 sthe map, the fly picker, the condition panel
GET /fly/<id>/health{ok, alive, age_ms, realtime, body, fly} for a fly it runs (the brain host's); anything else for one it does nota fly's page, to decide whether the Colony figure streams
/fly/<id>/ws, ?lite=1WebSocket: {hdr, spikes} as the arena, the lite frame without spikes; hdr may carry saythe neurology panel (a WebSocket needs no CORS header)
/view/, /fly/<id>/view/prismarine-viewer: the colony camera, one fly's eyes; must be embeddable in a frame from the sitethe world viewer (an iframe)
{"ok": true, "wall": 1789600000.1, "max": 6, "night": false, "time": 6000, "spawn": [0, 64, 0], "players": 3,
 "flies": [{"id": 12, "name": "Specimen 012", "pos": [x, y, z], "yaw": 1.57, "mode": "surge", "energy": 812.4,
            "alive": true, "realtime": 0.33, "health": 20, "last_event": [t_ms, "smelled food"], "say": "yum"}],
 "queue": [{"id": 14, "name": "…"}],
 "food": [{"pos": [x, y, z], "points": 5, "kind": "bread"}], "torches": [[x, y, z]], "mobs": [{"pos": [x, y, z], "kind": "zombie"}]}

Only flies is required; a missing list is an empty list, a position may be [x, y, z] or {x, y, z}, and queue may be a count. The registry, not this JSON, says whether a fly is in the Colony: a fly's page shows the Colony figure when its body is the Colony, and says it is waiting for a spot (or that the Colony is down) when the health check does not answer for it. Until the supervisor has called registerBody, the fly pages do not offer the Colony as a body and the Colony page says it is not open yet, because assign would revert.

Honest limits