Phaser 3 - Real-Time Multiplayer Game with Physics

Phaser 3 - Real-Time Multiplayer Game with Physics

What is so special about this example?

All the physics (MatterJS and Arcade) is entirely calculated on a NodeJS server. The client only received the positions {x, y} and other necessary properties like rotation, animation and tint of each object.
It uses a unmodified Phaser 3.16.2 version from npm.

Example

You can play the example here.

It runs on NodeJS on Heroku (Free Dyno in Europe) which causes the example sometimes to take about 1 minute to load.

Here is the link to its GitHub repository.

I really hope you :heart: it and can use it in your own projects :blush:

Video

Watch it on YouTube

18 Likes

The physics is entirely calculated on the server. The client only gets the coordinates {x, y, rotation}. This is why you will see the same boxes at the same place with the same rotation, regardless where you are in the world.

:wink:

1 Like

What started as an simple example, is now about to become a really funny co-op game.

The goal?
Simple! Just catch the huge blue star.
But, you have to work as a team to get it!

Thank you so much for making this! Iā€™ve managed to get to the second row of stars, but no luck with the big guy yet.

Iā€™m working on a project which will hopefully be built on Phaser and Matter, but I havenā€™t yet started my networking tests. Youā€™ve not only shown me that itā€™s possible, but also that it performs acceptably on mobile which has eased some concerns. I donā€™t want to derail your thread, but if you could answer some questions for me Iā€™d appreciate it a ton. If theyā€™re too off topic I can shoot you a message.

  1. Have you done anything special to account for tcp? If not, do you have any ideas or techniques in mind to account for network issues that may arise?

  2. Is there any fancy client side predictions/corrections happening besides applying position/rotation/velocity on the client when data is sent from the server?

  3. Are you utilizing Matterā€™s ā€˜enableSleepingā€™? Iā€™ve not been able to get it to work in my game, as it seems to disable the ability to control our character. Probably something to do with how velocity is being set, but I havenā€™t found a solution yet.

  4. Have you done any stress testing? I found the specs of free heroku dynos and it looks like youā€™re working with 512MB of RAM and 1 core. How many simultaneous connections can you handle? How many physics bodies can you run in one instance?

  5. Are there any big issues you ran into while working on this?

Sorry for all the questions! I appreciate any help you can give me in determining if this tech will work for us. Thanks again, and great work.

1 Like

Hi @pyxld_kris,

I have also only caught the big star twice. It works best in a team, putting 3 boxes below the star and then jump on each other to catch it.

  1. No. For the client? You should probably spin up multiple servers in multiple regions to lower the latency. Otherwise you canā€™t do anything. If the client has a slow and/or unstable network connection, he canā€™t play an real-time online game.

  2. Since this game works in real-time with multiple players, there is not client side correction (But you could of course implement this in another type of multiplayer game). Everything is calculated on the server. If the players latency is below 100ms, he will not notice anything. I guess, since youā€™re located in Austin, TX, your latency is much higher. Currently the server is located in Europe (where I live).

  3. I use this.Matter.Sleeping.set(this.body, dead) only for ā€œdeadā€ bodies. In this game dead bodies are the boxes which disappear after a certain time and will re-spawn later.

  4. I could not find a way to debug it on Heroku. This is the first time I use this service and only have a free account. But I have tested in on my docker-machine on EC2 (t3.micro) which has 1GB RAM and 2 cors. Each player uses about 30 kBps download and 5 kBps upload. The t3.micro instance is capable of handling up to 5 Gbps. I was running 4 game instances (in the same node app) with 50 objects each and the memory was about 190MiB and 30% CPU.

  5. Big issues, no. Everything works smoothly. The only thing special you have to do, is installing the required packages for canvas to work. But since I have dockerized the app, it does this automatically each time I publish it.


I can totally recommend you this approach for a real-time multiplayer game. I works great. Currently Iā€™m about to program a RoomManager which will manage multiple socket-io rooms and create a new Phaser instance for each room (all in the same nodeJS app). I will also add a /stats url, where you can see stats about the appā€™s cpu and memory usage and its logs.

For now, the game (same link as in my first post) creates a new room for each 4 players. Open 5 browser windows and you will see that the 5th player is alone in its own room (Phaser instance) and it shows its own public room id in the debug text.

I know that I wanted to publish it earlier, but I prefer to add all these great features first :slight_smile:

Hope this helps :smiley:

2 Likes

I have now added the page /stats which logs all console.log()'s and some usefull information about the game, cpu and memory. Also check out /physics if you have not yet.

