Page 1 of 2

how to record and play game input?

Posted: Fri Jun 24, 2022 9:09 am
by glitchapp
Hi,

I did not find a thread on this topic and I wonder what is the most efficient way to solve this problem:

I would like to be able to record keyboard input so that it can be used it to show recorded gameplay, demos or to use it to create game tutorials.

My keyboard includes this functionality like many gaming keyboards and I would like to implement it in a game. is there any library for this?

In summary I want to know how to:

Record game input

Play recorded game input.

Thank you!

Re: how to record and play game input?

Posted: Fri Jun 24, 2022 9:18 am
by darkfrei
Store inputs as

Code: Select all

timings = {
  {time = 14.631, scancode = "a", duration= 3.14},
  {time = 21.07, scancode = "d", duration= 0.087},
}
Update:

Code: Select all

pressed = pressedList
if timing.time > time and timing.time+timing.duration  < time then
  pressed[scancode] = true
elseif pressed[scancode] and timing.time+timing.duration > time then
  pressed[scancode] = false
end
And be sure that your dt by recording and by playing are the same.

Re: how to record and play game input?

Posted: Fri Jun 24, 2022 9:22 am
by glitchapp
thanks darkfrei, oh really is it so easy? I expected something more complicated.

I will test what's the output of timings after doing that thank you!

Re: how to record and play game input?

Posted: Fri Jun 24, 2022 10:30 am
by darkfrei
Maybe it will be better to go to the ticks, where the dt is always 1/60 second, then you are need several saved tables:

Code: Select all

Replay.keypressed = {
  {tick = 17, scancode = "a"},
  ...
}

Replay.keyreleased = {
  {tick = 24, scancode = "a"},
  ...
}

Replay.mousemoved = {
  {tick = 24, x=317, y=137},
}
By the update just keep the actual reading elements of lists and save to your isDown[scancode] all player inputs until the next tick.

Re: how to record and play game input?

Posted: Fri Jun 24, 2022 12:00 pm
by glitchapp
Thanks darkfrei, it is not as complicated as I thought but it is also not too simple so I will keep all of this respond in my folder and I will attempt it in the future, if I succeed I will post it here.

Re: how to record and play game input?

Posted: Fri Jun 24, 2022 12:30 pm
by BrotSagtMist
If you have, say a complicated 2D jump n run, this wont be accurate enough to replay a map.
Youre better of saving the positions of everything on the screen for every frame.

Re: how to record and play game input?

Posted: Fri Jun 24, 2022 12:48 pm
by glitchapp
No it is for a puzzle game and I think it would work, but thanks to pointing it out so that I know it needs to be adapted for other type of games.

Re: how to record and play game input?

Posted: Fri Jun 24, 2022 2:02 pm
by pgimeno
Depending on how your game is made, it can be super simple or it can require a lot of data acquisition for replaying it later.

Even for a puzzle game, for example, if it has smooth transitions, that introduces a timing element. If the keyboard is disabled during certain intervals (e.g. during a transition), then timing can become critical, say if you press a key at a moment very close to the time when the key is enabled. That can make a difference when replaying: depending on the dt during the replay, the keypress can be accepted or rejected. So, in that case, going for a more general approach where also dt per frame is recorded would guarantee the ability to replay it later and obtain the same results. It's not necessary to save every object as BrotSagMist said, that's overkill; just dt and input events, and if you use love.timer functions, that too.

Roughly, it would consist of this. If you use love.keypressed/keyreleased/textinput, you need to record the call with all the parameters that you use, together with their timestamp. The timestamp would be a variable updated by love.update(). If you use joystick callbacks, same thing. In love.update, you would capture the individual dt's to later reconstruct the timestamp.

At the time of replaying, you would ignore actual events and only call the callbacks with the recorded events. In love.update, you would ignore the incoming dt and use the saved one instead.

The more I think about it, the more it seems to me that it's worth writing a library for it that you can use in your game transparently, by monkey-patching Löve functions.

Re: how to record and play game input?

Posted: Fri Jun 24, 2022 2:19 pm
by glitchapp
Oh writing a library for it that others can use would be fantastic! I'm glad I touched on a topic that would be of interest for others.

The game does not have smooth transitions and it is the same game I started working on at the beginning of this year and managed to get working thanks to the help of darkfrei.

You can find the main thread for the game here:viewtopic.php?f=4&t=92580&p=246339&hili ... ts#p246339 and the offical website here: https://glitchapp.codeberg.page/

Re: how to record and play game input?

Posted: Sat Jun 25, 2022 7:22 pm
by Xugro
pgimeno wrote: Fri Jun 24, 2022 2:02 pmRoughly, it would consist of this. If you use love.keypressed/keyreleased/textinput, you need to record the call with all the parameters that you use, together with their timestamp. The timestamp would be a variable updated by love.update(). If you use joystick callbacks, same thing. In love.update, you would capture the individual dt's to later reconstruct the timestamp.

At the time of replaying, you would ignore actual events and only call the callbacks with the recorded events. In love.update, you would ignore the incoming dt and use the saved one instead.
Is there a problem with the speed of the playback? I am not sure.

Let's assume you have a fast pc and record your game with 60 fps. Then you send the recording to me. I have a slow pc and can only run the game with 30 fps. Since the playback would use the recorded dt's and my slow pc takes twice as long to recalculate everything, I would see the playback with half the original speed - wouldn't I? And I don't see where a timestamp would fix this problem.