I’m using subscenes to organize different layers for things to import but the problem I found is that the ghost instance Ghost Id isn’t unique and each loaded subscene has its own set of ids… This obviously causes an issue when trying to use the GhostRelevency system. I don’t actually want the the entities to be segregated ingame at all, I’m only using the subscenes to organize and determine what is loaded and when but once loaded, I want the entities to exist in the same conceptual space, including ei respecting each other’s ghost id’s and not clashing. I tried to understand more about subscenes and streaming? is that what I need? IDK I can’t seem to figure it out as the documentation seems a bit lacking outdated or otherwise hard to understand. Is there a way I can load a subscene into the same space as another subscene? I don’t understand how the ghost relevency system is supposed to work when different entities in different subscenes can share the same ghost instance ID and hence clash with each other and not exist in the same set. Are there any resources I can be pointed in the direction of?
There isn’t a guarantee that ghost IDs are unique however when combined with the spawn tick, they are unique. Unity has a struct for this - SpawnedGhost. SpawnedGhost has an implicit cast from GhostInstance so jobs/queries should query GhostInstance and cast to SpawnedGhost for a unique identifier for each ghost. In fact, I use a lookup for this in my project so I can look up entities from their SpawnedGhost:
[BurstCompile]
private partial struct GetGhostEntityLookupJob : IJobEntity
{
public UnsafeParallelHashMap<SpawnedGhost, Entity>.ParallelWriter GhostEntityLookupParallel;
public void Execute(
Entity entity,
in GhostInstance instance)
{
GhostEntityLookupParallel.TryAdd(instance, entity);
}
}
Just putting the above here in case it helps anyone else out however, your issue might also be about relevancy using a collection of RelevantGhostForConnections and that having only the ghost ID as the filter. My assuption was that ghost IDs are reused but only when ghosts are despawned so there cannot be 2 ghosts with the same ID created at the same time. This will cause and issue for sure and sounds like a bug to me. I’ve always kept all ghosts within 1 subscene and used other subscenes for non-netcode stuff like the environment. Separating them out sounds like a perfectly valid approach to me though.
I’m curious why RelevantGhostForConnection does use SpawnedGhost instead of ghost ID.
Oh thanks. I will check this out. Yes it does seem rather strange and unintuitive. I considered that it might be unintentional design as well.
Okay so it seems the RelevantGhostForConnection really only excepts a set of client-ghostid for the key with no way to distinguish?? This seems borked.
Is there a way to use subscenes only for management purposes but move or load or something like that an entity into the main subscene with thee rest of the ghosts?
There is not problem putting pre-spawned ghosts in different sub-scene basis and load as you want. This is how the feature it is intended to work.
The server is responsible to actually assing to the ghost a unique ghost id, one range of id reserved per each-sub-scene, that are not clashing with normal spawned ghost (the prespawned ghost has the MSB set).
For prespawned ghosts you can also infer from which sub-scene they were spawned (or better the section) they were spawned from by looking at the SubSceneGhostComponentHash component (you need to match the sub-scene that has the same has hash value in the SubSceneWithPrespawnGhosts component added to the scene entity.
Or you can also infer the same by looking at the PrespawnSceneLoaded singleton (the component is internal at the moment) and search the matching sub-scene with the matching ghost-id range.
From a relevancy perspective, everything works fine with just ghost id. There is no reason for the server to concern too much about ghost-id being re-used when a ghost spawn. Pre-spawned ghost in particular, when re-spawn because of relevancy, they are guarateed to get the same ghost id all the time.