Question on sync'ing properties (from tutorial)
in Photon Bolt
Super noob question: In the tutorial, we start by sync'ing transform. Great. Then we add color. Ok. But why is it that the mechanism for hooking up the sync'ing of the properties is completely different?
public override void Attached() // when object is live on the network
{
state.SetTransforms(state.CubeTransform, transform);
state.AddCallback("CubeColor", ColorChanged);
}
SetTransforms "seems" (it's not really explained in the tutorial) to be a way of setting up auto-sync of a transform property. Great. But for color we need to setup a callback for when the networked property changes, and then when it does, manually update the local property.
Transform seems to have a magic auto-sync ability. Are transforms 1st class and everything else 2nd class? Just wondering why we have two different ways of sync'ing different properties on the same object. Seems weird/inconsistent.
public override void Attached() // when object is live on the network
{
state.SetTransforms(state.CubeTransform, transform);
state.AddCallback("CubeColor", ColorChanged);
}
SetTransforms "seems" (it's not really explained in the tutorial) to be a way of setting up auto-sync of a transform property. Great. But for color we need to setup a callback for when the networked property changes, and then when it does, manually update the local property.
Transform seems to have a magic auto-sync ability. Are transforms 1st class and everything else 2nd class? Just wondering why we have two different ways of sync'ing different properties on the same object. Seems weird/inconsistent.
0
Best Answers
-
Hello @PurpleCat ,
Yes, they have different approaches because we treat them differently.
In the case of the Transform, that is the basic component of every Game Object and is one of the main set of data that most of the games will sync by default, we run some other optimizations and can also apply interpolation algorithms, for example. Keep in mind that the Transform a set of 3 vectors.
On the other hand, for the other property types, as they are more abstract, we expose the callback, so you know when the property value was changed and can take any action. This is just a convenient way to look at your entity state and be notified about this, instead of polling for changes.5 -
SetTransforms basically tells bolt "I want to link this state transform property to this underlying transform in unity". You need to do this on both the client and the server if you are doing a sync in this manner. On the server side this tells Bolt "When this transform changes, automatically link this to this state property" and conversely on the client, it means "Hey, I received an update for this state property transform which (if any) unity transform should I apply this to?". Keep in mind you can also turn this off by setting the unity transform to null (i.e. SetTransforms (state.myTransformProp, null).
For predicted controllers, the controller is predicting his movement locally. He doesn't want to apply movement that came over the network from the server since this is not predicted. So he doesn't use this mechanism in favor of the Command based input/rollback system (assuming using client prediction which is total optiona).
Finally, there is a third parameter for SetTransforms. This is the render interpolation transform. This is optional. If set (always to a child of the transform used as the second argument), Bolt will use simple render interpolation by essentially moving the child transform around in very steps each update to interpolate movement between fixed update ticks. This is only done on proxies however. Controllers/owners are skipped for render interpolation and you need to provide your own mechanism. Keep in mind render interpolation differs from interpolation which is also integrated into Bolt. They solve two different problems.
To answer the OP's question, as Ramon said Transforms are quite complex under the hood. They contain position/rotational information and they have a variety of requirements based on interpolation/extrapolation. It was a necessity to make this a first class concept. You can always sync your own position/rotation properties you want to handle all of that on your own.
As for all other properties, there is no need to set callbacks for them if you are going to simply poll them. Callbacks are optional but provide a very simple pattern for subscribing to changes.5
Answers
-
Hello @PurpleCat ,
Yes, they have different approaches because we treat them differently.
In the case of the Transform, that is the basic component of every Game Object and is one of the main set of data that most of the games will sync by default, we run some other optimizations and can also apply interpolation algorithms, for example. Keep in mind that the Transform a set of 3 vectors.
On the other hand, for the other property types, as they are more abstract, we expose the callback, so you know when the property value was changed and can take any action. This is just a convenient way to look at your entity state and be notified about this, instead of polling for changes.5 -
Sorry to hijack the thread, but I have a question about the same line of code.
state.SetTransforms(state.CubeTransform, transform);
Could you explain this method in a little more detail please. Specifically why this needs to be called on all clients (owner and non-owners and not one or the other) for it to work?
0 -
SetTransforms basically tells bolt "I want to link this state transform property to this underlying transform in unity". You need to do this on both the client and the server if you are doing a sync in this manner. On the server side this tells Bolt "When this transform changes, automatically link this to this state property" and conversely on the client, it means "Hey, I received an update for this state property transform which (if any) unity transform should I apply this to?". Keep in mind you can also turn this off by setting the unity transform to null (i.e. SetTransforms (state.myTransformProp, null).
For predicted controllers, the controller is predicting his movement locally. He doesn't want to apply movement that came over the network from the server since this is not predicted. So he doesn't use this mechanism in favor of the Command based input/rollback system (assuming using client prediction which is total optiona).
Finally, there is a third parameter for SetTransforms. This is the render interpolation transform. This is optional. If set (always to a child of the transform used as the second argument), Bolt will use simple render interpolation by essentially moving the child transform around in very steps each update to interpolate movement between fixed update ticks. This is only done on proxies however. Controllers/owners are skipped for render interpolation and you need to provide your own mechanism. Keep in mind render interpolation differs from interpolation which is also integrated into Bolt. They solve two different problems.
To answer the OP's question, as Ramon said Transforms are quite complex under the hood. They contain position/rotational information and they have a variety of requirements based on interpolation/extrapolation. It was a necessity to make this a first class concept. You can always sync your own position/rotation properties you want to handle all of that on your own.
As for all other properties, there is no need to set callbacks for them if you are going to simply poll them. Callbacks are optional but provide a very simple pattern for subscribing to changes.5 -
I should also note that early on Bolt had kind of a hard-coded, single Transform property as part of state. It later was pulled out into its own property - mainly because sometimes you don't need a transform at all - and sometimes you might want to support multiple transform properties in the same state.0