Skip to content

Contributor guide for feature flag usage #20867

@atlv24

Description

@atlv24

#20714 triggered some discussion about how we should approach features in bevy. There was some disagreement, and ive been thinking more about it and now believe we can reach an agreement. Proposal for a path forward:

  • bevy_* crates always only enable the crate they are named after and any transitive bevy_* crate dependency features. This means enabling bevy_mesh will enable bevy_image, because it has a non-optional dependency on it. This means that if you have a no-default-features bevy with only bevy_mesh feature enabled, you can still import bevy::image, even though bevy_image is not enabled. I think this makes sense, because bevy_image is needed to talk about bevy_mesh atm, so having it easily importable is good.
  • cross-crate features like gltf animations, which need both bevy_gltf and bevy_animation to work, never enable crate features. They are declared in feature_name = ["bevy_crate?/feature_name"] form, and propagated down to all relevant crates. This means we can have them all in default-features, and when a user wants to "remove" a default crate they can easily copy paste the feature list and just delete the crate-name features bevy_* which they do not want, without worrying about which other features are enabling these.
  • cross-crate features never start with bevy_. (i.e. no bevy_ui_picking_backend feature, as thats not an actual crate)
  • cross-crate features between bevy_crate1 and bevy_crate2 are named crate1_crate2, in the order that most makes sense, when possible. (lets call it ui_picking instead of bevy_ui_picking_backend, and gltf_animation instead of animation)
  • cross-crate features are granular if they can work in isolation: we can make feature groups at a higher level out of more granular features, but not the other way around. (i.e. no picking feature, but yes ui_picking, and we can have a reflect feature which enables a group of more granular reflect_ecs, reflect_camera etc. features, each of which do not force-enable any crates besides bevy_reflect thanks to ? feature syntax. note there is no bevy_reflect feature currently, it is always enabled)
  • cross-crate features need not propagate to identically-named features: for example reflect_ecs enables bevy_ecs?/bevy_reflect. There is no reflect_ecs feature on bevy_ecs, as that would be redundant and hurt single-crate UX.

Adopting this pattern means we need to rename a few features and add a few features:

  • animation becomes gltf_animation
  • bevy_ui_picking_backend becomes ui_picking
  • bevy_mesh_picking_backend becomes mesh_picking
  • bevy_sprite_picking_backend becomes sprite_picking
  • we add sprite_text, sprite_render_text, ui_text, ui_render_text, for gating bevy_text support on each of bevy_sprite, bevy_sprite_render, bevy_ui, bevy_ui_render
  • pbr_gizmos, sprite_gizmos features for gating bevy_gizmos support on bevy_pbr and bevy_sprite
  • potentially a few more such as discussed in make bevy_mesh optional for bevy_animate #20742
  • a new reflect feature which enables a feature group of reflect_* features such as reflect_ecs = ["bevy_ecs?/bevy_reflect"], reflect_app = ["bevy_app?/bevy_reflect"] etc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-Cross-CuttingImpacts the entire engineC-Code-QualityA section of code that is hard to understand or changeC-DependenciesA change to the crates that Bevy depends onC-DocsAn addition or correction to our documentationS-Needs-DesignThis issue requires design work to think about how it would best be accomplished

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions