Client world data updates during gameplay
Hello. Currently I am trying to work on an efficient system to update the client's world as they play the game. The server has all the data on where all objects should be, and it keeps tabs of every objects properties. I am trying to use the least amount of bandwidth as possible for each connection.
If the client moves around the world, he has to be able to see the updated objects such as foilage, objects, avatars, etc as he moves from zone to zone. I am trying to make it as smooth as possible so the client is little or not aware of objects updating around him.
As of now I have data files on the server that holds all the information on each object and it's properties. When a client connects they have to request information from the server to load the local objects in their area, then as they move around they will need to update the upcoming terrain with the other objects. I can't load all objects in the entire world as there is just too much information, and along with this as other players are changing the world around them, the objects have to update on all the other clients as well.
I hope this makes sense. Any good ideas on this, or any basic psudo code on how this could be accomplished? I seem to be having a tough time trying to figure this out. Thanks.
One common solution to your problem is to have each object maintain information about when the properties were last changed. For example, let's say a player took a hit and his HP dropped by 15 points. That would affect the "Health" property, causing it to change. Your object takes note of this, and marks it as "dirty" so that the network engine knows that it needs to be updated. Once an object has a dirty property, the object itself becomes dirty. Then, when you normally send out network updates, you simply pack every dirty object (possibly, add them to a list when they become dirty?) and send them to all nearby clients. Make sure that you only pack the properties that have actually changed. This can be accomplished by using bit masks, each bit representing a particular property.
Another, perhaps more flexible, way to do it is using the Observer-Observable pattern, in which the observers (clients, AI, ...?) are updated whenever an entity they are interested in (i.e., close to) changes. You might want to look into that.
EDIT: Oh, I should add that having your clients request a full list of objects around it is probably a bad idea. It would be easy for the client to choke your server by sending out such requests at a very high frequency. Instead, your server should "know" when the client needs a fresh object list (upon login or zone-in, perhaps). My advice to you is to allow the client to request as little as possible, especially if the request requires a lengthy response.
Another, perhaps more flexible, way to do it is using the Observer-Observable pattern, in which the observers (clients, AI, ...?) are updated whenever an entity they are interested in (i.e., close to) changes. You might want to look into that.
EDIT: Oh, I should add that having your clients request a full list of objects around it is probably a bad idea. It would be easy for the client to choke your server by sending out such requests at a very high frequency. Instead, your server should "know" when the client needs a fresh object list (upon login or zone-in, perhaps). My advice to you is to allow the client to request as little as possible, especially if the request requires a lengthy response.
the simplest approach here is to let the client have a radial view over objects around him. Say 30 meters or whatever makes sense with your distances.
The server will then upon login send the initial list with objects around the player, and every time something of interest changes, send and update to the player with the new properties of the object of interest.
ie: Server code
player.SendMessageToObservers(new MovePacket(x,y,z)); // sends move mesage to players observers
or
player.SendMessageToClient(new OpenTradeDialouge()); // sends message to player
When it comes to stuff like terrain, meshes etc, the client should have this locally, or else your bandwith usage will be huge (and gameplay laggy at best) ;)
The server will then upon login send the initial list with objects around the player, and every time something of interest changes, send and update to the player with the new properties of the object of interest.
ie: Server code
player.SendMessageToObservers(new MovePacket(x,y,z)); // sends move mesage to players observers
or
player.SendMessageToClient(new OpenTradeDialouge()); // sends message to player
When it comes to stuff like terrain, meshes etc, the client should have this locally, or else your bandwith usage will be huge (and gameplay laggy at best) ;)
This is almost close to what I was trying to do. Certainly trying to update all objects that have not changed is a bad idea. I do like the "dirty" property for objects, I may try this. I was just trying to think of the best way to do this. My game consists of MANY MANY trees and objects that players can plant/make, and since there are so many, I can't use pointers for each object. I will have to go by properties of X and Y.
As of now the terrain and main meshes are created locally on the client machine, and the terraform information is something the server sends out to deform the terrain.
Thanks for the reply, I just wanted to hear another side to this. I am having nightmares of actually going and coding this though, I know it won't be easy.
As of now the terrain and main meshes are created locally on the client machine, and the terraform information is something the server sends out to deform the terrain.
Thanks for the reply, I just wanted to hear another side to this. I am having nightmares of actually going and coding this though, I know it won't be easy.
Quote:Original post by Garrettwademan
I can't load all objects in the entire world as there is just too much information, and along with this as other players are changing the world around them, the objects have to update on all the other clients as well.
I don't think this is normally a problem, because storing the world is typically cheap (remember the server doesn't need the raw graphical info loaded), and because in most games the scope for changing the world is actually minimal. Objects that don't change can be sent one time only as static client data, for example. What are you storing that makes it impractical to hold in memory?
EDIT: Just saw your last post. How many is 'MANY MANY'? Obviously if you want to be able to have 100,000 objects in view then you're going to have to be able to send 100,000 sets of data and there's not much way around that. But if you can separate out the static qualities from the dynamic qualities you can send the first lot only once and then refer to them from the dynamic ones. The degree to which people can 'make' objects matters here, because it dictates the amount of information that they're injecting into the system.
Quote:Original post by Garrettwademan
I can't load all objects in the entire world as there is just too much information, and along with this as other players are changing the world around them, the objects have to update on all the other clients as well.
Are you referring to actual assets (terrain, meshes, textures, audio) or just the current state of the world, where client already has all of those?
Quote:he has to be able to see the updated objects such as foilage, objects, avatars
Typically, "fixed" or "mostly fixed" objects are pre-sent to the user in the form of a patch and "level data." Only actually changing objects (NPCs, avatars) get sent at runtime.
If you want the user to be able to burn down a forest, then you could start by modeling the forest, and then have a "burn down" modifier which takes a radius; send only the modifier to clients, and the clients will apply the "burned down" modifier to any tree/brush within radius.
If you want the entire world to be streamed to the user, then you should look at the Second Life protocol, because that's what they do. There is very little pre-calculated in their stream. Unfortunately, that also leads to really big bandwidth requirements, and fairly laggy loading when moving between areas, and their area size is only 256 meters to a side.
My terrain chunks (zones), meshes, audio, video, images are all on the client machine when they install. This information is not passed. The terrain can be terraformed so this is the only data that needs to be sent regarding the terraformed info on the terrain when the client enters that zone.
My foilage, or trees at this time, I have about an average of 70, maybe 80 per zone, I have 64 zones, but I will be adding many more objects. Each item has the following properties...
-Type
-Age
-Health
-X Position
-Y Position
-Subtype
Can you think of any other data I may need on this?
So sending data should not be an issue, I may have to send an array to each client rather than a data file. When a player is running across my zones, obviously the objects that are way in the distance won't be rendered, I can get rid of them easily, but say if the player starts to go back to where he came from, I need to send updated info to that player once again to reload those areas, what happens if the object near the cutoff view parameter was not removed and when the server sends update info, I place a model right on top of another? Any way to avoid this? I know I can make a function to figure out what is placed, but when we are dealing with TONS and TONS (maybe around 100,000 items in this world) it may take a bit of time. I think I will have to try a few techniques to see what works best.
By the way, thanks for all the input, this is making my mind think a bit.
[Edited by - Garrettwademan on May 19, 2009 12:31:59 PM]
My foilage, or trees at this time, I have about an average of 70, maybe 80 per zone, I have 64 zones, but I will be adding many more objects. Each item has the following properties...
-Type
-Age
-Health
-X Position
-Y Position
-Subtype
Can you think of any other data I may need on this?
So sending data should not be an issue, I may have to send an array to each client rather than a data file. When a player is running across my zones, obviously the objects that are way in the distance won't be rendered, I can get rid of them easily, but say if the player starts to go back to where he came from, I need to send updated info to that player once again to reload those areas, what happens if the object near the cutoff view parameter was not removed and when the server sends update info, I place a model right on top of another? Any way to avoid this? I know I can make a function to figure out what is placed, but when we are dealing with TONS and TONS (maybe around 100,000 items in this world) it may take a bit of time. I think I will have to try a few techniques to see what works best.
By the way, thanks for all the input, this is making my mind think a bit.
[Edited by - Garrettwademan on May 19, 2009 12:31:59 PM]
Quote:-Type (1 bytes)
-Age (1 byte)
-Health (1 byte)
-X Position (4 bytes)
-Y Position (4 bytes)
-Subtype (1 byte)
12 bytes * 100,000 = 1.2megabytes.
Divided by 64 zones = 18 kilobytes per zone.
That is, if you were to serialize entire world to client.
It's not really that much, not even for a dial-up modem, if serializing entire zone.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement