I built an island out of boxes and cones
No 3D models, no textures, no loading screen. /world is a village made from three.js primitives and stubbornness.

Type /world into this site and a small plane drops you on an island. You walk it on foot. Nine doors, a masjid that calls the adhan, a souq, a library, sheep that scatter when you get close. It looks like something that took a team and an asset store.
It didn't. There is not a single 3D model in it. No .glb files, no textures to download, no loading bar. Every tree, every wall, every roof, every sheep is built at runtime from three.js primitives — boxes, cylinders, cones. When the page loads, the island doesn't arrive. It gets assembled.
Why do it the hard way
The obvious way to make a 3D scene is to model it in Blender and ship the files. It also means megabytes of downloads, a loading screen, and a pipeline where the thing you see is decoupled from the code you wrote. I wanted the opposite: a world the code fully owns, that streams in as fast as JavaScript parses, and that I can change by editing a number instead of reopening a modelling tool.
So a tree is a cylinder trunk with a couple of cones stacked on top. A house is a box with a roof prism and window quads. A sheep is, embarrassingly, more boxes. Up close you can tell. From the camera height you actually play at, it reads as a village. Low-poly stopped being a limitation and became the look.
One atlas, no drift
The trap with a hand-built world is that three things end up knowing where the masjid is: the 3D engine that draws it, the minimap that plots it, and the heads-up display that points at it. Change one and the other two lie.
So none of them own positions. There is one file, the atlas, that lists every landmark: where it sits, how big its trigger radius is, the line the keeper says when you walk up. The engine reads it. The minimap is drawn from the same numbers. The HUD points using the same numbers. They physically cannot disagree, because there is only one source to disagree with.
React and three.js never touch
React is great at menus and terrible at a 60fps render loop. three.js is the reverse. So they don't share state — they share a contract. React hands the engine intent: set the joystick, set the time of day, pause, here are the other visitors. The engine hands back events: you arrived somewhere, the phase changed, you pressed a door.
Everything you can touch flows one way and everything the world reports flows back the other. No React component ever reaches into a mesh. That single rule is why the thing runs smoothly on a phone instead of stuttering every time a panel opens.
The doors are real
The point of a place is that things happen in it. So the doors aren't screenshots. Walk into the masjid and it pulls today's actual Mumbai prayer times and lights the minaret when a prayer is due. The post office is the same mailbox as the contact form on my homepage — post a card on the island, it lands in my inbox. The library writes your book suggestion to a real table. Other little figures wandering the island are other people, right now, on the same page as you.
And every one of those feeds degrades quietly. No prayer API, you get a fallback timetable. No database key, the island simply has no neighbours that day. Nothing that talks to the network is allowed to take the world down with it.
Thumbs
On a phone the left half of the glass walks and the right half looks. Press anywhere on the left and a joystick draws itself under your thumb; push it to the rim to run. Two fingers on the right pinch to zoom. Every finger is tracked by its own id, so walking while looking around — the thing you do constantly — just works instead of fighting itself.
It's a village made of the simplest shapes there are. That was the whole challenge, and the whole fun.