wheel
The physical spinner of **Helsinki Life**: a brass-cased ten-sector dial that appears beside the tram whose turn it is, turns while the spin runs, and eases to a stop with the spun number under its pointer.
wheel
The physical spinner of Helsinki Life: a brass-cased ten-sector dial that appears beside the tram whose turn it is, turns while the spin runs, and eases to a stop with the spun number under its pointer.
local Wheel = require("game.pieces.wheel")
local dial = Wheel.spawn(parent, "spinner")
dial:place({ x, y, z }, aspect) -- beside the active tram
dial:startSpin() -- on HL "spinStart"
dial:land(value) -- on HL "spinResult"
dial:update(dt) -- returns "tick" | "stop" | nil
The sectors alternate cream and HKL green with the ten in sun yellow, and each
carries its number in whichever of the two inks its own sector is not, so the
value the log reports is legible on the model itself. The dial is tilted toward
the camera so a tall frame reads the face, and the pointer stands at the root's
own -Z - the far, up-screen side of a board the camera looks north across.
Wheel.yawFor(value) is the hub yaw that puts a sector under the pointer and
Wheel.valueAt(yaw) is its inverse, so what the dial shows can be read back
and checked against what the rules reported.
Timing is its own: the dial turns freely for at least MIN_FREE_SECONDS
before it eases, so a caller that reports its value the instant it is asked
still gets a spin somebody can watch. After HOLD_SECONDS on the landed value
it shrinks away rather than being left behind on the board.
Scoped to this part · feeds back into the world's score.