5
\$\begingroup\$

I'm working on the design of a basic multiplayer HTML5 pong game, and I have a very basic question about architecture.

The implied physics is very basic, and the movements are not a problem. The players will be connected to the server via sockets, and the refresh rate is controlled in order to make things run smoother. My problem is with the ball movement. Where should I put the ball logic?

  • If I run logic on the client sides, the balls may be desynchronized.

  • If I run all the logic on one client side, acting as a host, this could work; but I don't know if this is a good practice.

  • I could run the logic on the server side, but I think that I will replicate all the physics and rules for the game that I can have with a simple javascript framework for game development.

What is the best approach, here?

\$\endgroup\$
  • 2
    \$\begingroup\$ Why not both? Calculate everything on the client side and validate it with the server side, just don't let the client-side calculations affect the server-side ones \$\endgroup\$ – Bálint Apr 5 '17 at 8:03
1
\$\begingroup\$

You should never make calculations of game mechanics on the client side. Just expect that there will be a hackers on the client side changing your code.

You should store the model data in the server and use it on the client side to draw the view.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ But not a big deal to duplicate movements immediately after user action, and correct it after server response. It make gameplay more responsive. Don't you think? ...Sure, it's not important in case of card-game or other kind of "slow games". \$\endgroup\$ – Vladimir Ishenko Apr 6 '17 at 13:26
  • \$\begingroup\$ It's actually done on both sides. You calculate on your side and send the important calculations to be verified on the server side. You can even see that in some MOBA games when you Auto Attack there is a possibility that you will see the attack hitting the enemy player on your side but no damage was done. Also, if your ping is big that means slower connection with the server - you can't even move sometimes - that is because the server hasn't verified if that is an appropriate position to move. But then pathfinding to that position is calculated by player machine. \$\endgroup\$ – Candid Moon _Max_ Oct 15 '17 at 0:06
0
\$\begingroup\$

I suggets to start with all logic on server for first. User press button - client send command "move", server moves, and send updates for both players.

Will be a bit laggy, maybe. Just a bit.

After that you can make vizualization on client immediate (before server confirm this movement). So user getting key-press feedback immediately. (But keep in mind - server always right, even with a bit late, so you need to sync pad after server response).

And after that you can tweak server a bit on ping-compensation. As your ball movements relatively predictible, your pad react immediatly (visually) and you know ping/delay value - you can dive into math and calculate ping compensation to correct objects positions on your table.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Lag the clients behind the server by x ms with the drawing of things and have the server do the movement of the ball and send the position every x ms to the clients. The clients should store a queue of the positions it's getting from the server which will be choppy if you just set those, but because you have a queue and you're lagging behind the server you can interpolate between the current position to the next position on the queue. This will give you nice smooth and accurate ball position controlled from the server.

You also want to store a rolling list on the server side of these positions that were sent so you have a small amount of history. You'll want this because the clients are lagging behind so when you get paddle movement commands at a point in time you then "rewind" the ball by looking at the history ball position list for the time you get the clients paddle movement minus the ping (the time it took you to get that movement). Then you can validate if a collision happened or not and the server ultimately controls the ball.

At the point of a collision because the ball is lagged behind on the client, on the server the ball may have went passed where the paddle is thought to be on the server. So when a collision from the rewind happens, you'll want to re-position the ball on the server at the collision point and run the physics from there which will reverse it's position. You might want to send that collision point to the users as well even if it's outside your interval of sending ball position because you'll want that specific point for them.

But this way the server controls all physics of the ball an the clients are all just lagged behind but they are none the wiser of that.

The side note of this is that how you tell if the ball actually did get passed a paddle. You'll just have to make that check happen farther away from the paddle based on how fast the ball can move and your update interval. In other words the server needs to consider the lag behind in ms the clients are doing when telling if a ball really got by a paddle.

Side note, this is how the Source engine works. When you shoot on your side that command is sent to the server and it knows how long it took to get there (ping). Let's say the server gets it at tick 500 and it took 50ms to get the command. It knows the clients are lagging behind by 150ms (this is a hardcoded value that the server decides on at the start) so it knows to look at (now - 150 - 50) in the history list of game states on the server. It'll find the closest snapshot and interpolate from there to get positions/rotations of everything in the game at that point which should have been what YOU saw at that point, and then runs the raycast on the shoot to tell if there was a hit or not. Same concept here really. The only difference is you having to snap the ball to the collision point if the server deems one took place.

| improve this answer | |
\$\endgroup\$
-3
\$\begingroup\$

What you can do is since it is a multi player games best for two player, you can create a group for two and then synchronize the movement on both the side. Ex: Since same Javascript file (Client Side) runs on both the machines, once two person joins the game, you initiate the game (movement of ball). I think no random calculations where made.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I will make it this way and post the results \$\endgroup\$ – Thesiles Apr 5 '17 at 9:51
  • 1
    \$\begingroup\$ You should not use the client side to actually update your game \$\endgroup\$ – Bálint Apr 5 '17 at 10:49
  • 1
    \$\begingroup\$ Don't forget to include the player as a source of randomness. When the ball gets to your side of the table, my copy of the client doesn't know whether, or how, you hit the ball back until at least one network trip latency later. \$\endgroup\$ – DMGregory Apr 5 '17 at 11:08
  • 1
    \$\begingroup\$ Mmm... So, then I need to make all the calculations about physics (bouncing ball with the walls and players) in the server side and spread the messages among the players. \$\endgroup\$ – Thesiles Apr 5 '17 at 11:38

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.