# melt
The transformation slice of *Pastel Astral Dream*: everything `film.melt(t)` drives.
Hard, matte, dry and still becomes soft, glossy, wet, flowing and coming apart — and
in this place what melts does not run down, it **lifts**.
Serves shots **6** (first drip), **7** (glacier), **9** (collapse), **10** (the column
begins) and **12** (the sea drops).
## What it puts in the world
Everything is spawned `temporary = true` under `pad_melt_root` and rebuilt from
`build()` on every scene load, so nothing here is written into the scene record.
| entities | what it is |
|---|---|
| `pad_melt_cap_1..26` | the mesa's upper 84 m, as 26 marshmallow pillows on a convex profile with four thin wafer strata through them. Sags, spreads and thins with the melt; from t≈62 its top **leaves**, scattering as it goes — this is the source of the rising column. |
| `pad_melt_lip` | the melt lip on the mesa's +Z flank: a shelf whose underside sits at y = 107.2, which shot 6's beads hang from. **Fixed on purpose** — a macro station 1 m from a surface cannot follow a surface that sags 8 m. |
| `pad_melt_hero_1..5` | the five beads of shot 6, in the order they let go (37.3 → 44.7). The first is 14 cm across, sized for a 12 deg lens 1.3 m away. |
| `pad_melt_glacier_1..130` | the ice-cream glacier: 26 transverse slabs, each five bands — blueberry, pistachio, strawberry, vanilla and a wafer stratum. Upper bands advance further than lower ones, so the strata **shear**. |
| `pad_melt_calve_1..16` | blocks that leave the snout on their own clock (45.5 → 88.5) and drift **up**. The one at t=80.6 is shot 12's "last calved block". |
| `pad_melt_plinth`, `pad_melt_cone`, `pad_melt_scoop_1..9`, `pad_melt_glaze_1..2` | the 90 m scoop tower on its wafer plinth. |
| `pad_melt_puff_1..80` | the powdered sugar the collapse throws. |
| `pad_melt_shard_1..26` | candy-glaze shards that scatter across the plinth and **stay** there, so shot 12 can still see them. |
| `pad_melt_drip_1..216` | upward drips: 96 on the mesa's flank and under its lip, 44 on the glacier, 36 on the tower, 40 on the shallows. The shallows group rides the sea's surface down as it falls. |
| `pad_melt_riser_1..120` | ribbons and droplets leaving the mesa top — the first 300 m of the column, where it is still matter and not yet weather. |
## Timings this slice fixes
| t | what happens |
|---|---|
| ~40 | the confection is wet enough that drips start everywhere |
| 37.3 – 44.7 | the five hero beads of shot 6, one letting go every ~1.2 s |
| 45.5 – 88.5 | sixteen calving events off the glacier snout |
| 61.2 | the scoop tower's top lets go, and the powdered-sugar burst |
| 61.2 / 61.9 / 62.6 | scoops 9, 8 and 7 release, in that order |
| 62 → 84 | `film.column` opens; the cap's top pillows lift and scatter |
## What it reaches into, and how to turn that off
Two things this slice moves belong to the **place** slice, because the drop and the
sag are melt's job while the geometry is place's:
- **the sea** — resolved by name from `pad_sea`, `pad_place_sea`, `pad_cream_sea`,
`cream_sea`, `OceanSurface`, `Ocean`, and moved to `baseY - film.seaDrop(t)`.
- **the mesa body** — resolved from `pad_mesa`, `pad_place_mesa`, `pad_mesa_root`,
`pad_marshmallow_mesa`, and moved to `baseY - film.melt(t) * 18`.
Both are re-resolved by NAME every frame and never held as a proxy, and both writes
are guarded: another slice rebuilding its content underneath this one used to take
the whole animator down with a stale-proxy error, and the only sign was one line in
the log. If place would rather own either, set `M.driveSea = false` /
`M.driveMesa = false` and this slice leaves it alone.
Add a name to `SEA_NAMES` / `MESA_NAMES` if place calls its entities something else.
## What other slices may read
```luau
local melt = require("@user::pad.melt")
melt.wetness(t) -- 0..1, the gloss this slice puts on every confection surface
melt.capTopY(t) -- where the mesa's top surface actually is: it sags, then leaves
melt.stations -- the station each of shots 6, 7, 9, 10 and 12 was framed and checked at
melt.anchors -- capBaseY / capRadius / lipUnderside / dripHero / glacierSnout / burstAt
```
`melt.stations.first_drip` is the one that matters most: shot 6 is a 12 deg lens
1.3 m from a 14 cm bead, and every number in it — the eye, the look, the lens — was
found by looking at the frame. Moving the camera off that line loses the bead.
## Two things worth knowing before editing this
**Every animator here is a pure function of `t`.** The tower's collapse is solved in
closed form (`fallY` — ballistic flight with two analytic bounces), every "random"
number comes out of `frand(i, salt)`, a positional hash, and nothing accumulates.
A rigid body would integrate, and this film scrubs.
**Wetness is not written to the `.material` assets.** `Material.setProperty` and
`Model:setMaterialProperty` both land on the AUTHORED material — and that rewrites
its `mat.yaml` on disk, which at 24 fps is a file write per material per frame. So
`build()` mints a runtime twin of each authored material with
`renderer.material.create(def, key)` and points every entity of that colour at the
one twin with `Model:applySessionMaterial(handle)`; the per-frame ramp then writes
the twin through `renderer.material.setProperty`, which touches no file. The
`.material` files under `mat/melt/` stay the one source of truth for the FROZEN
look, and `makeRuntimeMaterials()` reads their values back off them rather than
duplicating the numbers here.
# place
The archipelago of *Pastel Astral Dream*: seven confection islands over a sea of
poured cream, in their act I state — hard, matte, dry, dusted with sugar frost, and
mirroring. Geometry, materials, the sea and everything that lives on the islands.
Serves shots **1** (the frost macro), **2** (the establishing wide), **3** (the skim
and its bow wave), **4** (the cliff crane and its crack), **8** (under the cream) and
**12** (the drained shallows).
## Exports
- `M.build()` — creates every entity. Idempotent; guarded on `pad_place_root` being
alive. Sets `M.anchors` whether or not it goes on to build, so the camera slice can
ask for a station regardless of who ran first.
- `M.rebuild()` — tears the whole slice down (ocean included) and builds it again.
- `M.attach(film)` — registers the `"place"` animator.
- `M.setSeaLevel(y)` — moves the cream surface, its bed and the sprinkles riding it.
`melt` may call this; this slice already drives it off `film.seaDrop(t)`, and the
two agree because they read the same number.
- `M.anchors.frostRidge` / `M.anchors.crack` — exact world points, walked off the
islands' own surfaces, for the camera slice to stand at.
- `M.geom` / `M.mats` / `M.isles` / `M.sea` / `M.props` — the submodules.
## What is here, and what moves
| entity | what |
|---|---|
| `pad_place_mesa` + `_strata_1..3` | the 340 m marshmallow mesa and its wafer strata |
| `pad_place_cliffs`, `_cliff_peak_1..11`, `_cliff_inner_1..4` | 400 m of meringue whipped into peaks |
| `pad_place_glacier_1..3` | the ice-cream glacier: pistachio under strawberry under vanilla, sheared down toward its snout |
| `pad_place_shelf` | the wafer shelf the glacier calves over |
| `pad_place_isleD/E/F/G` (+ `_strata`, `_peak_*`) | the four background islands |
| `pad_place_sea` | the cream sea — a spectral ocean, recoloured and calmed almost to a mirror |
| `pad_place_sea_bed` | the cream 1.5 m under the surface. Rides the surface, never strands. |
| `pad_place_floor` | the wafer floor shot 12 uncovers |
| `pad_place_wake_1..6` | the bow wave shot 3 sheds |
| `pad_place_float_*` / `pad_place_strand_*` | sprinkles, bobbing and stranded |
| `pad_place_puff_*` | marshmallow puffs around the island feet |
| `pad_place_frost_ridge` + `_frost_clump_1..26` | the 4 cm ridge shot 1 opens on, furred with frost |
| `pad_place_glaze_panel`, `pad_place_crack` | the candy glaze on the cliff face and the fracture that runs up it |
**Everything that moves here is a pure function of film time `t`:** the sea falls as
`film.seaDrop(t)` says, the floating sprinkles bob and turn on it, a bow wave sheds
from the skim camera at fixed film times and runs out across the mirror, the frost
fibres shiver (hardest as a grain of sugar-snow goes past, twice in shot 1), the
crack runs up the glaze between t 22.6 and 28.6, and the cream's own emission ramps
with `film.uplight(t)`. Applying the same `t` twice leaves the world bit-identical —
measured: two captures of the frost macro at t = 1.90 differ by 0.0.
## What other slices drive on this
- **melt** — sags `pad_place_mesa`, and ramps gloss/wetness by writing `roughness`,
`clearcoat` and `subsurface_radius` on the materials `mats.NAMES` lists. Use
`mats.ref("marshmallow")` etc. rather than typing the identity.
- **look** — every light, the grade, the exposure. This slice adds none. It DOES
capture the sky into the environment's sky slot (`environment.captureSky` +
`ensureSkyFallback`), because a reflective surface no probe covers reflects black
and the sea is the largest reflective surface in the film.
- **camera** — frames `pad_place_frost_ridge` for shot 1 and `pad_place_crack` for
shot 4; `M.anchors` carries both as exact world points.
## Notes
- Geometry is procedural and RUNTIME — `renderer.mesh.create`, no mesh assets — so
`build()` re-makes it on every scene load and there is nothing to keep in sync.
Every wobble comes from `geom.noise2`, which is a pure function of its arguments,
so the archipelago is identical on every build.
- `geom.island` is the one primitive every land mass is made of: a closed surface of
revolution over a footprint that need not be a circle, with a Catmull-Rom vertical
profile, a radius wobble and an optional world-space warp.
- The materials all bind `@builtin::shaders.pbr`, which carries subsurface, sheen,
transmission and clearcoat on one shader — marshmallow reads as translucent matter
through `subsurface_color` + `thickness`, and the sugar frost is the `sheen` lobe.
- **`absorptionColor` on the ocean is an extinction coefficient, not a tint.** The
brighter a channel is, the more of it the body of the liquid eats. A cream sea
wants a very dark absorption; the preset values (`#322c29`) are already dark for
that reason and a "cream-coloured" one renders black.
- **`ocean:configure()` reports values it does not apply.** The config table comes
back holding the new colours while the surface keeps rendering the old ones
(#11266). Everything this slice sets goes through `Ocean.attach` on a freshly
spawned entity, which is why `rebuild()` tears the ocean down by name first.
- A material write fans out to an `onAssetReload` callback on every script component
holding that material. Writing unchanged values across twenty materials put this
engine into a watchdog cascade that ended in SIGILL (#10525), so `mats.ensure`
writes only what differs and the cream's emission ramp is quantised to 32 steps.
# @user::pad.score — the sound
Three movements and six beds, all synthesised into `/source/@user/pad/audio/` as
`.soundClip` assets, all looping, all mixed by volume envelopes that are pure functions of
film time.
## Why envelopes and not cues
A cutscene cue does not fire on a seek — a seek re-derives the frame that time would have
produced rather than running the clock through to it. A film that scrubs therefore cannot
put a sound on a cue and expect to hear it. Everything here is instead a looping source
whose gain is `f(t)`. Seek to 62.5 and the tower is coming down in the mix because
`collapse(62.5)` is 0.94, not because something fired on the way past.
## What is playing
Three movements in D flat — one tonal centre, so they crossfade instead of colliding:
| clip | act | material |
|---|---|---|
| `pad_score_i` | cold starlight | high bells over a thin high pad, **no bass at all** |
| `pad_score_ii` | the nebula front | the same key warmed — mid pad, a low third, mid bells |
| `pad_score_iii` | the rise | a low drone under an arpeggio that climbs out of itself |
Six beds. Sugar snow and the sea's glow are non-spatial, because they are everywhere. The
front, the glacier, the tower and the column are spatial and stand where the thing that
makes them stands — and two of them MOVE: the front's emitter rides `film.frontX(t)` across
the archipelago, so in shot 5 the sound arrives from the left with the light, and the
column's emitter climbs 420 m with `film.column(t)`.
The ears are `film_ears`, flown to the camera's eye by `film.ears`. Nothing here adds a
second listener.
## What the mixer says
Read at six film times with `audio.observe()`:
| t | audible | rms | what is up |
|---|---|---|---|
| 4.0 | 2 | 0.051 | movement I + snow |
| 33.0 | 4 | 0.107 | I crossfading out at 0.03, II in at 0.63, the front arriving at 0.43 |
| 48.0 | 4 | 0.113 | II + front + glacier |
| 62.5 | 8 | 0.273 | the collapse at 0.88 — the loudest moment in the film |
| 90.0 | 4 | 0.181 | III + column + sea glow |
| 96.5 | 3 | 0.013 | everything going out under the fade |
## How the clips were made
A deterministic additive synthesiser, run once per clip from scratch: a sine table, an
LCG for noise, exponential-decay bells, LFO'd drones, a one-pole bandpass for the noise beds,
and circular reverb taps. **Everything is loop-seamless by construction**: every partial
frequency and every LFO rate is snapped to an integer number of cycles per loop, the noise
beds equal-power crossfade their own tail into their head, and the reverb taps read modulo
the buffer length so the tail wraps round. Stereo width on the score is a circular Haas
offset, which widens without breaking the loop.
Nothing here was generated by a service, so nothing here can fail to arrive.
# @user::pad.astral
The sky and the weather of *Pastel Astral Dream* — everything above and between
the islands. Serves shots 1, 2, 4, 5, 11 and 13.
| what | how it is drawn |
|---|---|
| the void, the starfield, the star showers, the pale ringed body with its turning rings, the nebula band | `pad_sky`, a `sky`-domain shader on the scene's `Skybox` |
| sugar snow — falling in act one, rising in act three | `pad_snow`, two volumes that ride the film's eye: a 2.2 m one for the macros and a 1500 m one for the wides |
| the nebula front and its crossing | `pad_nebula`, a slab of churning additive puffs flown along X by `film.frontX(t)` |
| the column of melt leaving the mesa | `pad_column`, coarse (reads from 4 km) and fine (shot 11 flies through it) |
| the sugar moths | `pad_moth`, a population with flight, a wingbeat and an updraught |
## How it is built
Every population is **one draw**. The mesh is a lattice of degenerate quads — all
four vertices of a quad at one point — and the vertex stage hashes each quad's
world cell into a grain, a puff, a droplet or a moth, then places, animates and
billboards it. Nothing is simulated and nothing accumulates: a piece's position
is a closed-form function of the film's clock, which is what makes the whole sky
a pure function of `t` the way `film.apply` requires, and what lets the whole
astral cost a handful of material-property pushes per frame.
A piece's identity comes from the world cell it stands in rather than from the
vertex, which is what lets a volume be snapped along with the camera without the
field appearing to slide: a snap of one whole cell lands every piece on a cell
that already looked like that.
The shaders read `film_t + (v.time - uniforms.time)` rather than `film_t` alone,
so the previous-frame evaluation the engine runs to take a motion vector lands
one frame back and the matter reports the velocity it is actually travelling at.
## Driving it
`build()` and `attach(film)` are what the film calls. Beyond those:
```luau
local astral = require("@user::pad.astral")
astral.pin(33) -- hold the sky at one moment, whatever clock the world is on
astral.pin(nil) -- follow the film again
astral.paint() -- re-push @user::pad.palette into every astral material
```
`pin` exists because this world is authored by several sessions at once and any
of them seeking moves every slice — a frame taken to judge the sky is otherwise
a frame of whatever moment somebody else was looking at.
## Where the numbers live
`cell` in `POPS` and `cell` in the matching material **must agree**: the shader
recovers a piece's identity with `floor(world_position / cell)`, so the lattice
and the shader have to agree on where the cells are. Everything else that shapes
a population — its size, speed, density, fade distances — is on the material, and
every colour comes from `@user::pad.palette` through `paint()`.
# @user::pad.shots — the cutscene that IS Pastel Astral Dream
Thirteen shots, 97.0 s, matching `film.SHOTS` boundary for boundary. `film.playFromTop()`
plays this; `film.seekTo(t)` scrubs it; every other slice follows its clock.
## What another slice needs from this file
```luau
local shots = require("@user::pad.shots")
shots.stations.frostRidge -- { 82.32, 180.36, 48.69 } shot 1's whole frame
shots.stations.dripLip -- { 0.00, 107.15, 173.98 } where the beads hang
shots.stations.dripBead -- { 0.00, 107.90, 174.05 } mid-travel, shot 6's aim
```
Those three are a contract. Shot 1 is 29 cm from a 4 cm ridge on an 8 deg lens and shot 6
is 3.8 m from a 9 cm bead on a 12 deg one — at those scales there is no framing slack, so
the coordinates were read OFF the geometry `place` and `melt` built rather than asserted at
them. If either slice moves its subject, the number here moves with it.
## Three things this file decided, and why
**Screen handedness was measured, not assumed.** Two cubes at +X and -X, a camera facing
-Z, one capture: `+X` is on the right. So screen-right is `cross(forward, up)`, which is
`(-forward.z, 0, forward.x)`. Every "drifts right", "pans left" and "the ringed body is low
right" in the shot list is derived from that. Shot 2's bearing was chosen so
`right · ringDir > 0` — it is the reason that shot looks down the chain from the -X end
toward +X/-Z instead of the other way round.
**Shot 2 looks DOWN the archipelago rather than across it.** All seven islands span 3.2 km
of X. At the plan's 900 m on a 34 deg lens they cannot all be in one frame — the arithmetic
is not close. Stationed off the -X end and looking down the chain, every island lands inside
±19 deg of centre against a 28.5 deg half-width, and they stack in depth, which is a better
picture than the one that was impossible. Shot 13 deliberately repeats that bearing.
**The handheld in shot 9 is in the AIM, not the eye.** The tower is 164 m away; a half-metre
wander of the camera is 0.17 deg and invisible. A 4 m wander of the look point is 1.4 deg,
about 5% of the frame — a breath.
## The two places the world was not what the plan said
- The meringue cliff face is at **z = 323**, not the 210 the plan implies. A camera at
z = 250 stands inside the cliff and renders nebula.
- The glacier is a three-tier slab across x 116..738, z -470..-132, not a narrow tongue. The
plan's 60 m standoff on its axis puts the eye inside tier one, which renders flat pistachio.
Both were found by capturing from the shot's own station, which costs one call and needs no
play and no clock. Do that for all thirteen before touching anything else.
# look
The light, the grade and the luma gate of *Pastel Astral Dream*. One animator,
registered as `"look"`, is a pure function of film time `t`: it aims and colours
the key, sets the milky ambient floor, drives the post-process chain
(`pad_bloom` + `padGrade`), and sets the lens — depth of field, film grain, a
small flare.
## The key is the sun field, re-aimed
There is no sun in this film. But the engine's sun field is the one light that
carries the cascade shadow set, and this film's arc is that its shadows invert —
so `pad_key`, a single `Light { kind = "directional" }`, holds it and carries
whichever source is the key at time `t`:
| act | source | direction the light travels | colour |
|---|---|---|---|
| I | cold starlight, high and behind | `-0.42, -0.62, -0.66` | `keyStar` |
| II | the nebula front, above and LEFT | `+0.74, -0.50, -0.45` | `keyNebula` |
| III | the cream sea and the column, BELOW | `+0.22, +0.95, -0.22` | `keyUnder` |
Direction, colour and intensity are one weighted blend of the three, so the key
**swings** through each transition instead of cutting. The weights are the film's
own drivers and nothing else:
```
nebK = film.frontAt(t, x) -- has the front reached here
undK = max(film.uplight(t), film.column(t)) -- the sea and the column
wUnd = undK ; wNeb = nebK * (1-undK) ; wStar = (1-nebK) * (1-undK)
```
`x` is the camera's own world X, taken from `film.eyeAt(t)`, so the light line
sweeps across the archipelago as the front does. `pad_key_ring` (the pale ringed
body) and `pad_key_bounce` (the sea's light, straight up) sit beside it as
`DirectionalLight`s and do **not** swing.
**Nothing else in this world may carry a `Light { kind = "directional" }`** — a
second one moves the sun rather than joining it.
## The grade
`@user/pad/grade/padGrade.shader` is one post-process pass doing the whole
photographic finish. One reading decides everything in it: whether a surface was
drawn at that pixel, read from reversed scene depth (`0.0` where nothing was).
That gate is what lets this film be high key **and** keep a dark sky — the
confection and the void are exposed separately (`exposure` / `skyExposure`) and
lifted separately (`lift` / `skyLift`), so both halves of the film's rule hold at
once. The highlight shoulder rolls on the brightest channel and scales all three
together, which is what keeps pistachio, strawberry and marshmallow from all
printing as the same white at this exposure.
## The luma gate
The gate is stated against the FINISHED frame, which carries the camera slice's
letterbox (`shots.letterbox = 0.08` per side — 16 % of the frame at the void
colour, about 22 luma off the mean). A capture taken while the cutscene is not
playing has no bars, so:
```
barred = 0.84 * unbarred + 2.6 unbarred 130..190 == barred 110..190
```
`M.EV[shot]` is the per-shot exposure in stops and is where the gate is tuned.
Measure with a capture from the shot's own station at its midpoint — the eye,
aim and fov come from `@user::pad.camera.poseAt(t)` — and read the mean luma of
the returned frame.
## Exports
- `M.build()` — spawns `pad_look_root` and its three lights; registers the chain.
Idempotent, guarded on liveness.
- `M.attach(film)` — registers the `"look"` animator.
- `M.at(film, t) -> table` — the whole look at `t` as numbers, reading nothing
from the world, so it can be printed and diffed without rendering.
- `M.midpoints(film) -> { number }` — the thirteen shot midpoints.
- `M.EV: { number }` — per-shot exposure in stops. The gate.
## Notes
- Exposure is **manual**. The `exposure` system's adaptation is an integrator and
settles over seconds, so the same seek would give a different frame depending
on where the clock came from; this film scrubs, so exposure is a function of
`t` on `padGrade` instead.
- Focus comes from `@user::pad.camera.focusAt(t)` when that slice is loaded. The
`LENS` table here supplies only fStop and focal length, plus a focus fallback.
- The one thing here that is not a pure function of `t` is `lensFx.tick`, which
advances the clock the film grain is drawn against. A capture that pins the
renderer's temporal clock (`deterministic`) pins it too.
- **Never cache a component proxy across frames.** A proxy's environment reaches
the engine's computed-property registry, and a cached one puts that registry
inside the graph every hot reload has to rebind — `@user::pad.film` reloaded
straight into the 4096-node budget because of it. This module keeps entity IDs,
which are strings, and re-resolves the component each call.
# palette
One-paragraph description of what this module provides and who consumes
it.
## Exports
- `M.exampleFn(arg) -> result` — what it does and when to call it.
- `M.exampleValue: type` — what value it carries.
## Usage
```luau
local M = require("@<youridentity>::modules.palette")
M.exampleFn("foo")
```
## Notes
- Anything callers need to know about THIS module: required runtime
ordering, state ownership, side effects.
# @user::pad.camera — the part of the camera slice that runs
The shot list itself is `@user::pad.shots`. This module does the two things that have to
happen every frame.
## 1 · It makes a seek frame a shot
`cutscene.seek` only reaches a cutscene that is PLAYING. Without this animator, a
`film.seekTo(40)` in edit mode moved the whole world to t = 40 — melt, front, sea, sound —
and left the camera standing wherever it was. Every capture of a "shot" was then a picture
of the world at the right moment from the wrong place.
So the `camera` animator evaluates the shot list and flies `film_camera` to it:
```luau
local eye, at, fov = cutscene.evaluate(def.shots, t)
```
That is the same code path the played cutscene uses, so the edit-mode frame and the played
frame are the same frame, and the same seek twice gives the same picture. It runs whether or
not a cutscene is playing — while one IS playing its own camera outranks `film_camera`
anyway, and keeping the two in step means `capture { camera = "film_camera" }` is always
valid too.
## 2 · It publishes the lens numbers nobody else should re-derive
```luau
local cam = require("@user::pad.camera")
cam.poseAt(t) -- eye, aim, fov
cam.aimAt(t) -- the aim point alone
cam.focusAt(t) -- focus distance in metres, INCLUDING the two racks
cam.stations() -- the macro stations, re-exported from the shot list
```
`focusAt` is the one the `look` slice drives depth of field from. Everything focuses on its
own shot's aim point except two:
- **shot 6** racks 3.8 m → 25 m as the bead detaches — off the bead, onto the marshmallow
flank behind it.
- **shot 11** runs 12 m → 60 m inside the rising column, so the droplets passing the lens
are sharp and the rest is bokeh.
## Notes
`build()` repairs `film_camera` if the scene lost it, and sets its near plane to 5 cm — shot
1 sits 29 cm off a 4 cm ridge, which is uncomfortably close to the 10 cm default.
Everything here is a pure function of `t`. The animator reads the shot list and writes a
transform; it keeps no state between calls and integrates nothing.