Field Time Slots

This page defines how time of day and weather behave during field play. The key words MUST, MUST NOT, SHALL, SHOULD, and MAY are used as in RFC 2119 — they define expected behavior, not current implementation status.

The decision (playtest notes, post-#646): the game does not ship a dynamic day-night cycle. A moving clock in a field implies shops closing and NPCs going home — the wrong genre of simulation for this game. Time of day is authored per field: each field ships exactly one deliberate, tuned slot — its identity time (valley day, snowfield night, ruins torch-dark). The snowfield's pinned hour-22 night is the template; this contract generalizes it from a per-area spelling into the slot table.

The rules

The slot row

A slot row carries the area's identity: an hour (float — fractional hours pick a stable lerped palette between phase presets), an optional weather, and optional rig overrides applied after the phase preset (ambient/sun/moon energies, the moon's elevation via moon_pitch and its shadows, the sun's elevation via sun_pitch and its shadows via sun_shadows, the tonemap white point, and the vertex-color bake mix that blends the baked lighting toward white so the dynamic rig drives the look). A row MAY set geometry_casts_shadows: map geometry ships shadows-off (the bake is the look), and a rig that stands on real shadows — moon (moon_shadows) or sun (sun_shadows) — turns casting on so models shadow each other by position; either shadow row also skips the player blob shadow (blob + real shadow reads double). One carve-out on the sun side: a stage shell that ENCLOSES a room (walls + ceiling + backdrop, often one mesh) must not cast — its own shadow would delete the sun from its interior, and with it every dynamic shadow including the player's. At room build, each casting mesh is ray-tested alone against the applied sun; one that blocks every sample ray is disarmed from casting (it still receives), so the player and placed objects cast real shadows on it. Partial blockers — walls, rims — keep casting. Rows resolve most-specific-first: exact stage_id → variant prefix (s03a, s03b, tower floor styles) → area id → default day.

Area rowAreaHourWeatherNote
s03bSnowfield B caves (variant row)5.5 — pre-dawnsnow (open ceilings)LOCKED (walk-lab read-out): moon 0.6 @ −55°, ambient 0.05, bake 0.75, geometry casting; kinoko spores + anchors authored
gurhaciaValley (s01)10.0 — daysandthe cheat rig (#648): stage keeps its bake; sun 0.90 / ambient 0.40 @ −60° lights actors + lit_surfaces (greenery only — every hard-surface prop read out of place); the collision-shell shadow catcher multiplies the actors' dynamic shadows onto the walkable ground; sand drift
ozetteWetlands (s02)10.0 — dayinterim; #649 authors the overcast mood
riohSnowfield (s03)22.0 — nightsnowthe locked #646 rig (see below); s03a stages only now
makaraRuins (s04)10.0 — dayinterior hours; #650 authors torch-dark
paruForgotten City (s05)10.0 — dayinterim; #651 establishes identity
arcaMoon Facility (s06)10.0 — dayinterim; #652 authors fixture lights
darkDark Shrine (s07)10.0 — dayinterim; #653 authors the dark-interior pin
towerEternal Tower (s08)10.0 — dayinterim; #654 authors fixed-hour floors
cityCity field stages (s00)10.0 — daycoliseum debug arena excepts to noon

The snowfield rows split by variant (#657, the first variant row): s03b caves pin 5.5 — the sunrise ramp's midpoint, a stable lerped pre-dawn palette — under a blanket moon, LOCKED from the walk-lab read-out: sun off, ambient 0.05 floor, moon 0.6 at −55° elevation with real shadows and geometry casting (models and rocks shadow each other by position, the original's implied moon position), bake mix 0.75 so a breath of the blue bake survives under the moon. Open-ceiling B stages carry the row's snow; the five enclosed ones stay weather-skipped by the indoor gate. The s03a open-field stages keep the #646 night lock verbatim (hour 22, snow, sun energy 0, ambient 1.50, moon 0.35 with moon shadows on, bake mix 0.25 — geometry casting off: the bake is the look there). The B caves' light anchors are authored placed light effects from the stage config — the art ships no crystals, so the pools are the blue reflective anchors and the red mushroom clusters the warm accents, each kinoko cluster dusted by an authored pink spores drift. The interim rows (10.0 day) preserve pre-#655 behavior for areas whose identity issues (#648–#654) have not authored a slot yet; each issue replaces its row's values and locks them from a playtest read-out.

The valley row (#648) is the cheat rig — the art-direction call from the 2026-09-21 hardware passes: the stage keeps its authored bake (pure baked vertex color; no bake_mix, so the white-strategy pass never runs), and the dynamic sun lights only what the bake could not account for: the player and enemies (lit on their own spawn paths) and the row's lit_surfaces — the leaf greenery (1_reaf1–5) only, matched by material name after the per-surface split. The list is greenery-only by accumulated read-out: every hard-surface class lit on trial — the ground decals (1_deco1), oasis terrain (1_oas*), and the bridge/rail/lantern-stone set (1_bri2 the final strike: its mirror shader stays the lit variant under the keep-list, sunning the bridge against baked rock) — read bright and out of place against the baked world. Plants blend; stone and lumber don't. The toro lanterns keep their warm placed-light pools without being lit themselves. The stage's light-independence is forced, not assumed: some glTF materials import shaded (the diagnostic caught 1_flo1/1_view1/1_rock1/ 1_step2 — the low ground lit up and the panorama self-shaded under the rig), so a force-unlit pass flips every non-listed Standard surface to UNSHADED — the MeshBasicMaterial guarantee. That guarantee includes the bake's other half: the flip also forces vertex_color_use_as_albedo, because imports without the flag render raw-texture bright (the transparent ground detail planes and the flat cliff faces of the 2026-09-21 read-out). Mirror-wrapped surfaces (pass1, deco1) run the custom wrap shader, and a custom ALBEDO shader is lit by default — under the cheat they swap to its UNSHADED twin (COLOR_0 tint preserved) unless they're on the lit list. Lighting the floors themselves proved wrong twice over: it erased the bake's intentionally dark unwalkable low ground (the "you can only walk on the raised area" read) and drew harsh lines at lit/unlit floor boundaries. Instead the row carries shadow_catcher: the collision shell — the walkable surface, exactly — renders as a white, multiply-blended, per-pixel receiver lifted a hair above the walk height. Lit, it multiplies the bake by ~1 (invisible); inside a shadow it multiplies down — so the actors' dynamic shadows (the row's sun_shadows; the blob shadow is skipped under any shadow row) read as painted onto the authored look, the low ground keeps its baked darkness, and the unwalkable areas get no shadows at all. No geometry_casts_shadows: only the actors cast, so no rim scenery shadows into the play space; the panorama shadow-eye placement still runs. Sun 0.90 / ambient 0.40 at sun_pitch −60° is the actor-lighting character — and, via the catcher's multiply, the shadow depth (ambient is the shadow floor); the in-field tuner (,/. ambient, 9/0 sun, 7/8 elevation, P read-out) owns the balance until locked from a walk. Weather is a blowing sand drift (the valley's dust), the first non-snow weather type. The stone-lantern stages (s01a_td1/td2, the only 1_toro art) carry warm placed-light anchors at day-punch intensity. The boss arena's 2_kemu smoke stays un-authored — detection puts every cluster on the distant backdrop ring, scenery rather than sources.

The full sun-shadow rig that preceded the cheat (per-pixel stage, geometry casting, the enclosure carve-out, panorama shadow-eye placement and its rim pull) remains in the codebase and the row schema — sun_shadows re-arms all of it — documented here as the lesson: at every balance the dynamic stage shadows either read invisible (under half a stop) or read wrong (rim scenery casting into the play space; double lighting over the bake). A future row that wants real stage shadows re-authors those fields knowingly.

Weather precedence

Debug preview

The [ / ] keys preview the current field at an adjacent hour: they set TimeManager.current_hour and the field controller re-applies the active slot's rig at the previewed hour. The preview MUST NOT persist across cell transitions — each cell entry re-applies the authored slot. On fields whose slot ships rig overrides, the tuning keys (`,`, `.`, ambient; `[`, `]`, moon; `9`, `0`, sun; `7`, `8`, sun elevation; `-`, `=`, bake mix; `P` for the read-out) own those keycodes and the hour preview yields.

Explicitly deferred (phase 2 — do not build)

Supersedes the always-day ask in #605 (day becomes Valley's one slot).