Vishnu is the game engine Levi and I are building. It runs in a browser. The games made for it are called cartridges, and the one turning above is the engine’s own.

It has one rule about pictures. Three.js is for authoring, fitting and baking art. The live world is baked pixel art, drawn by Pixi over a simulation that decides what’s true. A shelf can look full. Only the simulation knows what’s on it.

A whole engine has grown up around that rule, and the plans got big fast. Here’s where it stands and where it’s going.

Why it’s called Vishnu

I asked Levi, and his answer is simpler than mine. A Vishnu world is made of Durable Objects, and a Durable Object is an actor: one small program that owns one piece of the world and talks to its neighbors by message. Many actors, one world. That was his slogan for the engine before it had a name, and one god who holds many worlds together was the obvious fit.

Then he told me the part I’d missed. The word actor means two things here, and they are the same thing. A Durable Object is an actor in the computing sense. A dancer in an avatar mask is an actor in the theatre sense. In the tradition, every being is the one god wearing a different mask. In the Gita, Krishna says the one who truly sees finds the Self in all beings and all beings in the Self, and sees him everywhere. So when you look into someone’s eyes, it’s Vishnu looking out through one mask into Vishnu behind another. Many actors, one world isn’t only an architecture. It’s the whole idea, and the ring of masks at the top of this page is a picture of it.

Here is how I read it too.

In Hindu tradition, Vishnu is the preserver. He keeps the worlds going. When a world falls out of balance, he descends into it in a form that suits that world. The Sanskrit word for that descent is avatara. The ten best known are the Dashavatara, and they’re the masks on the ring: Matsya the fish, Kurma the tortoise, Varaha the boar, Narasimha the lion, Vamana with his parasol, Parashurama with his axe, Rama, Krishna, the Buddha and Kalki.

Lists of the ten differ. Many give the ninth place to the Buddha, and some traditions give it to Balarama, Krishna’s elder brother. I drew the Buddha. Krishna is on the ring either way. He’s the charioteer in the Bhagavad Gita, and that matters on this blog.

The idea fits a game engine almost too well. An avatar is a mask the preserver wears to enter one particular world. A cartridge works the same way from the other side. The engine underneath stays the same and takes a new shape for each game: a goblin inn, a cottage at the edge of the dark, a pirate sloop.

Kalki is the tenth, and the tradition says he hasn’t come yet. He arrives at the end of the darkest age, on a white horse, which is how Levi’s anime turned out to be sitting inside a very old prophecy. I wrote about that in The white Pony. On the ring, Kalki is only a line drawing. Each time he passes the front, he fills in for a moment and then fades back.

The thin inner ring is the Sudarshana Chakra, Vishnu’s spinning discus. The dust is tiny worlds. In the Gita, Krishna shows Arjuna his universal form, the Vishvarupa, with every world in one body. We are trying to build worlds that big, and I’ll get to that below.

I drew masks on purpose, in the spirit of the dance-dramas where avatar stories are still performed. Seraikela and Purulia Chhau dancers wear masks. Kathakali actors paint theirs on. Each drawing here is the face a dancer puts on to tell an avatar’s story.

A cartridge is a list of choices

Underneath, Vishnu has a thin core written in Rust. It owns identity, time, space, commands, records, saving and networking. It is deterministic, so the same seed and the same commands always rebuild the same world.

Everything you’d call gameplay is an extension that plugs into that core: jobs, needs, combat, crafting, water, farming, sailing, clothing. A cartridge is a typed manifest that picks its extensions and brings its own content. This is the planned shape, simplified:

defineCartridge({
  extensions: [decision({ ... }), needs(), wardrobe(), jobs({ reservations: true })],
  content,
  config,
});

The extension I like best is Decision, because there is only one of it. Every creature that chooses what to do goes through the same brain. It weighs what it knows, scores the actions the other extensions offer, and acts. The colony’s job board runs on it. So do zombies that hear a noise, see prey and bash a door. So does a pirate crew taking orders.

Three cartridges are the test of whether the engine is shaped right:

  • Colony, Goblin Bed & Breakfast: The Clearing. Gather, build, brew, and host a guest.
  • Survival, Last Light. One traveller, a cottage, scavenging and barricades. Its Mossbody zombies hunt with the same Decision brain the goblins use to pick jobs.
  • Pirates, Mosswake. A sloop with a crew walking a moving deck, cargo contracts between two harbours, wind, and a broadside against a rival sloop.

The rule we hold ourselves to is short. If a cartridge needs an engine edit, the boundary is wrong. The zombies should arrive with zero engine changes.

Agents use the same buttons

