BoltEngine / Bolt-Tracker

New issue tracker for Photon Bolt
10 stars 2 forks source link

Add a checkbox like "Signal OnInitialState done" for BoltEntity or StateBehavior #165

Closed SubtleTechnology closed 4 years ago

SubtleTechnology commented 4 years ago

It could be a checkbox on the StateBehavior, or BoltEntity.

How to reproduce issue

  1. var go = BoltNetwork.Instantiate(playerPrefab);
  2. go.GetComponent().GetState().Health = 100;
  3. in OnAttach() of PlayerState of clients, Health may still be zero.

Expected Behavior

Health (and any other values of state that were initially set) should be 100 every time, once you check the box.. Developers shouldn't need to create custom tokens and code for this common purpose that Bolt could handle automatically.

Set the checkbox "Signal OnInitialState done", this would cause Bolt to only call a new override OnInitialState() after ALL the state variables initially changed from the owner who instantiated the object. For instance, add a boolean to bolt's internal state class like InitialStateNeeded per property. Any properties changed after the Instantiate and in the same frame (typically it is lines of code immediately after the Instantiate call, as an example but it could be other code outside of the custom behavior code and it might not be convenient or good design to put it at the same point of the Instantiate call), would have those booleans set to true. Each time a state property is replicated to clients, set it to false for that property. Once all InitialStateNeeded values are false for all state properties, reliably send a message to clients letting them know that initial state is done. If no properties were changed in the same frame as Instantiate, then just use a flag in the Create instead of as a separate message.

If that means multiple frames went by and the value may not be 100 for whatever reason anymore, that is fine. The purpose is just to have an event that tells the client that it can start doing whatever it needs to do instead of not knowing whether any of the state properties are valid.

For example, if you turn on that option and you instantiate the object and set A, B, and C properties on the state. After A B and C have been sent one time, it just needs to send a reliable message to clients that initial state was sent. It could be a new override like OnInitialState() just like OnAttach(). Without ACKs it's possible the clients didn't receive the state properties, but at least it's better than nothing.

Actual behavior

Health was zero;

Configuration

ramonmelo commented 4 years ago

Hello @SubtleTechnology ,

Photon Bolt is designed to keep in sync the Entities' States using a best-effort algorithm, relying on the fact that eventually, all state values will be in sync across all player instances. This means, that Bolt tries to pack all pending events/command/state changes into a single package and sent it over the network, if it's not possible, those pending data will be packet on the next send. Depending on the size of your state and all other data that needs to be synchronized, it is not possible to get a state in sync when the entity is attached.

What you are proposing is already implemented using Attach Tokens, this is the only way to guarantee that an integral piece of data will be delivered alongside your Entity when it's attached.

You can read more about the design description implemented by Bolt in this article and about the State details on this page.

Thanks for your feedback.