FIELD GUIDE № 20 · a DAINER.AI build note

How the hill was built.

One concept study, one signature move: a single climb value between 0 and 1 that drives the vegetation, the fog, the air temperature and the light at once. Everything you see on the line is downstream of that one number. Here is the brief it started from, the engine at the centre, and what each critique pass caught.

SITE · bukit-bendera SIGNATURE · drag-driven parallax biomes SCENE · procedural canvas 2D CDN · none PASSES · 5
01The brief it received

A hill railway you climb with your hand.

The director's brief was tight. It named the place, the palette, the type and one thing to prove. The rule for this wave: start from a world, not a wireframe — so the whole page had to be the Penang Hill funicular, not a page about it.

  • NameBUKIT BENDERA LINE — the hill railway, Penang, 833 m
  • ConceptDrag the funicular car up the hill and feel the climate change — station by station, fog thickens, air cools, jungle turns to mist.
  • Palettedawn blue rail red jungle summit mist
  • TypeLibre Caslon Text display · Mulish text
  • SignatureOne progress value (drag the car or scroll) drives layered parallax vegetation, fog density, temperature readout and light. The altitude gauge is the scrollbar.
  • VoiceA conductor who has run the line forty years.
02The signature technique

One value. Five keyframes. The whole mountain.

The climb is a single smoothed number, progress, eased toward the scroll position every frame. Instead of animating dozens of properties by hand, the scene stores five biome keyframes down the hill — sky colours, vegetation tint, fog and cloud density, particle colour, temperature — and interpolates between them by progress. Ask the engine for any property at any height and it hands back the blend. The temperature gauge, the fog banks and the tree colour are all reading the same table.

// biome keyframes down the hill: p, sky bands, veg, fog, cloud, particle, temp
var K=[
 {p:0,   /* Air Itam  */ fA:.05, cA:0,  t:31, /* … sky/veg colours … */},
 {p:.28, /* fern slope */ fA:.13, cA:.05, t:28},
 {p:.55, /* montane   */ fA:.30, cA:.36, t:24},
 {p:.8,  /* cloud line*/ fA:.43, cA:.6,  t:21},
 {p:1,   /* summit    */ fA:.5,  cA:.8,  t:19}
];
function seg(p){ // find the two keyframes p sits between
  var i=0; for(;i<K.length-1;i++){ if(p<=K[i+1].p) break; }
  var a=K[i], b=K[i+1], u=(p-a.p)/((b.p-a.p)||1);
  return[a,b,clamp(u,0,1)];
}
function num(key,p){ var s=seg(p); return lerp(s[0][key],s[1][key],s[2]); }
// …so fog, cloud, temperature, tree tint all ask ONE table:
var fA=num('fA',p);  // fog alpha at this altitude
var temp=num('t',p);  // °C, drops 31 → 19 up the line
Excerpt from the site's own source — the five-keyframe climb table and its interpolator. The full array carries the sky, ridge, fog and canopy colours too; trimmed here to the shape.

Because one number owns the mountain, dragging the car, scrolling, and pressing the arrow keys are three doors into the same state — no separate animation timelines to keep in sync. The counter-weight car that slides down past you at the passing loop is the same idea: a small window on progress around the halfway mark, faded in and out with a sine.

03What each pass found

The loop is the level.

The first draft is never why a scene looks finished. Five screenshot passes — desktop and mobile, top, middle and bottom — read like a hostile art director, each ending in one fix and one new complication.

Pass 01 — first light

Build the world, kill the void

FoundThe raw scene risked reading as a flat black terrain; the hero type floated with no anchor to the hill.
FixedLayered ridges, treeline, canopy and near-fronds with fog-mixing by altitude; a bottom scrim and text-shadow under the hero so the display type sits on the scene.
Pass 02 — the instruments

Make the climb legible as data

FoundThe atmosphere moved but the story of rising wasn't measurable; stations arrived with no rhythm.
FixedThe altitude gauge became the scrollbar; air-temperature and biome readouts tied to the keyframe table; station plaques reveal on stagger. Added a warm light shaft the car casts as fog thickens.
Pass 03 — the floor

Everyone rides, motion optional

FoundThe car was drag-only; nothing for a keyboard, and reduced-motion users would get a dead canvas.
FixedThe car became a labelled slider — arrow / Page / Home / End keys with a live aria value; a complete static frame under prefers-reduced-motion; grain overlay and the idle dusky-monkey easter egg at the passing loop.
Pass 04 — the small screen

Where the instruments collide

FoundOn mobile the fixed instrument cluster covered the lower lines of the station prose; the altitude gauge overlapped the hero paragraph and the footer; the printed page weight was wrong.
FixedA reserved right lane for the gauge, plaques anchored high to clear the bottom cluster, and an honest byte count.
Pass 05 — arrival

Two cars pass at the loop

FoundAt the colophon the ride's instruments were still hovering over the reading; the copy promised two cars passing that you never saw.
FixedThe fixed instruments dim away once you reach the build note's kin — the footer. And the counter-weight car now slides down past you at the passing loop, exactly where the conductor says it should.