Do I have my network logic right? (very basic logic question)

Started by
8 comments, last by Holy Fuzz 18 years, 9 months ago
I'm very new to game programming (I come from a database background) and I'm not sure I have the network logic right or not... The game I'm making is a Scorched Earth clone. However instead of turn-based it will be real-time but you can only shoot missiles every so often (every two seconds lets say). For several reasons (listed below), I'm going to use one main server that all players will connect to. At first there will only be one game going on at a time but anybody can connect to the server and join in the game (they will spawn in). Here's what I'm thinking about the network logic: 1) Player tells server "I want to shoot my gun with power 80 and angle 45" Player's game doesn't do anything. 2) Server decides that this move is valid (eg. player is not cheating or shooting too often) and then sends a packet to player 1 saying "Ok, shoot your gun at power 80 and angle 45." The server also tells the other players that player 1 shot his gun. 3) Each player calculates the ballistic trajectory however it doesn't actually mean anything. For example, if a projectile collides with something it is meaningless (see next point). 4) The server is also calculating trajectorys and if it sees a collision it sends out a collision packet to each player. Basically it's like this: The players tell the server what they want to do but the server calculates everything. This will keep all players in-sync and prevent cheating. Does this sound like a good plan? Will this be hard to implement for a newbie game programmer? Any other thoughts or ideas?
Advertisement
it's a good design really don't forget to timestamp things that way the server can send the collision event way ahead of the collision happening with a timestamp saying when it is to occur. And if you're a bit clever you can mask network latency behind animations making it seem truly realtime even for people with slow network connections.
HardDrop - hard link shell extension."Tread softly because you tread on my dreams" - Yeats
Im not an experienced network programmer, I only have done some easy games, but, yeah, your plan sounds cool, and thats the way it should happen, imho. Only one thing, which sounds like it isnt going to be a problem on this particular project, but be carefull not to overload your server. Sometimes using this approach in my games, I put too much calculation on the server when many clients join and start doing stuff. So you should move as much calculations (that arent that important, and dont need carefull cheat checking and syncing) as possible to the client side.
Since most cheater will use a cheat all game long, you could always redo calculation once in a while. let say you have 5 client connected, alternate client cheat checking every minute.
You should be fine. Problems with this approach occur when two fast moving objects collide, but because your tanks rarely fly though the air at high speed and bombs don't intersect each other, noone should notice.

(The problem is that the server decides two things collided, everyone else thinks they are in slightly different places and didn't, and if you wait for the server to tell you when collisions occur there is a suspicious pause inbetween "hit" and "bang")
Squirm,

Actually there will be a lot of things happening at the same time and projectiles can collide in the air.

I know what you are saying and I'm worried about it (the clients are drawing animations and see the projectiles miss because they don't receive the collide packet until a second later).

Do you have any suggestions on how to get around this? Even if I let each client handle collisions they can get out of sync and then I'm royally screwed up.

Perhaps a queue system would be best but that would get rediculously complicated. For example, whenever a new projectile is created (or an existing one is effected [eg. wind change mid-flight]) I can generate a table of "events" that will occur. This table is then sent to clients and the clients check against it every time...

Like I said though, I can see that getting insanely complicated.

[EDIT] The more I thought about my "table" plan, it still wouldn't fix the problem if a player uses a shield (for example) at the very last second.

sorry for a fairly late reply :)

In professional games (halflife? quake?) how often do you run round a corner, and then suddenly teleport back to where you came from, dead, because your client just found out you got shot?

It's annoying, but there isn't a great deal you can do about it... I think letting the server indicate collisions, and displaying an explosion 100ms after the client thinks two missiles went passed each other, won't be a big deal. People will forgive it if the game play is still good enough. Let the server make all the important "events" which result in objects being destroyed / created and just accept that you will get lag :}
Hey, I'm working on a very similary project (a top-down 2D tank game), and have gone through several iterations trying to get the system to work right. It's somewhat similar to yours in that the server has final say over the state of the game, but different in that clients have more influence in the server's decisions. The disadvantage of your system is that what the player precieves to be a hit is actually percieved to be a miss by the server, which can be frustrating for the player, but the advantage is that there is very little wiggle-room for cheating players. The advantage of my system is that the game feels much more resposive and accurate from the vantage point of the player, but the disadvantage is that it gives players a little more room to cheat.

