Replies: 2 comments 1 reply
-
Here is my personal understanding & opinion on the matter: Updated to reflect change of view I believe we definitely need the ability to store components referencing invalid entities, because they are totally safe and it is only the responsibility of the user to handle them. If we only store IDs without generation in scenes, we lose the ability to distinguish an obsolete entity (e.g. 2v0) with a new one that took it's place (e.g. 2v1). It's a nice thought to somehow not "expose" the internal ECS ids to scenes saved to disk, or scenes sent across the network, but it is completely impractical (would require mapping the entire scene's Therefore, I believe we should update the scene representation to use the full I think the best way to achieve it is to modify the (
entities: {
0: (
components: {
"game::Following": (4294967296),
[...]
},
),
4294967296: (
components: {
[...]
},
),
[...]
},
) A bit ugly to read for exported scenes from e.g. an editor, but it's always possible to "normalize" them to a sequence afterward if that were a concern.
Previous message:
To summarize, I'm still a bit on the fence. Semantically, it makes sense not to serialize the generation, but I don't see a practical way to solve the issue of invalid references, so serializing the generation seems like the best solution at the moment.
RationaleNetwork ABA issueThe purpose of a generationful ID is to prevent the ABA problem. In the context of Bevy's ECS, it's to prevent it throughout a Shatur's solution is to re-use the Entity's generation for this purpose. I don't it's necessary for the following reason: Scene are meant to be self-contained chunks of ECS state. They can be stored, used across worlds, and only represent a single point in time. In that context, there is no ABA problem, and the only purpose of Entity in a scene is to preserve the relations stored in Components (such as the hierarchy). In my opinion, the solution to solving ABA over the network should be that the user defines a Of course, this introduces a problem: Your components might contain Concrete example: Shatur's networking functionality as he posted it on Discord looked like this:
My proposal for such functionality would be something like this instead:
When the receiver receives a WorldDiff, they construct an EntityMap by composing So, since it works either way, IMO, this networking case shouldn't impact the final decision too much. The case of invalid referencesSometimes, users might save components containing obsolete Entity references. Invalid references cause an aliasing problem, because serializing an obsolete Entity without generation can give the same result as a newer valid Entity that happened to have the same ID. |
Beta Was this translation helpful? Give feedback.
-
Here are my thoughts on this, from the perspective someone making a game that makes very heavy use of custom relations. General PointsI want to talk out two general points up front. First, it doesn't, outside the very core of the engine, ever make sense to handle the fields on Second, we need to support "dangling"/"invalid" entity references in scenes. It is not reasonable to require users to ensure that no component on any entity has an entity referencing field pointing at a despawned entity when that is so easy to do accidentally and can be handled gracefully by systems, posing no problem outside of scenes. On NetworkIds
This would commit the sin I mentioned above of pulling the entity identifiers apart. I guess the idea here is to avoid having to provide a serialization for
At the point you are sending serverside entity IDs in a mapping table and in component data, they are no longer internal to the server anyway. What problem does introducing a separate NetworkId actually solve? Now your messages contain two different ID spaces and handling them requires two layers of mapping on the client (serverside entity ID -> NetworkId -> clientside entity ID). If the serialization layer were to do the first mapping (serverside entity ID -> NetworkId) and send component entity reference fields as NetworkIds then this approach would make sense, but so long as it does not, I don't see what is actually gained by doing this. What Then?I don't think there's anything wrong with serializing generation everywhere. We have perfectly usable IDs that are unique within a world already, so why not use them? The only sharp edge would be the ability to construct an To just throw a possible approach out there, a bit on However, I think it might be fine to just leave it unsolved - I suspect that, in practice, things will blow up in an obvious way if you forget to perform any entity mapping at all. |
Beta Was this translation helpful? Give feedback.
-
I am creating this discussion to address a controversial topic that has been brought up multiple times:
The issue
Currently, the scene format contains a inconsistency between components containing an Entity (u32 id + u32 generation), and the Entity's identifier (u32 id only).
This causes panics when loading scenes which contain hierarchies and other relations.
See #4793 for more information
In the past, we used to not serialize the generation. This has been changed in #6194 to allow certain networking use cases.
Past discussions on the discord, issue and the PR, have shown controversy over multiple points:
I think we should gather everyone's thoughts on the matter here, to serve as a summary to help decision making.
Concrete steps
If we decide to store the generation, we need to modify the scene format to identify entities with their generation as well.
If we decide not to store it, we need to revert the change to entity serialization, and fix DynamicScene creation.
Past discussions
https://discord.com/channels/691052431525675048/692572690833473578/1032774605800226836
https://discord.com/channels/691052431525675048/745805740274614303/1050108238617653308
#4793
#6194
Beta Was this translation helpful? Give feedback.
All reactions