Jump to content
  • Advertisement
Sign in to follow this  
tufflax

Client/Server--what do they know?

This topic is 4385 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey! I'm working on a game, and it's a real time multiplayer... eh... game. Everyone has an avatar and runs around killing stuff. Anyways, enough about gameplay. I and my friend started working on it a couple of months ago. We thought that we would use 2d graphics because neither one of us has any experience with 3d graphics, and we thought that it's the gameplay that matters. We got to a point were we had the clients running around with an avatar each, and the server was working. It was not a game, but at least it worked. At that time, the server knew everything, the client simply drew stuff and received input from the user. It worked fine, and we sent 2 shorts for position, 1 for sprite, 1 for health for each character on the screen, every frame. But, it was a pain drawing everything, and we thought that it would not hurt if the graphics were a bit nicer. So, we thought: why not, let's learn how to make 3d graphics and have that instead. It will probably make up for the trouble of learning it later. So, here we are. We have not learned a whole lot about 3d graphics yet, but one thing that we have thought a lot about is: "Was the client-server communication really any good?" What if the client knew more about the game, and the server just sent updates? But then all the monsters that will be in the game, what about them? There will probably be around a hundred in the game at any given time (think RTS). It seems like a waste sending information about them all the time when they might not even be showing on the screen. So what if the clients do not know about what's happening outside the screen. But then, if the user clicks on the minimap, and goes to a new spot, there might be many creatures there. And the server has to send information about all of them. Where are they exactly? What direction are they facing? What are they doing? How much health have they got? And so on. And oh, why did I mention that it's going to be 3d? Well, we thought when it's 2d sprites, all you have to know is which sprite. Now, the client has to know more, like, what kind of model, what direction is he facing, is he walking, is he swinging his sword etc. Also, we might make is so that the player can change camera height off the ground, and angle etc. So he might be seeing quite arbitrary portions of the map, too. Any ideas? We could probably come up with an OK solution, but I was mostly looking for information about how it's usually done. [Edited by - tufflax on August 11, 2006 9:45:24 PM]

Share this post


Link to post
Share on other sites
Advertisement
You should check out the multiplayer and networking forum. There's a bunch of good reading material there, especially in the forum FAQ.

Much of what you want to do has many ways it can be implemented. It will depend on how you choose to design your networking components. If you are writing your own networking code, you are free to design it however you see fit. If you choose to use an existing library (OpenTNL, RakNet, etc), you will use whatever methods they provide.

The general saying is: the clients need to know as little as possible in order to make the gameplay experience as good as possible. This will minimize your bandwidth consumption, and avoid disrupting your users' gameplay.

Things like animation (walking, running, attacking, etc) can be conveyed to the clients in a single byte (ignoring any other packet overhead). If a client pushes a button, this button state is sent to the server. The server says "client X is now attacking". The server broadcasts this to all other clients, who know that they should now play the attacking animation for client X. Things like health need only be broadcast when they change.

Things like player and enemy positions/orientations are different. The accuracy of this will be dependent on the type of game you want to produce. A turn based RPG can be lax in this department - all clients don't have to 'perfectly' sync up. Yet in an FPS, it is crucial that all players are in the exact same location on all clients' screens. Depending on your target platforms, you will have different bandwidth limitations. Brute force: send the positions/orientations of each player to every client every frame from the server. More sophisticated algorithms exist: dead reckoning, simple interpolation, etc.

For networking, I don't think 3D is any more difficult than 2D. If a networking component is designed well for a 2D game, it should be easily scalable to a 3D environment. Things like a messaging system, packet system, etc... This is all the same. The only thing a 3D game adds over a 2D game is an extra dimension - the Z axis - which implies extra data must be sent. 3D games will also be inherently more CPU/GPU intensive, so this could put a greater strain on your server which will provide you a tradeoff - minimize bandwidth (which requires greater CPU computation to determine what to send) or minimize CPU.

You will need to play around with all the variables and read up on all of your options. You will undoubtebly go through multiple designs and revisions of your networking componenet, especially since it is your first.

Share this post


Link to post
Share on other sites
I tend to use the model/view/controller paradigm for networked applications -- just think of the client as an external monitor and game pad.

You don't need to send it all kinds of information for it to display the visible characters and use the gamepad, and you shouldn't -- not only is it insecure, but it slows the game.

Share this post


Link to post
Share on other sites
The solution is to send events to the client, not complete states. An example:

You create a Gigantic Blob Monster called Bob. He has 1000 health, and is located at [400, 30, 494] and has a vertical axis angle of 90 (i.e. he's looking East). His starting animation has an ID of 0 (which means idle, but that doesn't matter).

You then send this data to the client.



#define MAX_MONSTER_NAME 33 // 32 + 0.

#define ANIM_MODE_REPEAT = 0
#define ANIM_MODE_ONCE = 1

#define MESSAGE_ID_MONSTER_CREATE = 1

#define ANIM_ID_IDLE = 0

struct MessageHeader
{
TimeStamp timestamp = GetTime ();
uint16 message_id = MESSAGE_MONSTER_CREATE;
uint32 data_size = sizeof (MonsterCreateData);
};

struct MonsterCreateData
{
uint32 monster_id;
uint32 type = MONSTER_GIGANTIC_BLOB;
char name[MAX_MONSTER_NAME] = "Bob";
uint32 health = 1000
Vector3 position = Vector3 (400, 30, 494);
Vector3 angle = Vector3 (0, 90, 0);
uint32 animation_id = ANIM_ID_IDLE;
uint8 animation_mode = ANIM_MODE_REPEAT;
};




