Skip to main content
GameDev.net gamedev.net
🔒 Locked

6 rather noobish questions

Started by QuigleyQ Jun 20, 2011 at 9:50 PM 12 replies 2.4k views
Original Post
QuigleyQ
QuigleyQ
[font="verdana, geneva, lucida,"]I'm planning on making a fighting game in C++ which multiple people can play over a network. I've never done any programming involving a network, so I have some questions.

1) What protocol should be used? I don't know the differences between TCP and UDP.

2) What changes would I have to make to play this over a LAN network, as opposed to the Internet?

3) How should I make sure that all versions of the game world are synced properly? I'm thinking of initializing one copy per computer, then only sending events like 'move up' or 'attack' between the computers, so not as much data needs to be sent. Is there a better way, or is this good enough?

4) If I do that, how do I make sure that I don't have timing issues? For example, A receives two events from C and D simultaneously, but B receives C's later, which could alter the internal state of the world. Butterfly effect and all that.

5) How should I make sure that random numbers are the same between all computers? Should I just send requests to one computer and have it send out a random number? Seems inefficient...[/font]
[font="verdana, geneva, lucida,"]
[/font]
[font="verdana, geneva, lucida,"]6) I have no clue which 2D graphics library to pick. I've looked at SDL, wxWidgets, Qt, and GTK+, but I don't know enough about any of them to decide. Also, [/font][font="verdana, geneva, lucida,"]I'm assuming I'll need a third party library for sockets and whatnot, so, do any of these handle that too?[/font]
empirical2
empirical2
1. TCP is reliable but laggy, UDP is fast but unreliable (that's how Understand it)
2. My little TCP game I just made worked in both. The socket API exposes a common interface.
5. You need send only the seed I should think. When the generator is given a seed it will spit of the same sequence of numbers.
6. For portability yes. I just programmed the windows sockets directly. But I'm crazy like that.
Varine
Varine
1. http://www.cyberciti.biz/faq/key-differences-between-tcp-and-udp-protocols/

3. You still might encounter lag, but you should test it first. Do what you're planning with it, and come back if that proves ineffective. You may want to check out some network engines and see how they do it.

4. This is one of many issues in the peer to peer networking world... You could set up a small amount of inherent delay (perhaps a few hundredths of a second), as many RTS games do. But obviously that's not very preferable. You could try a system where the host of the game acts as a dedicated server. So all conflicts would be handled there, and whatever one happened first (or whatever one is more likely, but the former is easier to implement) takes precedence. So it all comes down to whoever has a faster connection, thus possibly making it slightly unfair, but it does keep the game synchronized. You could also try some kind of a phase system, where the data is sent in phases (so many packets every second), and just limit the speed to the slowest connection. So if the host, let's say A, is receiving packets from B and C at the same time, but D is slightly slower, you just wait for D's to come, then it calculates everything and distributes the game state back.
QuigleyQ
QuigleyQ
Okay, I feel pretty stupid about number 5 now.
So, transmitting game state would be better than trying to preserve it on all the machines? Then the host could use UDP to update the clients?
ApochPiQ
ApochPiQ
There's no particularly good reason to use UDP over TCP. TCP is plenty fast and not inherently "laggy", contrary to popular misconception.

A single authoritative host that updates all the clients is a standard model for implementing multiplayer games. It can be handy to help curb cheating and unintentional drift between the game state on multiple systems, provided you can reasonably assure that the host itself isn't tampered with in some way.
SimonForsman
SimonForsman

Okay, I feel pretty stupid about number 5 now.
So, transmitting game state would be better than trying to preserve it on all the machines? Then the host could use UDP to update the clients?


It really depends on your game, as for TCP vs UDP the previous suggestions aren't all that accurate, TCP basically guarantees that all packets will arrive and that they will arrive in order (This means that if you send 10 pieces of data and piece 5 is lost pieces 6-10 will be stalled until 5 has arrived, with UDP you send discrete packets that may or may not arrive (if a packet is lost its up to your software to detect it and decide what to do about it). For fast paced action games where you're spamming the clients with the gamestate UDP is preferable (if a state gets lost you'll get a new, more up to date state before you're able to detect that a packet was lost anyway), for lower pace games TCP can be a better option.

(RTS games for example tend to use a lockstep protocol which preserves gamestate, only sends commands and can work very well with TCP)
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
QuigleyQ
QuigleyQ
Alright, so for transmitting game state, UDP is preferable. What about transmitting commands? They still have to get there quickly, but dropping one would be a problem. So that should use TCP, right?
frob
frob

Alright, so for transmitting game state, UDP is preferable. What about transmitting commands? They still have to get there quickly, but dropping one would be a problem. So that should use TCP, right?

Your statement show a lack of understanding of the protocols, and a lack of understanding of several basic concepts of inter-process communication (IPC).


Being in the For Beginners forum, this worries me.

Learn to stand before trying to walk, learn to walk before learning to run.







Based on your statements it seems you don't understand IPC. In that case you should use TCP, or more simple forms of IPC such as a shared file.

Using TCP means you don't have to understand details about what has been sent and what hasn't. You don't need to acknowledge data or deal with lost data, or deal with out-of-order data, or deal with duplicate data. TCP handles all those nasty details for you. And trust me, based on the questions you have been asking you don't have the requisite experience to handle them. You will still need to deal with connectivity issues, ports and NAT and public addresses and private addresses and more, which are probably more than enough of an obstacle at this point.

Using TCP means you write to it as a stream, the same as a file. You read from it as a stream, the same as a file. Sometimes there will be lots of data to read, other times there will be incomplete data to read. Once you've got the connectivity issues addressed, TCP is exactly the same IPC form as a set of shared files.

As a wonderful side benefit, you can use a set of shared file to simulate TCP networking. Just run two instances of the game on your computer, and each file is opened once for append by the sender and for read by the receiver. This will make it much easier to track down the nasty networking bugs you are certain to write by allowing you to see exactly what was written across the wire. Networking code is just a form of IPC. Shared files are a much more direct and less buggy form of IPC.

I'd suggest you master the easier forms of shared file communication before entering the more complex world of networked communication.
wolfscaptain
wolfscaptain

Alright, so for transmitting game state, UDP is preferable. What about transmitting commands? They still have to get there quickly, but dropping one would be a problem. So that should use TCP, right?


No, TCP will still ruin the UDP part if you mix them.
Instead, you can make UDP reliable, I suggest you to read this series of articles
http://www.gafferongames.com/networking-for-game-programmers/
QuigleyQ
QuigleyQ

[quote name='Henry S' timestamp='1308675820' post='4826058']
Alright, so for transmitting game state, UDP is preferable. What about transmitting commands? They still have to get there quickly, but dropping one would be a problem. So that should use TCP, right?

Your statement show a lack of understanding of the protocols, and a lack of understanding of several basic concepts of inter-process communication (IPC).


Being in the For Beginners forum, this worries me.

Learn to stand before trying to walk, learn to walk before learning to run.







Based on your statements it seems you don't understand IPC. In that case you should use TCP, or more simple forms of IPC such as a shared file.

Using TCP means you don't have to understand details about what has been sent and what hasn't. You don't need to acknowledge data or deal with lost data, or deal with out-of-order data, or deal with duplicate data. TCP handles all those nasty details for you. And trust me, based on the questions you have been asking you don't have the requisite experience to handle them. You will still need to deal with connectivity issues, ports and NAT and public addresses and private addresses and more, which are probably more than enough of an obstacle at this point.

Using TCP means you write to it as a stream, the same as a file. You read from it as a stream, the same as a file. Sometimes there will be lots of data to read, other times there will be incomplete data to read. Once you've got the connectivity issues addressed, TCP is exactly the same IPC form as a set of shared files.

As a wonderful side benefit, you can use a set of shared file to simulate TCP networking. Just run two instances of the game on your computer, and each file is opened once for append by the sender and for read by the receiver. This will make it much easier to track down the nasty networking bugs you are certain to write by allowing you to see exactly what was written across the wire. Networking code is just a form of IPC. Shared files are a much more direct and less buggy form of IPC.

I'd suggest you master the easier forms of shared file communication before entering the more complex world of networked communication.
[/quote]

I don't know the intricate details of how each protocol works, but I do know their differences now. And why would this worry you that it's in the beginners forum? Isn't that where it's supposed to be?

And to wolfscaptain: the two aren't being mixed into the same stream, one is going to the host, the other from it. Would that still mess it up?
EDIT: Never mind, that article you linked was really helpful. UDP it is.
frob
frob

I don't know the intricate details of how each protocol works, but I do know their differences now. And why would this worry you that it's in the beginners forum? Isn't that where it's supposed to be?

And to wolfscaptain: the two aren't being mixed into the same stream, one is going to the host, the other from it. Would that still mess it up?
EDIT: Never mind, that article you linked was really helpful. UDP it is.


It is always worrisome because network programming is a relatively advanced programming topic.

You are writing (and debugging) code that runs asynchronously spanning multiple processes and generally multiple machines using an inherently unstable communications medium. Isn't that enough of a challenge already?

Choosing UDP is certainly an option, but it incurs yet another complexity into your code. You have added the extra complications of randomly having missing data, duplicate data, out of order data, sometimes with duplicates and out-of-order coming out both out together.


There is an entire forum on the site dedicated to network programming. That forum's FAQ links to several articles that list various prerequisite skills, including understanding of serialization, synchronous and asynchronous debugging, journaling with playback (the beginning of which which were mentioned in my post of a shared file interface), and details about compiler-specific memory layouts.

Those are prerequisites to developing multiplayer games, although you can certainly learn with a baptism-by-fire by learning as you go. It's a painful route that can leave you and your code badly scarred, and sadly quite a few people have done it.

Those topics are generally far beyond the skills of most "for beginners" posts.

Four of your six questions have answers that fall into the prerequisite skills bucket. You can go the baptism-by-fire route and jump in at the deep end, or the step-by-step approach of developing inter-process communications by adding the fewest changes as required to go step-by-step into it. I recommend the latter.
rip-off
rip-off
If you structure your code correctly, you can switch from files to TCP and finally UDP at a later time with minimal changes. The main thing is to get the game working first. I think that this is the core of frob's suggestion. Start out with the easy path of getting two programs to communicate on the local machine (using files). Later you get it working on the local network (TCP). Finally, get it working on the internet (switch to UDP if TCP isn't feasible at this stage).

