How to approach Phaser 3 multiplayer with Physics?


#1

Hello :slight_smile:

I need to make a Phaser multiplayer game (turn based) that will use physics. I can deal with the server, sockets and basic Phaser setup, but I am not sure how to approach the multiplayer physics part.

The game will go as follows:

  • Player 1 is on the left
  • Player 2 is on the right
  • P1 shoots a cannon towards P2’s castle
  • If the castle is 100% broken - P1 wins
  • If the castle is not 100% broken - it s P2’s turn
  • During the shootouts the castle is breaking with physics (different parts are broken, or moved by collisions). One needs to hit the princess at the center to win.

My initial idea was that I could run the physics locally and use sockets to send the parameters of how to shoot the cannon. P1 shoots, the socket sends {velocity:{12, -2}}, then on the other player I shoot the cannon with the same parameters. But basic testing showed that repeating the same action on different devices does not reproduce equal results. The difference is small but it will build up with repetitions.

Any ideas and advises are welcome.


#2

Hii @kosmoskolio,

Have you found a suitable way of doing it?

Maybe calculating the physics only on p1’s device and mirroring the position of the bodies to p2?

Or calculating the physics on the server and send the positions to both players?

I’m curious how you solved it.


#3

I have not yet implemented any solution - but I am planning to do exactly what you said. I will take turns in using the players’ local physics and see if it works well.

  1. Round 1 starts
  2. P1 shoots a projectile (Each frame for ~5 secs I save the transform data for ~12 physics bodies)
  3. P2 receives a large JSON with the replay data
  4. On P2 device I replay what happened on P1 device by setting objects’ position, rotation and status on each frame for the ~5 seconds
  5. Now P2 shoots…

On theory it should work. It should deliver the same physics experience on both devices.

I will need to cap the frame rate to lower the amounts of data saved and transmitted.

I am afraid of bad performance on weak devices - not sure how well the update will work. I am targeting phones.

I will write back with results once I test it. End of the week probably as I am working on the networking part currently.


#4

@yannick, we have successfully implemented turn based multiplayer with matterjs as I have written in the previous post.
Step 1: player1 makes an action
Step 2: for XX frames we collect each moving object’s x, y, and rotation parameters and save them in a json.
Step 3: we save the object to the db
Step 4: player2 receives the json
Step 5: for XX frames in the update() function we manually set the x, y, and rotation parameters for each of the objects.
Step 6: it is player2’s turn to take action

As of now it is working pretty well. The game will be ready in a few weeks so I will be able to give more details by then.


#5

Cool. Thanks for sharing!

It look like this is the best solution for a turn based game like yours.


#6

Do keep in mind that anything done locally cannot be implicitly trusted. If the physics are not checked anywhere other than the player’s local machine, they could send any value, including an automatic hit. So it is extremely open to cheating.

I realize you are already well on your way here and likely will not be reworking the physics system from scratch, but what I would have suggested is that since the game is turn-based without the need for twitch-based reaction times, I would simply send the angle and any other data that the player is firing in to the server, calculate the trajectory and any canon ball damage on the server and then send the results to both players to animate. Perhaps a fuse burning animation could be added to help deal with the resulting small amount of delay.


#7

I agree with Jackolantern, allowing players to send physics results to each other is wide open to cheating. It will assuredly happen.

Give this article a read (all 4 parts).

I see two main approaches for you:

  1. Have the server run all physics and clients interpolate through physics data from the server.
  2. Have clients send their inputs/actions to a server, which then validates the data and forwards it to other clients. This sounds like what you were going for initially but the piece you are missing is deterministic physics on the clients.

I would recommend option #1 unless you are looking to save money and do peer-to-peer, in which case peers can validate their opponents (inputs instead of the server), and disconnect from cheaters.

I have option #1 running on my own project which also involves cannon physics, at https://tnks.io/. I actually ripped the math library and physics engine out of phaser and have it running on my server, so the clients can almost deterministicly predict their actions locally. The “fuse” Jack mentioned is implemented as a slow start to the projectiles.

Oh, and be wary of sending JSON. The serialization and sending of JSON was the single largest bottleneck on my tanks game. Switching to ArrayBuffers shaved 30ms off my server tick.


#8

I had some time to read about this subject and came up with an excellent example.

I could sucessfully implement MatterJS (including the entire Phaser 3 library) on NodeJS with Socket_io.

Maybe you will not include it in your current game, since you have already implemented a strategy, but maybe it helps creating your next project :slight_smile:

See post #1739 for the example

Also thanks, @sky-coding for you article.


#9

Implementing user input validation in order to block any potential cheaters is on my task list for sure.

As for the node / matterjs / socket.io - it is great that you have put up the example!

Thanks for the tips, guys!
For the current project I am sticking with the established approach - taking turns in calculating physics on the different clients. When the project goes live I will write back with results :slight_smile: