INSODIMENSIONStudios
CameraReference

Cinematic Shot Flows

The experimental UAgenticShotFlow asset — roles, segments, curves, movement models, corrections and playback in Agentic Gameplay Camera

Cinematic Shot Flows

Experimental. The cinematic half of this plugin — UAgenticShotFlow assets, the Sequencer flow track, the Stage rehearsal room and the editor toolsets — is Experimental in this release. Its API and asset formats may change between versions. The gameplay camera is the Beta half and does not depend on any of this.

A shot flow is authored coverage that is subject-agnostic: it names roles rather than actors, so one flow performs for any cast, anywhere. Everything that plays authored camera work — a runtime call, a Sequencer section, the editor Stage — reads the same asset and drives the same flow cursor, so what you approve in rehearsal is what plays in the game.

There is no DataTable and no JSON import for flows. Discovery is tag → asset: FlowTag is registry-searchable, so the camera registry finds the asset from the Asset Registry with nothing to configure.

Two flows ship with the plugin, under /AgenticGameplayCamera/Cinematic/Flows/:

AssetTagWhat it is
SF_Dialogue_ShotReverseAgentic.Cinematic.Flow.Dialogue.ShotReverseShot/reverse-shot coverage for two characters 2–5 m apart. Roles A and B, both required, head as the default bone. Establishing full shot at 35 mm, then two mirrored over-the-shoulder mediums at 50 mm that cut between each other and hold until a line-done signal.
SF_Combat_ExecutionAgentic.Cinematic.Flow.Combat.ExecutionTwo beats: the blow, then the landing. Roles Attacker and Victim. A 40 mm low medium, then a 0.7 s 85 mm close-up on the victim. Interrupt policy Sacred — a scripted kill gameplay can interrupt is not a scripted kill.

The Asset

FieldMeaning
FlowTagAgentic.Cinematic.Flow.<Family>.<Name>. The word a caller uses. Registry-searchable.
DescriptionOne line for the catalog.
UsageHintThe staging the flow assumes — "two characters 3–8 m apart".
RolesWhat must be bound at play time.
SegmentsThe timeline, in order.
PolicyEnd conditions, interruption, corrections, inserts.
RehearsalThumbnailPathA file path written by the Stage's publish step, not a texture reference.

The asset's own Validate is structural only — a valid tag, at least one segment, every subject role declared, no duplicate role names — and that is what the editor's data validation reports. Whether the film grammar is any good is a separate judgement, made by the evaluator against a rehearsal.

Roles

FieldNotes
NameReferenced by a segment's subjects and by Weight.<Role> curves.
KindCharacter (skeletal, bones meaningful), PointOfInterest (a landmark), Path (a camera path spline actor).
DefaultBoneAim socket for subjects that do not override it. Character only.
bRequiredPlayback refuses to start when a required role is unbound.
DefaultSubjectTagAuto-binds from the subsystem's subject registry when the caller binds nothing.

Register subjects once and let the flows bind themselves:

Subsystem->RegisterSubject(SpeakerTag, SpeakingActor);
Subsystem->RegisterSubject(ListenerTag, ListeningActor);
Subsystem->PlayShotFlowByTag(DialogueFlowTag, FAgenticFlowBindings());

Segments

A segment says when a shot starts, how it arrives, when it ends, and which of its values animate.

FieldNotes
NameLabel.
ShotThe shot itself: subjects, placement, framing, lens, intent.
EndOnHow the segment ends — see below.
TransitionInThe blend runs at the start of the incoming segment.
CurvesNamed curves over segment-local 0..1.
PinOptional world-space pose override.

A new segment starts out physical and composed: a 35 mm focal length, dolly-only group adjustment, head-room on, and a little lead room. So a flow shot moves the camera to its framing rather than zooming to it.

Ending a Segment

ModeBehavior
DurationEnds after Duration seconds.
SignalHolds until its signal tag is raised.
ExternalHolds until the orchestrator calls continue.

For Signal and External, Duration is only the estimate used for seeking, duration reporting and the Sequencer projection. It is never a timeout — a held segment holds.

A Duration segment's overshoot carries into the next segment, so boundaries never round up to a frame.

Transitions

Cut or Blend, with a time and a curve (the same curve vocabulary as the gameplay side: linear, ease in/out, overshoot, bounce, snap, anticipation, smoothstep, elastic, expo-out…). A cut has zero duration by definition.

