Networking System/Organization

Post your questions, suggestions and experiences regarding game design, integration of external libraries here. For irrEdit, irrXML and irrKlang, see the
ambiera forums
Post Reply
g0bl1n
Posts: 63
Joined: Thu Feb 21, 2008 8:45 am

Networking System/Organization

Post by g0bl1n »

I was wondering if I could get input on the best (in terms of optimization and security) networking organization. I've been playing around with Raknet and I've got most of the basics down, but I notice there is some lag in most of my examples (although I am running a server and two clients on one machine...but still if it is at all possible I would like to get this right the first time). The game I plan to work on isn't going to be that big in terms of the number of people playing it at one time (max of 4 at the moment). But I was planning on making the map pretty big, and that's where it gets a bit complicated.

So I guess I'll just throw some questions out there:
Object Management - The server must keep a list of all the "objects" in the world and their position, direction, etc... How often should this be updated? How should it be stored on the server? Should the server read/write from a file or keep a vector/array of everything? The players need to keep a local copy of this list on their system as well, how much of the "total picture" should be loaded onto their system at once?

Object Synchronization - I'm having a little trouble trying to understand how to make enemies and such move on the server side, because there isn't a delta timer on the server (since there isn't any Irrlicht stuff on the server, only a bunch of variables that get sent to clients that then turn it into Irrlicht stuff). Is this even a problem?

Sending Packets - Is it better to send lots of small packets or a couple of big ones? (Example: Instead of sending x,y,z,x rotation y rotation, and z rotation all at once, only send them if the variable has changed?). Should clients send packets to other clients? Or should clients always send to the server, then the server forwards those packets to another client?

Client Management:
If the clients should send each other packets, then should the clients keep a "client table" locally? Or could that turn into a major security problem? (I don't plan for my game to get "big" or anything, mostly there are a few of my friends that want to play a sand box space game with some elements from Minecraft (without the blocks, mostly the crafting system...aka get a bunch of raw materials to make stuff...), and since I happen to also be a DM for our rpg nights, I've had a story in mind for a while...but anyways...the point is I'm not really 100% worried about security, but I'd like to get things right the first time around).

And I'd like to get some input from anyone with experience in networked based games, any tips or tricks would be very helpful!!!

Thanks!
Goblin
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Post by hendu »

You should read the Q3 or Half-life postmortems, ISTR they both elaborated a lot on the networking side.
Sending Packets - Is it better to send lots of small packets or a couple of big ones? (Example: Instead of sending x,y,z,x rotation y rotation, and z rotation all at once, only send them if the variable has changed?).
Bigger is better, as long as you stay under the MTU (~1.5kb).
Should clients send packets to other clients? Or should clients always send to the server, then the server forwards those packets to another client?
May not work (NAT, firewalls).
Luben
Posts: 568
Joined: Sun Oct 09, 2005 10:12 am
Location: #irrlicht @freenode

Post by Luben »

Have any links to either or both of them lying around?
If you don't have anything nice to say, don't say anything at all.
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Post by hendu »

No, it's been over a year since I read either. But they were freely online back then.

edit: A quick google found this for half-life:
http://www.gamasutra.com/view/feature/3 ... tress_.php

edit2:
and this for q3:
http://trac.bookofhook.com/bookofhook/t ... Networking

Though the latter wasn't what I read, and IIRC the former was just a part of the hl one, both should be useful and interesting reads.
g0bl1n
Posts: 63
Joined: Thu Feb 21, 2008 8:45 am

Post by g0bl1n »

They were both good reads, I think the Quake 3 article was a bit more helpful (at least to me). So what I'm getting so far from both articles is: Send as much information as you can (staying under the mtu) and use udp.
Virror
Posts: 191
Joined: Mon May 02, 2011 3:15 pm

Post by Virror »

Every packet has overhead, so sending bigger packets deduces the amount of data sent, pretty simple ; )
3DModelerMan
Posts: 1691
Joined: Sun May 18, 2008 9:42 pm

Post by 3DModelerMan »

Read Game Coding Complete. They have my favorite architecture. Maybe on the server you could write only the least frequently accessed data to file and keep the rest in memory. That way you could read and writethe file from a seperate thread.
That would be illogical captain...

My first full game:
http://www.kongregate.com/games/3DModel ... tor#tipjar
Elfinitiy
Posts: 21
Joined: Thu May 26, 2011 10:23 am

Post by Elfinitiy »

