From 63effde6927084ea0cf5589a9f13fa4d31b16bc2 Mon Sep 17 00:00:00 2001 From: Elliott Pierce Date: Sat, 31 May 2025 18:38:17 -0400 Subject: [PATCH] add migration guide --- .../migration-guides/entities_apis.md | 59 +++++++++++++++---- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/release-content/migration-guides/entities_apis.md b/release-content/migration-guides/entities_apis.md index d6e7aa12df..9c20b6f68d 100644 --- a/release-content/migration-guides/entities_apis.md +++ b/release-content/migration-guides/entities_apis.md @@ -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`. -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` instead of `Option`. -`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` instead of `Option` for clarity. +`EntityIdLocation` is an alias for `Option`, 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`.