Internal state during simulation authority transfer

To the devs of coherence: I want to say that this is the first network solution I tried that truly feels AAA-like. The ease of creating multiplayer games with coherence is incredible.
Now to my question:
From reading the documentation, it is unclear to me how simulation authority transfer handles internal states of game objects, that are part of the game object, which are not synched. The simulator of a game object needs full information of the game object while network participants that are not simulating a game object do not need its internal state. This should be even avoided, to hinder cheating. An internal state might be for example the inventory of a player. Other players are not allowed to know the inventory of other players, while the simulator should have authority over the inventory. Is the whole game object somehow serialized during authority transfer and then sent to the simulator requesting authority? Or are only synched states of a game object sent and the internal state (for example the inventory) is reset?

Hello! Thanks for the kind words. I can assure you that only the properties that you mark as “Sync” are replicated to clients. So, if your simulator instantiates an object with position synced but a complex inventory object not synced, only the position will be synced to other clients. The inventory on clients will be the default object for the type.

To further clarify, we only sync primitives, so it is up to you as the developer to synchronize complex state.

https://docs.coherence.io/schema-explained/specification#primitive-types

Hello brit! Thanks for the fast response and the clarification of the sync mechanics. My question was aimed to find out the behaviour of authority handover with unsynched states. I have another example: a NPC with a complex internal state is simulated by Simulator A. Clients are not allowed to know its internal state so this state is not synched. Now Simulator A hands over authority to Simulator B. Since the internal state is not synched, after handover to Simulator B, the internal state is reset, is that correct? So during authority handover, the whole game object is not serialized and sent to the new simulator.

If this is the case, my question boils down to: is there a way to have the internal state be synched between Simulators but not to Clients?

Yes, but it’s a somewhat manual process. We have the concept of commands: https://docs.coherence.io/coherence-sdk-for-unity/networking-state-changes/commands

To orchestrate the situation you are describing, Simulator A would need to send a command with the serialized private state (probably mutliple commands that needs to be stitched together) to another client to transfer the private state. So, it would need to exist outside of just an authority transfer. It would look like Auth transfer → Commands to xfer private state.

We realize this is a cumbersome task, and we’re actively working on how we support List or complex object serialization in commands as a future feature of the SDK. In addition, we are working on the concept of a “global K/V store” at the project level that will let you store K/V at a granular permission level for data like this. I don’t have a timeframe on either feature at the moment, but it’s certainly a common need for all of us.

Does that answer your question?

Yes! Thank you. Altough, there may be an easier solution, which builds on top of your already existing synchronization functionality in coherence. I think my problem could be solved by allowing for a per network participant live query. The live query for the simulators for example would include the internal states of NPCs while it is not synchronized for/to clients. I know that the granularity of synchronization is for now only per object and not per component. One might just store the internal state in a second game object for every NPC, which is attached to this NPC. This game object is then only synchronized between simulators but not to clients. Is something like this already possible?

Hey!

You could solve it today by using Tag Queries. Internal state objects could be tagged with Internal and placed outside of game bounds so no player would ever reach them with their Live Query. All simulators would then use Tag Query with Internal tag to find those objects.

We’re also considering an approach where one could select if the synced property is “private” and so synced only to the Input Authority of the object and other simulators. The design hasn’t been finalized yet so I can’t tell exactly how this will be solved and when.

It is however a known problem, and one that pops up often, so we’ll be tackling it sooner than later.