bevyengine / bevyengine/bevy

ComponentInfo extensions

Open
#24,338 1 comment 0 reactions 0 assignees View on GitHub
A-ECS C-Feature D-Complex S-Needs-Goal
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 16h
Merged PRs (30d)
171

Description

## Problem

The behavior of components during some operations is defined through metadata that is stored in the `ComponentInfo` when it is registered with the application. This pattern comes up a lot (storage location, component mutability, cloning behavior, component hooks, required components, relationship details) and there's good reason why, because in effect it allows for handling trait-like polymorphism on an ECS level. The use of this pattern in the implementation of cloning (and in part relationships) specifically illustrates both why this type of behavior is necessary for those kinds of operations, and why it might be desirable for an end user to define similar behavior.

Cloning is a fundamental operation, but also an expensive one, so it's essential that _what_ gets cloned and _when_ is able to be controlled based on the specific use case. The current `EntityCloner` is pretty good in this regard as it takes an `EntityClonerFilter` from anything that implements `CloneByFilter`, but the filters are limited by only receiving the archetypes of the source and target entities and the identifier of the component type. This is fine if the cloner is only interested in including or excluding a static set of component types, but falls apart if new types implement `Component` and want to specify how that component should behave with that particular filter. That lack of specificity currently prevents the `EntityCloner` from being used in applications like rendering or serialization where partial snapshots of the world need to be made for a parallel task, but other crates may need to specify additional component types that are relevant to that task. This leads to patterns like `ExtractComponentPlugin` where a plugin has to be added to the application for every type that should be extracted by the renderer, or `RelationshipCloneBehaviorSpecialization` which once again defines how a relationship-type component should behave when cloned.

Once again, while cloning is a good example of where this used, this type of behavior is not limited to just cloning, has already been used internally to implement many recent features, and is necessary for implementing any kind of feature that defines interactions between types of components. A quick search of other feature suggestions reveals many ideas that, at a cursory glance, I imagine would also require the use of this pattern and the further extension of `ComponentInfo`. A non-exhaustive list includes: Mutually Exclusive Components (#23569) and similar features like kinded entities, Components as Entities (#23988) and similar features like resources and assets as entities, etc.

## Solutions

The solution is to expose some kind of API that allows for custom metadata to be stored as `ComponentInfo`. The scope of what this would look like it what I'm still uncertain about (especially in the context of other large ECS changes I know are coming). In the absolute most basic sense this could be achieved simply through a hook that runs when a `ComponentId` is registered for a given component type. With that alone it would be possible for each specific use case to manage its own store of metadata however it deems necessary, but again, this pattern is common (even just within Bevy itself) and most implementations are likely to have roughly the same set of concerns when it comes to storing and accessing that data so it's probably worth offering more support than just that. Admittedly, my knowledge on some of the finer implementation details of the ECS is limited, so this may be entirely impossible, but when I imagine how this could be achieved in the most maximal sense, my mind jumps to some kind of attribute/macro based solution to define extensions of `ComponentInfo` and then when types implement `Component` allowing them also define instances of those `ComponentInfo` extensions to be stored in the `ComponentInfo` for that `Component`.

Contributor guide

Open the contributing guide

Research direction

Start by reading the existing ComponentInfo and EntityCloner APIs, including CloneByFilter and the relationship-related behavior described in the issue. Compare those patterns with ExtractComponentPlugin and RelationshipCloneBehaviorSpecialization; done means defining and documenting an agreed approach for exposing custom component metadata, with its scope and integration points resolved.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
game-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.