# It's All Components and Entities??
`flecs` treats virtually all of data used by the ECS in a single homogenous way: as components on entities. In Bevy terms, this means:
- the row-ish identifier is always `Entity`
- the column-ish identifier is always `ComponentId`
- no `bevy_ecs` code uses `TypeId`: it's all `ComponentId` (except when generating `ComponentId` for Rust types)
- each resource is an entity, with its data stored in a component
- each system is stored as an entity, with metadata and system state on components
- ordering constraints are stored as relations between systems
- executors query for entities and then run them
- metadata for each component, resource and event type is stored in the ECS, with each type getting its own entity
This path is appealing to many contributors and users of Bevy because:
- new features (hooks, observers, relations, debugging tools...) just work on all of these different types of data, without needing reimplementation
- less complexity, less maintenance burden, lower compile times
- the existing powerful ECS features can be used to build more ECS features faster and easier
- because we're using these ECS features to build more ECS features contributors will think of ways to improve them for all users
That's a compelling argument! But there are some drawbacks:
- new users may be confused about the different concepts and how they relate
- it may become harder to understand our APIs by reading type signatures
- semantic errors (e.g. passing a resource into a query) may not be enforced by the compiler, hurting new users and making refactors more painful
- we may lose performance due to the increased generality
- e.g. we can't assume at the type level that we only have one resource
## Rules
Let's see if we can come up with some rules for these changes that mitigate the drawbacks.
### Rule 0: different concepts get different names
If two things are used in different ways, they need distinct names, and documentation needs to consistently refer to them as distinct.
The fact that "resources are implemented using entities and components" or "each system is stored as an entity" is something we should explain to advanced users: not hide. But that doesn't mean "resources are entities (or components)" or "systems are entities"!
Advanced features are *built out of* simple ones.
### Rule 1: trait bounds must be semantically correct
If `trait NewEcsDataType: Component`, users should be able to interact with it as a component in every meaningful way, and things should Just Work. This trait bound implies that "all NewEcsDataTypes are also components": we need to keep this promise to users.
### Rule 2: Strongly typed common APIs, weakly typed internals
While strongly typed APIs and restrictive trait bounds are great for new users and refactoring, they can be quite limiting, both for power users and for dynamic types.
Most users and call sites should use strongly typed APIs that take real Rust traits with unambigious names and bounds added for correctness. These should be what we teach, and preferred wherever we don't explicitly need to be generic.
Under the hood though, these APIs should call (public!) untyped APIs to do the actual operation. These will accept and return `ComponentId` and `Entity`, which the higher level API will translate to / from the strongly typed forms.
This means that the deepest internals of the ECS should not have trait bounds, use `TypeId` or require that any of the data represent actual Rust types.
### Rule 3: newtype identifiers, but provide escape hatches
Whenever possible, high level APIs should provide and use wrappers over both `Entity` and `ComponentId`. These should be stored, accepted as arguments and returned wherever possible.
However, these should be simple tuple structs with public fields, allowing users to extend the existing functionality with ECS-backed features of their choice.
These newtypes help communicate intent and prevent confusing errors without restricting users or obscuring the implementation.
### Rule 4: ECS internals should be hard to accidentally interact with
Interacting with the ECS internals can have surprising, difficult to debug, and destructive results! Messing with component metadata, despawning systems, resetting system state: all extremely confusing for users!
While we *could* simply make them all inaccessible, power users will rightfully complain. Instead, they should be public, but impossible to *accidentally* hit.
## Groundwork
We may need some additional tools to make these unifications viable.
### Groundwork 0: relations
Many of the constraints that we want to model (schedules, system sets, system ordering constraints) are graph or tag-like. We need relations to make this migration not suck.
## Cleanup
Some existing parts of Bevy violate these rules!
### Cleanup 0: remove `Event: Component`
Unlike a hypothetical `Resource: Component` bound, this doesn't map to users' intuitions properly. Remove it in https://github.com/bevyengine/bevy/pull/17333
### Cleanup 1: split apart observer and queue-based events
These operate in extremely different ways, and using the same name and trait makes teaching and talking about these event-flavored constructs very hard.
## Unification
Finally, on to the meat of things. There will surely be
### Unification 0: resources as entities
Many features like hooks and observers work on resources, but not components. This is very annoying!
This should be a nearly full unification: the concepts and behavior will be distinct, but resource data will transparently be component data to users.
Details:
- each resource gets its own `Entity`
- resource data `T` is stored as a raw `T` component
- each resource entity has a marker types `IsResource` and `ResourceEntity<T>`
- the former is useful for inspectors and generic reasoning
- the latter is useful for enforcing uniqueness
- `ResourceEntity<T>` has an `OnInsert` hook that despawns any other existing `ResourceEntity<T>` entities, preserving global uniqueness
- dynamic resources get a `DynamicResourceEntity` component that uses a more expensive scan (or relies on an index)
- `trait Resource: Component`: everything that you can do with a component you should be able to do with a resource, but the reverse is not true
- queries operate on resources by default (no default query filters here)
- in most cases, this is a good default and allows users
- `type Res<T: Resource> = Single<&T, With<ResourceEntity<T>>`, and equivalently for `ResMut`
- painless migration!
- still type-safe!
This may cause complications with `NonSend` types: we should plan how we want to handle that.
### Unification 1: systems as entities
We already store one-shot systems and observers as entities: ordinary systems should be entities too.
The final implementation of this work will be relations-heavy, but we can move incrementally still. Schedules can store the metadata still, but point to system entities.
### Unification 2: queries as entities
Store your queries as entities too and you can update them using hooks and observers.
### Unification 3: component and resource types as entities
Rather than using a dedicated storage for this metadata, we can move it into the ECS proper.
Each component type should have its own `ComponentInfo` entity. Resources should refer back to these same entities, rather than storing it on the resource entity itself, to avoid it being despawned when removing the resource.
These are dangerous enough that they should be excluded via default query filters.
This work also enables us to further unify `ComponentId` to store an `Entity`. As explained in Rule 3, this should be a newtype, not a removal of `ComponentId`.