BONEYARD · part · layer
The sky
src/22-sky.js · one module, no third-party code
ParametersFactory
How it works
Each star is a camera-space point (x, y, z) with y above the ground plane and z between zNear and zFar. A fixed seeded generator assigns one of three apparent magnitudes and places a restrained minority near an oblique broad lane; this creates astronomical hierarchy and composition without claiming a real constellation or adding labels. It projects to (vpX + f * x / z, vpY - f * y / z), the same projection as the row. Each frame z decreases by the camera's travel times the plane's factor (far plane slow, near plane fast); a star that passes zNear respawns at zFar, so the field never thins. The buffers are published on ctx.share.stars so HYPERSPACE and JUMP can streak the very same points, and ctx.share.warp (written by them) dims the dots as the streaks take over.
The horizon band is a vertical gradient from transparent down to the hour's tint at the horizon line. The tint is a linear blend between the two nearest of 24 stops (one per hour), so it drifts continuously through the evening. The core also mirrors the tint to --horizon-tint for the CSS floor.
Shake: HYPERSPACE and JUMP write ctx.share.shake ({x, y} css px) with a timestamp; every layer draws at that offset. The sky ticks first among the layers, and it clears any stamp older than 60 ms. ctx.share.punch is a transient 0..1 (writers spike it and decay it); the sky also folds in the switch flash (ctx.share.flashAt).
Provenance
- technique
- deterministic two-plane 1/z starfield with three fixed magnitude classes and a broad oblique stellar lane, drifting with camera z above a 24-stop horizon band tinted by the visitor's local hour
- lineage
- Star Raiders (Atari, 1979) and Galaga (Namco, 1981) multi-plane stars
- original
- the stars share the row's vanishing point and camera, so they stream outward at cruise and are the SAME points HYPERSPACE streaks (published on ctx.share.stars); the horizon band is a clock, not weather: 24 colour stops indexed by the real local hour (pre-dawn indigo, dawn amber, day pale, dusk orange, night blue-black). The ground stays black at every hour and the band's alpha caps at bandAlpha, so daytime reads as a pale grey-blue line on the horizon, never as daylight; the ramp is NOT clamped to dusk-night (clampDay: false) because at this alpha the day stops read as "a bright horizon at noon", which is honest. The seeded composition has sparse bright anchors, a middle field and fine distant dust, with no random flicker; reloading or drawing a still produces the same sky. Set clampDay to hold the daytime tint near dawn or dusk. In Full the stars fly with the row (speedGain plus a cruise, and warp multiplies it through HYPERSPACE), and at speed the near plane draws as short streaks. The sky is also the housekeeper of the shared punch: a stale ctx.share.punch / shake (no writer this frame) is zeroed here, so a switched-off room never leaves the world shaking.
- not
- twinkle (churn), a skybox, a moon, weather. No random flicker of any kind.
- deps
- none · Canvas 2D · 2026-09
- budget
- 0.12 ms/frame JS avg (1.2 max) @ 1440x900 dpr 1, headless desktop Chromium (2026-09-30); raster not in this number; phone TBD
- api
- mount(canvas, params, ctx) -> { tick(dt, t, cameraZ, pointer), resize(w, h, dpr), still(t), destroy() }
- license
- MIT, Desert Data Labs LLC
Budget: 0.12 ms/frame JS avg (1.2 max) @ 1440x900 dpr 1, headless desktop Chromium (2026-09-30); raster not in this number; phone TBD