Client/Server logic on same machine, singleplayer as a local multiplayer

Started by
8 comments, last by ApochPiQ 11 years, 4 months ago
Hello,

I've been doing a fair bit of research on the best approach for putting networking play into a game im working on, and I've read that many games today are developing their singleplayer gameplay just as a local hosted network game.

Does anyone have experience in this, or have any articles on the best approach for this?

I am conflicted with the idea of how to handle game logic for this, because if your "client" is running predictive logic that the server is master over (client predicts, server validates), then are you not leading to running the same logic checks twice on the same machine?

Is there a better way to look at this? A better way to separate or even merge the logic depending on the type of game you're playing (singleplayer or multiplayer) and keep the simple design of only having to develop one core part of the game that can be shared by both the single and multiplayer aspects?

An example of this would be:

  • Client moves, sends input to server.
  • Client hits a wall, has client logic to handle collisions.
  • Server handles the input and it too detects the collision, sends result back to client.
  • Client reads server response and if needed corrects.

And with this, there are two of collision handling checks.


I've love to hear other peoples experience of this sort of idea/problem and how they've gone about it.


Many thanks.
Advertisement

I am conflicted with the idea of how to handle game logic for this, because if your "client" is running predictive logic that the server is master over (client predicts, server validates), then are you not leading to running the same logic checks twice on the same machine?

Prediction is not a gameplay feature, but an optimization to fight lag. I would make the prediction code optional and turn it off when no network lag is present (single-player game).


A better way to separate or even merge the logic depending on the type of game you're playing (singleplayer or multiplayer) and keep the simple design of only having to develop one core part of the game that can be shared by both the single and multiplayer aspects?

You could provide two network layers, one based on tcp/udp and one emulating this,but without the need to do all the network related work. But to be honest, I would start with the local network approach, using the network stack udp/tcp to get single player up and running. This way you have already a good base to get your multiplayer game to work.
One approach might be to have the client-server split existing in your single player game as you describe, but disable the whole client prediction side of things.

Essentially, your client never bothers predicting anything (or if it's more convenient, predicts that you don't move at all), and your server effectively sends correction messages each and every frame regardless of what the client says has happened.

Edit: Beaten to it - I just said more or less the same as Ashaman73.

One approach might be to have the client-server split existing in your single player game as you describe, but disable the whole client prediction side of things.

Essentially, your client never bothers predicting anything (or if it's more convenient, predicts that you don't move at all), and your server effectively sends correction messages each and every frame regardless of what the client says has happened.

Edit: Beaten to it - I just said more or less the same as Ashaman73.


Can potentially add extra latency (one, two frame), you'd have to be careful with that.

Everything is better with Metal.

Yeah, I thought about not having the client do any prediction/checking if it was a local running game, and just have the server side do it all... lag will be minimal and not have much (if any) effect on the gameplay.

If it turns out to be the only suggestion that might be the way to go. cool.png


With regards to transport, I have already done what Ashaman73 suggested.... I will create a UDP transport, possibly a TCP one too at first (as it's a bit easier that writing a reliable UDP one) and I have a local transport that simply writes and reads from a buffer.
From experience, having a locally-hosted server with full functionality is much more useful than the negligible overhead of latency compensation mechanisms. It's extremely valuable to have your logic be identical in "single" and "multi" player modes, because that way whenever you play SP you're also testing your MP logic. This is great for code coverage and making sure your systems are robust. It also eliminates a lot of points of failure because all your code is the same path - you don't have special cases.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


From experience, having a locally-hosted server with full functionality is much more useful than the negligible overhead of latency compensation mechanisms. It's extremely valuable to have your logic be identical in "single" and "multi" player modes, because that way whenever you play SP you're also testing your MP logic. This is great for code coverage and making sure your systems are robust. It also eliminates a lot of points of failure because all your code is the same path - you don't have special cases.


+1000 :) It's always a bit of a long shot trying to persuade your lead / design that it's a good idea to start from a multiplayer framework and work your way down to single player game design, but it is a far more robust way than the other way round. The problem is, multiplayer is more often than not an after-thought, and it does involve some extra care and design steps.

Everything is better with Metal.

Thanks all for the input.

Onto my next item (which itself could be a new topic) regards to entity systems:

I have one written out working nicely, now I wondered if anyone else has used these with networked games? My view is to have one running on both client and server, and try to keep them synced.

Anyone else?
You could call that reflection, and is pretty much what I've seen done, with added synchronisation mechanisms.

There are a few caveats. For example, do your objects require in-order notifications of changes, or can work out of order.

For example, a change in one entity might trigger a given behaviour in another. If this arrives out of order, mayhem can ensue.

Also, does it requires an entity state to be mirrored (meaning any changes in the entity must be reflected together), or you can run updates on atomic elements out-of-order (your elements when changed will be flagged for transmission, and you can transmit the changes in any order and time you want).

This mainly depends on data dependencies, what entities depend on others, and what atomic elements / components depend on others, ect... In general, the less the dependencies, the better.

Everything is better with Metal.

It's worth noting that if you use a reliable in-order delivery protocol (i.e. TCP or a layer on top of UDP) it simplifies synchronization dramatically. All you have to do is transmit a stream of timestamped events that modify the game state.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement