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 runtime MUST NOT run a free-running clock during
field play. There is no 24-real-minute day.
TimeManager's hour changes only when a slot is applied or a debug key previews one. - Each field SHALL ship exactly one authored slot per
area — chosen deliberately in that area's own issue, not generated. The
slot MUST be applied once at field/cell entry through the
pin block in
valley_field_controller._ready(); lighting MUST NOT be re-tracked per frame. - The applied slot hour MUST own
TimeManager.current_hourfor the duration of field play, so hour-derived consumers (the sky palette, the moonlight) read the field's authored time, not a leftover session value. - Light MUST NOT come from the player. The old player-carried lantern omni was a night-visibility crutch from the free-running-clock era (#659 removed it): every field's lighting is authored — the rig and the stage's placed effects carry it, and the player reads as part of the scene, not a source.
- The city (s00) MUST be always day. The city scenes
carry no clock at all — their lighting is authored interiors. City stages
reached through the field controller (the coliseum debug arena) pin
12.0(noon, deliberate).
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). Rows MAY also
desaturate the preset's warm daylight: sun_color,
ambient_color, and the sky_top_color /
sky_horizon_color bands carry moods whose light must read
neutral (the wetlands' overcast, #649). 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 row | Area | Hour | Weather | Note |
|---|---|---|---|---|
s03b | Snowfield B caves (variant row) | 5.5 — pre-dawn | snow (open ceilings) | LOCKED (walk-lab read-out): moon 0.6 @ −55°, ambient 0.05, bake 0.75, geometry casting; kinoko spores + anchors authored |
gurhacia | Valley (s01) | 10.0 — day | sand | the 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 |
ozette | Wetlands A (s02a) | 10.0 — day | drizzle | the approved pre-transition look (#649): the WHOLE stage receives (lit_surfaces "*"), sun off, ambient 0.35 — the yellow-orange electric lanterns are the light, painting pools on the pathway and casting the actors' swinging shadows onto the lit ground; lit_props brings boxes/fences/drops/NPCs onto the receive path |
s02e | Wetlands E transition | 10.0 — day | drizzle | the rain breaks: the valley contract (unlit bake + catcher floor) with a faint warm sun (0.10) hung at the baked sun spot (sun_origin + pinned −49° pitch) casting the player's shadow under a drizzle — the baked rainbow reads |
s02b | Wetlands B (s02b_*) | 10.0 — day | drizzle | continues the transition's style verbatim (variant row) |
s02b_ga1 | Wetlands B turn | 10.0 — day | rain | the dark turn: sun off, the heavy rain, lightning — and the WHOLE stage joins the receive path (lit_surfaces "*"): full-bake edges beside the catcher-held floor read stupidly bright — the road into Z (stage-level row) |
s02z | Wetlands Z boss | 10.0 — day | rain | the octopus boss waits in the same dark downpour, lightning strobing (variant row) |
rioh | Snowfield (s03) | 22.0 — night | snow | the locked #646 rig (see below); s03a stages only now |
makara | Ruins (s04) | 10.0 — day | — | interior hours; #650 authors torch-dark |
paru | Forgotten City A+Z (s05) | 10.0 — day | — | the ambient-sun ladder (#651, kion 2026-09-28): valley-A cheat rig — bake kept, greenery keep-list (1_reaf1–5 + tuta1/kusa1 candidates), catcher floor; A+Z ambient-led: ambient 0.55 over a faint 0.25 sun @ −60° |
s05e | Forgotten City E transition | 10.0 — day | — | sun-led: sun 1.00 / ambient 0.25 @ −50°, higher sun (variant row) |
s05b | Forgotten City B (s05b_*) | 10.0 — day | — | the balanced middle: sun 0.60 / ambient 0.40 @ −55° (variant row) |
s06a | Moon Facility A (s06a_*) | 10.0 — day | — | the pristine lobby (#652, kion 2026-09-30): bake kept verbatim — no bake_mix, no lit_surfaces, so the sun can never light the stage — ambient 0.35 fill under a weak 0.30 shadow-sun @ −60°, catcher floor; the window rooms ride the row |
s06b | Moon Facility B (s06b_*) | 10.0 — day | — | the industrial dark: barely-sun 0.10 over ambient 0.25 — the composition is the authored colored fixture pools (per-stage effects.json lights, actor-only, the stage being unlit) |
arca | Moon Facility E+Z (s06e/s06z) | 10.0 — day | — | the transition and boss arena ride the area row between the two: sun 0.20 / ambient 0.30 |
s07a | Dark Shrine A (s07a_*) | 22.0 — night | — | the dark-interior pin (#653, locked 2026-10-02): bake kept, hour-22 base with the preset moon zeroed, ambient 1.30 (kion's second walk read-out — just light enough for the floor texture's detail under the fog) under a super-dim 0.10 pale sun @ −60°, catcher floor, dark edge fog 0.04; signature: white motes rising with a subtle swirl |
s07a_ga1 | Dark Shrine A reference | 22.0 — night | — | Point lights above the baked floor pools; no sun or catcher, ambient 0.35, lit floor receivers. Other A rooms retain their existing sun. All A rooms have 3D teal lanterns and denser white motes. |
s07b | Dark Shrine B (s07b_*) | 22.0 — night | — | Ambient 0.05, no sun or catcher. Lit stage receives room-specific floor pools; stage-only lights preserve actor exposure. Fog 0.18 with overhead bank, tonemap white 3.0, swirling motes, embers and spores. Teal pillar insets and solid lanterns mark the room. |
s07z | Dark Shrine Z | 22.0 — night | — | Boss arenas retain the pre-pivot rig: ambient 0.95 and unlit bake, awaiting their own review. |
s07e_ia1 | Dark Shrine E transition | 22.0 — night | — | No sun; ambient 0.35, two localized red point lights over baked highlights, red motes, and eight teal lanterns on 15-unit support poles. |
s080_sa0 | Tower entrance | 10.0 | — | Baked scenery; dynamic sun shadows on the collision-floor catcher. |
s081 | Tower floor 1 | 10.0 | — | Interior: sun off, ambient 0.15, blue stair and green panel lights for actors and props only. |
s082 / s083 / s084 / s085 | Tower floors 2–5 | 10 / 13 / 15 / 17 | — | Morning above ground, early afternoon at height, clouds at 3 pm, warm 5 pm above Earth. Dynamic actor shadows; unlit baked scenery. |
s086 / s087 | Tower high atmosphere / low orbit boss | 18 / 19 (provisional) | — | Dark sky, direct neutral sunlight, reduced ambient fill. Altitude rather than moonlit night. |
s08e_ib1 | Tower pre-boss interior | 18.0 | — | Ambient only; no sun or moon. |
city | City field stages (s00) | 10.0 — day | — | coliseum 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 (#650,
#652–#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.
The wetlands rows (#649) tell a weather arc in two
strategies (kion, 2026-09-23): A opens with the
approved dark-lantern look — the wildcard rig
(lit_surfaces "*", sun off, ambient 0.35): ambient owns
the whole stage's bake (the flat full-bright unlit bake read "ewww
too bright" in the free-field pass) and the yellow-orange lantern
pools paint the pathway, their omnis casting the actors' swinging
shadows onto the lit ground. E breaks the rain with
the valley contract — unlit bake + the
shadow_catcher floor and a faint warm sun peeking
through at the baked sun spot (the transition's flatter, brighter
read); B carries the transition.
s02b_ga1 is the turn, back on the wildcard with the
sun off, the heavy rain, and lightning, on the road into
Z, where the octopus boss waits in the same
downpour. (A fake glow disc was tried and read as a circle in the
air under the hanging lanterns; the wildcard and the valley contract
each won the read-outs where they now sit.) The ambient sits dark
(0.35 on A, 0.30 through the transition and the turn — the kion
locks) with overcast sky
bands, and the blob shadow skips under the shadow/post rows — blob
+ real shadow reads double. The transition's sun is a faint WARM 0.10
(1.0/0.94/0.82) hung at the stage art's baked sun spot —
sun_origin places and aims the directional at the origin
(the E stage read: 15.8/14.7/−55.6), with sun_pitch −49
pinned OVER the aim (applied after it) for longer shadows — the
rainbow maker lights the actors and casts their catcher shadows; the
panorama eye placement then anchors the compat shadow frustum without
touching the aimed direction. post_lights names the lamp surface material
(0_light, merged into every s02a stage mesh) whose
vertices are clustered on the XZ grid — each connected blob is one
post — and each hanging lantern gets an electric omni pool
(yellow-orange 1.0/0.7/0.3 — the kion color call, the debug blue
retired after receive-path confirmation — light radius 11, ~1.2m under
the pole tip, energy 5 (the kion ×0.50 read-out) on a flattened 1.0
falloff: true
inverse-square starves a lantern hanging ~3.8m over its pool; no
flame particles ride them — the lamps are electric). The s02b/e/z
variants ship no such
surface and place nothing. The lanterns cast — the one
deliberate exception to the placed-omnis-never-cast convention: in the
moody dark the nearest lantern is the dominant light, and the actors'
shadows must swing with it rather than stay pinned to the weak sun
(kion's dark-room read-out, 2026-09-23). The compatibility renderer's
dual-paraboloid omni shadows land on the catcher — the stage's only
per-pixel receiver, which takes every light's shadow.
lit_props raises the
field-scoped GameElement flag so boxes, fences, drops, and field NPCs
load per-pixel like the player and enemies — the flag is cleared on
field exit, so city scenes sharing those subclasses keep their baked
look. Weather is the arc's rain in two weights on one recipe —
blue-gray streaks on FIXED_Y billboards through the volume above the
player: rain, the A/Z heavy-overcast downpour (380
streaks, 0.32 alpha, a purposeful 8–10u/s fall), and
drizzle, the E/B transition break (160 short streaks,
0.22 alpha, a gentle 6–8u/s fall — the E stages' baked rainbow,
s02_0_niji, reads under it and the peeking sun), built by the shared
WeatherController like snow and sand. The storm rows
(s02b_ga1, s02z) also carry
lightning: a scene-level cool directional strobing
random multi-pulse strokes — each flash lights the receive path (on
the wildcard-lit turn, the whole room blinks) from a fresh azimuth,
never casting. The wetlands walk lab
(wetlands_walktest) owns the tuning until locked from a
read-out.
The Forgotten City rows (#651, kion 2026-09-28) are the valley-A cheat
rig again — the stage keeps its bake, the greenery keep-list
(1_reaf1–5, the same leaf class the valley lit, plus the
vine 1_tuta1 and boss-grass 1_kusa1 as organic
walk-lab candidates) receives the sun, and the catcher floor takes the
actors' dynamic shadows — with the variants telling one simple story:
the ambient↔sun balance. A (and Z,
the boss arena riding the area row) is ambient-led deep-forest shade —
ambient 0.55 over a faint 0.25 sun at −60°.
E, the transition into the area, is sun-led — 1.00 sun
over 0.25 ambient at a higher −50°. B is the balanced
middle — 0.60/0.40 at −55°. No weather yet: the area's signature
particles (falling leaves vs. photon motes) are #651's open identity
question, and the s05a_sa1 spore pools already read under
the rig. Starting values pre-lock; the paru walk lab
(paru_walktest) owns the numbers until a read-out locks
them.
The Moon Facility rows (#652, kion 2026-09-30) are the valley-A
contract with the area's own twist: the facility's bake IS the look —
kion's call was to keep it untouched, so the rows carry no
bake_mix and no lit_surfaces, and that silence
is the contract that the sun can never light the stage — it exists to
cast the player's shadow onto the catcher floor and to key the actors.
A, the pristine lobby, runs a low 0.35 ambient fill
under a weak 0.30 sun at −60° ("just enough of a shadow" — kion); the
window rooms (ic1/ic3/lc1/lc2/nc2/tc3, the moon through
the glass) read right baked and just ride the row. B,
the industrial dark, runs barely any sun (0.10) over the darkest fill
(0.25) — the composition is the authored colored fixture
pools: per-stage <stage>_effects.json
plain lights whose pools reach only the actors, the stage being unlit
(first drafts shipped for s06b_ga1/lc1/td1). Placed omnis
ride a cull mask off the catcher's private render layer — the #670
contract, ported to the field, so a pool never brightens the multiply
floor past ×1. E and Z ride the area row between the two (0.20 sun /
0.30 ambient). Starting values pre-lock; the arca walk lab
(arca_walktest) owns the numbers, and doubles as the
accent-authoring loop — K inventories the stage's
materials, L prints an effects.json anchor at the player's
feet, R reloads the file live.
The Dark Shrine rows (#653, kion 2026-10-01) are the arca contract
pinned to the night base: the rows' silence keeps the stage unlit (the
bake IS the look), hour 22 gives a near-black sky where any peeks
through and the preset's 0.55 moon is zeroed — kion's rig is a
low ambient (A 0.20, B 0.15) under a super-dim pale sun whose only job
is the minimum floor shadow on the catcher. The area's identity is the
signature motes rising from the ground — white on A,
black on B and in both boss arenas — which ride the row's new
signature key, not the weather key: the
indoor gate exists for precipitation, and the shrine's motes ARE its
indoor identity, so they spawn indoors by design (the weather-precedence
contract below is unchanged — motes are not weather), and they
swirl as they rise (tighter turbulence eddies plus a gentle
orbit — kion's follow-up ask). The B/Z black flavor runs a ~1000-mote
storm (kion 2026-10-03: "like 4x the particles") with a second emitter
of red embers riding with the dark body, and on B/Z the fog is
concealment, not mood — the bright open-air courtyards
ship no ceiling and their edge textures fall apart at Godot scale
(0.18 density, fog_height 5.0 / −0.7, tonemap_white 3.0
dimming the too-light bake). The
dark edge fog (the
row's fog_density / fog_color) dissolves each
room's far edges into the dark — clouds at the boundary instead of hard
walls against unmodeled space — and on B/Z it runs as concealment
(fog_density 0.18) under a ceiling cloud
bank: fog_height 5.0 with a negative
fog_height_density (−0.7) piling the dark fog overhead,
burying the white skybox that leaks through open roofs. The lab's
[/] keys sweep the density. kion's walks locked
the ambient at 1.30 (A — the fog dimmed the first 0.90 lock; 1.30 is just
light enough for the floor texture's detail) with B scaled to
0.95. Sparse candle/urn accents land per-stage as
<stage>_effects.json plain lights (first drafts in
s07a_ga1/lc1,
s07b_ga1/lb1). The port also fixes the classification bug
the issue flagged: s07 joined the indoor prefixes (a Dark
Shrine no longer tracks the outdoor cycle). The shrine walk lab
(shrine_walktest) owns the numbers and
the accent authoring (the arca K/L/R loop).
Weather precedence
- A quest-authored
weatherkey (session level) MUST override the slot row's weather — explicit per-quest authoring beats the area default. - Otherwise the slot row's weather SHALL apply (this is the #609 unification: per-area weather config, not scattered prefixes).
- Indoor stages MUST NOT spawn weather particles
regardless of source. Weather means precipitation (snow, sand, rain,
drizzle); a row's
signatureeffect — the shrine's rising motes — is ambient life, not weather, and spawns indoors by design (#653).
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)
- Additional slot variations per field (valley evening, wetlands dusk-rain, …) — added one at a time only after that field's first slot is locked and plays well.
- Selection/advancement logic — rolled at field selection vs. fixed A→B progression. This only becomes a real question once variations exist.
Supersedes the always-day ask in #605 (day becomes Valley's one slot).
Eternal Tower material and lighting contract
Tower scenery MUST retain its baked lighting, including mirrored materials. Dynamic lighting MUST affect actors and lit props without relighting the room. Outdoor actor shadows MUST use the collision-floor catcher. Floor-1 accents MUST be shared by the game and preview, spawn once per room, and exclude the catcher.
Colored glass, cloud cards, and force fields MUST preserve smooth alpha and authored color. Matching texture aliases MUST share scrolling and wrapping. Floor glass MUST draw after the underlying transparent inset. Coplanar orange sign overlays retain a small surface offset and their authored vertical mirror.
This is an accepted first pass (2026-10-06), not a final art lock. A future Tower pass should revisit light placement and balance, glass sorting while walking, the opaque floor-1 fence variant, and the provisional orbital hours.