Is character movement deterministic?

I’m working on a replay system in Roblox Studio right now, and I need to know something.

Is Roblox movement deterministic?
So, for example, if a player does a certain string of inputs and then did the exact same string of inputs again (using a macro for example), would the player’s movement have the same outcome both times?

A great example of a game that does this is Trackmania. As you can see, players can use Tool Assisted Speedrunning to create runs like this consistently (no matter how many times you do this exact set of inputs, the game will always do the same thing):

Does default Roblox character do this? If not, is it possible for it to do this?
Thank you! If you have any questions, please don’t hesitate to ask! :slight_smile:

5 Likes

In short, no. Your character’s HumanoidRootPart is moved by Roblox’s realtime physics engine, and is simulated on your device with a variable time-step. It’s not deterministic. In practice, the same input over a short period of time will give basically the same results, but over the course of a whole game, no way, there would be a lot of divergence.

To do playback, you have to record the end result, not the input.

2 Likes

If you’re willing to put in some work, you can achieve some degree of determinism with chickynoid.

It is effectively a library that converts roblox’s networking and replication into a server authoritative one. You can view inputs coming in for a frame, take snapshots of specific frames, etc. It’s never gonna be 100% consistent because it’s roblox but this is the most authentic way of getting the result you’re looking for (bar making your own server authoritative library).

3 Likes

Nope, even chickynoid isn’t. Subtle floating point errors and differences between cpu vendors means this can’t work from just inputs.

3 Likes

I was not saying chickynoid was the best solution, but that it’s the closest you can get to achieving this result authentically (that is, replaying inputs from a list).

As for floating point and differences between cpus, that can just be resolved the same way as network desyncs.

  • Save the game’s state every couple of seconds (from the server) when recording a replay. Make sure these replays note down the time they were saved at, starting from 0.
  • Have the server send the client the list of inputs the player used and the list of states it built up
  • Client notes down the time the replay started and every frame checks to see if enough time elapsed for it to load the next snapshot. Client also replays inputs.

You’d have to tweak chickynoid heavily no doubt, but it’d be a lot faster than making your own from scratch. You’re effectively taking a snapshot every couple seconds and filling the empty space with an approximation of what the player did.
This should more or less sync up in most scenarios because desyncs for characters in chickynoid are corrected nearly seamlessly, since they get rolled back.

It’d also leave a much smaller impact memory-wise than saving the entire state of the game each frame.

1 Like

You can also take a hybrid approach, where you save an authoritative game state snapshot once every few seconds or so (rather than every frame), and use inputs and the almost-deterministic behavior between these keyframes.

That IS the approach I’m describing in that reply.