1
\$\begingroup\$

Suppose two players in a game want to build a city together on a blank tile-based game world simultaneously in a peer-to-peer connected context.

When a player clicks on a tile it changes the state (or tile ID) of that tile, which is saved into a text file for later reading by the renderer.

For example, in the image below a player has modified some tiles from "empty" (1) to "road" (2):

enter image description here

What method should I employ to transmit these changes to connected peer-to-peer clients?

\$\endgroup\$
  • \$\begingroup\$ Are you asking about how to implement shared state in a P2P system? I think that's more a Theoretical CS question than Game Development. (Want me to link some papers?) \$\endgroup\$ – Anko Feb 14 '14 at 0:57
  • \$\begingroup\$ @Anko Please do \$\endgroup\$ – Sad CRUD Developer Feb 14 '14 at 1:47
  • 1
    \$\begingroup\$ OK! :D The scuttlebutt JavaScript library uses a gossip-based system to replicate data in real time. Its source code might be a good read. For a less realtimey, more databasey approach, check out Distributed Hash Tables like as Chord or Kademlia. \$\endgroup\$ – Anko Feb 14 '14 at 1:54
1
\$\begingroup\$

You will need two mechanisms:

  • First, you will need to be able to transmit the entire world state to a user. You don't want to do this regularly, but you will need it to transmit "initial" world states to users as they join the game or potentially at the very beginning of the game.
  • Second, you will need to be able to transmit packets to all connected clients that notify them of state changes (deltas). Something of the form "change tile (1, 2) to state 3."

You mention this "text file" that you save the state into after every change; that seems unnecessary. Unless your levels are massive you should keep the entire state in-memory at all times, and share it with the renderer. Disk is one of the slowest forms of memory so having to hit it twice per frame on average is undesirable.

Since your game is running in a P2P context there is no central authority to validate the moves or resolve races (two players clicking the same tile at the "same time"). To help alleviate this, especially if your game is real-time and not turn-based, you can synchronize each player to a known good clock when the game starts, and have players transmit the timestamp on that clock with each move, which can be used to resolve races. This can also be done with a sequencing number, or consider an approach where every client gets a vote on the correct state of the game and that majority vote wins (this is sometimes useful in cheat detection as well).

Note that you may need to buffer some moves in memory on all clients to account for the possibility that other clients can "replace" locally-made moves.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.