GNet Proper Practices?

BlitzMax Forums/BlitzMax Programming/GNet Proper Practices?

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.


TaskMaster - won't the difference be up to 260ms if the server decides the result of a hit?



Depends, do you have bullet flight time, or is it instant. Both have an advantage and a disadvantage.

If it is instant, the disadvantage is the lag will hurt a little, the advantage is the players do not see the bullet, they see a players gun go bang, and they see a player take a hit. The players aren't really going to know if the person doing the shooting was still aiming directly at them or not...

Something like this: the firing client, fires, if the client decides it should be a hit, then let the client treat it as a hit. It also sends information about the shot to the server, where the server can then decide if it was a hit, this is more of a check to make sure the client isn't cheating. Then the sever sends the hit info to everybody else. If the server knows the target had moved and it is a miss, then the player who fired the shot may notice that the targets health went back up. Unless of course you have a one shot one kill game. Then you may have to let it be a server check before th shooter client shows it as a hit.

If there is bullet travel time, then the advantage is the client doesn't have to decide hits or misses at all. Client fires, send a packet to the server, I am firing from here, in this direction, this kind of bullet, at this speed, etc...

Then during the lifetime of the bullet, if at any time the server decides the bullet has impacted another player, it sends that information to everybody. Bullet index 33 hit player 2 at this position doing this much damage. Let the clients receive this packet and play an explosion anim or whatever needs to happen. The disadvantage of this method is that the players see the bullet, and if there is a bit of lag and a player was able to just dodge a bullet but didn't update the server in time for the server to realize the bullet missed, then the server tells everyone you got hit. But most players chalk this up to Internet lag and live with it if it is only off by a few pixels and it was close. That is when you get that, "Oh man, I dodged that bullet" exclamation from the player. :)

The important thing is to have a good balance of not too many updates, but enough updates to make the game look good.

Take the multiplayer spacegame I worked on years ago for example, to give you an idea. It was 2D like asteroids. The server knew what type of ship each player was. So, the server new the player acceleration, rotation rate, max speed, etc. I sent a packet whenever a player pressed a key that would change something about his position. This seems like a lot, but remember, the average player, while playing will only press about 1 key per second when playing quickly. So, 1 packet a second is great!

If the player held the up arrow down, I sent a packet that told the server the player was pressing thrust. And, whenever a player sent a packet to the server, I always put all of the players position info in the packet. So even a a chat packet might have this in it: I am at position X,Y; my heading is z.zz; my velocity is a.aa; and here the the chat text I just typed (of course, it was just the data, the server knows exactly what data to expect, none of the "I am..." data is really sent). On the average a packet can be about 1.5kb, so as long as you don't send more than that, you are not really wasting any bandwidth by padding a single packet.

Also, I would send a location packet if the player does not press a button in 3 seconds, just to make sure the player and the server are synced up every once in a while. This also acts as a keep alive. So, the server knows if the player dropped out for some reason. And, when I got a keep alive packet from the player. I would match every packet against what the server thought the current location was, and if it was close, then I would update the server and tell all of the other players. If it was way off, I would send a packet telling the client where the server thought it should be and the client would update.

So, it might go something like this:

player presses thrust - send player info packet
server sends the players packet to all the other player
player stops thrusting - send player info packet
server sends the players packet to all the other player
player starts turning right - send player info packet
server sends the players packet to all the other player
player stop turning right - send player info packet
server sends the players packet to all the other player
player fires - send player shoots packet with player info attached to it
server sends the players packet to all the other player
server sends packet telling everybody there is now a bullet at this location heading in this direction, at this speed

There is no reason to keep sending packets that the player is turning, because the server knows how fast the player can turn, so it knows what direction the player is facing at all times, just because it knows he is turning. The server just needs to know when he stops turning. When the player says he stopped, he sends his current location, current heading (direction facing), current velocity, etc. This helps make up for the lag. Instead of the server being a little bit wrong about the facing because of lag, the player told the server exactly what heading he was facing when he quit turning.

Anyway, I hope this helps you somewhat. It is just my take on how to do it, and it does work fairly well. I wrote that game in VB years ago and it worked just fine. :)

Eventually I'll get around to writing an updated version in BMax.