No clue what to call this, any help welcomed

Started by
7 comments, last by riuthamus 10 years, 8 months ago

So, we are getting into the late stages of our game development and are trying to manage how we send information from the server to the client and vis versa. If you are unfamiliar with my project we are making a voxel based world ( that has very much modified itself into a dual contouring method for terrain and such ). Right now we have an issue with sending edits to the terrain. Here are the methods we can think of:

1) Player modifies the terrain and sends the information to the server, client waits for the server to send the processed information back and then the client sees the action that was taken

2) Player modifies the terrain and sends the information but the client thinks everything is fine. If lag occurs for whatever reason the client doesnt see this and gets ported back or replaced to the last time they were in sync.

3) Some other method we cant think of....

In talking with the coder(s) this is the convo we had:

well... I cant think of a way to have the client keep a copy of the octree, sending it will become way too expensive while most computers are going to crap bricks anyways.

so at this point its have each modification lag a little bit, and everyone sees the changes at the same time. Or have each client recieve the octree or recieve changes. If they recieve changes their game will lag fairly badly and the octree net packet will be fairly large. (turns out to be able to modify terrain i cant change how it currently is. This is unless someone can give me another way to do it.) right now its about 30kb per region or so. That would probably increase quite a bit, also the block depth needs to be increased anyways so it will probably be around 50-60kb per octree. Then they will each have to generate it, and if you dont have the most powerfull computer that is going to be fairly slow as well. As well as any changes you make will make it to other people at an unknown time, depending on how fast their PC is.

So in other words it would be fast for you, but everyone else would look like an idiot, or have it slightly slower for you, but everyone else also has the correct looking changes and you know that they can see what you see

I am posting this here because I know many of you understand the network side of the house and our issue seems to be with the network process. It is possible that it could be somewhere else but our octree and dual contouring methods seem solid ( seem being the key word ). Thanks for any thoughts or suggestions you could provide to help us with this. If you need more of an explanation let me know.

Advertisement

There are two ideas coming to mind. A replication method and/or a command queue of single cells modifications.

The replication method requires the syncronisation of the clients with the server. This will be more or less a must have in your case, e.g. in the case of that a client joins your server or if the client doesn't hold all of the terrain of the server in memory at once. This could be done by checksums of blocks. The client, when connecting to the client, sends all checksums to the server, the server will keep this saved for each client to compare it to the current state of the world around the client. If the server detects an invalid checksum it will starts to send a new block to the client. Just don't expect that all clients are always on sync, this will not happen and is often not necessary. Compare a multiplayer game (especially MMORPGs) with two players on two monitors side by side and you will see what I mean.

The second method (your number 1) helps to sync the replication faster by propagating modifications faster to the clients. Instead of replicating a whole block all the time, you could send only modifications of single cells to the clients as stream (if client is able to see it) and do reactivate the replication mechanism after the modification of a block stopped, in this case the replication by checksums will be reactivated and any error will automatically be corrected.

PS: in general, send the modifcation command to the server and execute it there,instead of modify the state on the client and replicate (merge!) it on the server afterwards.

I might look at this from the gameplay side of things first. Using Minecraft as the example, how would you deal with the action there? My first inclination is to break out the steps involved. Player gets out pick, points at a voxel, left clicks, pick starts swinging and rock breaks down until it breaks. That to me suggests the obvious solution, you have a multi-step event. Of course you don't specify if such edits take time or are supposed to be instant but hopefully this gives you a starting point:

c1. Client starts interaction with voxel, sends message to server: "start interact with x;y:z at time xx:xx:xx".

s1. Server receives message and starts a countdown to when the item should destroy. Probably minus average ping time to make it snappy.

c2. "IF" client stops or changes targets or whatever before item should destroy: "stop interact at time xx:xx:xx".

s2. "IF" received before the change is made, cancel timer.

s3. Not interrupted or network hitch whatever prevented client from canceling before timeout, destroy item and send update to all clients. In the case of cancels being a little laggy, it should not be all that notable as it is the unusual case.

There are a couple edge cases of course. 2 clients attacking same voxel, instant actions wouldn't use this and you'd have to just deal with latency, etc etc.

