TakeRecorder in Headless Editor (or replay alternatives)

Pretty sure I already know the answer here, but I’m wondering if it’s possible to use the TakeRecorder functionality when GEditor is not available.

I wrote a bunch of code that uses TakeRecorder start/stop programmatically for a procedural rendering system (i.e., this thing goes wide, we’d run this across a lot of machines on a farm) and it works beautifully when running inside the editor locally.

When running UnrealEditor.exe headless (with -game -RenderOffscreen -NoLoadingScreen -Unattended) it failed. After some debugging I noticed the TakeRecorder code opens up the Sequencer UI panel, which depends on GEditor being available – which doesn’t exist during -game headless mode.

Any suggestions for alternative options to capture some kind of “replay” of what happens during one game run, so I can play it back later in another game run?

I guess my two options are:

  • Use the DemoNetDriver system (i.e., Network Replication) to store a replay for later playback.
  • Reimplement my own version of TakeRecorder/TakeRecorderActorSource and bake out the actor’s skeleton bone information every frame. But just looking at how much code there is in TakeRecorder/Sequencer/Movie plugins, this leaves me rather nervous.

Welcoming suggestions.

For anybody stumbling upon this post…

It turns out that take recorder works just fine in headless mode (in editor builds, but with the --game argument). If you look at TakeRecorder.cpp you’ll actually notice that all the code that interacts with the UI is protected by if (Sequencer.Valid()), almost as if it was written with the explicit intent to make it support headless mode.

The only place it breaks down is with the initialization of the SequenceAsset. When the recording mode is “render into existing asset”, it needs to ask the SequencePanel what asset that is. Fine, that needs the UX, can’t do much about that. Not easily anyway. But when the recording mode is “create new asset” and it calls UTakeRecorder::CreateDestinationAsset, at the very bottom it tries to open up the sequencer panel, and then returns false if it fails.

I added an bAllowHeadless parameter to the FTakeRecorderParameters structure, and at the end of CreateDestinationAsset if we’re in “allow headless” mode, I just return true instead of trying to open up the sequencer panel.

And from then on, the take recorder appears to run just fine, writing a proper sequence .uasset file to disk, just as it would when running inside the editor.

So far so good… hooray!