Peer to Peer game network for RTS games

Started by
9 comments, last by middy 18 years, 1 month ago
I have just completed my master thesis about this subject. I hope you will spend a few minutes viewing my site and commenting on it. One thing is what an professor thinks, another is how game-developers think http://www.p2pgamenetwork.com/ Thanks
Advertisement
I don't understand why you didn't just start out with the regular RTS structure? An RTS is probably the simplest game to make Peer-to-peer and reasonably cheat-proof compared to the player-run server model.

The lock-step model really doesn't need to change much at all between player-run server, authoritative server, or peer-to-peer. The biggest difference is that you have to send your commands to all peers, instead of a single server, leading to an N-fold increase in upstream bandwidth requirement for N players. Also, you'll be getting updates from N peers instead of a single server, leading to (N-1) packet headers of increased downstream bandwidth usage. Other than that, it should be identical to the traditional model.

Note that you can construct the code such that it is 100% deterministic; you don't need to exchange hashes and re-sync players, assuming that you're using reliable, in-order networking (i e TCP). Thus, anyone cheating in any way that changes game state will run themselves out of sync, and won't have an enjoyable game experience.

So, what problem were you trying to solve when moving away from that model?
enum Bool { True, False, FileNotFound };
Hello hplus0603


Thanks for your reply, good questions.

We did start out with the regular RTS model as a case but we wanted to improve it, in scalability and cheat-prevention.

First of all I am not using the lock-step since this have the disadvantage of the slowest Peer setting the speed of the rest. Meaning in turn that it scales badly, something seen in Age of Empires over the Internet. Instead we are using the Neo protocol which will leave "slow" peers out in the cold, in case of package loss or congestion, requiring that the particular peer resyncronizes.

Our model states that no player runs his own game, meaning that he serves others and others serves him. This fixes the "too much information" cheat. Traditional P2P games such as AOE are tamper proof but player has information about the position and forces about every other player, meaning that he can hack his client and reveal his opponents position. A cheat even Blizzard havent been able to prevent in Warcraft III.

Finally our model scales much better then traditional P2P game network due us being able to store many commands in a single packet and our P2P network being relatively small while supporting many players.


Quote:I am not using the lock-step since this have the disadvantage of the slowest Peer setting the speed of the rest.


That's not actually a limitation, right? Simulation for the game can't be 100% of the CPU load; there has to be some time left for the graphics. Thus, the "slowest" peer can still keep up with the game rate -- else it would be below spec, and should be kicked.

If it takes a long time to render a frame (say, 200 ms per frame) for the slowest peer, then that means that the command latency is increased by 200 ms, which is different form the game actually progressing slower than intended.

Quote:Instead we are using the Neo protocol which will leave "slow" peers out in the cold


Is that any better than increasing command latency? The slow peers will likely just not be able to play the game in this case, as their state will be almost continually out of sync. Not to mention that state re-sync uses 10x to 100x more network bandwidth than just sending commands; if the slow peers cause this to happen continually, I don't understand how this can still scale better than lock-step. Do you have data on this effect? (Couldn't find it in the thesis)

Quote:Our model states that no player runs his own game, meaning that he serves others and others serves him.


Right, but with three or four machines in my room, or a network of cheater friends, I'll be pretty likely to find out who actually serves my game.

The only way to avoid unit reveal hacks is to design the game so that everybody sees all the units, or to use a trusted central server that only sends what you can see (which means that using lock-steps becomes "more interesting" :-).
enum Bool { True, False, FileNotFound };
Quote:
That's not actually a limitation, right? Simulation for the game can't be 100% of the CPU load; there has to be some time left for the graphics. Thus, the "slowest" peer can still keep up with the game rate -- else it would be below spec, and should be kicked.

If it takes a long time to render a frame (say, 200 ms per frame) for the slowest peer, then that means that the command latency is increased by 200 ms, which is different form the game actually progressing slower than intended.


Thats true but we cannot prevent package loss or congestion or even kid-brothers starting kazaa :-) wich would leave an single Peer unsyncronized. In the old model this would slow or stop the entire game. In our model only a single Peer is affected. Having the game running onwards regardless of the troubles of a single player is common in client-server games why not P2P game networks.

Quote:
Is that any better than increasing command latency? The slow peers will likely just not be able to play the game in this case, as their state will be almost continually out of sync. Not to mention that state re-sync uses 10x to 100x more network bandwidth than just sending commands; if the slow peers cause this to happen continually, I don't understand how this can still scale better than lock-step. Do you have data on this effect? (Couldn't find it in the thesis)


