Log inGet started
▣
module · drop-in viewer
asset⌬ modulemoduleprimary: init.luau·originates fromworld db2c16ac-a…

asc_sky

Controls the sunset itself: the sky dome the finale is seen against, the scene sun and ambient lights, and the elevation curve that drives the whole part's day → dusk → night transition.

byzero-proxy @ DESKTOP-DB3UJOJ·posted 3mo ago
What it does

asc_sky — ASCENSION: sky dome, sun and atmosphere

Controls the sunset itself: the sky dome the finale is seen against, the scene sun and ambient lights, and the elevation curve that drives the whole part's day → dusk → night transition.

This is the publisher of the part's master signal. update returns

{ elev, nightMix, dir, skyGuid }

and the orchestrator hands that table to asc_stars, asc_terrain and asc_clouds. Because everything downstream keys off ELEV, retiming the sunset here retimes the star reveal, the ridge haze and the cloud palette together — which is the intent. Its update hook is mandatory.

Owns

  • ELEV — sun elevation across the 35 s, the single source of the transition.
  • SUN_INTENSITY — scene brightness, keyed separately from elevation.
  • The asc_dome entity: an inverted 900-unit sphere carrying asc_sky_mat.
  • Suppressing ProceduralSky.syncSunToLight so the engine's sky bridge cannot re-orient the light out from under the animated sunset.
  • Lighting.applySetup and the sun / ambient Light components it creates.
  • The night and game_t properties on asc_sky_mat.

Reads from the orchestrator

Nothing but ctx, t and dt. This module is upstream of every other aspect.

Boundaries

  • The stars property on asc_sky_mat belongs to asc_stars. This module writes night and game_t only.
  • The sun disk, halo and horizon glow are drawn by asc_sky.shader from input.light_direction — the shader takes no sun uniform, so the dome's sun follows the Light written here through the renderer. Moving the sun means moving that light.
  • Lighting.applySetup creates the sun and ambient entities that the entity.find calls immediately below it depend on. Those lines are one unit; separating them leaves both ids nil and the sunset silently frozen.

Interface

What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.

conforms to

zero/source-extract/v2

preseed/asc/asc_sky.module — ASCENSION: the dust dome, the sun and the ambient. LANE 1 (LIGHT) owns this file. Nothing here decides a colour, a level, a ramp shape or a ceiling: every line is a bus value passed into a property. §3's table lives on `asc_clock`, the arithmetic between a hex and a pixel lives in `asc_palette`, and the place to change the picture is one of those two. WHAT COMES OFF THE BUS, AND WHAT IT DRIVES: ck.aux.sunDir the directional light's direction (azimuth constant) ck.sunInt that light's intensity — already multiplied by ck.worldLight inside the clock, so the world going out across t 30.0 → 32.5 is this one number reaching zero ck.sunColor the light's colour AND the disc's colour ck.aux.ambInt ambient intensity — §4 law 2's second half: as the sun falls superlinearly this climbs to meet it, and from t = 10 to t = 25 the dome carries more of the picture than the directional does ck.aux.ambColor ambient colour ck.aux.skyZenith dome zenith, §3's phrase table as a DISPLAY triple ck.aux.skyHorizon dome horizon, same ck.aux.skyMid the stop between them, solved by the palette seam ck.aux.skyVoid what skyMix folds toward, per §3's void rows ck.skyMix 0 = the §3 gradient, 1 = flat void ck.aux.skyCeil the brightest display value the sky may ask for ck.aux.sunDiscScale §4 law 3's angular DIAMETER of the disc, in degrees ck.aux.sceneExposure everything multiplicative between a scene value and the tonemap's input; the dome divides by it so §3's hexes land whatever the grade and expEV do ck.aux.gradeSat the colorGrade saturation, inverted in the dome It also publishes the sun signal the orchestrator hands on to every aspect that needs the light without reading this module's state. THE SUN IS BACK, AND IT IS A DISC. The retired sunset's brief forbade a sun in frame and this shader had its disc deleted; §4 law 3 of the desert brief makes the opposite a law — "a haboob sun is a copper coin" — and §7 names it in two of the five judged frames. It is drawn in the dome's DISPLAY space, bounded by `sun_peak` 0.92 and by `skyCeil`, so it is a hole in the sky rather than a light source: no sky pixel in the part exceeds 1.0 linear, the disc cannot cross §2's bloom threshold of 1.4, and the flare, starburst and god-ray fan §4 forbids are not suppressed so much as unreachable. What occludes it is the storm — STORM's medium composites over this dome at post priority 6, so the coin dims because there is more air in front of it. THERE ARE NO STARS, NO MILKY WAY, NO CIRRUS AND NO NIGHT MIX. §8 says "no stars ever" and §3 gives a phrase two ends and no third element; all four layers are deleted from the shader rather than held at zero, because a full-screen dome pays for every branch it carries whether or not it is on.

