How to record and replay game events (demo files)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By unfa

I am wondering what it would take to produce a “game demo” file recording all game events and allowing them to be played back later producing deterministic results every time, regardless of game performance.

id Software’s game engines since Doom seem to be supporting such a feature and it was used to play back an example gameplay underneath the main menu screen.

Have anyone implemented something like that?
I guess it’d be quite similar to building a multiplayer game.

Possibly the same tech could be used to craft machinimas - generating game events from a timeline.

:bust_in_silhouette: Reply From: denxi

I’ve made this for my game, it works pretty well. I record all my inputs during process, then when the physics process happens, it consumes any inputs recorded, like so:

func _process(delta):

    if Input.is_action_just_pressed("jump"):
        jump = true
func _physics_process(delta):
    if jump:
        #Do the jump stuff
        jump = false

This setups means I can run a frame counter that adds 1 every physics process. Using that counter, I create a dictionary, and every single frame I record the players inputs. This is done through a script on the player which exports the status of any inputs I want to a separate node, which then stores those inputs in a dictionary, under the key named after the current frame. So the final output looks something like:

replay = {

    "1" : {
        "jump" : false
        }

    "2" : {
        "jump" : true
        }

    "3" : {
        "jump" : false
        }

    etc.
}

Then, when I play the replay, instead of using process and the Input manager to record my player’s inputs, I simply slot in the appropriate inputs by checking the replay’s dictionary under the current frame’s key.

If you do the process exactly like I have laid out, it’ll work, but it’ll be super slow to save long replays. I have optimized it so that it only records CHANGES in input, to save on space, and I use an input coder to reduce the characters of each input to save on space as well, this is just what a first draft would look like, to get the basic idea across.

Thanks! I wonder what happens when performance during re recording drops and the frame rate is reduced?

Wouldn’t that make the playback break?

unfa | 2020-02-14 16:34

To my understanding, physics frames will never be skipped or dropped, only delayed. This means that as long as you don’t rely on delta, desync due to lag should never occur. I stopped using move_and_slide because of that possibility, because it uses delta as an argument by default, whereas move_and_collide does not.

denxi | 2020-02-15 14:05