Pins

A pin replaces the framing solve for its segment: placement, movement model, smoothing and the collision probe all stand down and the authored poses are honored exactly. Corrections still run. Key times are segment-local seconds, not normalized — a signal-held segment has no known length, so clamping at the last key is the honest answer.

A pin is world-space and therefore level-bound. Curves port to any cast in any set; a pin does not.


Shot Size

Two fields can name a shot's size, and they are not the same thing:

  • Framing.Size is the control the distance solve reads: aim at this band.
  • Intent.SizeStart is the assertion the contract checks: this shot is a close-up.

Explicit control always wins; an undeclared control falls back to the intent, so a shot that only asserts its size is still aimed at that band. A genuine disagreement — both declared and different — is reported as a warning rather than silently resolved.

Bands are frame height in centimetres at the subject's depth. They are contiguous and total, and a boundary belongs to the tighter size.

SizeBand (cm)Automatic head-room
ExtremeCloseUp0 – 35−0.15
CloseUp35 – 750.08
MediumShot75 – 1900.12
FullShot190 – 3200.15
LongShot320 – 1000000.20
Unspecifiedframe-fill fit0.10

The solve aims at a band's geometric centre so the result classifies back to the same size. When a pose is unachievable, a fixed degrade ladder runs — loosen the size one band, swap the orbit side, raise the height — and every step it took is recorded rather than hidden.

Curves

The curve vocabulary is fixed and closed; an unknown name is rejected, not ignored. Every curve is relative to the pair frame — origin at the weighted group centre, x along the line of action, z up — so the same move plays for any two actors anywhere. A present curve overrides the shot's static value for that segment; an absent one leaves it alone. Curves run first, so a movement model composes on top of them.

CurveUnitWrites
Weight.<Role>0..1That subject's framing weight
Heightcm above group centrePlacement height
Distancescale on the solved distance (1 = as solved)Placement distance scale
Orbitdegrees in the orbit reference framePlacement orbit
RolldegreesPlacement roll
FocalLengthmmLens focal length
Aperturef-stopLens aperture
FrameFillfraction of frame heightFrame fill (size Unspecified only)
PathAlpha0..1 along a Path role's splineConsumed by the Path model only

Movement Models

A shot holds one primary model and any number of layers. A model is a pure function of segment-local time and never touches the world: where a move needs level content it publishes a request naming roles, and the world-aware caller fulfils it.

ModelSlotNeedsEffect
Staticprimary—Holds the pose solved at segment start.
Trackprimary—Follows with a dead zone (8 cm by default), smoothed by the shot's own smoothing.
Orbitprimary—Degrees per second on the orbit — a rate, not a sweep.
PushInprimary—Distance scale 1 → an end scale over a curve. The lens never moves.
DollyZoomprimary—Focal length to an end value with distance scaled by the focal ratio. No-op on a non-physical lens.
Pathprimarya Path role, and a look-at role that is a subjectRail travel with manual progress along the spline.
POIDriftprimarya PointOfInterest role that is a subjectDrifts the pair-frame offset toward the point at a speed; the solve re-aims.
RackFocuslayera from-role and a to-role, both subjectsLens only. The pose is identical with and without it.
Handheldlayer—Adds amplitude onto the shot's own shake; sets frequencies only where the shot declared none.

A layer placed in the primary slot is rejected by the validator, not quietly ignored. The primary runs first, then each layer in author order.

There is deliberately no Crane model — a crane is the Height, Distance and Orbit curves on a segment.


Policy

FieldNotes
InsertsSignal → flow pairs: reaction flows played over the top.
InterruptSee the table below.
bLoopRestart from the first segment at the end.
EndActionReturnToPrevious, SwitchToMode, Hold or Custom.
EndModeTagThe gameplay mode tag for SwitchToMode.
BlendInTime / BlendOutTimeView-target blend onto and off the shot camera. Default 0.3 s.
CorrectionsCorrection objects, run in priority order.

Interruption

The policy is read from the flow currently playing, so an insert can declare its own answer.

PolicyResultWhat happens
SacredIgnoredNothing moves. Only an explicit segment skip gets through.
YieldAbortedThe flow ends as interrupted, the view blends back to the pawn, and the end action does not run.
ResumeSuspendedThe view blends back to the pawn and the cursor is kept — same segment, same elapsed time, same cast — until you resume it.
ReactThenResumeReactedThe signal is offered to the policy's inserts; the reaction plays over the top and the interrupted segment resumes itself. With no matching insert, the signal is ignored.