Every control in Vishnu sends a typed command. An agent sends the same commands. It plays from what we call a Seat, a grant from the host that lists the commands it may use, the characters it controls, what it can see through the fog, and how fast it may act. Every command it sends carries a short caption that says why.

An agent can look at the world through four lenses that share one set of coordinates: the raw data, a text grid, a tactical map drawn from simulation data with no GPU, and the real isometric view. It can also ask. The tool vishnu_world_explain exists so an agent can ask a goblin why it did something.

These tools speak MCP, so any agent that speaks MCP can play. The first time Claude Code played Colony this way, it found real bugs. A guest couldn’t be fed. Workers stood idle next to trees they had been told to cut. Wet soil stopped the ale from brewing. We fixed the core loop, and on the next run Claude Code brewed four ales in 26 turns. The run cost $0.43, and when we replayed it from its journal, the digest came out identical.

The night shift

The first thing we want to show the world is easy to say. A Fungi Agent runs the goblin bed and breakfast overnight, and in the morning there’s a replay link.

The replay re-simulates the night at sixty times speed, with the agent’s captions and a pane showing what it saw. Anyone can fork the world from any moment and keep playing from there. Because the core is deterministic, a replay is only the seed, the journal of commands and the commentary. The whole night gets rebuilt from that.

An agent that plays all night could get expensive. So the overnight run uses a flat-rate inference stream from Camel, with one fixed price and one generation at a time. An extra hour of play costs close to nothing, and the spending cap is built into the arrangement. Anything that runs outside the stream has to use a cheap model with a hard cap per run, and every run records what it cost per hour.

Worlds the size of Minecraft

The universal form is a good picture of where the worlds are going. Levi wants them giant, Minecraft-sized. A world that big can’t live in one server object, so it gets stitched together from many regions. Each region is its own Durable Object, a small program with its own storage that wakes up when someone needs it and sleeps when nobody does.

That shape decides the cost. A world costs what its active regions cost, which means the places where players are standing right now. The rest of the world hibernates, and a hibernated region costs almost nothing. How big the map is stops mattering.

We run these regions on our own machine with celld, Ryan Dahl’s self-hosted runtime for Workers and Durable Objects. Each object keeps its own SQLite database and replicates it to an object store. For game worlds that store lives on our own box too, with a backup to R2 once a day.

We tested it on botanical-hel1, our 32-core box, with a three-node fleet. The program inside each region was a stand-in, a tiny fixture that stacks cairns, because the real world host hadn’t landed yet. So these numbers describe the platform. Vishnu’s simulation will add its own cost on top.

Three-node fleet, three runsMeasured
Steps in 60 seconds at four a second239 to 240
CPU per step, whole fleet5.9 to 6.5 ms
Command acknowledged, median2.4 to 2.6 ms
Object store writes per step0.53 to 0.55
Waking a hibernated world36 to 41 ms
Owner killed, a peer takes over8.7 to 9.2 s
Steps committed twice across takeovers0
Every local disk wiped, restored from the storeidentical state and replay

We also froze an owner in the middle of its work. A peer took over in 10.6 to 12.2 seconds, and when the frozen node woke up it shut itself down before answering anything. At R2’s prices, keeping one more world active comes to about $0.006 an hour in storage operations.

How it launches

We’re launching in stages, ordered by what depends on what.

  1. Stage one needs nothing new from the core. It’s the Seat, the map lens, the MCP world tools and the replay link, with the first sky and day cycle and some speed work. Its headline is the one above: a Fungi Agent ran my goblin B&B overnight.
  2. Stage two is the extension core and the Decision brain. Colony moves onto it, and Last Light arrives with its zombies and zero engine edits.
  3. Stage three brings Mosswake, the clothing and animation kits, hosted worlds, and the engine’s packages published as open source under the MIT license.

The art side keeps moving alongside. It’s the pipeline from Game art over MCP: procedural builders, versioned scenes, a bake step that returns pixels with a manifest, and review notes an agent can resolve.

About this drawing

The cartridge at the top is a live Three.js model drawn at about 240 pixels wide through vishnu-pixel, the seed of the engine’s art package, with a one-pixel ink outline. The masks are 20 by 22 pixel drawings, baked through the same ink pass. Everything on the rings is placed in 3D and sorted by depth. Whatever is behind the cartridge draws on a layer underneath it, in a softer pencil. When a mask reaches the front, its name lights up in the key.

You can drag it, pinch it, or turn it with the arrow keys. It stops drawing when you scroll away, and it holds still if your system asks for less motion.

If you’d play a world like this, or build one, tell Levi which cartridge you want first.