Improbable Icon


Reading local entities, strategies and hurdles


I have been experimenting trying to figure out the most efficient way to get entity positions using the Spatial OS API. So far I have been using the SpatialOS.GetLocalEntity() function which is light weight, fast, and reliable but with the major limitation that it depends on entities being in very close proximity no more than 100m.

I would like there to be goal entities that could be miles away from the players and I would like all players to equally be able to access these goal positions. At first I made the discovery that I could increase the distance of reading if I did “.AddPositionComponent(initialPosition, CommonRequirementSets.PhysicsOrVisual)” to the goal entity.

At first I thought I had solved all my problems but using PhysicsOrVisual instead of the regular “CommonRequirementSets.SpecificClientOnly(clientWorkerId)” included not having multiple clients be able to read the entity at the same time since SpatialOS.GetLocalEntity() would return Null for the other inquisitive clients. Also the goals were sometimes very unstable and glitchy with their presence, a goal could entirely disappear for a certain client and might recover after some time.

I get the impression that using PhysicsOrVisual for a PostionComponent is a bad strategy because of the experiences mentioned above. I was wondering if there is a way though to increase the range of reading local entities especially for specific entity types that the client might be really interested in? Otherwise is there any suggestions from experienced Spatial Developers of ways to have clients read the position from a goal entity constantly and efficiently, and have that entity be possibly miles away. This technique would also be great for displaying where players are at. Imagine you have a city and just by glancing around you can see where all the other players are located in the city, and in real time just see how how they moving in perspective to the screen coordinates.

Thanks for the help.


I’m just another developer learning Spatial OS myself and am not going to claim that I’m burdened with excessive experience but here are my thoughts.
I am using my knowledge and experience of large distributed systems.

I hope any Improbable staff will correct me if I’m wrong in any assertions below.

First, the workers are localised spacially. The area they cover is determined by the components on entities that they have write access to and the load balancing algorithm of Spacial OS. This area is considered their authority area.
They will only read components of entities that are within a certain limited distance from their authority area and only one worker has write access to any specific component of a specific entity.
So for your goal entity, only one worker instance will have write access to it at any given time.
If your players travel too far away from the goal then they will lose the goal from their read/local area. They won’t see the goal anymore.
They can still query the world and get the current status of the goal in that manner.
I would not advise this because it will be costly and the players will be sending numerous unnecessary queries.

I would look at the Command functions.
Component commands are sent by other workers to the worker that has write access of a given component.
I would also look at the conventions of large distributed systems of propagating updates to interested parties when there is a relevant update, this can be referred to as Lazy evaluation.

The general idea is to have updates propagated/calculated only when needed. One way of doing this with Spacial OS is to have each player have an entity themselves that represents their current view of the goal and or other players if applicable and the goal would send them updates via commands when there has been an update of the goal that would be relevant to that player.
This current view would be very lightweight and only contain the info they are actually interested in.

The goal would still have components as before and the player workers can send commands for the goal components when they have a relevant status update. The worker that has to write access to the goal components at that time will update the components in response to the commands received from the player workers and, if relevant, send commands with the updates to interested parties.
The goal can have a component that just lists Entity Ids of interested players.

This is a bit more complex than what you started with, I know. This sort of functionality is complex at best of times in large distributed systems.

The complexity is in that each worker is a separate running process and can be running on a different server to each other. Spacial OS is like a bridge relegating messages between these workers and giving some guarantee of delivery.

I hope this helps, happy to discuss further, I may find whatever you decide on useful in my own application.