A a1 = new A; // a1 receives client-ID temp-18 and server-ID 1
A a2 = new A; // a2 receives client-ID temp-42 and server-ID 2
// During sync, temp-18 is matched with 2 and temp-42 is matched
// with 1. Creation circumstances are identical, so this makes sense.
a1 = 0;
// This command, executed on the server, results in the following
// command being run on the client:
a2 = 0;
What additional means can I use to perform the matching mentioned above, so this situation does not occur?
Synchronizing object creations
I am currently laying out plans for the core of my game, which should have a multiplayer mode. My approach is to process everything on both client and server, and have the server send corrections to the client. The entire set of objects is, therefore, re-synchronized on the client using data sent by the server. All objects are referred to by an unique identifier (ID) that is known by both the client and the server, so the server can prefix its commands with the ID of the object it is altering or destroying: everything works correctly in these cases. What is causing me headaches is the creation of objects. Every object must receive, when it is created, an unique identifier. It is easy to transmit as a synchronization packet the ID of the object to be created along with the data needed for the creation. However, this would effectively prevent the client from creating objects on its own (since it cannot guess the ID of the object), keeping it permanently out of sync with the server. My idea is to give objects created on the client a temporary ID. Then, based on the circumstances of the creation (creation time, ID of the creator, creation arguments), the temporary ID would be matched with a permanent ID received from the server - unmatched permanent IDs would cause an object to be created for them, unmatched temporary IDs would be destroyed. However, some object creations can be as generic as "create a shared object of type X with default initial values" - the kind of thing that could happen a dozen of times in a given frame for a given owner. The matching might then be faulty, because while the creation circumstances are identical for all objects, some local objects on the client might have decided to point at one instead of the another. This is illustrated in the following example:
Hello!
I had a bit of a struggle to understand your problem, but I hope I do now get it. Let me recap by a small example:
You create default object a1 and a2.
You set their position.
The serveur does the same, and sends the sync.
Bad luck, the matching actually matches server a1 with client a2 and inversely.
Server sends huge correction to make a1 move to a2 and inversely.
I think it is all in the way you will make this matching happen. Maybe if you match in order (lower server ids with lower temps ids), that would work fine in most cases? And if the server has to sometimes swap two objects because of inverse matching, the client should hopefuly almost not see anything.
I had a bit of a struggle to understand your problem, but I hope I do now get it. Let me recap by a small example:
You create default object a1 and a2.
You set their position.
The serveur does the same, and sends the sync.
Bad luck, the matching actually matches server a1 with client a2 and inversely.
Server sends huge correction to make a1 move to a2 and inversely.
I think it is all in the way you will make this matching happen. Maybe if you match in order (lower server ids with lower temps ids), that would work fine in most cases? And if the server has to sometimes swap two objects because of inverse matching, the client should hopefuly almost not see anything.
The problem does indeed disappear when the created object is write-only, since no matter what the client does to the object, the server will compensate. However, if the client attempts to read data from the wrong object, chaos ensues.
Consider Foobar the Sorcerer, casting a level 2 "enchant armor", thus enchanting his pointy hat (enchantment temp-18) by +1 and his bunny slippers (enchantment temp-42) by +2 on the client. However, on the server, PlayerTwo the witch casts an instant-hit spell at Foobar, reducing his "enchant armor" spell level: the spell now only enchants the bunny slippers (enchantment 1) by +1.
During synchronization, temp-18 is matched to 1 (they have the same bonus and same creator). Now, the client believes the hat is enchanted by +1, while the server knows that the slippers are, and not the hat. What can be done to keep these in-sync?
The obvious solution to this would be to also associate "hat" and "slippers" with the created objects. However, in order to do this, it is necessary for "hat" and "slippers" to be entities (so their ID can be synchronized). And these two must be created at one point or another in the game, which reiterates the problem (unless all objects, spells, bullets, and everything, are created at the beginning of the game, which is highly improbable).
Consider Foobar the Sorcerer, casting a level 2 "enchant armor", thus enchanting his pointy hat (enchantment temp-18) by +1 and his bunny slippers (enchantment temp-42) by +2 on the client. However, on the server, PlayerTwo the witch casts an instant-hit spell at Foobar, reducing his "enchant armor" spell level: the spell now only enchants the bunny slippers (enchantment 1) by +1.
During synchronization, temp-18 is matched to 1 (they have the same bonus and same creator). Now, the client believes the hat is enchanted by +1, while the server knows that the slippers are, and not the hat. What can be done to keep these in-sync?
The obvious solution to this would be to also associate "hat" and "slippers" with the created objects. However, in order to do this, it is necessary for "hat" and "slippers" to be entities (so their ID can be synchronized). And these two must be created at one point or another in the game, which reiterates the problem (unless all objects, spells, bullets, and everything, are created at the beginning of the game, which is highly improbable).
just curious, but what situations would the client want to create something first?
in FTA, i honesntly can't remember if the client creates a bullet right away anymore or not... it WAS like that at some point... there are SOO many ways to do this, with SOO many different tweaks to try... you have to find the right balance of security, bandwith usage, and latency hiding... these are all very specific to your game.
however, the generate flow is like this (if you want to be 100% service authoratitive):
1) user pushes fire. he sends "can i please shoot a bullet now? the time is T"
2) server gets a the message. he validates this is OK. he then creates a bullet on HIS simulation. this is the starting point of the bullets life, at THIS point in time, NOT when the user actually pushed fire. he then tells all the the clients, "the client with ID 123 fired his gun. he's at X,Y, and the time right NOW is T"
3) everyone gets this message, including the original guy who shot the bullet. (although you can avoid sending the clients ID back to this guy, send him a slightly different packet which says YOU shot the bullet). everyone puts the bullet at X,Y. then then check when T was, and do TimeNow - T, then jump that far in space.
Now, this is all 100% secure, right? but your original post was asking about how to make the bullet appear on the client side first, i'm assuming.
So, it's simple. when step 1) comes, just start drawing a bullet and assume everything is going as normal. when step 3) comes, the bullet may jump a little bit depending on latency.
The local client should track this bullet and display any results - if it hits a wall, show a richochet particle affect. If it hits a person, show a blood particle afffect. just assume everything is 100% peachy.
The server determines what "really" happens to this bullet. there are lots of tricks to telling the client "hey dude, that bullet didnt hit the wall next to you, but actually caught you in the face".
in my game, i would have little numbers pop up with the amount of damage done ONLY when the server sent a packet saying "a bullet hit client X for Y damage".
this way, in a perfect world, everything would look great. when errors popped up, the user might see a bullet hit a wall with a particle effect explosion, but then moments later he sees a blood spurt / numbers above his head.
PS - please give more details on your game... 2d/3d? what view? what genre? what platform??
in FTA, i honesntly can't remember if the client creates a bullet right away anymore or not... it WAS like that at some point... there are SOO many ways to do this, with SOO many different tweaks to try... you have to find the right balance of security, bandwith usage, and latency hiding... these are all very specific to your game.
however, the generate flow is like this (if you want to be 100% service authoratitive):
1) user pushes fire. he sends "can i please shoot a bullet now? the time is T"
2) server gets a the message. he validates this is OK. he then creates a bullet on HIS simulation. this is the starting point of the bullets life, at THIS point in time, NOT when the user actually pushed fire. he then tells all the the clients, "the client with ID 123 fired his gun. he's at X,Y, and the time right NOW is T"
3) everyone gets this message, including the original guy who shot the bullet. (although you can avoid sending the clients ID back to this guy, send him a slightly different packet which says YOU shot the bullet). everyone puts the bullet at X,Y. then then check when T was, and do TimeNow - T, then jump that far in space.
Now, this is all 100% secure, right? but your original post was asking about how to make the bullet appear on the client side first, i'm assuming.
So, it's simple. when step 1) comes, just start drawing a bullet and assume everything is going as normal. when step 3) comes, the bullet may jump a little bit depending on latency.
The local client should track this bullet and display any results - if it hits a wall, show a richochet particle affect. If it hits a person, show a blood particle afffect. just assume everything is 100% peachy.
The server determines what "really" happens to this bullet. there are lots of tricks to telling the client "hey dude, that bullet didnt hit the wall next to you, but actually caught you in the face".
in my game, i would have little numbers pop up with the amount of damage done ONLY when the server sent a packet saying "a bullet hit client X for Y damage".
this way, in a perfect world, everything would look great. when errors popped up, the user might see a bullet hit a wall with a particle effect explosion, but then moments later he sees a blood spurt / numbers above his head.
PS - please give more details on your game... 2d/3d? what view? what genre? what platform??
FTA, my 2D futuristic action MMORPG
sorry, i should have read more then just the first post before replying. let me think about this....
Quote:
Original post by ToohrVyk
The problem does indeed disappear when the created object is write-only, since no matter what the client does to the object, the server will compensate. However, if the client attempts to read data from the wrong object, chaos ensues.
Consider Foobar the Sorcerer, casting a level 2 "enchant armor", thus enchanting his pointy hat (enchantment temp-18) by +1 and his bunny slippers (enchantment temp-42) by +2 on the client. However, on the server, PlayerTwo the witch casts an instant-hit spell at Foobar, reducing his "enchant armor" spell level: the spell now only enchants the bunny slippers (enchantment 1) by +1.
During synchronization, temp-18 is matched to 1 (they have the same bonus and same creator). Now, the client believes the hat is enchanted by +1, while the server knows that the slippers are, and not the hat. What can be done to keep these in-sync?
The obvious solution to this would be to also associate "hat" and "slippers" with the created objects. However, in order to do this, it is necessary for "hat" and "slippers" to be entities (so their ID can be synchronized). And these two must be created at one point or another in the game, which reiterates the problem (unless all objects, spells, bullets, and everything, are created at the beginning of the game, which is highly improbable).
FTA, my 2D futuristic action MMORPG
Consider Foobar the Sorcerer, casting a level 2 "enchant armor", thus enchanting his pointy hat (enchantment temp-18) by +1 and his bunny slippers (enchantment temp-42) by +2 on the client. However, on the server, PlayerTwo the witch casts an instant-hit spell at Foobar, reducing his "enchant armor" spell level: the spell now only enchants the bunny slippers (enchantment 1) by +1.
the flow if this would go like this.
keep things SIMPLE. don't try to repreent the bunny slipper and the hat, or any of that stuff. those should just be graphics drawn to the screen. the only data that should be here is a single value, called "total armor level" (or whatever).
1) foobar casts enchant armor. he sends to the server "id like to cast spell with ID X on myself".
2) server gets the request. does validation. does randomization or whatever, and then comes up with a new "total armor level" for this client. he DOES not send this to anyone - only the server should care about this, since he does the damage calculations and such.
I would keep things simple and just give each player individual "body parts", each with their individual armor values. Then, you don't have to track the notion of slippers or hats.
So, the server then sends to the clients "player X has just casted spell Y. his new head armor level is Z, and his new feet armor level is Q".
OK, im just brainstorming out-loud at this point, because i would need more details on how all this stuff is stored/ tracked / etc.
Let's assume you have an Item ID which uniquely identitifes an item in the world (be it in someones backpack, equipped, laying on a dead body, on the floor, whatever). You also have a Spell ID, which uniqueley identitfies each spell.
So, now that we have this established, we can easily "stack" as many spells onto whatever items we want.
So, let me start over now.
1) player A casts the armor enchant spell. he sends to the server "please cast armor enchant".
2) server gets this. validates the request. does calculations and then responds back to the client AND all other important clients with "player A has cast spell with ID 1. Items with ID's 2 and 3 are now affected by this spell".
3) client gets the message. it takes "player A", "spell X", and then renders the spell casting affect. it takes the "items with ID 2/3 and Spell X" data and then updates these items and their properties.
OK, i probably totally lost you at this point - i didn't mean to crap all over your thread, but this is an interesting problem... while my post isnt fully fleshed out i hope it at least sparks some ideas.
the flow if this would go like this.
keep things SIMPLE. don't try to repreent the bunny slipper and the hat, or any of that stuff. those should just be graphics drawn to the screen. the only data that should be here is a single value, called "total armor level" (or whatever).
1) foobar casts enchant armor. he sends to the server "id like to cast spell with ID X on myself".
2) server gets the request. does validation. does randomization or whatever, and then comes up with a new "total armor level" for this client. he DOES not send this to anyone - only the server should care about this, since he does the damage calculations and such.
I would keep things simple and just give each player individual "body parts", each with their individual armor values. Then, you don't have to track the notion of slippers or hats.
So, the server then sends to the clients "player X has just casted spell Y. his new head armor level is Z, and his new feet armor level is Q".
OK, im just brainstorming out-loud at this point, because i would need more details on how all this stuff is stored/ tracked / etc.
Let's assume you have an Item ID which uniquely identitifes an item in the world (be it in someones backpack, equipped, laying on a dead body, on the floor, whatever). You also have a Spell ID, which uniqueley identitfies each spell.
So, now that we have this established, we can easily "stack" as many spells onto whatever items we want.
So, let me start over now.
1) player A casts the armor enchant spell. he sends to the server "please cast armor enchant".
2) server gets this. validates the request. does calculations and then responds back to the client AND all other important clients with "player A has cast spell with ID 1. Items with ID's 2 and 3 are now affected by this spell".
3) client gets the message. it takes "player A", "spell X", and then renders the spell casting affect. it takes the "items with ID 2/3 and Spell X" data and then updates these items and their properties.
OK, i probably totally lost you at this point - i didn't mean to crap all over your thread, but this is an interesting problem... while my post isnt fully fleshed out i hope it at least sparks some ideas.
FTA, my 2D futuristic action MMORPG
I'm assuming this is for a networking system where representing a specific client can be done in some small number of bits -- ie up to 63 player multiplayer.
Client-created objects can only happen as a result of the local client performing some action -- objects created because some other player (not on my machine) performed some action will get to me from the server when that action gets to me from the server.
Thus, the server "object create" message can contain a "client+ID" field which tells everybody who created the object, and what local ID that client used when creating the object. When you receive object create, you compare your own client identifier with the "client" part of that field; if it matches, you know the server object create message replaces your local object with id "ID".
Another option is to just let the clients assign the IDs for client-created objects, and keep them as the global ID for the object for the lifetime of the game. Give each client a subrange of the global ID space, and use that subrange for all objects created by the client.
Client-created objects can only happen as a result of the local client performing some action -- objects created because some other player (not on my machine) performed some action will get to me from the server when that action gets to me from the server.
Thus, the server "object create" message can contain a "client+ID" field which tells everybody who created the object, and what local ID that client used when creating the object. When you receive object create, you compare your own client identifier with the "client" part of that field; if it matches, you know the server object create message replaces your local object with id "ID".
Another option is to just let the clients assign the IDs for client-created objects, and keep them as the global ID for the object for the lifetime of the game. Give each client a subrange of the global ID space, and use that subrange for all objects created by the client.
enum Bool { True, False, FileNotFound };
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement