Follower, holds, fades, animated frames
Music playback and overlays internals
One owner of the music channel per client that follows a shared timeline, plus the generalized animated-overlay renderer used by atmosphere, intros and scares.
1. The local follower
Cinematic has no soundtrack of its own. A mission or a feature supplies a source callback that returns a descriptor, and every client follows the same published timeline.
private _token = ["missionAtmosphere", createHashMapFromArray [
["source", {missionNamespace getVariable ["myMusicState", []]}],
["gate", {if (missionNamespace getVariable ["myIntro", false]) then {"yield"} else {"active"}}],
["fadeOut", 1.5], ["fadeIn", 2], ["descendingFade", 10]
]] call FF_cinematic_fnc_musicStart;
The descriptor is [CfgMusic class, measured duration, start serverTime, volume, loop, rank, mode]. Start returns a
positive ownership token or -1. Duration must be finite, positive and at most one day; start is bounded to
±1 billion seconds; volume is clamped 0–1 and rank to -100–100. An empty track means silence; an empty source array means
"no valid snapshot yet", so it neither acquires nor stops audio. Invalid snapshots leave playback untouched.
| Call | Side | Purpose |
|---|---|---|
musicStart(ownerID, config) | Local client | Acquire the channel with a source and gate; returns token |
musicStop(ownerID, token) | Local client | Release; the token prevents an old scene from stopping a replacement |
musicHold(holderID, held, haltNative) | Local client | External ownership of the channel, up to 32 named holds |
musicPlan(previous, next, time, track, fades) | Local | Transition planning: switch time, fades, completed one-shot |
musicOffset, musicSelect, musicSelection, musicTick, musicCatalog, musicOverrides, musicRequest, musicRelease | Local / server | Seek maths, selection helpers and director-side support |
The channel has exactly one owner: a second identifier cannot acquire the follower until the first stops, and reusing an
identifier replaces its configuration and cancels the previous follower. Both APIs reject remote execution — call them
locally on the clients you mean. A single 0.2 s CBA worker drives playback and MusicStop handles real track ends.
Equal class/start/loop descriptors never restart music; volume-only changes fade over two seconds. Looping tracks seek to
elapsed time modulo their length, including late join; one-shots seek but never restart after their duration.
2. Gates and external owners
The optional gate callback returns active, stop or yield. Stop halts and restores an owned
track and waits; yield gives up native identity without touching audio, letting an already-active external owner keep
playing. An external system claims the channel before it starts playing:
["briefing", true, true] call FF_cinematic_fnc_musicHold;
// play briefing music here
["briefing", false] call FF_cinematic_fnc_musicHold;
Native playback resumes only when every hold has ended. The third argument halts the current native track before the
takeover; pass true when taking over, because false does not cancel an already-scheduled engine
fade. The same call exists as the local CBA event FF_cinematic_musicHold, which is how the Utils ready room
coordinates its bed without depending on Cinematic.
3. Animated overlays
The overlay renderer generalizes the atmosphere and scare picture layers: named overlays, weighted frame sequences, bounded animation cost and clean replacement.
| Function | Purpose |
|---|---|
overlayStart(id, config) | Starts or replaces a named local overlay; returns a token or -1 |
overlayConfig(input) | Validates and normalizes configuration, bounding animation cost |
overlayFade(id, target, time) | Fades one overlay without restarting it |
overlayTick / overlayStatus | Frame worker and read-only status |
overlayStop / overlayStopAll | Release one overlay by token, or every owned overlay |
Public state is FF_cinematic_overlays and FF_cinematic_overlayPFH, with
FF_cinematic_overlayGeneration invalidating stale callbacks. Horror keeps its themed frames and its fade/control
keys as themed presets; the renderer itself lives here.
4. Camera helpers
prepareCameraPath(frames)validates and expands weighted frames[positionASL, rotation, [FOV, weight, …]]without touching game state; invalid or oversized input returns an empty array.animateCamera(camera, frames, duration, smooth, onComplete)drives a supplied camera along those frames and returns a CBA frame handler (or-1). Spectator uses exactly this driver, which is why camera transitions there are cancellable.
5. Limits
Verified offline: descriptor validation, seek offsets, transition planning (loop modulo, expired one-shots, future starts, silent startup, descending transitions, completed priority tracks) and overlay configuration bounds. Not verified: real audio, track-end events, seek accuracy, volume restoration, ready-room/intro/death handovers, JIP and mission cleanup.
Related functions
FF_cinematic_fnc_musicStart— Acquires the local music follower with an explicit source and channel gate.FF_cinematic_fnc_musicStop— Stops the named follower, with optional ownership-token protection.FF_cinematic_fnc_musicHold— Adds/removes a local external music-channel hold before another system takes ownership.FF_cinematic_fnc_overlayStart— Starts/replaces a named local animated overlay and returns its ownership token.FF_cinematic_fnc_animateCamera— Animates a supplied camera with weighted Bezier frames.FF_cinematic_fnc_prepareCameraPath— Validates and expands weighted camera frames without changing game state.