About this map

I run a D&D campaign on the Sword Coast and wanted a map of it that had weather.

So this is the Sword Coast as a sheet of paper lying in a dark room. You can tilt it, turn it, and zoom in until you find the places where the pen ran dry. The sun crosses it. Clouds drift over it, and you can push them aside with the cursor. It rains and it snows, and at night there is a moon.

Every mark on it was drawn by code. The 2015 original (Mike Schley’s, for Wizards of the Coast) was read only as a survey: where the coast runs, where the mountains and forests sit, which way the rivers go. None of its artwork is shown.

The northern Sword Coast in evening light, seen low from the sea: mountains raised in relief, names lettered by hand.
The north of the sheet, an hour before sunset.

The survey

A program reads the original and writes down geography: a height field, the distance to the coast at every point, masks for forest, marsh, snow and rock, the roads, and 145 rivers as lines with widths.

Heights were the hard part, because a painted map has no elevations. The first version guessed. It knew where the mountains were and grew plausible ones there, and they were wrong: 30% of the crest lines in the drawing landed on a ridge in the terrain. The second version reads the relief out of the artwork itself, from its shading and its crest lines. Now 83% do.

The pen

The ink comes from a simulated dip pen. Its nib has two tines. Press harder and they spread, and the line swells. The nib carries a load of ink that runs down as it writes, so a long stroke turns grey and broken toward its end. Then the pen is dipped and the next stroke starts dark.

About 300,000 strokes draw the coast, the hachures on the mountains, the marsh, the roads and the border. The ink is kept as data: how much of each pixel a stroke covers, how wet the pen was there, and which of three inks it is (iron-gall black, vermilion, indigo). The viewer lays ink over paint itself, every frame. That is why a line stays sharp when you zoom in, and why it catches a low light a little differently from the paper around it.

The coast by the Sword Mountains at the closest zoom: the inked shoreline, an islet, a road in red dashes, hachures on a mountain, single trees.
As close as the map goes: the shoreline, a road in vermilion, hachures, single trees.

The paint

Under the ink is watercolour. Pigments are mixed by subtraction, the way paint mixes, so one wash over another darkens and shifts hue as it would on paper. A wash pools darker at its edge. Pigment settles into the grain of the sheet.

The trees

There are about 283,000 of them. Each tree is placed once and used three times: the pen draws its crown, the brush colours it, and the viewer lights it as a small dome. It is the same tree each time, so the outline, the colour and the highlight line up.

The lettering

The names are written too. An alphabet was built stroke by stroke for a broad-edged nib: Roman capitals for cities, an italic for places, a looser italic for rivers and seas, and a small plain hand for the smallest names. Every letter has at least three shapes, and the hand never writes the same one twice running. The whole thing was then exported as a font, Stonebrook Quill, which sets the headings on this page. It has a page of its own.

The viewer

The page is Rust compiled to WebAssembly, drawing with WebGL2 directly. There is no engine and no three.js. The only JavaScript is the few lines that load the module.

The land is a height field cut into chunks that get finer as you come closer. Shadows are found by marching from each point toward the sun across that height field, and the work is spread over several frames. The sea has a swell that bends around headlands, worked out once at start-up by solving for how waves arrive from open water. Rivers carry water downhill along the lines the pen drew. The clouds are volumes, ray-marched, over a small fluid simulation whose only job is to remember where you pushed.

The target was 60 frames a second at 1440p. At first a frame took about 25 milliseconds. It takes about 13 now, mostly from drawing the scene in three passes where there were eight, and from dropping the resolution a little when a frame runs long. On a fast connection the painted sheet appears in about a second. Full detail is about 25 MB and streams in behind it.

Rain clouds over the Moonshae Isles, seen from the south-west.
Rain over the Moonshaes.

What went wrong

The sheet used to sit on a desk. The desk was drawn as a full-screen pass that wrote its own depth, the scene was multisampled, and at a low angle the two disagreed. Flat sea came out in horizontal streaks. The desk went.

The rivers were invisible, then too blue, then darker than the sea they ran into. A script now measures them against the sea, and they have to match.

Some of it is still wrong. The hill country reads as fields of round mounds. The forests are flat on top. Ten rivers end nowhere.

How it was built

With Claude Code. One session ran the project and handed work to other agents: the survey, the pen, the paint, water, clouds, lettering, sound, the phone layout. Each agent checked its own work by rendering frames in a headless browser and looking at them.

My part was looking. Most of what I typed was a sentence long. The rivers are a bit blue. The foam should fade as the camera rises. You can probably get rid of the desk.

The rain, wind, surf and thunder come from ElevenLabs and the music from Suno. Sound stays off until you turn it on. The font was exported with the fontations crates.

The stack

Elliot Bonneville · elliotbonneville.com · @elliotbnvl