Improbable Icon

What all gets synced when a entity crosses worker authority?

v10-1-0

#1

I’m curious as to what all is synchronized between workers when an entity crosses from one to the other. Is .schema data the only thing that passes? Or do the workers keep in sync on everything within the entity (mono script states, etc)?

I am trying to figure out what all I need to keep in schemas (and why/when). This question came to mind when I dug into the TargetNavigation.schema. I’m trying to figure out why data is stored there in the first place since its transient and not static (such as max health.)

Thanks!


#3

Hello @VectorXStudios,
Thanks for bring up this question. Upon a worker transfer, only your schema defined component properties will carry over. The state of your MonoBehaviour scripts will not carry over.

Your previously authoritative worker A will either lose authority over your entity X but still see it (in which case your X will remain in A's scene but all scripts requiring component writers will be disabled) or X will be completely removed from A's view (in case A is not supposed to see X anymore after the authority transfer, in this case, the behaviour is identical to when the entity is completely deleted from the point of view of A). In both cases OnDisable() is called on all scripts requiring a writer. In the latter case, OnDisable() and OnDestroy() is called on all scripts attached to X.

At the side of your worker gaining authority (worker B), your entity is either freshly added to the scene, at which point Awake(), Start() and OnEnable() is called on all scripts. (For A the behaviour is the same as if the entity was freshly created for the entire simulation) The component values of X from the point of view of B will be the canonical component values of the simulation. In case A has been aware of X before (but just hasn’t been authoritative over it), all scripts which require a writer are now enabled while all other scripts are enabled already. The component values of X have been kept in sync with the canonical values of the simulation until that point.

What happens inside a worker stays inside a worker, i.e. B doesn’t know what is happening locally to X on A. Only schema defined component values are synced, i.e. if A changes X's canonical component values, the values will also change on B's side. When it comes to the TargetNavigation behaviour, your analysis is spot-on. We are saving (among others) the position an NPC is supposed to move to because that information would otherwise be lost if an NPC changes workers mid-transition.

In case of commands, a command will fail during an authority transfer, i.e. If you send a command and your worker loses authority on the component before a command response is received, your command callback will immediately be invoked with an error message telling you so. For more information on that matter, please see: https://spatialos.improbable.io/docs/reference/10.1/workers/commands

Hope this helps, :slight_smile:
Jonas


#4

Thanks for the clarification! And now another question… :slight_smile:

What design pattern should I follow for things like A* or nav-mesh navigation? Since they cannot be pre-baked in prefabs, I’m struggling a little with the pattern to use. For example, I generate a A* nav grid on a worker but how do I know when the worker loses control to another worker? Do I create a schema with a 500x500 nav-grid to pass over?

Or, can I not really use things like A* and nav meshes? Do I need to do more of a autonomous car LIDAR approach with casting thousands of rays and AI to move around?


#5

@VectorXStudios, this is an excellent question.
Path-finding is a topic that we are still exploring ourselves and we are planning to release a tutorial once best practices are established. Off the top of my head, I would say a naive approach would be:

  • The it is feasible to have a single global nav-mesh for the entire world, have that nav-mesh pre-baked.
  • Always save the global destination where you want an entity to go as a component.
  • If an entity now switches workers mid-transition, just resume the path-finding on the new worker (in Unity, presumably that would mean to call NavMeshAgent.destination = myComponent.Data.destination in OnEnable()).

In case your world is so big that a single global nav-mesh is not feasible you could have a hierarchy of nav-meshes:

  • Have a global low-resolution nav-mesh that spans over the entire world and is the same on all workers.
  • Have smaller local nav-meshes which span over a sub-set of the world and only exist on single workers.
  • If you now pick a destination far away that is outside of your local nav-mesh, transition to the higher-hierarchy nav-mesh, walk to the node closest to your destination on your higher-haierarchy nav-mesh, then transition back to the lower-level nav-mesh corresponding to the local area (you might be on a different worker at this point).
  • (So kinda like a real-world traffic network, where you have highways connecting landmarks/cities and local traffic networks inside each city so-to-speak). :wink:

Please be warned that this approach is pure speculation and might not be sound. :slight_smile:
Jonas


#6

How can you specify that an object exists on only one worker? Is there a size boundary or something I can rely on? Trying to figure out how to design this. Also, keep in mind that the navigation cannot be pre-baked as the world constantly evolves. A player could build a house for example, right in the middle of a previously navigable area.


#7

@VectorXStudios,
The answer to your question depends on how you want to structure your game but here are a couple of clues:

  • You could partition your terrain and model the fragments as entities. Your worker would then only check out parts of the terrain that are relevant for the area it’s authoritative over. You could also have a grid of invisible dummy entities which represent smaller nav-meshes or act as markers to guide your path finding. These entities would also be checked out only by the workers that are interested in them.
  • A worker could calculate it’s approximate position and area of interest by taking the position of all entities that are currently in its local view. (Please refer to the Universe API for more details: https://spatialos.improbable.io/docs/reference/10.1/workers/unity/universe-api) Using that information, a worker could constructs its relevant nav-mesh periodically.

Hope this helps,
Jonas


#8

Gotcha. I wonder if it would be useful to be able to query workers for their zone of authority in x,y,z terms?


#9

Hey @VectorXStudios,
Unfortunately we don’t provide this feature at the moment though I agree that such a feature would be super useful. I have raised a feature request on your behalf and we will consider it for the future. A workaround in the short-term would be to manually calculate an area of interest using the aforementioned Universe API. Note that the area of interest of a worker can take irregular shapes depending on the state of your simulation and the the area of interest of other workers in the proximity. A simple (x,y,z) coordinate representing some notion of a workers “center position” might not give you all the information you need. :slight_smile: