shots
The framing maths and the shot lists of *First Light: Nearside*. Pure data and pure functions: `NearsideCam` reads it to stand the camera up, `Staging` reads it to build the opening and the two endings, and either can be evaluated on its own against a made-up screen size.
game.staging.shots
The framing maths and the shot lists of First Light: Nearside. Pure data and
pure functions: NearsideCam reads it to stand the camera up, Staging reads
it to build the opening and the two endings, and either can be evaluated on its
own against a made-up screen size.
local Shots = require("game.staging.shots")
local f = Shots.framing(1080, 1440) -- the portrait framing
local eye, at, fov = Shots.solveFollow(rover, heading, f)
Shots.screenYOf(eye, at, fov, point) -- 0 at the top edge, 1 at the bottom
Nothing here is a pixel
A framing is stated as the rover sits this fraction down the frame, with at
least this many degrees of sky above the horizon, and the camera pitch that
produces it is solved from the live field of view. Two anchors — TALL for the
3:4 shape the game films at, WIDE for a landscape monitor — blend by aspect,
so a window between them slides rather than snaps and a resize never jumps.
screenYOf is the inverse: hand it a world point and it says where that point
lands down the frame. It is how a shot is checked without eyeballing a capture.
What is in it
framing(w, h)— the framing for a screen, blended by aspect.solveFollow(rover, heading, framing, pushIn?)— the chase: eye, aim, lens.screenYOf(eye, at, fov, point)— where a point lands down the frame.intro(ctx, short?)— the opening, as a cutscene definition, built around wherever the rover actually stands.shortis the retry's re-establish.stationCenter(rover, finishZ)— the station the winning shot points at.wonDirective(rover, finishZ, framing)— the swing across Peary Station.lostDirective(framing)— the fall away from a rover the light caught.
Scoped to this part · feeds back into the world's score.