This example is currently running on a free dynon under Heroku, so the URL may change in the futur.

Haha! I was just playing with someone random and we got the star! Whoever you are, if you see this :+1:

Thank you so much for the detailed reply Yannick! Youā€™ve helped a ton. Iā€™m going to continue along down this path and see where it leads us. That stats page is also incredibly awesome, so thank you for that as well.

I wish you the best of luck on this project, and many more to come. Hopefully Iā€™ll be able to help you in turn some day.

Kris

Glad you got the huge :star2:!

Thanks, it helps a lot seeing people like my work :blush:
Best of luck also to you. Hope you can build a great game based on this example.

The example with MatterJS is now more or less finished. Iā€™m now about to implement Arcade physics, since most do know this better and it is much easier to use.

In the finished example, the client will be able to choose which physics engine he wants to use in the game. Its cool and it demonstrates how you can start multiple Phaser instances with different scenes and physics based on what the client chooses.

Youā€™ve gotten Arcade Physics to work with Node? After a good amount of research, it looked like Arcade couldnā€™t be decoupled from the Phaser core and this was thought to be a bad idea.

I would LOVE to be able to use arcade, but networked gameplay is a requirement for us. Are you running phaser headless? Or have you managed to decouple the physics system completely?

Yes, it works!

Iā€™m about to add a platformer game to this example with arcade physics. I just need to add some stars and some enemies.

Iā€™m running it in headless mode.

Iā€™ve uploaded the latest version to the server. Take a look at the links below.

Feel free to open multiple browser windows and track the stats in /stats

Hi @yannick,

Thank you very much! This is simply awesome :heart:
Are you using a NodeJS library ? Such as :

Canā€™t wait the link to the github repository :star_struck:

No, none of them. Did not even know they existed. This is the first time I make a real-time multiplayer game.

I simply use express and socket-io and programmed a own RoomManager. It is very easy to make. You will see.

Iā€™ve finally published the source code and a overview video (check the first post).

I think it became really nice :star_struck:
Let me know what you think!

Hi @pyxld_kris,

I thought a lot about your question ā€œHave you done anything special to account for tcp?ā€ And how, I finally have a good answer. Please take a look at topic #2080.

Thatā€™s such a nice example. Iā€™m really glad you published it on github.
Iā€™d like you to elaborate or guide me on how is your webpack/nodemon configuration working. I have some questions:
Ā· Running ā€œdevā€ will get webpack to recompile and nodemon to restart? Isnā€™t it too slow to recompile before each restart? Just asking, because I never done this myself.
Ā· With auto recompiling + auto restarting you just refresh the client page and voila, server with changes are being used?
Ā· Whatā€™s the reason to separate physics and stats in different webpacks?

Thanks again, really!

ā€“ EDIT ā€“
Extra question, is it really worth it using webpack for a project made with JS? Iā€™m using ā€˜use strictā€™ in my server code and type=ā€œmoduleā€ in my client for ES6 modules.

Hey Yannick,

Glad to see youā€™re still working on this! Iā€™m going to respond in your new topic, but I donā€™t want to clutter it up with potentially unrelated stuff so Iā€™ll ask here.

What were the issues you encountered with this project that pushed you to create the UDP library?

Thanks for all of your hard work!

  • Kris

Yes, it is slow. But you can tweak the webpack configs to improve it. If I would work on a large project, I would probably use webpack-dev-server to serve the /client, /physics and /stats over it, instead to serve it over the node server like in production. This will retranspile the code and restart the browser immediately. Also I would configure the /server to retranspile and restart via nodemon, only if a file needed by the server has changed. This will make development much easier.

Only for readability. You could of course merge them.

Yes, it is worth it! Since you can use ESNext syntax or TypeScript. Btw Iā€™m using TypeScript in this project.
Please take a look at a starter template. It uses webpack and does a lot of work for you. You will see that it opens many new possibilities and it is just much easier to develop with it.

The only issue with this project is the TCP connection. Iā€™m happy with anything in this multiplayer example except the connection. I tried a lot of stuff to improve it. I tried ā€œNginx proxy with TCP_NODELAYā€, I read a lot, but nothing seemed to improve the connection.

So I decided to make it work over UDP. I have built the core for my library by now. Now Iā€™m about to build a nice user-friendly API for it (It should look similar to the one of socket.io). After that I will build another Real-Time Multiplayer Game with my new library and publish it in this forum :slight_smile:

1 Like