Interrupting never releases a segment's signal hold, so raising a signal keeps its one meaning.

Corrections

Four correction classes ship, each declaring its own tag:

ClassTag
CollisionAgentic.Cinematic.Correction.Collision
ConstraintsAgentic.Cinematic.Correction.Constraints
DitheringAgentic.Cinematic.Correction.Dithering
ShakeAgentic.Cinematic.Correction.Shake

Each has bEnabled and a Priority (lower runs earlier; 100 by default). A correction reports true only when it actually moved the camera, which is what makes the trace a record of what fired rather than a list of what was configured. This is the same source-agnostic pipeline the gameplay corrections use.

Occlusion is not a correction: a blocked pose goes through the degrade ladder and is reported as occluded frames on the trace.


Playback

Reach the subsystem with Get Cinematic Subsystem (from a player controller) or its world-context variant, then:

CallPurpose
PlayShotFlow(Flow, Bindings)Play an asset you already have.
PlayShotFlowByTag(FlowTag, Bindings)Resolve the tag through the registry and play it.
StopShotFlow(bBlendOut)Stop; the view blends back to the pawn over the policy's blend-out time.
ContinueShotFlow()Release an External segment — the orchestrator's "next".
SkipShotFlowSegment()Advance as if the segment had ended. Works while paused and while holding, and is the one input a Sacred flow still takes.
SeekShotFlow(FlowTime)Jump to an absolute flow time — what a Sequencer scrub calls every frame.
RaiseCinematicSignal(SignalTag)Release a Signal hold, or trigger an insert.
InterruptShotFlow(Signal)The gameplay seam; returns what the policy decided.
ResumeShotFlow()Continue a flow suspended by a Resume interruption.
IsPlayingShotFlow() / IsShotFlowSuspended()State queries.
GetActiveShotFlow() / GetShotFlowBinding(Role) / GetShotFlowTime()What is playing, who is bound, and where the cursor is.
RegisterSubject / ClearSubject / ResolveSubjectThe subject registry that feeds role auto-binding.

All of these are Blueprint-callable.

The three doors — a direct call, a Sequencer flow section, and the editor Stage — drive one player, so behavior does not fork by entry point. When an external driver such as Sequencer owns the clock, it takes time control and advances the flow with its own frames.

Playback is deterministic: the same flow, the same tick deltas and the same signals produce the same events.

What the Trace Reports

One trace entry is opened per segment entry, so a looping flow records each pass. Every field is measured, never requested: the transition kind and time, when the segment was entered, how long it held, which side of the line the camera was on, the requested and solved size, how many degrade steps ran, whether the pose was still unachievable, the occluded / clipped / out-of-reach / solved frame counts, and which corrections fired.

A flow ends as Completed, Stopped, Replaced, Skipped or Interrupted, and the most recent completed trace stays readable afterwards.


Authoring and Rehearsal (Editor Only)

The Stage is a rehearsal room shipped as /AgenticGameplayCamera/Stage/L_Stage: it spawns stand-ins for a flow's roles, plays the authored sequence for real, and can capture a PNG sequence and a WAV of the session with measured frame intervals. Its settings live under Project Settings → Plugins → Agentic Camera Stage.

The Stage, the flow catalog and the authoring tools live in the Editor modules (AgenticCameraEditor and AgenticCameraToolsets), so they are absent from a packaged game entirely. Rehearsal is a development activity; only the runtime flow playback, which lives in the Runtime module, ships in your game.

With Epic's Experimental ToolsetRegistry plugin enabled, the same surfaces are exposed to an agent as toolsets: list the flows, describe one (its roles, per-segment shape, exposed curves, staging hint, and the schema the authoring calls accept), and export the whole catalog as JSON. The catalog is generated from the flow assets on every call and never stored, so it cannot drift from what would actually play. Export is one-way — nothing reads a flow back from JSON.

Without ToolsetRegistry, IsAvailable reports false and the toolsets are simply absent. The camera and the flows behave identically.

Sequencing flows into a scene — who speaks, what happens next, when a flow plays — is deliberately not in this plugin. A shot flow performs authored coverage against whoever is bound; deciding that beat 6 follows beat 5 belongs to your own narrative or quest system, which drives this camera by playing a flow tag.