Skip to content

Instantly share code, notes, and snippets.

@thomasboyt
Last active March 23, 2016 00:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomasboyt/a8494fedda24d35d189e to your computer and use it in GitHub Desktop.
Save thomasboyt/a8494fedda24d35d189e to your computer and use it in GitHub Desktop.

So, I'm making a browser-based golf game that's a shameless Desert Golf clone, with the added gimmick of being "massively multiplayer." The idea is that there's a server that generates levels, sends them to each connected client, and everyone plays a level together. The "multiplayer" component is that clients can see the "ghosts" of other balls, as well as a leaderboard at the end.

There's two parts to the netcode: the client needs to send some data about the ball to the server so the server knows where the ball is, and the server needs to then broadcast this data to the connected clients.

The solution I came up with was to run the same physics simulation (using p2.js) on the client and server. The client will send data for each swing to the server, which would contain the x and y velocity vector to apply to the ball. The server would broadcast this vector to each client along with the ID of the ball, so each client can visualize the "ghost" ball's movement. The server runs the same simulation so that it can be the "source of truth" for whether or not a ball reaches the hole (not that this is exactly heavy on anti-cheat, but I did want to at least avoid the clients being able to send {inHole: true} to the server and win instantly).

The problem that arises from this solution is, kinda obviously, one of synchronization. The physics simulation relies on stepping individual frames, and if it were out of sync with the client somehow, then the client could end up seeing a completely different game state from what the server believes is true (e.g. "hey, the ball went in the hole in my game, but the server didn't think so, so now I'm stuck").

So I figure there's some kind of pattern you can use for maintaining sync, but I'm not sure what that looks like. I figure you need to make sure that you're receiving messages from the server in order and on time, and then some sort of time-step synchronization...?

Mostly I'm trying to figure out if there's open source prior art I can look at, or at least a neat blog post somewhere.

@fritzy
Copy link

fritzy commented Mar 23, 2016

Some physics engines are really bad at this because they hash inconsistently. I'm not sure about p2.js though. In the end, the server should be saying "the ball had this vector (position and velocity) at this exact time". If the client has something pretty close to that in it's past, the client need not do anything different. If the position is off enough for the user to notice, the client needs to re-simulate that vector from that time to current and then re-render. The time can be a vector clock. Let the simulation run for a bit so that time-sync doesn't matter... we just know at this offset, this happened, and you rework to that.

@fritzy
Copy link

fritzy commented Mar 23, 2016

At that point, the server just needs to check in on an interval to make sure the client is in the right state, as well as when another player actually does something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment