Environment · function
celestialStateAt
Convert a timestamp and an authored azimuth into sky state.
Explained in Sky and atmosphere.
function celestialStateAt(whenMs: number, sunAzimuth: number, out: CelestialState, site?: CelestialSite): voidimport { celestialStateAt } from '@driftengine/core';Parameters
| Parameter | Type | Description |
|---|---|---|
whenMs | number | |
sunAzimuth | number | |
out | CelestialState | |
site? | CelestialSite |
In depth
The caller decides where the timestamp comes from and must keep it out of a deterministic simulation if wall time should not affect gameplay.
sunAzimuth is where the world's north points, as an angle in the xz plane from +x toward
+z. It was an arbitrary offset in the model that knows no latitude and it means the same thing
there; with a site it becomes load-bearing, because the sun's own azimuth is then derived and
this is what relates it to the world's axes.
site is what turns the simplified model into the sited one, and omitting it is not a
degraded mode — it is the model every world here was authored against. See the header.
Which hour the timestamp names depends on whether the site states a zone, and that is the one thing to get right before anything else here matters:
- A site naming
longitudeDegorutcOffsetHoursmakeswhenMsa plain UTC instant —Date.now(), orDate.UTC(…)for an hour chosen outright — and the engine derives that site's own hour from it. The answer is then a function of the arguments and of nothing else, which is the only form that gives every machine the same sky. - A site naming neither, or no site at all, reads the hour off the timestamp through the
host machine's time zone, which is what this function has always done. Every world
authored against it is tuned that way, so it is kept exactly: the same argument gives the same
numbers, bit for bit. But the same argument on another machine gives another hour, so a caller
in this form must build the timestamp from local parts —
new Date(y, m, d, h)— for the host's offset to cancel rather than be added.
moonPhase is the reason the first form is worth taking even where the sun already looks
right. It comes from the timestamp's absolute value rather than from the hour, so the
build-it-from-local-parts trick that steadies the sun leaves the moon drifting by the host's
offset — a fiftieth of a lunar cycle across the world, invisible and still not a fact about the
world.
The equation of time stays the caller's, and it is the last correction left: a real sun runs up to about a quarter of an hour ahead of or behind mean time across the year, from the Earth's eccentricity and its tilt. The zone and the meridian are the engine's as soon as a site states them; this one is not, because it is a property of the planet's orbit rather than of the place, and a world with an obliquity of its own has an equation of time of its own. A caller measuring a shadow against an almanac applies it to the timestamp; a caller lighting a world does not care.