4
\$\begingroup\$

How do I approach multiplayer games for debugging? When debugging locally - how can you prevent yourself from disconnecting? The debugger halts network activity.

\$\endgroup\$
2
  • \$\begingroup\$ This might be a question for stackoverflow. I'm not sure how a game developer would answer this differently than any other developer. At this high of a level, the difference between a game and any other networked application are negligible. \$\endgroup\$
    – House
    Commented Jul 12, 2013 at 21:11
  • 2
    \$\begingroup\$ This is a good read on the subject: gafferongames.com/networking-for-game-programmers/… \$\endgroup\$ Commented Jul 12, 2013 at 21:41

3 Answers 3

6
\$\begingroup\$

By far the most effective way I have found to handle this problem is to eliminate it entirely.

I should say, up front, that the techniques I'm talking about here require that your game is really well architectured. You need to be able to create multiple instances of the game, update the game without rendering anything, render to a specific viewport, plug in different network connection objects (a simulated network is ideal for this), and so on.

It also requires your game is reasonably fast. Being able to simulate at a few hundred frames per second really helps.


If you can manage that, you can do two very powerful things:

First: you can run multiple instances of the game in a single process, connect them together with a virtual (or actual) network, and test them all on a single screen. This is fantastic by itself - but comes in really handy when you can just hit "pause" in the debugger and the entire process, including every instance of the game, stops at once.

Second: If you really want to go all out, you can run an "offline" simulation of the game (again with multiple instances in the one process). You can use this to do powerful things like graph out the positions of objects over time to see if they're moving correctly.

This is cool on its own. But it becomes extremely powerful when debugging if you set it up so you can re-run that simulation on-demand (being a network game, it should be highly deterministic) and then have Debugger.Break() get called on a specific frame.


I've got a DevLog video here showing both techniques being used in development of my game, Stick Ninjas.

Here are some screenshots. First, multiple instances of the game in the one process. Check out the packets flying across the simulated network.

Multiple Game Instances

And, second, the game graphing out object positions over a short run with a specific set of inputs and network conditions. Both client and server states are graphed.

Graphing Tool


The origin for these techniques is something I came across, while researching, about how the networking for Quake was developed. (See this page for some details).

Basically the idea was that the engine takes everything as an input: actual user inputs, packets, even clock ticks. That way - all those inputs can be recorded and replayed through the engine at a later time (perhaps with a debugger attached, perhaps in a debug build, perhaps with a specific frame scheduled to cause Debugger.Break() to get called).

This is, itself, an excellent idea for debugging. Although, with the tools I've described above, I haven't yet found a need to fully implement recording and playback yet for my project.


Of course, all of these depend on your game being deterministic and behaving itself. You might find you need to use some of the techniques in this excellent article (that John McDonald already beat me to linking in the comments).

I really like the first technique: Basically set the game to pause if the network times-out. This is important - not so much because of your network thread - but because network clocks getting out of sync can be problematic.

But, also with these techniques, I'm yet to encounter a need to implement them in practice.


The last technique I should briefly mention is plain ol' unit testing. I'm not really huge on unit testing everything. But one thing you absolutely should unit test are your methods for reading and writing data into packets. These are methods that you need to rely on with 100% confidence. An error in one of these methods can be a nightmare to track down.

For good measure, I also have a few unit tests that set up an instance of my game world, push it across a virtual network, and make sure it comes out unscathed at the other end.

\$\endgroup\$
0
1
\$\begingroup\$

Here's a few options:

  1. Debug by displaying debug information on screen, or to the debug console.

  2. Use a network packet inspection tool like Wireshark.

  3. Don't keep the game breakpointed in the debugger for too long - examine the state quickly, resume execution, and repeat. If need be you can also increase timeouts in debug builds.

  4. Use UDP for everything. Because it's connectionless you don't have any timeouts imposed on you. Of course this also means there's more code to write because you don't get things like automatic retries for dropped packets.

\$\endgroup\$
1
\$\begingroup\$

Actual network threads are perfectly happy to be unused for long periods of time. If your debugging activity stops voluntary activity, and that upsets the server, you need to fix that problem at the server.

If the nature of your problems is real-time interaction in unexpected ways, then a certain Heisenberg effect is inevitable. You best bet is to instrument your application to keep communication history, and use the logs forensically.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .