Skip to main content

Bindings and Retargeting

A sequence is built against particular instances in your place, but it rarely has to play against only those. Flow gives you three ways to point a sequence at something else, from the finest to the broadest.

Public bindings​

Promote a track's subject in the editor (Promote to Binding... in the track menu) and give it a name, and scripts can supply that subject per play:

door.Touched:Connect(function()
Flow:Play("DoorOpen", { Bindings = { Door = door } })
end)

One DoorOpen sequence now serves every door in the game. A binding remembers the class of the subject it was promoted from, and warns if you pass an instance of a different class. Passing an instance for a binding that hasn't been promoted warns and is ignored, so the hidden bindings behind directly assigned subjects can't be overridden by accident.

Container bindings​

A promoted binding marked Container in the Inspector stands for a whole set of instances. Tracks bound to instances inside it store paths relative to it, so passing a different container retargets all of them:

-- Every track bound inside the "Chandelier" container follows the new model
Flow:Play("ChandelierSwing", { Bindings = { Chandelier = workspace.Hall.Chandelier2 } })

The root​

Every directly assigned subject is stored as a path below the sequence's root. Pass a different root to move the whole sequence at once:

-- Plays the cutscene authored in Room1 against an identical Room2
Flow:Play("RoomIntro", { Root = workspace.Room2 })

When the root is a part or a model, its pivot is the sequence's origin and stored positions are relative to it, so the sequence plays in the new room's position and orientation, not the original's. When the root is game, a Folder, or a ScreenGui, positions are absolute.

Root is a local playback option; a synced playback uses the root saved with the sequence.

Sequence parameters​

Sequence parameters are named values a script can override per play. Add them under Sequence Parameters in the Inspector (with nothing selected), then pass new values in Parameters:

Flow:Play("DoorOpen", { Parameters = { OpenAngle = 120 } })

Built-in section types don't read sequence parameters. They exist for custom section types, which read them with context:GetSequenceParameter(name). See Section types.

How a subject is found​

When a sequence plays, each track's subject is resolved in this order:

  1. An instance passed in Bindings, for a promoted binding.
  2. The binding's subject preset, if it has one.
  3. The stored path under the root, if the instance there carries the id the editor stamped on it.
  4. A search under the root for an instance with that id. This finds a subject that was renamed or moved.
  5. The stored path, even though the id doesn't match, with a warning. This covers an instance that was deleted and rebuilt.
  6. Nothing: the track is skipped with a warning, and the rest of the sequence plays.

Steps 3 to 5 are why directly assigned subjects are safe to rely on: you can rename and reorganize your place and the sequence still finds them.