We do not propose that command latency should not be used we simply state that one should use it to a certain boundary. We havent dealth with it in details since its known method. Resyncronization is not how we scale more effeciently. We scale more effeciently because a game is run by a small P2P group (called a region) working as a distributed server for the players. Furthermore the gameworld can be cut up and distributed to several of these regions.

Lock-step have to resynchronize as well since package loss may appear and it is very hard to ensure a completely synchronize time and calculation. This is apparent in many P2P RTS games when they are put under pressure.

Quote:
Right, but with three or four machines in my room, or a network of cheater friends, I'll be pretty likely to find out who actually serves my game.

The only way to avoid unit reveal hacks is to design the game so that everybody sees all the units, or to use a trusted central server that only sends what you can see (which means that using lock-steps becomes "more interesting" :-).


The thesis desribes our network as a heap of different games managed by a single
trusted server. We are talking 100 of players playing and serving different games. Our model needs one “server”(we call it a NEO node) node pr 5 players so we can group high connection bandwidth. This also means that we need resynchronization since a NEO node may leave at any time, and a new one can join.

Imagine the model as logging into game-spy playing say battlefield. You get a list of different games to play, but instead of servers each game is served by one or more p2p network. By joinning a game you also participate in hosting another game.

To find out who serves your game you must discover every Neo node in the region and manage to hack at least 50% of them. Since these nodes are assigned by the central authority this is hard todo.

But in all fairness our system can use a lockstep protocol instead of the NEO protocol without any featureloss wether one or the other is the best remains to be tested under more complex settings than we had time todo.


I hope it makes sense


As far as security holes go, There is a huge one when it comes to a peer to peer game in which the entire gamestate is not sent across the wire.

And that is session master migration. With a server based game, when the server leaves, the game is over. But from what I can tell from this model, another player in another game is your server. He does not have any incentive to stay in the game, and his game will most likely end before yours does. At this point in time the authoratative "master" node would have to be re-elected. (if the master node were to end gracefully he can send his gamestate to the new "master" node.) If he does not exit gracefully, the new master node must be informed of gamestate by the respective clients.