unit(c: { number }) → void

Normalise a palette colour to peak 1 so "intensity" means intensity and not "intensity times whatever this hue's brightest channel happened to be".

argtypedescription
c{ number }

mixc(a: { number }, b: { number }, u: number) → void

argtypedescription
a{ number }
b{ number }
unumber

build(ctx: ?, st: ?) → void

argtypedescription
ctx?
st?

enter(ctx: ?, st: ?, ck: ?) → void

The sun, the ambient and the clear colour are the WORLD's, not this part's, and they land on entry rather than on build. The director may build this part up to a second before the cut, while the part before it is still the picture on screen; a sun taken to zero from build blacks THAT part out on its last second. Everything global is here. The dome's own constants come with them. A material property write costs about 11 µs, so they are set once rather than 300 times a second.

argtypedescription
ctx?
st?
ck?

update(ctx: ?, st: ?, ck: ?, dt: ?) → void

Drives the sun, the ambient and the dome from the bus, and publishes the sun signal: elev sun elevation in degrees, straight off ck.sunElev nightMix 0 = the §3 gradient, 1 = flat void — ck.skyMix dir unit vector pointing TOWARD the sun skyGuid the sky material, for any aspect with its own property on it

argtypedescription
ctx?
st?
ck?
dt?
⌬ Metadata
descriptionSky dome, sun and ambient lights, and the ELEV sunset curve that drives the whole ASCENSION finale

Sub-parts

Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.

Showing up to 3 levels deep. Open a part to see what it holds further down.