Structuring your code correctly means that only a small portion of your code is responsible for interacting with IPC. More importantly, only a small portion of your code should be responsible for deciding what to send and how reliably to send it. So you have perhaps two subsystems, the "transport layer" which is responsible for getting bytes from one process to another, and a replication layer responsible for figuring how best to keep the two processes data sets in sync (or as close to in sync as possible).

But it is easy to re-write code. Don't worry too much about getting this all correct ahead of time - you almost certainly will not. Nor would I, and I've done this before!

One trick with TCP is to use nonblocking sockets on the sending side. That is, if you detect that sending will block your program, place any partially sent message in a buffer. When the socket becomes writeable again, you can write the rest of the partial message and then just the latest state, which avoids both trying to send intermediate state (if you can afford to lose it) and blocking your program.


No, TCP will still ruin the UDP part if you mix them.
[/quote]
I have no idea what you're suggesting here. Can you explain?

In practise the opposite happens, a badly behaving UDP application can cause congestion which TCP reacts to by reducing the window size. The UDP application typically doesn't react to the congestion and will continue to flood the network with packets. TCP will keep reacting to the congestion as it continues, which basically means that UDP will "win". This isn't to say that UDP packets won't be dropped, they will, but many UDP applications will just spam more out regardless.

But even then this is only applicable if you can congest the network, for a local fighting game I don't think that will be the case.
empirical2
empirical2
A tip for TCP.
I only recently created a very simply multiplier game so although everyone else will go 'duh obviously' this caught me out and wasted a bit of time and head scratching.

If you choose TCP, remember its stream based. So each send command is not gaurenteed to have the same number or greater of recv commands on the other end. What I mean is although I knew the data may be split I was not expecting the data sends to be stuck together, so my game was loosing specific packets.

Therefore I needed to send my data with headers for my reader function to separate them out.
QuigleyQ
QuigleyQ

If you structure your code correctly, you can switch from files to TCP and finally UDP at a later time with minimal changes. The main thing is to get the game working first. I think that this is the core of frob's suggestion. Start out with the easy path of getting two programs to communicate on the local machine (using files). Later you get it working on the local network (TCP). Finally, get it working on the internet (switch to UDP if TCP isn't feasible at this stage).


Alright. I was trying to write up an outline for this before I started, since some of my projects have been messes. I'm trying to get a general idea of how the final program should be set up. But, yeah, I should just work bottom-up.




[color=#1C2837][size=2]Don't worry too much about getting this all correct ahead of time - you almost certainly will not.
[color=#1C2837][size=2]

[color=#1C2837][size=2]

[color=#1C2837][size=2]That's actually reassuring, in a kind of counter-intuitive way. Thanks!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.