eureka-site/README.md
Meta Vens 70eeae235c README: front door with entry points and live versus planned
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 20:09:04 +02:00

10 KiB
Raw Permalink Blame History

How we built a PS1 dungeon to sell a code-review workflow

Eureka is a Claude Code skill built on one rule: the agent that writes the code does not get to certify that the code works. It needed a landing page. This repo is that page, and it turned into a PlayStation 1 game you scroll through.

Served at https://eureka.gamecult.org/.

Front Door

  • Value: the landing page for Eureka, a scroll-driven WebGL dungeon rendered as a PlayStation 1 game, plus MIT-licensed parts you can lift: a PS1 material and dither pass for three.js, a scroll-on-rails camera pattern, and self-contained organ builders.
  • Problem: explain a code-review workflow (the agent that writes the code does not certify it) as something you travel through rather than read about.
  • Entry points:
    • prototype/index.html: the copy; each <section data-stop> pins one camera stop.
    • prototype/ps1.js: the reusable PS1 kit (ps1() material, framebuffer()); prototype/organs.js: the organ builders; prototype/world.js: the scene and ROUTE; prototype/main.js: the scroll timeline.
    • Run locally: python -m http.server 8765 --directory prototype.
    • BRIEF.md and gpt6-copy.md: the two source briefs; docs/research/landing-claims-audit-2026-10-09.md: copy claims labelled CURRENT, STALE or UNVERIFIED against the doctrine.
  • Live: the page served at https://eureka.gamecult.org/ from prototype/; deployment is in gamecult-ops at runbooks/eureka-prototype-yggdrasil.md.
  • Planned: nothing recorded in this repo beyond refreshing copy flagged STALE or UNVERIFIED in the audit.

Two briefs, neither in charge

We started with two documents, and both are in this repo.

The first was BRIEF.md. The agent that had been running Eureka on a live multi-repo campaign wrote it with no guidance from us, because we wanted the view from the ground. It is good on evidence. It lists real defects, each caught by a pass that did not write the code, sitting behind a green suite. It is also confident about things nobody had asked it to decide, such as which static-site generator to use. We kept the evidence and overruled the rest. The dated rulings at the top of the file record what was overruled.

The second was gpt6-copy.md, a long copy draft that came out of a longer conversation about where Eureka and GameCult are going. The page's text is cut from it, along with its taste for short lines that land one at a time.

A camera on rails

The reference was acko.net. What we took from it was specific: the page background is a WebGL scene, and scrolling moves the camera through it along a fixed path. Reading the page is the same as travelling through it.

So the page is a route. Every section of text pins one camera stop, and unnamed points in between shape the flight. It begins in a hall where a cracked monument reads ALL TESTS PASSING, in front of a wall of green checkmarks. The next stop looks at a floor hatch stencilled GREEN, which has been pried up. Below the hatch, the route runs:

  1. Down a shaft into Eureka's organ chamber.
  2. Through a lattice where Soul's probes flip green nodes to orange.
  3. Along a gallery of specimen cases: the mutation runner's four false greens, and one empty case.
  4. Past an archive where the rules keep their evidence.
  5. Into the vanishing twin's chamber, where Epiphany's scaffolding stands mostly empty.
  6. Up a second shaft into the hall, where the monument has now split along its crack.

One number owns all of it. Scroll position becomes a path parameter u, and u drives the camera, the organs, the probe animation, the staccato lines, and the monument splitting at the end. There is no second clock to drift out of sync.

Going full PlayStation

The first pass rendered at low resolution with a dither, which was tasteful and wrong. Then we found keijiro's Retro3D, a Unity shader of about 20 lines, and went all the way to PlayStation 1. The whole effect comes down to a few tricks, and each one ports to WebGL in a line or two:

  • Vertex snapping. The PS1's geometry chip had no sub-pixel precision, so every projected vertex snaps to a 240-line pixel grid. That is where the wobble comes from.
  • Affine textures. Texture coordinates are multiplied by depth in the vertex shader and divided back out per pixel. That cancels the GPU's perspective correction and gives the PS1's texture swim. Large floors are split into tiles, as PS1 games did, so the warp looks charming rather than broken.
  • 15-bit colour with the console's own 4×4 ordered dither, applied in a final full-screen pass.
  • Everything else: lighting computed per vertex, fog to black, no mipmaps, nearest-neighbour filtering, and half-transparent surfaces for glass and Soul's crystal.

