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): void
import { celestialStateAt } from '@driftengine/core';

Parameters

ParameterTypeDescription
whenMsnumber
sunAzimuthnumber
outCelestialState
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 longitudeDeg or utcOffsetHours makes whenMs a plain UTC instant — Date.now(), or Date.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.