The paintings are the land
In February 2022 I made one room in Adventure Game Studio. The background was a
public-domain painting — David Johnson's Near Squam Lake — with a walkable area
traced onto the shore and exactly one hotspot: a man by the water who says Hey man,
beautiful day for a walk, isn't it?
The idea behind it was that thousands of
masterpieces are out of copyright, and every one of them is already a finished
adventure-game screen with the characters standing in it. Just add hotspots.
Four and a half years later I pointed Claude at that folder. The first thing it
built was the obvious continuation — paintings as rooms, walk around inside one, leave
through a door. Which was when the actual idea showed up: not make the paintings a
thing, but instead use the paintings in a cohesive matter to build a world by connecting
paintings together.
So: drop the rooms. Fourteen landscape paintings, all CC0 from The Met's open access collection, scaled and stitched edge to edge into one continuous world 18,207 pixels wide. You are Friedrich's Wanderer, who has been standing on that rock since 1818 and would like one walk in sunshine. You go right. Nothing stops you.
The one rule that makes it work
The note I was given was it would be nice if the avatar was always the size of the
people in the painting
, and that turns out to be the entire trick. Every painting has
its own horizon and its own eye level, so each segment carries two numbers: hz,
the row where its horizon sits, and k, how fast people shrink going into it.
A figure standing on ground row y is drawn about k · (y − hz) pixels
tall.
Both numbers are interpolated across the 240-pixel blend at each seam, so the Wanderer changes size while he crosses from one painter's world into the next. Get it wrong by a little and he is a giant in Bruegel and an ant in Cézanne.
k is 0.7 and the Wanderer is the
size of the boys.
k is 0.22 and the same man is a
speck. Same rule, a factor of three apart.The unglamorous half
A script asks the Met's API for each painting, downloads it, and estimates where the
horizon is. It is right most of the time. Five of the fourteen are overridden by hand in
a dictionary called HORIZON_FIX, and all fourteen shrink rates were typed in
by eye. Worth saying out loud, because it is the part that never makes it into the
write-up: the automated part got maybe seventy per cent of the way, and the last thirty
per cent was looking at fourteen paintings and typing numbers until the people were the
right size.
The build also scales every painting so its horizon lands between rows 440 and 600, and where a painting's proportions would otherwise crop out its own subject it grows the sky upward or the ground downward by mirroring the edge rows, blurring them and feathering the join over forty pixels. Cheap, invisible, essential.
The day turns gold
One number drives the whole colour arc: how far along x you are, squared, scaling a warm overlay laid over everything. Walk far enough and the light goes amber without a single keyframe anywhere.
Where the light runs out, the Wanderer sits down, and the last thing said to him is the line the man in Near Squam Lake said in 2022. That hotspot is now the ending.
What it weighs
- paintings
- 14, all CC0, all from The Met
- world
- 18,207 px
- playthrough
- 3–5 minutes
- talk
- 14 encounters, 41 lines
- the game
- 430 lines of JavaScript
- total build
- 3.2 MB
No engine, no framework, no build step in the browser — plain canvas, two script
tags, world.json and story.json. The Wanderer himself is zero
image files; he is canvas paths, which is why he can be redrawn at any size the horizon
asks for. He is also painted out of Friedrich's original canvas so that the playable one
can stand where he stood.
Every painting is credited on screen as you walk into it, and all fourteen are listed again at the end. That is not a legal requirement — CC0 asks for nothing. It is the actual subject. Thousands of masterpieces belong to everyone, The Met hands them over through a public API for free, and almost nobody does anything with them.