Lab / notes
How a shared world would run for real
The database, the one-memory rule, moderation, and how the island could keep growing as people arrive.
Both demos run entirely in the browser. The only thing that needs a server is the part that makes One Memory shared: storing each memory and handing the album to the next visitor. Here is how that works on williamkamfar.com, what is already built, and what I'd add as more people arrive.
What's built
- The island: a 512 by 512 generated heightmap drawn with a voxel-space renderer at 320 by 180, quantized to a 44-colour palette with ordered dithering. Trees, ghosts and photo markers are depth-tested sprites.
- A memory is where you stood: position, heading and how far you tilted the camera, the walk that got you there (at most about 400 samples of position and heading), a caption and the time the server saved it. That's a few kilobytes. The photo itself is never uploaded. The island is deterministic, so anyone's browser renders the same photo from those numbers, along with its depth map. Nothing about the visitor is stored.
- Storage picks the first option that works: the Claude artifact database when the page runs as a Claude artifact, then this site's
/api/memories, then the visitor's own browser. - The API is a Cloudflare Worker backed by D1. I tested it locally with Wrangler: two separate browsers each left a memory, each saw the other's ghost and photo, and a second memory from the same browser was refused with a 409.
visitor's browser Cloudflare
+-------------------------+ HTTPS +--------------------------------------------+
| one-memory.html | --------> | static assets: the site in dist/ |
| island, renderer, UI | +--------------------------------------------+
| all run client side | GET/POST | Worker /api/memories |
| localStorage: a random | --------> | checks the pose, walk and caption; |
| token for this browser | | one memory per token, 3 per network a day |
+-------------------------+ +----------------------+---------------------+
|
+----------------------v---------------------+
| D1 (SQLite): the memories table |
| pose, walk, caption, place, time |
+--------------------------------------------+
in the browser, from the album:
poses --> photos + depth rendered --> splats placed in 3D --> fit colour and opacity --> compare
next: R2 for photos, a baked splat file,
Turnstile on POST, live presenceForgetting, seasons and the rebuilt island
- The island forgets. A memory's strength halves every 30 days. Ground stays in full colour for about three weeks after its last photo, then fades back into the contour sketch over the next two months. The only way to keep a place is for someone new to photograph it.
- The island changes. Its colours follow the real calendar: flowers in the meadow in spring, orange woods in autumn, a lower snow line and a frozen lake in winter. The camera always sees the island as it really is on the day the photo was saved (the UTC date), even where your eyes see the sketch. It sees only the island: terrain, trees and trail posts, with no hikers or floating frames, and with the clouds and water held still.
- The album doesn't forget. Every photo and its depth map turn into Gaussian splats: one soft, coloured ellipse per 2 by 2 block of pixels, placed in 3D at the measured depth. A fit then adjusts each splat's colour and opacity by gradient descent (Adam), one photo per step, so that the splats seen from each photographer's spot reproduce that photo. Recent photos are weighted more, matching the 30-day half-life.
- Rebuilt against real. The viewer renders the reconstruction and today's island from the same camera, and reports how much of the ground in view is remembered and how much of that has changed since it was photographed. Drag the time slider back and the reconstruction shows the island as it was remembered on that date.
- What's simplified. Full 3D Gaussian splatting starts from points found by structure from motion and also optimises each Gaussian's position, size and 3D shape, with colour that changes with viewing angle. Here positions and sizes come straight from the depth maps, splats are flat ellipses facing the screen, and only colour and opacity are fitted. It runs in plain JavaScript in about 11 ms a step, around 40,000 splats for four photos.
The rules, and how they're enforced
- One memory each. The browser keeps a random token and the database allows one memory per token. Clearing site data gets around that, so each network is also capped at 3 memories a day, counted with a salted hash of the IP address rather than the address itself.
- Only real views of the island. The server stores a pose, never pixels, and every photo is rendered from its pose, so nobody can put a picture of their own in the album. A script can still choose where to stand and what caption to write. The walk must be a walk: neighbouring samples more than 60 units apart, or a walk that ends somewhere other than the photo, is refused. Memories saved before this change (none on the live site) keep the pixels they stored.
- Captions are the risk. They're plain text, 80 characters, rendered as text. A protected
/api/memories/hideendpoint takes one down without deleting it.
What would change as it grows
| Step | What | Why |
|---|---|---|
| 1. Launch | The code in this repo: one Worker with static assets, one D1 database | Free tier; a memory is a few kilobytes, so D1's free 500 MB holds well over 50,000 |
| 2. Photos from poses | Done: memories store where the camera stood, and browsers render the photos | Storing pixels cost about 90 KB a memory and let a script upload any picture it liked |
| 3. Bake the reconstruction | A scheduled job fits the splats on the server, with positions, sizes and anisotropic shapes optimised too, and publishes one compressed splat file with levels of detail | Every visitor currently rebuilds from scratch, and the browser fit is capped at 160,000 splats |
| 4. Abuse | Cloudflare Turnstile on the save, a report button, a short review queue | The token and network cap stop casual repeats, not a determined person |
| 5. A growing world | Keep the remembered area as a small grid on the server; open new places while the island is more than 25%, 50% and 75% remembered, and close them again if it fades | The world should change because people came, not because I shipped an update |
| 6. Live presence | A Durable Object per island: people walking right now appear as faint lights | Ghosts are the past; this adds the present without chat |
| 7. Doors | Use the Loop Trail's portals so a memory's photo becomes a door into that exact view | Joins the two experiments: the island grows inward as well as outward |
Privacy
No accounts, names or emails. The only identifiers are a random token the browser made up and a salted IP hash used for the daily cap; an hourly job deletes the hashes after about a day. Captions are public, and the page says so before you leave one.