M6 Float
Characters and props can float. The Marigold's running gag, gag.kettle_gravity, says:
"Whenever the bridge kettle boils, the ship's artificial gravity hiccups: everyone floats
for a beat, then drops." Two watch-its wrote it ("All three float a foot off the deck and
hang there for a beat. Gravity THUDS back.", "The three of them drift up off the deck, mugs
and all"), and nobody floated. Only the sounds carried the gag.
Read with docs/design/m1-compiler.md (timing, blocking, performance channels),
docs/design/m1-engine.md (the sampler, the card), docs/design/m6-performance.md
(stepping, squash) and docs/design/m6-props.md (held and loose props).
What a float is
- Gravity lets go of some people for a while. Their feet leave the floor, they rise, they hang there weightless, and they come down. The floor point under them does not move.
- Rise. Up to the height over 0.7 s, eased in and out, each a few frames apart.
- Hang. A slow bob (a tenth of the height, up and down every 1.6 s) and a small drift (4 cm or so, a slow wander), different for each of them. Arms drift up and out and the legs dangle. That, more than the height, is what reads as weightless.
- Landing.
drop(the default): gravity comes back at once. They fall the way things fall (a third of a second from a foot up), accelerating, and land together on the landing frame. A little squash on impact, as much as the style'ssquashStretchallows.settle: they drift down over most of a second and stand.
- The feet are back on the floor exactly on the landing frame, and stay there.
- Postures. A float lifts whatever posture they are in. Someone seated floats up off the seat still sitting, and comes back down into it; someone crouched behind a console floats up crouched, cap first. Only standing legs dangle.
- Props.
- Held props go with the hand. Nothing new: a held prop is drawn at the hand the card drew.
- Loose props float only when the cue says everything does (
props). Then every prop the scene stands somewhere (on an element, at a mark) rises off it with its own drift, and lands back on the same spot. A prop picked up mid-float leaves its float for the hand. Set dressing that is no prop of the show stays put: it is part of the set. - (implementation) A held prop let go of mid-float (a
let_goprop cue, EpisodeIR 1.12: "bobs up out of the Captain's hands") hangs where the hand left it and floats there,propsor not, until the float lands; then it falls to the floor beneath.
- Shadows. A blob shadow stays on the floor under the body, and shrinks and fades as
they rise. A projected shadow (
groundShadow: projected) falls where the light puts it, as it always does. - The camera does nothing special. The framing solver sees the lift (eye points rise with it), so a shot that starts mid-float frames them where they are. The heuristic director goes wide for the float.
The data
EpisodeIR 1.7. A new cue, float:
{ "type": "float", "id": "a05f1", "heightM": 0.3, "until": "a06s1", "landing": "drop",
"from": "a05", "at": { "with": "a05", "offsetSec": 0.4 } }
characters: who floats. Left out: everyone on stage when it starts.heightM: how high the feet hang off the floor. Default 0.3 (a foot), 0.05 to 2.durationSec: from leaving the floor to landing. Default 2.5.until: the cue they land on. The feet are back on the floor as it starts, so a THUD lands on the impact. Withuntil,durationSecis not used.landing:droporsettle.props: loose props float too.- In the cue chain a float lasts its whole span, or, with
until, its rise. A float that lands on a later cue lets the scene play on under it, as a held gesture does. - Whoever adds a float raises the episode's
schemaVersionto 1.7. (implementation)core/src/director/versions.ts(FLOAT_SCHEMA_VERSION,neededVersion) says so for both directors andedit_episode, as for every other feature. An episode that also walks up to someone (1.8) is 1.8.
Timeline 1.7. Both additions are optional, so a Timeline without floats keeps its bytes.
Actor.floats: one span per float. The cue (id),startFrame(the feet leave the floor) andendFrame(they are back on it),heightM(the hang height), andoffset: keys of the body's offset from its floor point (x, y, z in meters), interpolated with each key's ease, as position keys are. The first key is atstartFrameand the last atendFrame, both zero.squash: after a drop, the figure squashes byamounton the landing frame and recovers overframes.
ScenePropPlacement.floats: the same spans for a loose prop, on top of where it stands.
The compiler decides the curve; the engine only interpolates keys.
The compiler
core/src/compile/float.ts, after blocking, before the cameras.- Who. The cue's characters, else every actor visible as it starts.
- When. From the cue's start to the landing: the
untilcue's start, else the start plusdurationSec. A landing before the rise has finished is a warning (float.too_short) and the float takes its default length. - Each of them gets a stream seeded by the actor's seed and the cue's id. It draws the rise's delay (up to 3 frames), the height (±12%), the bob's phase and the drift's direction. The same episode floats the same way every time.
- Keys. A key at the start (zero), at the top of the rise, then one every half bob (high, low, high…) with the drift, eased in and out between. The fall starts where the hang curve is at that frame, eased in (accelerating), and the last key is zero on the landing frame. A settle eases down.
- The ceiling. An interior's ceiling stops the rise: the top of the head stays 5 cm under it.
- Tracks. Each actor's track carries the offset, so body points (eyes, head) rise with it. The framing solver, look targets and film grammar see what the engine draws. A look at someone who floats follows their eyes up and down, as it follows a walk.
- Props. With
props, each scene prop standing on a place when the float starts floats over it, with its own drift and the same landing. - Version. A Timeline with a float says 1.7.
- (implementation)
core/src/compile/float.ts:planFloatstimes each cue,floatActorsputs the spans on the tracks (ActorTrack.floats,liftAt;pointAtadds the lift) andfloatPropson the scene's placements. A half bob is 0.8 s, so the keys come every 19 frames at 24 fps; a 3 s float is about eight keys. A floater named but not in the scene isfloat.not_on_stage, one already off the floorfloat.overlap, and anuntilthe scene lacksfloat.until_unknown; each warns and floats no one new.
In the engine
- Sampler.
RwActorStategainslift_m(the offset),float_weight(0 on the floor, 1 at the hang height) andsquash. All are read at the stepped frame (characterStep), as every actor channel is, so a float on twos moves on twos. The sampler stays a pure function of the frame. - Card. The quad is placed with its feet on the floor point plus the lift. The blob shadow stays on the floor under the body: it shrinks and fades with the height.
- Pose. By
float_weight: the arms drift up and out from the shoulders, the elbows soften, and standing legs dangle (knees bent a little, toes down, one leg more than the other).squashscales the figure about its feet, as a posture change's squash does. - Looks and reaches are taken from the lifted body, so a floating character looks at a floating partner level.
- Props. A held prop follows the drawn hand up. A loose prop with a float span is drawn at its place plus the offset.
- (implementation) A dangling foot points its toes down, so it hangs a few centimetres below the line the sole stood on; the body is lifted, so it never reaches the floor. Someone seated floats up still sitting, knees bent as on the seat, and the hands leave the lap as the arms open out. A held gesture (hands behind the back) keeps its arms. The blob is 1 / (1 + 1.5 h) of its size and 1 / (1 + 2.5 h) as dark at h metres up: at a foot, two thirds of its size and just over half as dark.
The director
The heuristic director reads floats from the action.
- Floating: "floats", "float(s) up / off the deck", "drift(s) up", "hang(s) in the air", "weightless", "the gravity hiccups", "gravity cuts out (fails, goes)".
- Landing: "gravity THUDS back (comes back, returns)", "drop(s)", "land(s)", "fall(s)",
"come(s) down", "hit(s) the deck (floor, ground)" make
drop; "drift(s) down", "float(s) down", "settle(s)" makesettle. A landing in the same sentence as the float ("floats for a moment, then drops") ends it there, a beat long; a later one ends it on that sentence's sound (the THUD), else on its paragraph. - Who: the characters a sentence names; "everyone", "all three", "the three of them", "both", "they", or nobody named, is everyone on stage.
- How high: "a foot" (0.3 m), "two feet", "an inch", "a metre".
- Props: "everything", "mugs and all", or a show prop named in the sentence.
- Several float sentences before a landing are one float ("The gravity HICCUPS. All three of them float a foot off the deck"). A negated clause ("nobody floats", "does not float") makes none.
- A float with no landing written lasts 2.5 s. One that lands in its own sentence keeps its paragraph on screen until they are down.
- Coverage. The float goes wide: a shot that holds everyone floating, as a walk does.
- (implementation) Read in
core/src/director/action.ts(floatIn,namesProp) and played inheuristic-perform.ts; the cue isaNNu1("up"). A clause whose subject is nobody ("but nothing floats this time") makes no float either. A paragraph that starts a float holds at least 2 s from it, so they rise and hang before the next line. - (implementation) The wide cuts in 0.35 s into the float, half way up: the framing
solver frames them where they are at the cut, so an LS keeps rising heads in, and the
cut lands on the action. It is a set's setup that shows everyone both then and a second
in, else an LS on them, and the framing balance never re-sizes it. A line too short for
a shot of its own plays in it rather than take its time: the ninth watch-it's "Found it!"
did, and the whole float played on a medium shot of Otto. The balance no longer
re-sizes an establishing shot either: the kettle screenplay showed it could tighten one
to MLS (
grammar.no_establishing). - (implementation) "The gravity HICCUPS" boiled the kettle: the kettle's boiling state says the gravity is about to hiccup, and "The" of "The bridge kettle" counted as naming the kettle. A prop is now named by a word of its own, not by "the".
The model director gets the float cue in its performance schema, and the brief says when
to use it.
Drifting
What happens in the air plays out. The tenth watch-it wrote "Otto plants her feet on the Captain and pushes off. The Captain spins gently away" and "Otto darts across to the Chief", and they played as pauses and a walk on nothing.
- Data: a
driftcue (EpisodeIR 1.11) hasaway(a character, element or mark pushed off),toward(one drifted to),spin(whole turns; negative the other way), and optionaldistanceManddurationSec. - Compiler (
core/src/compile/drift.ts):- A drift moves the floor point under the body, as a walk does without the steps. The
float keeps them up, they come down where they drifted to, and a later walk starts
there. Route planning (
planDrift) fixes each drift's glide in cue order, as it fixes walks. - A push carries 0.6 m along the line between them. Whoever was pushed off goes the
other way as far, since things push back without gravity. A drift toward someone goes
up to beside them (0.9 m short), or
distanceMof the way. Everything stays 0.3 m inside the walls. - A drift toward something comes to rest clear of everyone else (0.6 m) and the furniture (0.25 m): where the straight way ends, else as near as that round what they drift to (30° at a time either way, up to 90°), else short of it on the way. The eleventh watch-it's Otto and Chief both drifted "toward the kettle shelf" and came down 4 cm apart, one inside the other.
- The scene's axis lapses while the pair floats and is drawn again where they land
(
docs/design/m1-compiler.md, "Legal side"), so cameras stay in the room after a drift turns the old side to a wall. - The glide eases out over
durationSec. The default is 1.2 s, longer for a long way at 1.5 m/s. A spin keys the facing every quarter turn, so each step turns the short way round. - In cue order with the walks, a drift stops a walk still under way (they are off the floor) and glides from where the body is, by the push. A walk starts from where the body really is.
drift.not_afloatwarns when someone is on the floor as a drift starts: they slide. (implementation) A spin alone moves nobody, so on the floor it is a twirl on the spot and says nothing.
- A drift moves the floor point under the body, as a walk does without the steps. The
float keeps them up, they come down where they drifted to, and a later walk starts
there. Route planning (
- Director: while a float is under way, it reads "pushes off the Captain" and "plants
her feet on him and pushes off" (off whoever else the sentence names) as
away. "Spins", "twirls", "tumbles" and "somersaults" makespin(two turns for "twice"). "Drifts" or "floats over to" someone or something maketoward, and so does a walk written mid-float, since nobody walks in the air. The paragraph holds until a drift toward someone arrives, so gravity does not come back first. Outside a float none of this drifts anyone.
Editing
edit_episode gains set_float: add a float (who, how high, how long or until which cue,
the landing, whether props float, and when), or change one by its cue id.
(implementation) Also remove, refused while a cue or a shot is timed from it. A new
float is uNN unless named; characters: [] floats everyone again, and until and
durationSec replace each other.
Watch it
A scratch copy of Marigold with the Captain on the bridge. The kettle boils and WHISTLES, the gravity HICCUPS, all three float a foot off the deck and hang there for a beat, and gravity THUDS back. Directed heuristically, voiced, rendered on lavapipe, with a strip of the rise, the hang and the drop.