Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm making a simple little MOBA just for fun. I was making everything single-player then I realized "oh crap I should probably add multiplayer, huh."

I've never done anything with networking before, so learning how to integrate Lidgren into my game was fun and awesome. The thing is, I pretty much know the way I'm doing things is wrong, because it's not robust enough for mainstream games to use, as far as I know, but what's wrong with it?

What I'm doing is, basically, whenever a player does an action, it sends a message to the server saying "hey, I just did this thing." The server and the client are both running the same simulation. The server then sends a message to all other clients telling them that that guy did that thing.

For the most part, except in a few cases, when a player does a thing, the client assumes it's cool and goes ahead with it on its own. So when you right-click somewhere to move there, that player's client just starts moving his guy there, and then sends a message to the server telling it about it.

So basically:

  • Player 1 casts a spell to make him move 100% faster for six seconds
  • Player 1's local client adds that buff to his Unit object
  • Player 1's client sends a message to the server saying "hey I just cast this spell"
  • The server makes sure he really did have enough mana to cast that spell, and if so, adds that buff to the server's copy of that Unit object
  • The server sends a message to all other clients saying "hey this guy just cast this spell"
  • Every other client receives the message and goes "ah okay cool," and adds that buff to their local Unit object for that player

I've been skimming through stuff to see how big games do multiplayer, and it's kind of confusing for someone who's just starting to dabble in this stuff, but it looks like the Source engine sends a packet containing all of the changes to everything in the world every tick? Again, totally new to this stuff, but can you really push that much data that frequently?

Sorry if this is a bit rambly, but basically, I was wondering why my simpler system isn't the right way to go, because if it was, other games would use it, right?

share|improve this question
5  
One step you're missing is that the server also sends this message to the original client (not just everyone else) to confirm or deny the simulation's result, the originating client then either keeps on going or adjusts itself to the new reality. Other than that this method is fine and the other answers below will help you get a deeper undersanding of other aspects. –  Patrick Hughes Jul 10 '13 at 17:35
1  
What's awesome is that the rest of us have reasonable hope that network is not that hard. It's doable. –  ashes999 Jul 10 '13 at 21:02

3 Answers 3

up vote 11 down vote accepted

In addition to Byte56's answer, there are a couple more things to consider:

How are you going to communicate between the clients about player movement? Unlike most other player actions, which tend to be isolated events and likely somewhat infrequent, movement is continuous. There is a limit to the rate at which you can (and want to, for that matter) send and receive updates. The Client-side prediction that Byte56 mentioned typically involves periodic updates about client position and velocity. The client then locally interpolates between them, using something like a Cubic Spline.

A second issue, which connects back to the previous ones, is that UDP does not have guaranteed delivery. You can not be certain that every message you send arrives, or even arrives in the right order. You could send packets 1, 2, and 3, and the server receives 3 then 1 and not 2. Often they'll be in the right order, and often they will arrive, but not always. So, you need a system that is robust to losing packets. A simple confirmation system is sufficient. Typically used is a bitfield telling the other node whether it has received the last 32 messages (for a 32bit int), and what the last message received was. This way, you can label messages as critical or not, and resend if they don't receive critical ones. There is a pretty decent discussion of it here.

You also need to keep in mind, when doing this, that your clients will be out of sync with eachother. Each will be showing the other players interpolating between their previous two network frames while you're working on the next one, in the best case scenario. So you need a system that takes into account (fairly) that what a player saw when he performed an action was not the actual state of the game when he did that action. He was reacting to an old, out-of-sync game state.

Finally, if this game is intended to be competitive, you also need to worry about cheating. Thus, to the extent possible (and reasonable), you must distrust the clients and verify their actions were possible. "No, you can't walk through that wall. No you can't walk faster than your run velocity. No, you can't claim to have hit that target." etc.

For more ideas, I recommend browsing the other articles in that second link.

Good luck!

share|improve this answer
2  
+1 This is the real answer, mine is just the preface. –  Byte56 Jul 10 '13 at 16:51

What you're describing is essentially client-side prediction, but you don't say what happens when the server and client disagree.

It evolved from the days when the client was just a dumb terminal, sending its input to the server, and the server told the client the outcome. However, once games moved beyond the LAN (and frequently before) the latency was noticeable in this situation. What you're describing, client-side prediction was introduced to fix that. Now the client also simulates the movement while waiting for the server to respond. Then they come to an agreement on the outcome. With the server being the authority.

The next steps are how you respond to disagreements. If you don't have anything in place for that, you'll get the client rubber-banding or tele-porting when the client and server disagree.

share|improve this answer

Timing. The other answers don't mention the timing of events on the server and the different clients. Depending on the game, this could be something to watch out for. Latency (aka Lag) introduces a variable delay between when a packet is sent and when it is received. Time can be tricky, but I'll try to explain the potential issues as best I can. There are some games that can get by without worrying about this, but here's a simple example of where it can cause problems.

Assume that everyone acts on packets as soon as they arrive.

@ Time 0 (wall time), Player 1 puts up a shield   (Message has been sent, but not received by anyone)
@ Time 1, Player 2 shoots player 1   (Message has been sent, but not received by anyone)

Assume Time 0 (T0) and T1 are close together.

What happens next depends on who is looking at this, and on the order in which the packets arrive on the server. The server should always have the final say. IF the server receives the packets in the order given above, then the server will apply the shield before the shot and player 1 (P1) will survive. From P1's perspective, having put up the shield himself, he will see the shield before the shot and survive. But what about P2? They will see the shot right away because they shot it, but will they see the shield first? If (T0 + latency between P1 and the server + the latency between the server and P2) > T1, the shield will come up after the shot, and P2 will think their shot has killed P1. The server will have to correct this situation somehow.

If however, the server receives the packets in the reverse order (which is quite possible, even if T0 < T1), then the opposite occurs. P1 is wrong (and dead), while P2 is correct (and victorious).

There are a few ways to deal with situations like this, but the easiest is to let the server do everything. You can attempt to simulate this on the client, but don't allow any permanent actions, like death. The players will have to wait for important game-changing confirmations from the server.

Sending a timestamp with actions can be beneficial. IF you mostly trust the clients, then you can use these timestamps can be used to determine which action happened first, instead of following our first assumption. This can be tricky, because receiving messages from the past usually means you need to be able to reverse time.

Time is fun eh? No matter what you end up doing, it's helpful to be aware of these time issues.

share|improve this answer
    
+1 Good overview of timing issues. –  Byte56 Jul 10 '13 at 20:38

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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