Log In  
Follow
puddleglumm
[ :: Read More :: ]

Hello friends! I'm attempting to implement replay functionality in PICO-8. (e.g. re-watching your last race in a racing game) I started by changing my update function, so that instead of invoking game actions directly, they are added to a command queue. Imagine something like this:

function move_player(x, y)
    -- move ZIG for great justice
end

function update_game()
    if btnp(➡️) then
        add_cmd(move_player, {1, 0})
    end
        -- other input handling here

    process_commands()
end

An entry in the queue is a function, parameters (passed as a table), and the frame that the command was added (e.g. 23). At the end of the update function I execute everything in the queue that is scheduled for the current frame. process_commands uses an index to track where the next command is, and increments the index whenever it executes one. To replay a game, all I have to do is reset my game state and command queue the index to 1, and run my game engine against the already-populated command queue. So far so good, easy enough to implement and it's working fine.

The next thing I thought was how I could use this to run a demo mode for the game. I play the game, I somehow persist the command queue, and use it to drive the demo mode. So now I need to persist this command queue outside of the Lua runtime. My first thought was looking into serialization of data in Lua, but if I understand Lua correctly I'd be serializing the same functions over and over, and it looks like I don't have access to string.dump anyways.

My best idea now is creating a table that keys the string value of my function names on the various game action functions, and add some code to add_cmd to actually build a string of Lua code that will re-create my table. Seems kinda derpy but it would work, and does require me to change the name table if I change or add game actions.

Another alternative would be to record the raw input data for every frame and re-write my input handling code so that exactly where the input data is coming from is abstracted. Then my data is just a bunch of booleans that are easily serializable, but I hate this because now I'm tracking way more data than I care about, and it makes handling actual user input while the replay is running less straightforward.

How would you approach implementing replay functionality in PICO-8?

I'm a lifelong programmer but very new to game development, feel free to criticize / correct as you see fit, you won't hurt my feelings! I love learning.

P#137023 2023-11-06 18:46