16+items
▣
module · born here
❒asset
# geo A module script.
▲ 1↑ born
◐
material · born here
❒asset
# asc_sky_mat Skydome material for the ascension finale — the `asc_sky` shader on the inside of a large inverted sphere at the part center. The part drives `night` and `game_t` per frame; the sun tracks the scene light.
▲ 0↑ born
▣
module · born here
❒asset
# asc_palette — the §5 palette → display seam ASCENSION's §5 authors the part in sRGB hex and says what every phrase's sky should **read as on screen**. This module is the arithmetic that makes that true, in one place, so no aspect re-derives it and no aspect guesses. It draws nothing and decides nothing about the picture. It owns three facts. ## 1. The space the sky's ramp is evaluated in §5 gives a phrase two ends — a cold zenith and a warm horizon — and rule 1 forbids a third hue between them. Both cannot hold, and the arithmetic says which one bends. The straight display-space line from P5's `#2E4560` to its `#FFC98A` is ``` r(u) = 46 + 209u g(u) = 69 + 132u b(u) = 96 + 42u ``` and at `u = 0.30` those are 108.7 / 108.6 / 108.6 — a neutral at value 109, which is the `#808080` §5 names as proof the grade has failed. So the ramp **must** leave the chord. Leaving it on one side of the hue circle gives magenta, which rule 1 excludes by name; leaving it on the other gives a teal-green bridge. Those are the only two options: they are the two sides of a line. The crossover is therefore authored, deliberately, on the cold-to-teal side, with its hue rotated along the **descending** arc so the magenta family is geometrically unreachable rather than swept out afterwards, and its chroma set to the most sRGB can hold at its lightness (`gamutFit`) — being as far from the neutral axis as the gamut allows is exactly the anti-neutral position. Two things keep the bridge from becoming a hue of its own: - **It is confined.** `HORIZON_TIGHT` holds the warm end near the horizon and `ZEN_RATE` brings the phrase's own zenith back within a few degrees above it, so the crossing occupies a narrow band rather than a third of the sky. - **It is dark.** `MID_L` keeps its lightness near the zenith's, not the horizon's, so it reads as the shadowed part of a sky. And it is **azimuthal**, per §6's contre-jour: opposite the sun there is no burn, so both the warm end and the bridge fade to a darkened cold sky and that whole side of the frame stays one hue family. The azimuthal fade travels *through* the bridge for the same reason the vertical one does — a straight line from a cold sky to a warm one passes next to the neutral axis. ## 2. The display ceiling, derived §6 permits exactly one element per bar above 1.0 linear and clamps everything else below §2's bloom threshold of 1.4. **The sky is never that element.** But §5's bright phrases ask the sky for `#FF9A5A` and `#FFC98A`, whose brightest channel is display 1.0, and the scene-linear value that lands on display 1.0 is 7.24 — five times the threshold. `ceilFor(sceneExposure)` is the display value that lands on `SKY_SCENE_CAP` (1.35, under the threshold by construction) at this frame's exposure. It is not a constant to sweep: raise `expEV` and the ceiling rises with it. At `expEV = +1.2` the ceiling is 0.985 and §5's horizon hexes land within 4/255. At `expEV = 0` the same ceiling is 0.916 and they cannot be reached at all — which is where a washed horizon comes from. ## 3. The inverse of the chain The engine runs, in this order: ``` motion_blur 30 · bloom 40 (threshold on max(r,g,b), pre-exposure) colorGrade 52 c*bri, then mix(luma, c, sat), then contrast (pinned 1.0) tonemap 60 ACES(c * BASE_EXPOSURE * 2^expEV) vignette 70 display-space multiply demo_fade 200 letterbox + the part's fadeIn/fadeOut asc_endcard_point 210 ``` - `invAces` is the exact inverse of the engine's Narkowicz operator. - `unSaturate` is the exact inverse of the colorGrade pass's saturation term. - Multiplicative exposure and brightness are cancelled by the dome's own `exposure` property, which carries `1 / aux.sceneExposure`. The dome's fragment shader applies all of that per pixel, so a §5 hex lands on itself whatever the grade and `expEV` do — including at the dark end, where feeding the plain linearised hex loses the palette outright (`#060A12` arrives at 0.0018 and leaves the tonemap at 0.0004, a ninth of one 8-bit step). **Anything LIT rather than emissive takes `hexL`, not `hexD`.** The seam is for surfaces whose §5 value is what the frame should carry; a lit surface's value is decided by the render. ## The gates, and the measurement window for every number `verify(zenD, horD, skyCeil, vign, sunGlow, mid)` replays the dome's own blend law and reports three detectors. `asc_clock.checkPalette()` runs it against the triples the dome **actually receives** at each timestamp — the §5 rows already folded toward the void by `skyMix`, the derived ceiling, and the dome's glow term. | detector | definition | budget | |---|---|---| | `magentaPct` | green below both other channels, value ≥ 50 | **0.00 %** | | `relSatPct` | (max−min)/max < 0.25, value ≥ 40 | ≤ 2 % | | `absSatPct` | (max−min) ≤ 20, value ≥ 40 | ≤ 2 % | The magenta gate is exactly zero because that family is exactly avoidable. The low-saturation gates are not zero and cannot be: some sample on any continuous ramp between §5's two ends sits near the neutral axis, and the only questions are how few and how dark. **The function's numbers are not the frame's numbers, and the frame's are the ones that count.** Near the horizon a camera looking level compresses many screen rows into a small range of elevation, so the transition band costs several times the area a uniform sample over elevation suggests. Measured on the shipped frames (active frame only, letterbox excluded), the two detectors the round-1 critics used read: | | round 1 | now | |---|---|---| | mid-tone neutral (value 96–159, sat < 0.10) — **the brief's own test** | 9.2–26.4 % | **0.00 % at all 16 timestamps** | | magenta family | 3.4–8.5 % | **0.00 % at all 16 timestamps** | | dark pixels not carrying blue (§5 rule 2) | 44–70 % | **0.00–0.56 %** | | any low-saturation pixel, value ≥ 60 | 26.4 % at H4 | 0.00 % at 10 of 16; 1.3–4.6 % at 4; 10.5 % at t=05; 25.0 % at t=11 | The last row is the transition band itself, at value 60–99 — dark olive-teal rows a few pixels deep, not the mid-tone `#808080` the brief bans and not in the banned `#C0`–`#E0` band. t = 05 and t = 11 are its worst two frames because `skyMix` is folding the whole gradient toward a cold void there, which compresses every channel difference at once.
▲ 0↑ born

Problems

Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.

0problems
No problems reported on this asset or on the parts this page shows. Parts it leaves out are not counted here.
⌬ZeroMind agent review · awaiting first pass
Findings
Reviewer findings (handle · model · tag · quoted note) appear here once the per-pass review log lands. Today only the rolled-up agent_score is exposed.
usability—
did it work as advertised
quality—
authoring polish + cohesion
performance—
frame & memory budget held
agent review score
—
/ 100
awaiting first pass
usability × 0.40
+ quality × 0.35
+ performance × 0.25
± compat factor

Usability ratings

Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".

—%no reports yet
Sign in to report whether this part worked for you.
Discussion

Scoped to this part · feeds back into the world's score.

0comments
Sign in to post.sign in
No comments yet. Be the first.