Here's what happens when the player fires a gun:

1) Player clicks to fire weapon.
---2) Bullet object is spawned on player's client.
---3) "I have fired" message is sent to server.
4) Server recieves "I have fired" message.
---5) Server performs a "sanity check" on message to make sure that the player was able to fire.
---6) Assuming the sanity check passes:
------7) Bullet object spawned on server.
------9) "Player x has fired" message sent to all other clients.
10) Meanwhile, the player's *client* is performing collision detections between the bullet and the other tanks in the game. If the bullet collides with another tank:
---11) The bullet is deleted and a collision animation is created, but no actual damage is inflicted upon the hit tank.
---12) A "bullet x collided with tank y" message is sent to the server.
13) Server recieves collision message.
---14) Server performs a "sanity check" on the collision to make sure that it was in the realm of plausibility. Note that if the previous sanity check failed, then so will this one since the specified bullet doesn't even exist according to the server.
---15) Assuming the sanity check passes:
------16) Bullet object is deleted from server.
------17) Collision message is forwarded to all other clients.
------18) Damage is calculated and sent to *all* clients.
19) Player's client recieves damage message.
---20) The specified damage is applied to the affected tank.

The difference is, essentially, that the *client* performs the collision detection while the server "looks over the client's shoulder" to make sure that it's not cheating. The problem here, of course, is that the server must give the client a little bit of leeway to make its own decisions, which could, in theory, allow a cheating player to gain a small advantage over the other players. In practice, though, I don't think taking advantage of the wiggle-room will be effective, since cheating will result in more failed sanity checks.

There are some issues with this model. For example, say the client fires a bullet but the server fails the sanity check. We have an instance where a bullet exists on the client but not on the server. Now, this bullet cannot affect gameplay, since it must again pass a sanity check (which is garaunteed to fail) for any damage to actually occur, so it is essentially a wasted bullet. This discrepency between client and server is just tough-luck for the client, and must be lived with.

Hope that gives you some ideas.

- Fuzz

[edit: formatting]
If you really want that kind of responsiveness you could try spawning a 'ghost' bullet on the client, and replacing it with a real one when the server informs you of it, or timing it out if the server doesn't. I'd still be inclined to give the server the only say in who hit what though.

What happens in your tank game if tank A and B are very close, but C is quite distant. C shoots at A. C hits A. B receives "A is dead" message from server. A shoots at B. A hits B. Server receives A hit B message. A receives C hit A message.

B received a message indicating that A died, but A fired and hit before receiving the same message. Does B get to watch a tank which no longer exists fire a bullet and kill it? It's this kind of situation that led me to believe that the server is the king, and the clients can predict, but never inform, the game state.
In that particular situation:

1) C shoots at A, sends message to server.
2) Server recieves "shoot" message, handles it.
3) C thinks he hit A, sends message to server.
4) Server recieves "hit" message, handles it, and determines that A is now dead.
-- 5) Server sends "A is dead" to all clients.
6) B recieves "A is dead" message.
7) A shoots at B, sends message to server.
8) Server recieves the "shoot" message from A, but does not pass the sanity check since A is obviously dead. (note: the server could now inform A that it's shot failed a sanity check, though my system doesn't actually do this; by the time A recieved this message, A would probably already think it had hit its target anyway)
9) Server recieves the "hit" message from A, but does not pass the sanity check since the initial shot failed the sanity check in the first place.
10) A (and C, presumably at some point) recieves "A is dead" message.

Note that neither B nor C ever recieve any indication that A fired, and even though A thinks it hit B and visually indicates so to the user, there is no actual damage done to B. The incorrect visual feedback to player A is just something that has to be lived with, and happens rarely enough to be fairly insignificant.

This topic is closed to new replies.

Advertisement