_release-content/migration-guides/resources_as_components.md
#[derive(Resource)] implements the Component traitIn 0.19, Resource is a subtrait of Component and #[derive(Resource)] implements both Resource as well as Component.
This means it's no longer possible to doubly derive both Component and Resource.
Instead, you should split them up:
// 0.18
#[derive(Component, Resource)]
struct Dual
becomes
// 0.19
#[derive(Component)]
struct DualComp;
#[derive(Resource)]
struct DualRes;
Consequently, UiDebugOverlay is split into GlobalUiDebugOverlay (resource) and UiDebugOverlay (component), and UiDebugOptions is split into GlobalUiDebugOptions (resource) and UiDebugOptions (component).
#[reflect(Resource)] ChangesIn 0.19, the ReflectResource is a ZST (zero-sized type) and only functions to signify that the trait is reflected.
Instead, #[reflect(Resource)] also reflects the Component trait, so use ReflectComponent instead.
This is likely to show up in code that uses reflection, like BRP (Bevy Remote Protocol) and bevy_world_serialization.
Now that resources are components, they can be queried using 'broad' queries. These are queries that query all entities. Examples include:
Query<()>Query<Entity>Query<EntityMut>Query<EntityRef>Query<EntityMutExcept>Query<EntityRefExcept>Query<Option<&T>>These should rarely come up in real games, but if they do, they might conflict with resource access, i.e.
fn system(entity_query: Query<EntityMut>, some_resource: Res<MyResource>) {} // err! entity_query conflicts with some_resource
To fix this, you can narrow down the query by using either the Without<MyResource> or Without<IsResource> filter.
The IsResource marker is attached to all resource entities, so it always filters them out.
The same is true for non-send data:
fn system(entity_query: Query<EntityMut>, some_non_send: NonSend<MyNonSend>) {} // err! entity_query conflicts with some_resource
This can be fixed by adding a Without<MyNonSend> filter to the query.
Previously there were two types of resources: Send resources and !Send resources.
Now that Send resources are stored as components, !Send resources have little in common with their Send counterparts.
This is why non-send resources are being renamed to non-send data.
The following APIs are affected:
App::init_non_send_resource is deprecated in favor of App::init_non_send.App::insert_non_send_resource is deprecated in favor of App::insert_non_send.DeferredWorld::non_send_resource_mut is deprecated in favor of DeferredWorld::non_send_mut.DeferredWorld::get_non_send_resource_mut is deprecated in favor of DeferredWorld::get_non_send_mut.ResourceData<SEND: true> is removed, while ResourceData<SEND: false> is renamed to NonSendData.Resources<SEND: true> is removed and Resources<Send: false> is renamed to NonSends.UnsafeWorldCell::get_non_send_resource is deprecated in favor of UnsafeWorldCell::get_non_send.UnsafeWorldCell::get_non_send_resource_by_id is deprecated in favor of UnsafeWorldCell::get_non_send_by_id.UnsafeWorldCell::get_non_send_resource_mut is deprecated in favor of UnsafeWorldCell::get_non_send_mut.UnsafeWorldCell::get_non_send_resource_mut_by_id is deprecated in favor of UnsafeWorldCell::get_non_send_mut_by_id.World::init_non_send_resource is deprecated in favor of World::init_non_send.World::insert_non_send_resource is deprecated in favor of World::insert_non_send.World::remove_non_send_resource is deprecated in favor of World::remove_non_send.World::non_send_resource is deprecated in favor ofWorld::non_send.World::non_send_resource_mut is deprecated in favor of World::non_send_mut.World::get_non_send_resource is deprecated in favor of World::get_non_send.World::get_non_send_resource_mut is deprecated in favor of World::get_non_send_mut.Before using components and resources they must be registered to a world.
The registration process for components and resources is very similar and now that Send resources are components, we're able to simplify some of the code; removing / deprecating some methods.
Components::register_resource_unchecked is renamed to Components::register_non_send_unchecked.Components::get_valid_resource_id was deprecated in favor of Components::get_valid_id.Components::valid_resource_id was deprecated in favor of Components::valid_component_id.Components::resource_id was deprecated in favor of Components::component_id.ComponentsRegistrator::register_resource is deprecated in favor of ComponentsRegistrator::register_component.ComponentsRegistrator::register_resource_with is renamed to ComponentsRegistrator::register_non_send_with.ComponentsRegistrator::register_resource_with_descriptor is removed in favor of ComponentsRegistrator::register_component_with_descriptor.ComponentsQueuedRegistrator::queue_register_resource_with_descriptor was removed in favor of ComponentsQueuedRegistrator::queue_register_component_with_descriptor.ComponentsQueuedRegistrator::queue_register_resource was deprecated in favor of ComponentsQueuedRegistrator::queue_register_component.ComponentDescriptor::new_resource was deprecated in favor of ComponentDescriptor::newComponentDescriptor::new_resource was deprecated in favor of ComponentDescriptor::newWorld::register_resource_with_descriptor was renamed to World::register_non_send_with_descriptor.Resources were also removed from Access, which keeps track what data any given query / system has access to.
Access::add_component_read and Access::add_resource_read were deprecated in favor of Access::add_read.Access::add_component_write and Access::add_resource_write were deprecated in favor of Access::add_write.Access::remove_component_read was deprecated in favor of Access::remove_read.Access::remove_component_write was deprecated in favor of Access::remove_write.Access::has_component_read and Access::has_resource_read were deprecated in favor of Access::has_read.Access::has_any_component_read and Access::has_any_resource_read were deprecated in favor of Access::has_any_read.Access::has_component_write and Access::has_resource_write were deprecated in favor of Access::has_write.Access::has_any_component_write and Access::has_any_resource_write were deprecated in favor of Access::has_any_write.Access::read_all_components was deprecated in favor of Access::read_all.Access::write_all_components was deprecated in favor of Access::write_all.Access::read_all_resources and Access::write_all_resources were removed.Access::has_read_all_components was deprecated in favor of Access::has_read_all.Access::has_write_all_components was deprecated in favor of Access::has_write_all.Access::has_read_all_resources and Access::has_write_all_resources were removed.Access::is_components_compatible was deprecated in favor of Access::is_compatible.Access::is_resources_compatible was removed.Access::is_subset_components was deprecated in favor of Access::is_subset.Access::is_subset_resources was removed.Access::resource_reads_and_writes, Access::resource_reads, Access::resource_writes were removed.Access::try_iter_component_access was deprecated in favor of Access::try_iter_access.FilteredAccess::add_component_read was deprecated in favor of FilteredAccess::add_read.FilteredAccess::add_component_write was deprecated in favor of FilteredAccess::add_write.FilteredAccess::add_resource_read and FilteredAccess::add_resource_write were removed.FilteredAccess::read_all_components was deprecated in favor of FilteredAccess::read_all.FilteredAccess::write_all_components was deprecated in favor of FilteredAccess::write_all.FilteredAccessSet::add_unfiltered_resource_read was deprecated in favor of FilteredAccessSet::add_resource_read.FilteredAccessSet::add_unfiltered_resource_write was deprecated in favor of FilteredAccessSet::add_resource_write.Due to the split storage it used to be possible to both access an entity and a resource in a WorldQuery implementor.
This is no longer valid. In order to access multiple different entities for a WorldQuery implementation, use WorldQuery::init_nested_access.
See the implementation of WorldQuery for AssetChanged for an example of how this can be done correctly.
Since resources may now be immutable, the following now carry a Mutability = Mutable bound:
ResMutWorld::resource_mut, World::get_resource_mutUnsafeWorldCell::get_resource_mutEntityWorldMut::resource_mut, EntityWorldMut::get_resource_mutDeferredWorld::resource_mut, DeferredWorld::get_resource_mutTemplateContext::resource_mutExtractResourcePluginIf you are calling these in a generic context and the resource is always mutable, you need to add this bound to your type parameter:
// 0.18
fn my_generic_system<R: Resource>(mut res: ResMut<R>) {
…
}
// 0.19
fn my_generic_system<R: Resource<Mutability = Mutable>>(mut res: ResMut<R>) {
…
}
If the bound cannot be added, there are a couple of options:
World::modify_resource and World::modify_resource_by_id. They behave exactly like their component counterparts.UnsafeWorldCell::*_assume_mutable methods and make sure that the safety conditions are satisfied. UnsafeWorldCell::get_resource_mut_assume_mutable has been provided for this explicit purpose. It is also possible to use the *_assume_mutable component methods, but you will first have to retrieve the resource entity from ResourceEntities.Since MapEntities is implemented by default for components, it's no longer necessary to add derive(MapEntities) to a resource.
// 0.18
#[derive(Resource, MapEntities)]
struct EntityStruct(#[entities] Entity);
// 0.19
#[derive(Resource)]
struct EntityStruct(#[entities] Entity);
Next, World::clear_entities now also clears all resources, and World::clear_all now clears all entities, resources, and non-send data.
Lastly, World::remove_resource_by_id now returns bool instead of Option<()>.