During my playtests, I have encountered that creating entities may timeout (at least on my local machine). Since I want to ensure that entities are indubitably created I have written a piece of code that should ensure this behaviour, even when commands timeout.
I would like it if others, and especially people from Improbable could check this for potential pitfalls. I have tried to keep all angles covered but without intimate knowledge of the network stack I would love a second opinion here.
First, I reserve an entity id. I do this because a CreateEntity command may fail but still create the entity. By having the entity id beforehand I can verify whether creation did complete or not:
void Initialize() {
SpatialOS.WorkerCommands.ReserveEntityId(response => {
if (response.StatusCode != StatusCode.Success) {
// this must(!) succeed; do it again!
Initialize();
return;
}
var entityId = response.Response.Value;
[CALL ENTITY CREATION CODE WITH THE ABOVE VALUE]
});
}
Secondly, I invoke the CreateEntity command with the reserved ID and when it fails I do an extra check if it really failed or whether the response didn’t arrive properly:
void Create(entityId, prefab, entity) {
SpatialOS.WorkerCommands.CreateEntity(
entityId,
prefab,
entity,
response =>
{
if (response.StatusCode.Equals(StatusCode.Failure))
{
// if the entity doesn't exist then creation failed; otherwise it is created
// but the command failed to return a value in time
if (SpatialOS.Universe.Get(entityId) == null)
{
Debug.Log("Failed to create " + prefab + ": " + response.ErrorMessage);
Create(entityId, prefab, entity);
return;
}
}
Debug.Log(prefab + " " + entityId + "created");
}
);
}
The only caveat I can think of currently is that this may go in an infinite loop (and going deeper on the call stack, potentially causing a stack overflow) if entity creation doesn’t happen.
When testing this I did encounter a weird situation, I could get following error when creating an entity:
23:26:19.669 INFO [EngineLogMessageHandler] [Worker: UnityWorker0] Failed to create Moon: EXPIRED: Entity Id reservation for Id<Optional[1807]> could not be found.It might have been expired or never existed. -[WorkerLogger:Unity]
How long do reservations exist? Can they expire within a few seconds?