add migration guide

This commit is contained in:
Elliott Pierce 2025-05-31 18:38:17 -04:00
parent 9baf15a932
commit 63effde692

View File

@ -1,17 +1,52 @@
---
title: Entities APIs
pull_requests: [19350, 19433]
pull_requests: [19350, 19433, 19451]
---
`Entities::flush` now also asks for metadata about the flush operation
that will be stored for the flushed entities. For the source location,
`MaybeLocation::caller()` can be used; the tick should be retrieved
from the world.
In 0.16, entities could have zero or more components.
In 0.17, a new state for an entity is introduced: null/not constructed.
Entities can now be constructed and destructed within their spawned life cycle.
This opens up a lot of room for performance improvement, but caused a lot of breaking changes:
Additionally, flush now gives `&mut EntityIdLocation` instead of `&mut EntityLocation` access.
`EntityIdLocation` is an alias for `Option<EntityLocation>`.
This replaces invalid locations with `None`.
It is possible for an `Entity` id to be allocated/reserved but not yet have a location.
This is used in commands for example, and this reality is more transparent with an `Option`.
This extends to other interfaces: `Entities::free` now returns `Option<EntityIdLocation>` instead of `Option<EntityLocation>`.
`Entities::get` remains unchanged, but you can access an `Entity`'s `EntityIdLocation` through the new `Entities::get_id_location`.
### `Entities` rework
A lot has changed here.
First, `alloc`, `free`, `reserve`, `reserve_entity`, `reserve_entities`, `flush`, `flush_as_invalid`, `total_count`, `used_count`, and `total_prospective_count` have all been removed.
Allocation and freeing have been made private, but there are new ways to accomplish this.
Reservation and flushing have been completely removed as they are no longer needed.
Instead of reserving an entity and later flushing it, you can `World::spawn_null` (which does not need mutable access), and `World::construct` can be used to "flush" it.
The counting methods have been reworked in the absence of flushing:
`len` and `is_empty` now deal with how many entity rows have been allocated (not necessarily the number that have been constructed/spawned),
and the new `count_constructed` and `any_constructed` are similar to the old `len` and `is_empty` behavior.
In terms of getting information from `Entities`, `get` and `contains` has been reworked to include non-constructed entities.
If you only want constructed entities, `get_constructed` and `contains_constructed` are available.
Additionally, `get` now returns `Result<EntityIdLocation, EntityDoesNotExistError>` instead of `Option<EntityLocation>` for clarity.
`EntityIdLocation` is an alias for `Option<EntityLocation>`, as entities now may or may not have a location, depending on if it is constructed or not.
`EntityDoesNotExistError::location` has been replaced by `EntityDoesNotExistError::generation` of type `EntityGeneration`.
This is because a not constructed entity is now still considered to exist.
The only way an `Entity` can not exist is if it has the wrong generation; the right one is now in `EntityDoesNotExistError::generation`.
If you only want constructed entities, the new `ConstructedEntityDoesNotExistError` is available.
As an alternative to `free`, simply create a `EntityWorldMut` (if it fails, it's already been freed), and despawn it.
If the entity was already destructed, despawning will just free the entity internally.
### Entity Pointers
All entity pointers location information has changed from `EntityLocation` to `EntityIdLocation`, as they can now point to non-constructed entities.
This extends to archetypes too, many `.archetype` methods now return `Option<&Archetype>`.
Notably, `EntityWorldMut` continues to have panicking methods which assume the entity is constructed.
### Entity Commands
`Commands::new_from_entities` now also needs `&EntitiesAllocator`, which can be obtained from `UnsafeWorldCell::entities_allocator`.
`Commands::get_entity` does not error for non-constructed entities.
If you only want constructed entities, use `Commands::get_constructed_entity`
### Other entity interactions
`BundleSpawner::spawn_non_existent` is now `BundleSpawner::construct`.
`World::inspect_entity` now errors with `ConstructedEntityDoesNotExistError` instead of `EntityDoesNotExistError`.
`QueryEntityError::EntityDoesNotExist` now wraps `ConstructedEntityDoesNotExistError`.
`EntityDespawnError` has been renamed to `EntityDestructError`.
`ComputeGlobalTransformError::NoSuchEntity` and `ComputeGlobalTransformError::MalformedHierarchy` now wrap `ConstructedEntityDoesNotExistError`.