Input-based Recording & Playback


(Zachary Lewis) #1

I was talking with @azrafe7 on the issue, VCR-style Game Replay/Record feature, and @Draknek and I both agreed that this is something best left for the user to implement on an as-needed basis. Naturally, I decided that I should see just how hard something like this would be to implement. Here’s what I came up with.

End Result

Overview

For this system, I assumed the user will drive input from a World that will be passed to an Entity for movement. The input is checked by a helper function that will both record the input and deliver it to the input to wherever it needs to go.

Checking & Recording Keys

/**
 * Checks to see if a key is pressed, then handles and records it.
 * @param	key The key to check for input.
 */
protected function checkInput(key:uint):void
{
	if (Input.check(key))
	{
		_player.takeInput(key);
		_recording.addInput(key);
	}
}

Currently, _player is hardcoded, but this should be changed to accept any InputEntity.

The playback system is also very hardcoded. Ideally, a recording should be able to replay itself.

Recording Playback

/**
 * Updates the current time of the recording and passes input to the ghost.
 * @param	deltaTime The time since the last frame.
 */
protected function replayRecording(deltaTime:Number):void
{
	_replayTimestamp += deltaTime;

	while(_playbackRecording != null && _playbackRecording.timestamp <= _replayTimestamp)
	{
		_ghost.takeInput(_playbackRecording.key);
		_playbackRecording = _playbackRecording.nextRecord;
	}

}

Next Steps

  • Input is recorded for every Input.check(), which means a new item is added for each key held every tick. This should be changed to only track key presses and releases .
  • Only key-based input is recorded. This setup should be versatile enough to support mouse clicks as well.
  • Using a variable timestep will result in unpredictable playback. For a sample like this, it’s fine; however, when replaying a precision platformer, these slight variations in playback can result in incorrect playback due to keys being pushed slightly off from when they actually were. Keyframes should be considered to make sure positioning is exactly correct.
  • Interpolation should be considered to smooth out playback.

What are your thoughts on this system? Do you think this is a good way to handle playback?


(azrafe7) #2

[quote=“zachwlewis”] You just feed the input into an entity. You won’t have to worry about input conflicts at all.[/quote]

Ah… Now I get what you meant with that!

Agree this works well only with a fixed timestep. Implementing keyframes and interpolations should definitely improve the smoothness of the playback.

And saving the seed could be helpful to make randomness deterministic.

…searching some more material on the matter…


(Zachary Lewis) #3

Sorry I wasn’t more clear. It was late and my brain wasn’t firing on all cylinders when I responded to that issue. :tongue: