Description
What problem does this solve or what need does it fill?
Entity currently can't be default constructed or represent a "never valid" entity. Which is extremely useful for sparse relational data structures like grids and oct/quadtrees. This is easily sidestepped via Option<Entity>
, as rust does - so there's not a hard limit here or anything of course.
The issue is that Option will introduce some memory overhead, which can become significant in flatter data structures like grids.
What solution would you like?
I'd like to be allow the compiler to leverage memory layout optimization, to remove the storage overhead of Option<Entity>
. This could be done by changing either id
or generation
to a NonZeroU32
. I'd propose that generation
should be the one considered for the change, as it has less public API surface.
What alternative(s) have you considered?
- Use raw entity IDs without the generation and accept the risk of reused ids.
- Take the bit representation of Entity, increment it for storage as an wrapped NonZeroU64 and then decrement it to convert it back.
- Accept the overhead of the
Option
- Use less sparse/flat/smarter representations for relational data (ie. chunks)
Additional context
In my particular case, I have "TileCoord" component and a "MultiTileCoord" component that create a relation between entities and a particular grid square. On top of that, I maintain a fixed-size grid structure that is updated as TileCoords are altered to accelerate neighbourhood queries and generate certain events (ie. neighbour changed, tile moved ontop). As a result, some of the grid squares would be empty which can't be represented with Entity
alone, so I need to utilize Option<Entity>
and incur the storage overhead.
On an example 1-layer grid of 256x256, this is an overhead of about ~256KiB. This isn't a pressing issue in my case, since I'm currently using the 2nd alternative I outlined. I just thought it might be a nice space optimization to put into core.