Ghost Optimization

I am still a bit of a newbie when it comes to ECS and Netcode but based on my understanding:

There is a 128 unique limit on ghosts

Each ghost authoring consumes one of those

There must be some packet usage to specify which of the 128 you are using.

Why cant we use a little more overhead to specify which of the 128 and which prefab it maps to? So that all ghost components that only interact with a transform for instance can use the same one out of the 128 limit?

(I see that it might not be as simple when multiple ghost fields are added bc it will be hard to determine which slice of fields contribute to a new map.)

Is there a better way to do the following now? Have a ghost entity with an int id and a ā€˜new item tagā€™, collect these ā€˜new item tagsā€™ in client world and create prefabs for them from the id and then add ā€˜second stage tagsā€™ on the prefabs, removing the ā€˜new item tagsā€™ then assigning the linkedentitygroup from the prefab to the ghost entity from the ā€˜second stage tagsā€™.

1 Like

Hey downfall,

No, itā€™s specifically a limit on in-use ghost components (denoted by GhostField or GhostComponentVariation), and this limit can be increased to 256 via the NETCODE_COMPONENTS_256 compile time flag.

I believe each component must only be present in a loaded ghost type to be considered ā€œin useā€.

The limit is relatively technical:

  1. The DOTS safety systems must be able to inspect fields on job structs to find RW and RO component types (like ComponentTypeHandle, BufferLookup etc).
  2. It also doesnā€™t currently support containers of type handles (weā€™d need a NativeList<DynamicComponentTypeHandle> in our case), and does not provide a broad way for us to specify ā€œreads so many ECS types in practice, that we would prefer to just treat this job as special/exclusiveā€.
  3. Therefore, we unroll the DynamicComponentTypeHandle into 128/256 fields (see DynamicTypeList), so that the safety system can find them appropriately.
  4. We also have highly generalized snapshot send systems. E.g. The GhostSendSystem (and all related systems) handles snapshots for all connections, for all ghost types, in a few jobs. We therefore compile this unrolled list of type handles via DynamicTypeList on the fly, and pass them into these jobs.

Can you more explicitly describe your use-case? Itā€™s hard to make sense of what youā€™re trying to do here. We do support runtime generation of ghost prefab types (see GhostPrefabCreation.ConvertToGhostPrefab), but to do so, you must call this API identically on the client and server (including in the same order, IIRC), with identical component lists, and identical LinkedEntityGroup and transform hierarchy data.

1 Like

Thanks for the detailed response - i am adding items to the world (loot) and i am making a ghost containing the id of the prefab that it correlates to instead of making a ghost per prefab so the client would have to take the ghosts and instantiate the prefabs too based on the id

Claude / gpt told me that the authoring contributed to the limit so thats where that came from

1 Like

Ah, yeahā€¦ You canā€™t trust 'em with anything :sweat_smile:

2 Likes