Sign in to follow this  
Toolmaker

RTS and networking

Recommended Posts

I'm currently in the process of designing the network component for my RTS game and therefor thinking about how I'm going to handle everything. But, I'm not really sure on how to approach things, so I figured, I'll let have some people take a look at my design and help me iron out the possible bottlenecks. To start out: I'll use a TCP and an UDP connection for in-game data transmissions. The TCP channel will be used to setup the initial connection, negotiate an UDP port number, start the game and to sychronise the game clock. Once this is done, the game can begin. The idea is this: One client serves as host. The host will be hosting the waiting room and accept new clients and display them in the waiting room. Once everyone has accepted the settings, the host will send a StartGame message to all the clients, followed by a ClockSync. Each client will respond to the ClockSync with a ClockSyncAck and set it's own clock to 0. The host will then determine the latency between the Clocksync send and the ack and send this value back to the client from which the ack came with a ClockAdjust. Each client will adjust the clock after that(No Ack to that). After this, the TCP channel will be closed. As it's an RTS, the game will be a simulation of what happens on the other side. Each client will send updates to the other clients about movement, newly issued orders, firing of bullets and major events like unit/building destruction, unit deployment, etc. Each update will be send along with a clock and the kind of update, for instance: [clock] MoveUnit [playerID]:[UnitID]:[Location] [clock] WeaponFire [playerID]:[UnitID]:[TargetLocation] [clock] BuildingDestroy [playerID]:[BuildingID] If a player's unit was send to move to a location at clock index 1520 and the current index is 1524, the unit will be given the order and immediately have the Update() called with the delta time. Every 5 seconds(or at a different time interval) a heartbeat will be sent over the UDP channel to ensure connectivity. If there hasn't been a heartbeat for 12 seconds(2 missed heartbeats), a client will send a ProbeClient message to the client it can't contact. If there hasn't been a reply to that within 5 seconds(Or a heartbeat for that matter), the client will escalate this to the others and they will decided to either await the client for another 30 seconds(Showing a dialog that the connection has been possibly dropped) or give the chance to kick the missing client and continue their things. Any flaws in my design? Are there things to improve? What would you do differently? And what data type should I use for the clock? Fixed point decimal? int64? float? Toolmaker

Share this post


Link to post
Share on other sites
Peer-to-peer means significantly higher messaging overhead. Is there any reason why you wouldn't just tunnel all the data through the host?

Also, for RTS networking, it's customary to only use TCP, because there's too many units to work well over lossy UDP (check out the lock-step method, and the 1,500 archers article in the Forum FAQ).

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603
Peer-to-peer means significantly higher messaging overhead. Is there any reason why you wouldn't just tunnel all the data through the host?

Also, for RTS networking, it's customary to only use TCP, because there's too many units to work well over lossy UDP (check out the lock-step method, and the 1,500 archers article in the Forum FAQ).


I did, and I've decided to take a different approach on it. However, using UDP has the added pro of that if the connection to the host dies, the other clients can continue with what they were doing. In other words: The game will not collapse immediatly if the host dies.

Still, relaying over the host still adds significant overhead, except the overhead will be only on the host side, instead on all of the clients. While I don't have to bother with 28.8K bandwidth, it's still a good thing to consider a max. upload of 80K.

From the AOE article I understood to make things meterable, run a bunch of tests, etc. So what I'm going to do now, is make a simple network engine as a prototype, using an existing UDP library for .NET.

Toolmaker

Share this post


Link to post
Share on other sites
Shouldn't the packets be limited to input only? What if someone is to forge building destruction packets when they have no units nearby to destroy a building?

Share this post


Link to post
Share on other sites
Quote:
relaying over the host still adds significant overhead


The host (as each machine) still needs to receive all data for all players. The only difference is that that host sends all data for all players to all players, as opposed to all data for itself to all players. Given that Warcraft III could do 12-way fights over dial-up (more or less), that seems like a tried-and-true model.

However, if you get the peer-to-peer model to work, without state de-sync, I'd be really interested to hear what you ended up having to do to make it work! Please keep us posted.

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603
Quote:
relaying over the host still adds significant overhead


The host (as each machine) still needs to receive all data for all players. The only difference is that that host sends all data for all players to all players, as opposed to all data for itself to all players. Given that Warcraft III could do 12-way fights over dial-up (more or less), that seems like a tried-and-true model.

However, if you get the peer-to-peer model to work, without state de-sync, I'd be really interested to hear what you ended up having to do to make it work! Please keep us posted.


According to the "1500 archers over 28.8K", they used a peer-to-peer model(source). However, it's a rather difficult system to initially set up, but once it works, it works great.

I'm going to write some simple test applications this weekend and try it out. I can easily implement the system AOE used, since I would just buffer up the commands, instead of executing them directly.

And yes: For a RTS simulation I only need to send orders. I need to re-work what I intend to do. My earlier post isn't very up-to-date anymore.

Toolmaker

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this