If I wanted to break this network model (and tell me if i'm wrong here), i could determine my master node (by packet sniffing), I could then, from a different computer, launch a DOS attack against that machine. The machine would stop responding to our game, and our game would have to notify the main authorative that our master node had vanished. We would be assigned a new node. When this happened, and the new node attempted to gain information about the clients to reconstruct the gamestate, I modify my gamestate to say that i have more resources than I do, and more units than I do.

Because there is no authorative four our gamestate at the moment, and the game state has been hidden from the other players, no one can contest my data. And I have successfully cheated.

You could chose to stop the game when this happens, and kick everybody back to the lobby, but this will occur whenever someone shuts down their computer, their game crashes, they unplug their network cable, their internet goes out, They kill their game task, etc..

Anytime a master node timesout, for whatever reason, I have the opportunity to cheat the system. Not just a simple fog of war cheat like this protocol wants to avoid, but a full blown, I have 30,000 of the toughest units and a bazillion resources type of cheat.

Anytime I AM a master node, I have the opportunity to mess with complete strangers, and be entirely successful because I am the only one with the master state.

I'm not trying to blow holes into your thesis for fun, I am a professional network game programmer, and work mostly on peer to peer models for consoles. I have been through the QA, and gotten the reports back from customer service, and seen these issues firsthand. Players disconnecting or pulling their cables out cause they are loosing, or turning of their machines, happens ALL THE TIME.. it's not a small random occurance.

Just something to think about, and maybe address in your model.

Quote:
And that is session master migration. With a server based game, when the server leaves, the game is over. But from what I can tell from this model, another player in another game is your server. He does not have any incentive to stay in the game, and his game will most likely end before yours does. At this point in time the authoratative "master" node would have to be re-elected. (if the master node were to end gracefully he can send his gamestate to the new "master" node.) If he does not exit gracefully, the new master node must be informed of gamestate by the respective clients.


Well I have to empathise that a single game is served by several (NEO)nodes in a p2p network. Each node serving as an entrace to the game for other players (we call them primary nodes). No player is aware of all the members of this p2p group (we call it a region).

If a NEO node leaves as they do.The region leader requests a new NEO node from the central authorithy (CA) ( a secure server). The CA elects a random free node to be a new NEO node and this node joins the region and recives the gamestate while the game is running. We only experience a total crash if every node in the region leaves at the same time. Here we have trouble reconstructing since no player is aware of the entire gamestate.

Quote:
If I wanted to break this network model (and tell me if i'm wrong here), i could determine my master node (by packet sniffing), I could then, from a different computer, launch a DOS attack against that machine. The machine would stop responding to our game, and our game would have to notify the main authorative that our master node had vanished. We would be assigned a new node. When this happened, and the new node attempted to gain information about the clients to reconstruct the gamestate, I modify my gamestate to say that i have more resources than I do, and more units than I do.

The only node you can DOS is YOUR primary NEO node which would disconnect you from the game. And the game cannot be reconstructed from your gamestate since you do not have it all.

Quote:
Anytime I AM a master node, I have the opportunity to mess with complete strangers, and be entirely successful because I am the only one with the master state.

Not unless you manage to cheat the other master-nodes(NEO) in your region.They will check your gamestate just like in Age of empires.Basically if you control 50% of a region you control it since state updates are done by majority votes.

Quote:
I'm not trying to blow holes into your thesis for fun, I am a professional network game programmer, and work mostly on peer to peer models for consoles. I have been through the QA, and gotten the reports back from customer service, and seen these issues firsthand. Players disconnecting or pulling their cables out cause they are loosing, or turning of their machines, happens ALL THE TIME.. it's not a small random occurance.

If I was afraid of attack against my thesis I wouldent have posted :-)

It is cool to have professionals looking at ones work.
Quote:The region leader requests a new NEO node from the central authorithy (CA) ( a secure server).

But then it's not really P2P; if the CA goes down all your games die (not immediately, but when master nodes leave, which is quite common). Or am I missing something?
Most P2P networks, in reality, need some central server to set up firewall punch-through introduction and do match-making.

If you think about it, not even the greater internet is "peer-to-peer" if that's the way you want to define it, because everybody needs access to the root name servers.
enum Bool { True, False, FileNotFound };
Ok.. so let me get this straight then..

Players in a game, do not communicate directly to the other players in their game, but through this neonode (which can be a player in a different game, which has his own neonode)

A neonode knows the full gamestate. The number of neonodes that persist the gamestate is equal to the number of players in a game? (each player communicates through a unique neonode)

The game is actually "played" (game logic wise) on the neonodes, and the communication between neonodes is similar to that of an existing RTS (neonodes send each other full gamestate updates). The neonode that a player is connected to then sends down information to the peer which he is hosting.

On session master migration, the remaining neonodes send gamestate to the newly elected neonode, and connection is made with the orphaned player.

This model seems to incur a moderate bandwidth overhead, as if i am playing a game i expect to send commands to my neonode, as well as recieve relevant gamestate updates from my neonode. But I can also assume that I am acting as a neonode, in which case I send and recieve a more broad set of updates to the other neonodes simulating this game.

I'd say it's certainly a novel idea. Understanding it a bit more, the only real place I can see abuse occuring is for a neonode to send his client an incorrect view of the world, or relaying all updates to the client, giving the client a full gamestate.

But thats a fairly small hole in the scheme of things, because there would be no way to coordinate a cheat easily. There is definately a chance of random griefing by neonodes, and because it would be random and anonymous it would be much harder to track down griefers. But I don't think socially, it would be so much of a problem. I think grifers do things mostly for the reaction, and as a neonode, you would not really hae the opportunity to witness the reaction.

You may want to readdress your realtime protocol like hplus said. Disadvantaging slower players, tends to give players a bad outlook on the reliability of the game. And by funneling traffic through the neonodes, you are adding a significant amount of latency to the system. This means if you have been so unlucky to get a neonode that has a bad connection to you, or one of the other neonodes controlling your game (regardless of your connection) you can be penalized. Personally, I feel that this is much worse than bringing everyone down to the lowest common denominator. I don't want my gameplay experience to be hampered by another peer that I have no control over.

There are ways not to slow the game down when using a turn based method like age of empires, where you send commands to execute during a future turn. the number of turns in the future to execute a command can scale with latency, so that the game does not pause or stutter, but remains fluid. commands issuing 400ms later than they were issued is probably not a big deal in an rts, as long as the player gets immediate notification from his UI. If the little guy says "yes sir!", and proceeds to move 1 second later, it is not going to impact gameplay significantly.

You need to understand that you have traded cheat resistance for greater latency, and bandwidth. It's important to build a system that is tolerant of latency, and is extremely playable for those with low latency (because your model has increased the likelyhood that a player will have a bad connection (by adding 2 new, unpredicatble routes into the equation).

I would readdress your realtime ingame protocol, and try to find a way to scale, based on latency, a turn based method similar to AOE. (This will work to offset the extra bandwith that is added by being both a player and a neonode, as a turn based network model will send less packets, and decrease the amount of header bandwith (which is a big concern in realtime models)





This topic is closed to new replies.

Advertisement