---
url: "https://github.com/adilzhanY/berlin-walk/blob/main/PROMPT.md"
title: berlin-walk
source_kind: github
author: adilzhanY
captured: "2026-09-02T12:32:29+00:00"
comment_tree: false
topics: [ai-impact]
summary: An AI agent built a full 3D Berlin walkthrough in 4 hours using raw WebGL2 and real OSM data, showcasing autonomous coding capabilities and cost metrics.
status: ok
---

# adilzhanY/berlin-walk

- stars: 0
- language: JavaScript
- topics: —
- license: MIT
- created: 2026-09-02T01:23:02Z
- archived: False

---

# Berlin Walk

**A walkable, flyable 3D reconstruction of central Berlin in the browser, from a single link. Raw WebGL2, real OpenStreetMap data, no engine, no libraries. Built end to end by Claude Fable 5.1 in one night.**

**Try it: https://adilzhany.github.io/berlin-walk/** (WASD to walk, F to fly)

![Flying through the Brandenburg Gate and up over Mitte](https://raw.githubusercontent.com/adilzhanY/berlin-walk/HEAD/docs/flight.gif)

You spawn on Pariser Platz in front of the Brandenburg Gate. Walk east along Unter den Linden to Museum Island and the TV Tower, south to the Holocaust Memorial and Potsdamer Platz, north to the Reichstag and the Spree. Or press F and fly over all of it.

## The experiment

The whole project comes from one prompt, [PROMPT.md](PROMPT.md), handed to Claude Fable 5.1 inside Claude Code with the instruction to ask nothing and keep going until the site was live. The rules were strict on purpose:

- Rendering in raw WebGL2. No Three.js, no wrapper of any kind. Shaders, buffers, camera, matrices, culling, shadows, post processing all written from scratch.
- Physics from scratch: a capsule character controller against building walls, stairs and curbs, no walking through walls or into the river.
- Audio from scratch on the raw Web Audio API: traffic, water, birds, U-Bahn rumble, footsteps that change on cobblestone, asphalt and grass. Everything synthesised, no audio files.
- The map is real. Download OpenStreetMap for the bounding box, parse the XML with your own parser, triangulate every polygon with your own ear clipping, extrude every building.
- Ship as static files under 25 MB. No backend, no CDN, no runtime dependency.

Everything below was measured, not estimated.

## What it looks like

| | |
| --- | --- |
| ![Pariser Platz and the Gate](https://raw.githubusercontent.com/adilzhanY/berlin-walk/HEAD/docs/screenshots/01_spawn_pariser_platz.png) | ![Unter den Linden](https://raw.githubusercontent.com/adilzhanY/berlin-walk/HEAD/docs/screenshots/03_unter_den_linden.png) |
| Spawn point, Pariser Platz | Unter den Linden with its lindens |
| ![Holocaust Memorial](https://raw.githubusercontent.com/adilzhanY/berlin-walk/HEAD/docs/screenshots/04_memorial.png) | ![Berlin Cathedral at 18:30](https://raw.githubusercontent.com/adilzhanY/berlin-walk/HEAD/docs/screenshots/05_cathedral_evening.png) |
| Inside the memorial field, 2711 stelae | The Cathedral in evening light |
| ![Night](https://raw.githubusercontent.com/adilzhanY/berlin-walk/HEAD/docs/screenshots/06_pariser_platz_night.png) | ![TV Tower](https://raw.githubusercontent.com/adilzhanY/berlin-walk/HEAD/docs/screenshots/07_tv_tower.png) |
| Night, windows lit by a per window hash | The Fernsehturm from Karl-Liebknecht-Strasse |

## Claude Fable 5.1 in numbers

One session, one agent plus two short lived subagents (data pipeline, audio), no human code. Effort was set to high for the first hours and dropped to medium after the session limit was reached at 2:40 in the night and the run resumed.

| Metric | Value |
| --- | --- |
| Wall clock, prompt to live URL | 4 h 08 min (23:17 to 03:25) |
| Lines written | 7,895 (JavaScript, GLSL inside JS, HTML, Markdown) |
| API calls in the main session | 137 |
| Tokens processed | 34.6 million (33.8 million of them cache reads) |
| Cost of the main session | $27.49 |
| Subagents | 363k tokens on top, roughly $3 to $8 |
| Commits | 5 to reach the live site |
| Screenshots taken to check its own work | about 30, through a headless browser it wrote itself |

### Where the tokens went

Almost all of the 34.6 million tokens were prompt cache reads: the agent re-reads its own growing context on every call, and cache reads are priced at a fortieth of fresh input. The tokens it actually generated, 236 thousand, are what the code and the reasoning cost.

```mermaid
pie showData title Tokens by type (main session)
    "Cache reads" : 33770227
    "Cache writes" : 554852
    "Output" : 235622
    "Fresh input" : 33425
```

### Where the dollars went

The picture flips for money. Output tokens are the expensive ones, so writing 7,900 lines of code and shaders was the largest line, and the 33.8 million cached tokens cost less than a coffee.

```mermaid
xychart-beta
    title "Cost by token type, USD (main session, total 27.49)"
    x-axis ["Output", "Cache reads", "Cache writes", "Fresh input"]
    y-axis "USD" 0 --> 14
    bar [11.78, 8.44, 6.94, 0.33]
```

### What it wrote

```mermaid
xychart-beta
    title "Lines written by area"
    x-axis ["Data pipeline", "Engine core", "Rendering", "Game layer", "Shared and boot", "Docs"]
    y-axis "Lines" 0 --> 3200
    bar [2883, 1487, 1162, 882, 864, 464]
```

The data pipeline is the largest piece: an OSM XML tokenizer, feature extraction for buildings, roads, water, parks, trees, rails and landmarks, ear clipping with holes, extrusion and roofs, the bespoke Gate, Reichstag, Cathedral, TV Tower and memorial generators, and the binary tile bundle writer with its unit tests.

### How the time was spent

```mermaid
gantt
    title One night, 23:17 to 03:25
    dateFormat HH:mm
    axisFormat %H:%M
    section Setup
    Read prompt, tooling check, plan       :23:17, 23:35
    section Data
    Overpass fetch and retries            :23:24, 23:45
    Pipeline (subagent)                   :23:40, 02:57
    section Engine
    Math, GL, tiles, camera, controller   :23:35, 00:30
    Materials, sky, shadows, trees, post  :00:30, 01:40
    Audio (subagent)                      :23:42, 23:50
    section Game
    Intro, landmarks, minimap, photo, share :01:40, 02:40
    section Verify and ship
    Screenshots, fixes, quantisation bug  :02:45, 03:15
    Build, README, GIF, GitHub Pages      :03:15, 03:25
```

Note the gap between 02:00 and 02:45: the session hit its usage limit, the pipeline subagent was killed mid file, and the run resumed at 02:45 with effort lowered to medium. The subagent picked up where it stopped.

### What went wrong and got fixed by the model itself

- Overpass returned 406, then 504. It changed the content type, then rewrote the query to exclude route relations that were pulling in bus lines across the whole city.
- Headless screenshots never fired because the page runs a render loop forever. It wrote a DevTools protocol client on Node's built in WebSocket instead of relying on the `--screenshot` flag.
- Ground layers z-fought. It inspected the binary bundle, found that 1/32 m vertex quantisation had collapsed six ground layers onto two heights, and moved 531 of 532 tiles to a 1/128 m grid.
- The TV Tower was invisible from the Gate. It queried the loaded tile from inside the page, proved the tower was drawn, zoomed into the pixels, and found the sunlit concrete matched the sky brightness. Lighting rebalanced.
- The character controller was tested by scripting key presses into the simulation and checking the final position against known wall coordinates.

The honest gaps: no phone or integrated GPU was available, so those frame rates are unmeasured. The ground is flat with visual curbs only, a documented decision. And there is no Fable 5 run to compare against, which would have been the interesting chart.

## What is real and what is generated

Real, straight from OpenStreetMap (52.508 to 52.525 N, 13.365 to 13.405 E): every building footprint with its height, floors, roof shape and colour when tagged, including courtyards and building parts; the road network with widths, lanes, one way flags and surfaces; the Spree and the Spreekanal, parks, the mapped trees and tree rows, railways, bridges, stations; the outlines of the landmarks.

Generated: facades (window grids, shop fronts, cornices, lit windows at night, all in the fragment shader from a per building seed), roofs, the domes, columns and the quadriga, the TV Tower, the 2711 stelae on their undulating ground, lane markings, cobblestones, grass, water, sky, sun position from date and latitude, shadows, fog, and every sound.

## Controls

WASD or arrows to walk, mouse to look, Shift to run, Space to jump. On a phone the left half of the screen is a joystick and the right half looks. Gamepads work.

- F: flying mode. Fly where you look, Space up, Ctrl down, Shift faster.
- P: photo mode. Hides the UI, freezes time, time of day slider, saves a PNG.
- M: mute. Sound starts after the first click or key press.
- [ and ]: nudge the time of day.
- Share: copies a link that opens exactly this view.
- Stats: frame time, GPU time, draw calls, triangles, loaded tiles.

Get within 40 m of a landmark and a card slides in with one sentence of history. Find all eleven for the completion screen.

## Performance of the site itself

| Metric | Value |
| --- | --- |
| Download | 10.5 MB uncompressed, 4.55 MB gzip |
| Tiles | 532 (28 by 19, 100 m each) |
| Triangles | 308,100 in the bundle, about 149k drawn per frame |
| GPU time per frame, 1080p, high tier | 2.3 ms on an RTX 5070 (60 fps, vsync capped) |
| Pipeline | 2.3 s from the 22.6 MB Overpass extract to world.bin |

Three quality tiers (high, medium, low) are chosen from the measured frame time in the first three seconds; force one with `?quality=low`.

## Building it yourself

    npm install              # esbuild, the only build time dependency
    npm run fetch            # Overpass XML into data/raw/
    npm run world            # parse, generate, tile, write public/world.bin
    npm test                 # pipeline unit tests
    npm run serve            # http://localhost:8080/
    npm run build            # dist/, ready for GitHub Pages

The architecture, the data formats and every deviation from the plan are in [docs/PLAN.md](docs/PLAN.md). `tools/screenshot.js` is the headless verification harness.

## Credits and licence

Map data copyright [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors, ODbL. The page carries the same attribution in its footer. Code under the MIT licence.
