Advertisement

Server-client or P2P, is one more suited for a style of game?

Started by March 20, 2015 11:03 PM
3 comments, last by hplus0603 9 years, 8 months ago

I am making a Bomberman clone and have the game logic all set up, and now I'm ready to add in networked multiplayer.

This is my first time attempting network code for a game and have read about client-server setups, P2P setups and their main advantages and disadvantages.

It seems like some game genres are more convenient for certain network structures than others. For example, P2P is common in RTS games.

Well, I consider Bomberman to be like RTS of sorts, just greatly simplified in rules and player options. It has real-time action like a shooter or fighting game, but not as fast-paced (although I know Awesomenauts also uses P2P and that is an arena fighter). I am going to make it support up to 4 players and then after having that work, see if it scales well to 8 players.

Currently I have some test server and client setup in the game, using Lidgren. Just for sending string messages through each other and displaying them in their windows, nothing more. If I were to use P2P instead, I was planning on just sending player input states every time the input state has changed for that player. The input state is encoded in a bitmask which would help in sending data to a minimum.

Would P2P be better for this sort of game, or client-server? And am I correct in the kind of data I am going to send to the other players (or server), or should I send the players' own position and bomb data?

I know I still need to deal with input lag, and sending player data directly is more prone to user hacking, but I want to start with the basics first because I think that the network structure I choose will greatly impact how I will update the game logic.

New game in progress: Project SeedWorld

My development blog: Electronic Meteor

so you need to think about a few things first. think of something like collision detection? what machine/computer is going to determine when a player gets hit by a bomb? does each player only determine their own collision and then report that to the rest of the peers if they die? what if a player modifies his packet so he NEVER reports that he dies?

For a small game like this I think it depends on how easy you want it to be for someone to cheat. I personally would always go with a client/server model. That doesn't necessarily mean you need a dedicated server. You could designate one of the peers to be the dedicated server. This way the server can be authoritative making all decisions. All clients would connect to it and not directly to each other. If the server detects someone cheating it can just disconnect them. Of course whoever has the machine that has the authoritative server on it could technically cheat by modifying the server packets, but at some point you have to trust something.

I would have each client send their position to the server at a set rate of say 10 times per second. They will also send a message for something like bomb placed every time they want to place a bomb. The server will verify that the position the client says they are at is possible based on their last known position (ie not too far away, didn't go through a wall, etc) and that the location they placed a bomb is valid and they had bombs available to place. If these are valid and accurate it will forward the information to all users. If the information isn't valid then the server can just drop the packet and ignore it, or at best send a message back to the player telling them they are incorrect and moving them back to the last known valid location.

Since this does take time you will need to include some kind of time stamping on the packets so everyone will know how long ago this was actually requested and can do some interpolation on their side graphically so things don't just pop or jump around but can do so more smoothly.

Advertisement
Note that there are two different topologies here!

One is your physical networking topology: Does each of your players find other players on their own, or does the traffic go through a central server?

The second is your gaming topology: Does each of your players send/receive updates to/from all other players, or is one player elected "host/leader/serer" and receives/collates/broadcasts for all others, or do you have a central server doing that?

The typical solution (that is most common, most robust, fits most cases, etc) is:
- discovery of other players (matchmaking) and making sure their firewalls cooperate (NAT punch-through) is coordinated by a central serer
- one player is assigned "host" of the game, and the other players connect to that player
- once the match is made and the game is started, the central matchmaker server doesn't see more traffic from the players

This is, at the game level, a client/server set-up, but at the physical networking layer, a hybrid between central-server, and clients-talking-to-clients, so from a physical networking point of view, it counts as being "peer to peer" in that the central server isn't involved in gameplay traffic.
enum Bool { True, False, FileNotFound };

ncsu121978:

Currently I have gotten far enough in the network part of the code that the clients send two pieces of data: an input command state (encoded as a byte or possibly short), and the player number (byte). Nothing else about the game state is being sent.

The input command state is agnostic to whether the player uses a keyboard, joystick or some other input device. I send data only every time the command state changes from the previous frame.

The server applies the input commands to the appropriate player(s), and updates its own game. From here I don't know if the server should relay these same input commands to the other clients, or that it should send its updated game state. Sending the game state sounds better, since input commands are going to be delayed even more going to the other clients.

Rewinding to a previous game state to compensate for lag is something else I haven't yet tried for a client-server setup. Do you rewind everything, players, bombs, destroyed blocks, or do you just rewind the players' positions?

I have only tested multiple instances on one local machine, but so far the players in the server game move as they do in the clients. Client / Player 2 moves up, and Server / P1 sees P2 move up on his screen. They go to their same positions as they would, bombs placed are in the same places on all screens.

Even power-ups work as they should. Since the same player walks over the same powerup on all screens, on every instance of the game he is powered up and can place more/better bombs.

Validating the player positions sounds like a good idea, though. All players walk at the same fixed speed, so I guess the server can track the walking distance of all players in the last few seconds and if it's absurdly or even slightly higher than it should be for the time interval, it can assume that a player is cheating.

hplus0603:

In the long run I am thinking of hosting a master server online, a bit like Valve does for their source games but simpler. I don't expect to get a ton of traffic. I work as a web developer so I have knowledge building a dynamic website, using APIs to communicate with other machines, etc. Using online hosting to maintain a list of available game hosts.

I'm expecting that I could get my game to communicate to a web API and send relevant information about its IP, latency, etc. in certain intervals to let the master server know that the host is still "alive". The web server will check and validate the data and it does its own updating on a database. I won't use the program to directly edit the database, don't wanna pull another Super Meat Boy here.

But right now I am more focused on getting the network code working on local machines, before I can start testing with remote IPs. I just figure that deciding between client-server or P2P should be done early in the process of turning your game multiplayer, because it looks like it will impact everything on how I program the network code and how the game logic should be updated.

New game in progress: Project SeedWorld

My development blog: Electronic Meteor

I just figure that deciding between client-server or P2P should be done early in the process


Yes, that is correct!

P2P game topology is generally more robust to one player dropping out -- there is no "host" that can drop and end the game for everyone.

However, if you go P2P, there are significant problems if player A can see player B, and player A can see player C, but player B can't see player C (this happens all the time with Internet firewalls) There is also the problem of enforcing game rules -- either you need a significantly more complex "voting" based anti-cheating simulation, or you need to trust the sending client.

I would suggest using a client/server topology, and tell the player that is the host to port forward a given port to the game for now. Those players that know how to port forward, can host; those who don't, can't. Once you have a matchmaker server, you can start doing NAT punch-through and remove the port forwarding requirement.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement