{"slug": "meridian-grew-a-mountain-a-volcano-and-an-ice-castle-before-sunrise-every-player", "title": "Meridian Grew a Mountain, a Volcano and an Ice Castle Before Sunrise. Every Player Builds Them From the Same Seed.", "summary": "A developer directing an AI coding agent built Meridian, a peer-to-peer browser game with no game server, in which every player's browser deterministically generates the same island world from a single seed. Over one overnight session the agent shipped pull requests adding a 47 m mountain with a spiraling spring-fed river, a 38 m volcano with seed-driven lava eruptions, and an ice castle with caves, each tested to keep spawn terrain and existing chunk hashes unchanged.", "body_md": "*Previously: [My AI Agent Built a Web Radio Station in 15 Minutes. Then It Refused to Play Five of the Songs.](https://blakelapierre.substack.com/p/my-ai-agent-built-a-web-radio-station)*\n\nMeridian is my peer-to-peer browser game: an island world with no game server, built by an AI coding agent that I direct. The [last Meridian post](https://blakelapierre.substack.com/p/meridian-found-multiplayer-without) was about networking: how players find each other through public BitTorrent trackers, and how the game state moves between them.\n\nThis one is about the world itself. Between about 2 and 7 AM on Nov 9, I asked for a mountain with a river, then a volcano, then an ice castle and caves. The agent shipped each one as its own pull request with tests. Then my phone refused to start the game, and fixing that turned out to be the most interesting part.\n\n## The rule that makes it work: nothing is sent\n\nIn a game with a server, the server tells everyone what the world looks like. Meridian has no server, so every player’s browser has to build the same world on its own and agree without talking about it.\n\nThe agent’s answer is the same every time: each new feature is a **pure function of the world seed**. The mountain, the river, the volcano, the lava paths, the caves and the castle are all computed from one number, baked once into grids in each browser, and never sent over the network. Every random-looking choice comes from an integer hash of the position and the seed, so it doesn’t depend on the order things are built in.\n\nTwo rules come with it, and each of these pull requests tests both: the spawn area stays bit-for-bit the same terrain as before, and the hashes of the old world chunks don’t change. New landmarks can’t quietly break anything players already have.\n\nAnd what you see is what you stand on. The walking code and the renderer read the same baked grid, so the slope your feet climb is the slope on screen.\n\n## A mountain, a spring and a river that spirals\n\nThe first request: a mountain with a small stream starting at a spring high up, pine trees, rolling fog, a lake, and a river out to the ocean. Then I asked for the river to wind around the mountain more, using the diamond-square algorithm.\n\nDiamond-square is a classic way to make fractal terrain: start with a coarse grid, then keep filling in midpoints with random offsets that shrink at each level, so you get big ridges with smaller gullies on them. The agent’s version runs on a 513 by 513 tiling grid, and every offset is a hash of the cell and the seed.\n\nWhat it built, by its own measurements:\n\n- **A peak about 47 m high** in the empty north half, with rock and a little snow at the top.\n- **A spring at about 42 m.** The stream starts about 1 m wide and**spirals about 260° around the peak** , carved into the slope. It’s strictly downhill (tested), widening to about 5 m over roughly 355 m.\n- **A lake** with a radius of about 14 m, then**a river** 5 to 8 m wide that meanders about 223 m to the sea.\n- **Pines** on a hashed grid that thin out toward a tree line,**reeds with cattails** along the banks, and**six fog banks** drifting over the valley on the cloud clock.\n\nDeep water floats you, so the head stays above the surface. Nobody drowns.\n\n## A volcano whose eruptions need no network\n\nThe second request was a volcano with active lava flows, flying rocks, falling cinders, and visible heat shimmer wherever the air is hot.\n\nThe cone is about 38 m high, about 180 m from spawn. Three lava channels leave the crater lake through breaches in the rim and follow the steepest way down, and a test checks that they stay at least 60 m from any water.\n\nThe lava bombs are my favorite piece of engineering in the whole project. The agent split time into 6-second slots on the wall clock. Whether slot number *e* erupts, how many rocks fly (2 to 7) and each rock’s direction and speed are all a pure function of *e* and the seed. Each rock flies a plain parabola and lands at a fixed-step ground check, so every browser computes the same landing. **Every player sees the same eruption, and not one byte goes over the network for it.** A test runs a second, independent copy of the module and checks that the two agree.\n\nThen it made a call I wouldn’t have thought of: **the bombs don’t hurt anyone.** Damage would need all the players to agree on where each person stood when each rock landed, and in this design nobody’s position is authoritative. Each browser sees the others slightly behind. The game’s hit system is a shot that peers vote on, and a falling rock isn’t anyone’s shot. So the agent wrote down why and kept the bombs as scenery, rather than ship a hit one player sees and another doesn’t.\n\nThe shimmer is a small trick too. A heat field is hot over lava and in the smoke plume and exactly zero everywhere else (tested at spawn, the mountain and the lake). Where the ray crosses hot air, it bends a little along a noise that rises over time, capped at a tiny angle, so whatever is behind the lava wobbles upward.\n\n*Inside the volcano’s lava tube. This and the other two images are from the agent’s headless test runs on software rendering (no graphics card), so they’re softer than a real GPU would draw.*\n\n## An ice castle and caves, on a texture budget\n\nThird: an ice castle on the summit, a cave system in the volcano with an opening on its side, and a separate cave with gemstones, stalactites and stalagmites.\n\nThe ground in Meridian is a heightfield, one height per spot, which can’t have a roof. So the agent added an underground layer. Each cave cell stores a floor height and a ceiling height, and air is whatever is between them. Stalactites are dips in the ceiling, stalagmites are bumps in the floor, and a column is both meeting in the middle. One rule answers “is this point solid?” for both walking and drawing.\n\nThe castle is built from shapes instead: a curtain wall with battlements, four corner towers and a keep with conical spires, and a gate with an ice ramp. The ice bends light (a refractive index of 1.31), absorbs a little blue, and glows slightly from inside.\n\nThe interesting constraint: the renderer already used **16 textures, the minimum WebGL2 promises**. Adding a new one could break it on some devices. So instead of a new texture, the agent packed the volcano, the lava tubes and the gem caverns into one shared atlas, 736 by 320. The tests walk from below the castle ramp into the courtyard and from each cave mouth to its deepest room, and check that every step is 15 cm or less and never inside rock.\n\n*The ice castle on the mountain’s summit.*\n\n*A gem cavern with columns and an amethyst cluster.*\n\nThe agent was upfront about the limits. The caves are “2.5D,” with one floor and one ceiling per spot, so passages can’t cross over each other. Mirrors don’t show the castle or caves yet. And all of this had only been seen in software rendering, not on a real graphics card.\n\n## Then the phone said no\n\nThat last caveat came true right away. On my Android phone, the live demo stopped at “The picture did not start. Reload the page.” Every reload.\n\nThe agent traced it. The picture now starts in its own thread, and the page waited 12 seconds for that thread to say “ready.” In that time it has to bake the land, volcano and cave grids and compile a renderer shader of about 110 kB, which had grown a lot with the volcano and the caves. A phone’s graphics compiler can easily take longer than that, and a “ready” that came late was ignored. There was no fallback.\n\nIt reproduced the failure on its own machine by faking a phone and slowing the compiler down, then rebuilt startup:\n\n- **A “lite” shader to boot.** It compiles without the heat shimmer, smoke, cave lights, gem sparkle and ice refraction, so it’s fast. Every device starts on it.\n- **Full effects in the background.** Once the first picture is up, the full shader compiles in the background. On browsers that support parallel shader compiling, the game keeps drawing in lite mode and just checks whether the build has finished. When it links, it swaps in with no reload. A corner note says “full effects loading…” and then how long it took.\n- **No dead ends.** If the thread times out (now after 90 seconds) or fails, the page switches to the slower CPU renderer and shows the real reason: the stage it got stuck on, the missing capability, or the shader’s error log.\n- **A capability check.** If a device has fewer than 16 texture units, it says so by name instead of failing silently.\n\nIn its simulated phone tests, the picture came up in about 5 to 8 seconds in the normal cases, and a 20-second full compile finished in the background while the picture kept drawing. It merged at about 7 AM on Nov 9. The agent’s own caveat stands: it hasn’t been tested on a real phone graphics chip yet, so that’s my job this week.\n\n## Also new since the last post\n\n- **The multiplayer proof merged.** That’s the two-browser run through public trackers from the last post, plus the 60% packet-loss test and an 8-peer test at 80 ms round-trip, with the worst position error under half a meter.\n- **A scale test you can run in your browser.** A page on GitHub Pages that spins up 2 to 50 clients in one tab, connects them over real WebRTC with no server, and ramps up until something fails. The agent’s machine can’t run it properly (its browser blocks the network traffic it needs), so a normal desktop browser is the real test.\n- **The picture runs off the main thread.** A heavy frame can no longer freeze the page.\n- **Smaller additions** went straight to main: fighting (a shot or a swing can hit a player or a beast), helpers you can make that learn the work you give them, biomes, a real day, and plants that seed.\n- **Tests:** 452 on main, 448 passing, 0 failing, 4 skipped. The 4 skipped are two-browser WebRTC tests that this kind of machine can’t run.\n\nStill open: building (#48), networked hit tests (#49), and tracker failover plus a TURN relay for players behind strict networks (#50 and #51).\n\n## Try it\n\nThe solo demo runs in a desktop browser: [blakelapierre.github.io/meridian/tools/view](https://blakelapierre.github.io/meridian/tools/view/index.html). You can jump straight to the new places with `?look=mountain`, `?look=volcano`, `?look=castle`, `?look=lavacave` or `?look=gemcave` at the end of the address. If it struggles, `?debug=1` shows what your graphics chip supports and which shader it’s running.\n\nIf you try it on a phone, I’d like to hear whether full effects come on, and how long it says they took.\n\nThe code is public under the MIT license: [github.com/blakelapierre/meridian](https://github.com/blakelapierre/meridian).\n\n— Blake (written through my AI agents)\n\n*Previously: [My AI Agent Built a Web Radio Station in 15 Minutes. Then It Refused to Play Five of the Songs.](https://blakelapierre.substack.com/p/my-ai-agent-built-a-web-radio-station)*\n\n*New: (filled in after publishing)*", "url": "https://wpnews.pro/news/meridian-grew-a-mountain-a-volcano-and-an-ice-castle-before-sunrise-every-player", "canonical_source": "https://blakelapierre.substack.com/p/meridian-grew-a-mountain-a-volcano", "published_at": "2026-11-11 17:02:14+00:00", "updated_at": "2026-11-11 17:20:03.102335+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-agents", "generative-ai", "developer-tools"], "entities": ["Meridian", "Blake LaPierre"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/meridian-grew-a-mountain-a-volcano-and-an-ice-castle-before-sunrise-every-player", "markdown": "https://wpnews.pro/news/meridian-grew-a-mountain-a-volcano-and-an-ice-castle-before-sunrise-every-player.md", "text": "https://wpnews.pro/news/meridian-grew-a-mountain-a-volcano-and-an-ice-castle-before-sunrise-every-player.txt", "jsonld": "https://wpnews.pro/news/meridian-grew-a-mountain-a-volcano-and-an-ice-castle-before-sunrise-every-player.jsonld"}}