Gamestates for Lag Compensation?

I’m trying to sketch out an online-multiplayer system for a fighting game; but it’s dependent upon being able to “roll back” the gamestate and recalculate everything, once an input from the other player has been received. Getting and sending information isn’t so important, right now. What matters is being able to properly work with data once it’s in the local client.

Is there anyway to covertly rewind and replay gamestates “behind the scenes”, so that players can enjoy a more consistent experience? Is there any alternative method for the BGE?

What do you mean with “gamestates”?

Replay makes not much sense, as the time is already spend. Typically if you get inconsistent data (e.g. the position of an object does not match the position received from server) you need to decide how to resolve this conflict.

This can be either …

  • ignoring it (the local data remains as it is)
  • overriding it (the received data overrides the local one)
  • a mix (calculating new data with the input from local and from server e.g. to get a smooth transition)

I know agoose77 is working on a networking add-on, and I’ve seen him talking about different aspects of networking design like this. But yeah, on my very light trips to find out more about networking stuff, I’ve seen that it seems to be those three options, with the last being the most desirable.

I think what Alfonso needs is some way to go back and check for collisions that would have occurred had the opponent’s input been received earlier.

By keeping a record of key objects and keystrokes over the past few hundred frames or so, you can re-simulate what would have happened. However, the main problem is that the BGE only updates collision data at the beginning of each new frame. There currently isn’t any way to manually tell the game engine to update the collision data for one or more objects over the course of a single frame. This means you would have to re-run the logic AND re-render every frame until you reach the “present”.

Ideally, you would be able to just recalculate all the physics collisions that may have occurred over the course of X frame during the execution of logic in a single frame without rendering everything again.

Exactly that makes no sense. Why would you recalculate yet another past?

All you get is that two instances of the game created different results (which is natural due to different input). You need to determine how to deal with the differences right at the moment you recognize them. You should do it in a way that the differences of the next future is as less as possible.

The past is gone, you can’t change present as it is there already, but you can change future buy affecting the present.

It may be necessary in networked games because the “present” you’ve arrived at is incorrect due to your opponent’s input arriving late. So you go back to when the input actually occurred and calculate a new, correct present.

When I refer to “past”, “present”, and “future”, I’m of course not referring to real time. I’m references the previous, current, and potential new game states we may arrive at.

It’s sort of possible with stock BGE. But you’re limited to raycasts via python.

  1. Save the last xx ms of positions etc.
  2. Set positions/orientations to the time you want
  3. Run suspendDynamics() and restoreDynamics() on each object
  4. Do your raycasts
  5. Revert everything back

No idea how much overhead this would produce. But if you’re only checking a few objects…

EDIT
Example here
https://dl.dropboxusercontent.com/u/19279604/const/test.zip

This won’t work for the current tick iirc, as the scene graph won’t have mapped any changes to bullet yet.

What I’m trying to do is recreate the netcode of GGPO, since it’s a fighting game I’m aiming to make. Only two players would be in-game at a time, so it won’t get too complicated to handle.

For those that don’t know GGPO, here’s a 15-second video of how it works in a high-latency environment: https://www.youtube.com/watch?v=q0TZdY9_XHo

At 4 seconds, the game WOULD have ended with the fireball; but the other player was able to parry it on their end. In a very timing-intensive genre such as fighting games, where everything can hinge on single split-second decisions, this sort of technology is absolutely essential to playability online.

It may be something I have to hack into the engine itself (I’ve played with Blender’s guts, before), but implementing true savestate functionality may be necessary for me to do. The trick seems to be getting the main loop of the engine and cloning everything it processes, and building a stepping-function that runs independently from rendering; easy to say, but probably hard to do.

Better explanation of GGPO: http://ggpo.net/

I don’t think there are many network games that wouldn’t need to do lag compensation. It’s important in all real time games and most notable and difficult examples being multiplayer FPS games because of the player count and huge amount of raycasting.

It may be something I have to hack into the engine itself (I’ve played with Blender’s guts, before), but implementing true savestate functionality may be necessary for me to do. The trick seems to be getting the main loop of the engine and cloning everything it processes, and building a stepping-function that runs independently from rendering; easy to say, but probably hard to do.

There’s no reason agoose’s lag compensation method wouldn’t suit the fighting genre as well. But I suggest that you don’t worry about lag compensation too much until you have playable version of your game.

Like i said, I’ve written a patch for that

It’s sort of possible with stock BGE. But you’re limited to raycasts via python.

  1. Save the last xx ms of positions etc.
  2. Set positions/orientations to the time you want
  3. Run reinstancePhysicsMesh() on each object
  4. Do your raycasts
  5. Revert everything back

No idea how much overhead this would produce. But if you’re only checking a few objects…

Oops, step #3 is actually to suspend/restore dynamics. Not reinstancePhysicsMesh.
Here’s an example (note you’ll need the system console to see results):
https://dl.dropboxusercontent.com/u/19279604/const/test.zip

Observe that when space is pressed, the target moves & is detected by a raycast in the same frame.
Take out the lines with suspend/restore and it no longer works.
(tested with a build from yesterday)

nifty trick, it forces bullet to update?

HHAHAHAHAHH!

you just solved my “ghosts issue” ! with wrectified compound assembly system!

Nice! xD

But yeah, it does force an update. At least for the object it’s called on.
restoreDynamics makes a call to UpdateCcdPhysicsController, which basically re-adds the collision goodies for that object directly to the physics environment.
But if not first suspended, nothing will happen.

@Alfonso
I used to have a gamestate module laying around…
It worked something like:


# Set the state to 200ms ago
statemanager.setState(200)

<do raycast here>

# Revert to the current state
statemanager.revert()

Re-writing it is on my short-term roadmap. But it should be easy enough if you’re comfortable with Python.

Would it be possible to run animation, so that hitboxes move and morph as they need to (along with spawned projectiles, etc.), without going through the time-consuming process of drawing everything? So long as I can quickly interpolate from a previous state and catch up, everything is aces~

Two things about your addon, while I’ve got your attention:

  • Your video playlist is completely out-of-order. :frowning:
  • Where is the “BGE Networking for Dummies” tutorial, if there is one?

It sounds like what you’ve got is right up my alley, so far. Now I just need to learn how to use it.

To be clear - this isn’t for my addon. The patch is separate, and I also have a git hub repo which has it applied to trunk.
My addon is somewhat discontinued, as there are better ways to do networking than what it can provide.

Oh, no wonder I couldn’t figure it out, then! I’ll bugger around and try to build a copy of Blender with it. And fix your BGE Network System playlist~!

This is my GitHub

Could you give a rough example of how to implement rollbacks, with your code, in a game? Like, how would a game go about handling receiving an input command for 3 frames ago; pulling up that past point, and replaying 3 frames “behind the scenes” to get the proper situation?

UPDATE: That may not be necessary. I’ll be sketching and experimenting without needing gamestates as I’ve been going on about them.

I’ll reply in due time but quickly, the server doesn’t do any replay, the client does. The server runs in the present - nothing runs in the past (generally speaking) whilst the client has to deal with the latency of its commands (again, this is not exactly the case)