What is FPlaybackCapabilities?

Hello Epic Games Developers / Community,

I’ve been looking into the FPlaybackCapabilities class, defined in “Runtime/MovieScene/Evaluation/PlaybackCapabilities.h”

, and I’m trying to fully understand its role within the MovieScene evaluation system. My current understanding is that FPlaybackCapabilities acts as a flexible container or “buffer” associated with a playback object. It seems designed to hold heterogeneous capability objects (potentially inheriting from IPlaybackCapability using different storage methods (inline, raw pointer, shared pointer)..To ensure I’m understanding this correctly and can use related concepts effectively, I would greatly appreciate it if you could clarify the following:

  1. Design Intent: What was the primary motivation for creating the FPlaybackCapabilities system? What specific problem within MovieScene’s playback or evaluation architecture does it solve?
  2. Intended Usage: How is FPlaybackCapabilities typically used within the engine? Are there common scenarios or best practices for interacting with it? Is it primarily intended for internal engine use, or is it designed for game developers to extend or utilize directly?
  3. Relationship with Other Systems: How does FPlaybackCapabilities relate to or interact with other key classes like FSharedPlaybackState, IMovieScenePlayer, UMovieSceneEntitySystemLinker, and the Sequencer evaluation loop itself?
  4. Extensibility: Are game developers expected or encouraged to define their own custom capability types (inheriting from IPlaybackCapability FPlaybackCapabilities or similar) and add them to an instance? If so, are there any guidelines or examples for doing this safely and effectively?
  5. Documentation: Is there any official documentation, articles, or examples describing the FPlaybackCapabilities system?

Hello!

Design Intent: the problem we were trying to fix was two-fold.

On one hand, we have Sequences that can be played from a variety of “playback situations”, each with different “things they can do”, or, well, “capabilities”. For instance, a level sequence can set the view target (via a camera cut track) but that doesn’t make sense for a Niagara Sequence or a UMG Widget Animation. Some Sequences may or may not have a Director Blueprint, support broadcasting Blueprint events, and so on. So we had a lot of accumulation of virtual methods on the IMovieScenePlayer interface, with some implementations stubbing methods out. We didn’t want to keep accumulating virtual methods on this interface, and wanted a more modular approach… breaking that interface into multiple interfaces, basically. So now we can query the FCameraCutPlaybackCapability to see if we can run a camera cut track and set the view target.

On the other hand, the IMovieScenePlayer interface was designed to be implemented with a UObject underneath. This was starting to be problematic for optimization efforts, especially for UMG Widget Animations. You could easily get hundreds of animated widgets on screen, and each one would have a UObject allocated for playing the animation. We wanted to be able to run Sequences without necessarily having to create a UObject. So effectively, playback capabilities render the IMovieScenePlayer interface obsolete, and in fact in UE 5.6 you’ll see that UMG Widget Animations run without a player (we only have a simple structure to keep time, plus a few playback capabilities)… although of course we still need to create the old player when we hit legacy/deprecated APIs, for backwards compatibility.

Intended Usage: we use playback capabilities to setup a Sequence for playback. Generally the only playback capability you need is the FMovieSceneEvaluationState, which has basic stuff like a repository for bound objects (which makes possessables work). The rest is optional -- for instance, again, whether the Sequence can handle camera cuts, or whether it supports spawnables, and so on. Between UMG, LevelSequenceActor, and other places setting up Sequences for playback, each adds whatever playback capability makes sense for that kind of Sequence.

Relationship with Other Systems: playback capabilities are stored on the FSharedPlaybackState, which is now the sort of central object for playback. The playback capabilities container supports storing things inline or as pointers to accommodate different memory layout, ownership, and lifetime requirements. Several Sequencer’s ECS systems query for capabilities during playback in order to do their work. For instance, the Spawnables system will look for a Spawn Register to do its job. Who needs what capability isn’t really documented since we didn’t really expect people to need to know about it -- you’d have to make up a new kind of Sequence for it to matter to you.

IMovieScenePlayer is now a playback capability itself. This is done for backwards compatibility, and for accessing it without a hard dependency on it from the core evaluation code. We use to require an IMovieScenePlayer (the evaluation code would often call directly on it) but not anymore. As I mentioned before, the new UMG Widget Animation code is our first proof of concept for not needing an IMovieScenePlayer anymore. We will probably deprecate that interface in a far future.

Extensibility: in theory we would encourage game devs to make their own playback capabilities to work with any custom tracks they want to write, but in practice we haven’t done much work to enable it. In particular, there’s no proper extensibility API on, say, Level Sequences, for 3rd party code to register new capabilities. You’d need to sub-class ALevelSequenceActor or something. We would probably wait for someone to have a proper use-case for it before we spent time on it.

Documentation: there isn’t any documentation besides the default one generated from the code comments.

There, I hope it helps! Feel to ask more questions, although I’d love to know what use-case you’re dealing with and what you have in mind.