The client will recieve the MessageHeader and MonsterCreateData. It can then happily create the monster, load up it's animations, position it in the right place and continually animate it forever. You never have to send the client another message about that monster until it does something else.

Now, lets say the monster wishes to walk to a certain location. Instead of updating the client every frame, we just send a message to it that the monster wishes to go to xxx, it's going to use yyy animation and move at zzz spead.


#define MESSAGE_ID_MONSTER_MOVE = 2

#define ANIM_ID_WALK = 1

struct MonsterMoveData
{
uint32 monster_id;
Vector3 current_position = Vector3 (Monster->GetCurrentPos ());
Vector3 current_angle = Vector3 (Monster->GetCurrentAngle ());

Vector3 new_position = Vector3 (Monster->GetDestination ());
float move_speed = Monster->GetMoveSpeed ();

uint32 animation_id = ANIM_ID_WALK;
uint8 animation_mode = ANIM_MODE_REPEAT;

uint32 animation_finished_id = ANIM_ID_IDLE;
};




We send that along with the standard MessageHeader. The client will recieve it and will reposition and reorientate the monster with the current position and angle (if the monster was stationary before this isn't needed, but if it was already walking it will help to keep everything in sync). It will then change the animation to a walking one and begin moving to it's destination position at the speed specified. Once it gets there it will revert back to it's idle animation.

You see? You've only had to send 2 messages to the client about the monster and already it's walking about. Your bandwidth usage has been cutdown dramatically and the load removed from the server.

For clients, the problem is a little tricker as they generally aren't moving from point to point, but just in a set direction. All you have to do is send a message to each client stating the current position, angle, and movement speed and they can exrapolate the rest. If he changes direction, just send a DirectionChanged event to the clients and everything will keep on moving smoothly.

That's the general idea of it anyway. Never resend anything you don't have to. If the monsters health hasn't changed then what you sent the client the first time is still true, so it doesn't have to be changed. If it takes damage, send a TakeDamage event that reduces its health.

Of course, in reality it's far more complex than this but it should give you a working basis :)

Share this post


Link to post
Share on other sites
MENTAL offers some really useful advice there.

Tufflax,

If you want to have someone to chat with and ask questions to about this kind of stuff, in your own language, let me know. :)

Share this post


Link to post
Share on other sites
Thanks for the replys guys!

Ravuya: So you mean that the client should only know about things that are visible to him? I don't quite understand what you mean with that paradigm and game pad.

And MENTAL: So you mean that the client knows about Bob even if Bob is not visible to him? I can see pros and cons with both approaches (the client knowing everything vs knowing only what is visible). If the client knows only what is visible, that's less units. But, if a new units begins showing, that's more information that needs being sent when the unit first walks onto the screen (or the player scrolls the camera). Also, if I'm to draw a minimap, knowing everything would help. And yes, of course sending only what is really necessary is good.

SymLinked: Yeah, maybe later when I start coding etc. Right now I'm just thinking.

I guess I have to work out what's best for me, but if you guys have any more pieces of advice I'll gladly read them.

Thanks again!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by tufflax
Thanks for the replys guys!

Ravuya: So you mean that the client should only know about things that are visible to him? I don't quite understand what you mean with that paradigm and game pad.

And MENTAL: So you mean that the client knows about Bob even if Bob is not visible to him? I can see pros and cons with both approaches (the client knowing everything vs knowing only what is visible). If the client knows only what is visible, that's less units. But, if a new units begins showing, that's more information that needs being sent when the unit first walks onto the screen (or the player scrolls the camera). Also, if I'm to draw a minimap, knowing everything would help. And yes, of course sending only what is really necessary is good.

SymLinked: Yeah, maybe later when I start coding etc. Right now I'm just thinking.

I guess I have to work out what's best for me, but if you guys have any more pieces of advice I'll gladly read them.

Thanks again!



imo you should send information about anything the player can see within the next 50ms or so, for an RTS you could send information about anything that isn't hidden by fog of war. (if you send information about units hidden by FOW maphacks would be easy to make). for an FPS you'd generally use a simple culling system to avoid sending information about invisible entities (you should probably pretend that the client has a 360 degree FOV though so info about entities behind the player should be sent),

more exact culling to prevent wallhacks is possible aswell (hlguard for halflife does this) but its rather expensive in terms of cpu power.

also the server could keep track of what it has sent to the clients in the past, thus it would be possible to only send the data that has changed.

Share this post


Link to post
Share on other sites
Quote:
And MENTAL: So you mean that the client knows about Bob even if Bob is not visible to him? I can see pros and cons with both approaches (the client knowing everything vs knowing only what is visible). If the client knows only what is visible, that's less units. But, if a new units begins showing, that's more information that needs being sent when the unit first walks onto the screen (or the player scrolls the camera). Also, if I'm to draw a minimap, knowing everything would help. And yes, of course sending only what is really necessary is good.


What you tell the client and when you tell it is purely up to you, I was just describing how you should tell the client about BoB. If it's an RTS then I strongly suggest that you send the client events about monsters not coverted by the fog of war, regardless of where the camera is. Otherwise the client is going to lag out when the player tries to move the viewpoint.

Imagine the player clicking on a random square on the minimap. If you are telling the client about monsters the moment they are created the client will have all the information ready and can immediatly draw the area accuratly. If you only send data to the client about monsters currently in it's viewport, when you try and move the camera the server will have to send a lot of data to the client at once as the client will have no idea what's there.

Have a look for the Supreme Commander trailer - it doesn't use any fog of war, meaning yours and your enemies units are fully visable at all times. It can dynamically zoom out to a tactical map where you can see the entire game being played out in realtime.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!