http://developer.valvesoftware.com/wiki ... mpensation
Here's a very good example of Lag Compensation
g0bl1n
Posts: 63
Joined: Thu Feb 21, 2008 8:45 am

Post by g0bl1n »

So would the client's delta timer be based locally on their Irrlicht instance or would the server send this value? Also what would be the best timer for the server? I'm guessing using Irrlicht wouldn't be so bad, but I was thinking of keeping the server barebones (just the terminal/command prompt window). So could one just use the ctime header and do calculations based on that?

This was the lag optimization in the article above:
Command Execution Time = Current Server Time - Packet Trip Time - Client View Interpolation

However what would the Client View Interpolation be? Some kind of ratio between the client time and server time?

Would it be easier to sync the client's time with the server's time? It would mean there would be less packets being sent, however, I bet sending the current server time with any information wouldn't make too much overhead. This game will probably be 2D to begin with (I have no modeling skills...). So I'm rarely sending enough data at one time to make a difference.

As of know I'm sending updates like so (from a client to server):

Code: Select all

BitStream ostr;
ostr.Write(static_cast<MessageID>(ID_UPDATE_OBJECT));
ostr.Write(id); //unsigned int
ostr.Write(static_cast<double>(x));  //f32
ostr.Write(static_cast<double>(y));  //f32
ostr.Write(static_cast<double>(direction));  //f32
rakClient->Send(&ostr,HIGH_PRIORITY,RELIABLE_ORDERED,0,serverAddress,false);
Which is 28 bytes (I'm quite sure how big the message id is, but even so its way under the mtu). This works fine, although it looks a little choppy on other clients, so I'm guessing that's were interpolation comes in. But I'm not quite sure how to do that just yet!

@3DModelerMan - Any specific edition? I'm assuming it wouldn't matter, but I figured I'd ask just in case!
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Post by REDDemon »

Usually both server and clients try to predict datas. For example on a client side you can see other players running smoothly only if the client itself can predict where a player is going.

You need also to do that on server side for example for moving NPCs. Usually it is possible to send every while a syncro signal. So that every client can iterpolate its data with real data. But when interpolation ends obviously the real position of another player is changed.

The real position is usually computed by the server with some checks to prevent cheating but without frustating players (If a player see that his sword hit another player or monster the sever must count that hit as a valid hit.)

to achieve that is possible using different times:

1) time on server
2) time on client.

if the shot appens 35 ms after the syncro the server must check if that shot was really possible. the only data the server has are the interpolations between the data sended by the players. If for example a player is far enough from another player a "hit message" will be ignored and possibly will be signaled as a "possible cheat".

There will be always a different timing between server and clients. So if the server says that the last syncro was 380 seconds, the client will send a hit request at time 380,035 seconds. But when the hit message reach the server probably on the server the time will be 383 seconds or later so it must check back in the time. You must set a maximum delay for messages. For example a hit with 10 seconds of delay is assumed to be invalid.

Common things that appens are for example player walking trhough walls (maybe they turned around a wall, but since you/or the server are doing simple interpolations you will see the player walking through the wall).
Or sometimes you attack someone without touching its life.
Another common thing is that you are hitted by someone when apparentely there is no one near you.
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
g0bl1n
Posts: 63
Joined: Thu Feb 21, 2008 8:45 am

Post by g0bl1n »

What would be the best way to implement this? Something like:

Code: Select all

Server stores the position of every object into a vector (maybe make a class that stores x, y, direction, timestamp, and the id of the object).

Server sends sync packet.

Client sends attacks/movement (with another timestamp?).

Server checks based on timestamp of packet if attack/movement is possible, then sends out the new position, direction, ... updates.
And for interpolation, would it be feasible to instead have the local objects on the client side move towards their new positions instead of having the client set the position instantly? So something like (very limited example).

Code: Select all

xDest=10;
x=0;
moveSpeed=2*dt;
maxDist=15;

if(x!=xDest)
{
     if(distance(x,maxDist)>=maxDist)
     {
          x=xDest;
     }
     else if(x<xDest)
     {
          x+=moveSpeed;
     }
     else
     {
          x-=moveSpeed;
     }
}
Then update the xDest instead the x with a packet from the server. I haven't tested the code above (it would be a whole lot more complicated) but I was hoping to get an opinion on if it is even feasible to experiment with (ignore the obvious problems! Such as variable type declarations, undefined functions, etc...).
Post Reply