Nothing here is a model file. Every texture is drawn to a <canvas> at load, and every mesh is built in code.

The organs

Eureka's faculties come from Epiphany, the larger system it grew beside and then absorbed. Aquarium already defines how each organ looks, as raymarched distance fields with PBR materials. We demade them:

  • Self is a black core inside gold orrery rails.
  • Soul is a see-through verdict crystal with a white oath light, blue edges and a red risk seam.
  • Hands is a dark tool with three enamel jaws and a hot cutting edge.
  • Imagination is an opal seed wrapped in curling ribbon petals.
  • Life is a teal nautilus shell carrying an ember and memory beads.
  • Eyes is a black-glass lens in blue-metal gimbals, behind spiral aperture petals that narrow as evidence arrives, with cyan evidence sparks.

They sit on Aquarium's own orbit slots, so the camera's circuit around the chamber is the Aquarium layout. The seat where Epiphany kept her Face belongs to the viewer: in Eureka, the operator is a human.

Epiphany's chamber is the vanishing twin: the twin absorbed before birth, whose cells the survivor carries. All eight cages still stand, mostly empty. Eyes has already gone to Eureka; Body and Face rise out of their cages and drift toward her as you pass.

The thing at the far plane

GameCult's mark is a camera aperture, and we wanted it to hang behind the fog as a megastructure. An earlier AI rendering showed the whole thing, evenly lit and front-on, and it read as a medallion. Scale comes from what you can't see. This aperture is a separate sky layer: it follows the camera's rotation and never moves closer. It is tilted so you see it at an angle and held at a fixed depth of fog. Its six blades are habitats (forest, desert, ice, falls, highlands, a night city) around a gold hub, with stations in orbit. Underground it fades to a faint presence. The iris opens as you read.

Small machines that earned their place

  • Framing follows the text. Text panels covered the subject in most shots. We didn't retune 26 camera angles. Each section already says which side its panel is on, so the camera shifts its framing toward the other side, eased between stops.
  • Stops are checked. The page's sections and the route's stops must match one to one, in order. The page checks this on load and says so in the console when they don't.
  • Motion is optional. Without JavaScript, or with reduced motion turned on, it is a readable page of prose. Reduced motion replaces the flight with a still frame per section.
  • Verification ran headless. The in-app browser we were using could not capture the page once it had scrolled, even with rendering paused. Every stop was checked with headless Chrome driven by puppeteer instead, using the ?debug readout and the ?wp=N jump.

Take the toys

The retro 3D adventure is what makes this page special. Sharing toys is what GameCult is for, so it's all MIT: take any of it.

  • The PS1 kit is prototype/ps1.js, about 240 lines. Only a little of it is specific to this page: the brand palette, and two opt-in effects (nodes for the lattice probes and cells for the wall's re-graded checks) that you can ignore or delete.
    • ps1({ map, color, emissive, rim, alpha, ... }) returns one three.js material with vertex snapping, affine textures, per-vertex lighting, rim light, fog and PS1 half-transparency, each switched on by options.
    • framebuffer(renderer) gives you the low-resolution target and the 15-bit dither pass.
    • There are helpers for canvas textures, tiled floors that keep the texture warp in check, and merging many parts into one draw call.
    • Copy it next to three.js, point your meshes at ps1(), and your scene is now 1997.
  • The scroll-on-rails pattern is about 40 lines of main.js: turn scroll position into a path parameter by interpolating between section anchors, then let everything else read that one number. The framing shift away from text panels is another 10 lines on top.
  • The organs in prototype/organs.js are self-contained builders. Each one returns a { group, update(t, k) } object you can drop into any three.js scene, as long as ps1.js comes with it.

If you make something with them, we'd love to see it.

Where things live

File Owns
prototype/index.html The copy. Each <section data-stop> pins a camera stop.
prototype/world.js The scene, the aperture, and ROUTE.
prototype/organs.js The organ demakes and the twin's scaffolding.
prototype/ps1.js The PS1 material, the framebuffer and dither, and geometry helpers.
prototype/main.js The scroll timeline and the frame loop.
prototype/vendor/ three.js 0.186.1 (MIT).

Run it locally by serving prototype/ over HTTP, since ES modules won't load from file://:

python -m http.server 8765 --directory prototype

The Yggdrasil deploy is documented in gamecult-ops, in runbooks/eureka-prototype-yggdrasil.md.