Hopefully I understood the problem well enough that this is useful.

Well, I spoke with him ( earthmark ) and another coder that just happens to be my roomate ( 015r ) and they kept discussing a few different points. Without going into crazy detail and boring all of you, the problem is that octree's are rather large. When a player modifies a block the node that the octree is associated with has to be sent. If our estimates are correct this is close to 44kb being sent just for the octree alone.

I will have him post in here to give a bit more of an explanation but these are great ideas so far. Thanks guys for the post as you have always been instrumental in the development of our team! Speaking of... glad to see you around Ashaman, i figured you were probably busy with your game!


Well, I spoke with him ( earthmark ) and another coder that just happens to be my roomate ( 015r ) and they kept discussing a few different points. Without going into crazy detail and boring all of you, the problem is that octree's are rather large. When a player modifies a block the node that the octree is associated with has to be sent. If our estimates are correct this is close to 44kb being sent just for the octree alone.

One aspect of octrees is that they don't change too much if you delete a single block inside them. You should be able to just send the difference between the old and new octree (probably just a leaf is gone, perhaps one node that becomes a leaf, or perhaps two nodes are changed, and so on with lower and lower probability). If all else fails, just diff the octrees as a starting point (by constructing a new octree which has nodes if and only if the old one and the new one are different at that node) and send that over for the client to reconstruct using his old octree.

The octree lends itself well to your geometry as well, and to your gameplay since you're only removing blocks a few at a time and that change is localized (i.e. you're not deleting random blocks from all over the map) which should make this rather efficient.

If you're already doing that, well, 44kb sounds a little excessive for a single block..

Another option is to not send octrees at all but only changes in blocks (deletion, addition, etc..) and let the client figure it out, which may be easier to implement. But I guess it depends on how your octree and netcode are set up.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”


Well, I spoke with him ( earthmark ) and another coder that just happens to be my roomate ( 015r ) and they kept discussing a few different points. Without going into crazy detail and boring all of you, the problem is that octree's are rather large. When a player modifies a block the node that the octree is associated with has to be sent. If our estimates are correct this is close to 44kb being sent just for the octree alone.

One aspect of octrees is that they don't change too much if you delete a single block inside them. You should be able to just send the difference between the old and new octree (probably just a leaf is gone, perhaps one node that becomes a leaf, or perhaps two nodes are changed, and so on with lower and lower probability). If all else fails, just diff the octrees as a starting point (by constructing a new octree which has nodes if and only if the old one and the new one are different at that position) and send that over for the client to reconstruct using his old octree.

If you're already doing that, well, 44kb sounds a little excessive for a single block..

I agree, I kept saying ( not a coder here so i said it in non 01010101001 speak ) there has to be a way to send just that one block that was changed. He and Telanor seem to be under the impression that you must send the entire octree for that chunk. Probably because we are so new at all of this. The issue we had with the array was that it did not provide enough detail without using up too much memory. So we went with the octree because it has the ability to combine nodes if nothing has changed ( in theory reducing the size ). I guess the part they were struggling with was figuring out how to send only the changed block rather than the entire octree!

This might just be what he needed. thanks!!

As Bact points out, there really should be a method of sending a focused change without the entire octree being required. If the server is authoritative over the world something like "break voxel x/y/z" would be sent and all clients would make the change locally at the appropriate time. Even using the case of multiple blocks being broken from say an explosion, this is a tiny little message compared to an entire octree worth of data by the sounds of things. This does imply absolute ownership of block destruction being on the server which means each and every block modified is a message to the clients, but that is still fairly trivial bandwidth in comparison to big chunks of data and still less and infrequent when compared to normal movement/orientation data sent regularly.

Thank you for the ideas with the octree, they are a heck of a good idea. However at this point we are not even at that point. The issue we are having at this point is changing the tree, as posted here: http://www.gamedev.net/topic/646244-octrees-accordions/

Going to bump this one last time and see if anybody else can take a second look. Again thanks for the suggestions so far as they will most certainly help down the road.

This topic is closed to new replies.

Advertisement