-
Notifications
You must be signed in to change notification settings - Fork 26
Open
Description
Problem
Systems often use the same combination of traits. Repeating those combinations and calling entity.get(...) everywhere creates boilerplate and risks mistakes. Mature ECS ecosystems provide composite views (“aspects”) so systems work with one coherent object that exposes a set of required and optional components.
Proposal
Add an Aspect API to define composite views of traits:
// Define an aspect once:
const Transform = world.aspect({
read: [Position],
write: [Rotation],
optional:[Scale]
})
// Use it anywhere:
for (const t of Transform) {
t.rotation.angle += 0.01
if (t.scale) t.scale.s *= 1.001
}Semantics
- Entities appear in the aspect only if they have all read/write traits.
- optional traits are exposed as possibly
undefinedbut do not affect membership. - Exposed fields are direct references consistent with Koota’s mutation and change‑detection model.
Prior art (authoritative references)
- Unity DOTS Aspects (
IAspect): group several components into one strongly-typed struct for ergonomics and performance. - EnTT (C++): views/groups iterate composite sets (with excludes).
- Miniplex (TS): developer-friendly “with”-style iteration over entities possessing specified components.
Performance considerations
- Compile to tuple queries: aspects should internally compile down to the same optimized path as tuple queries (no extra
getper trait per entity). - Avoid per-entity object creation: aspect items should be lightweight views; if a wrapper object is needed, reuse a single ephemeral object per step and document lifetimes.
- Optional traits: retrieving optionals should be O(1) and ideally part of the selection plan rather than secondary lookups.
Edge cases to define
- Write permissions: only traits declared in
writeshould be mutable through the aspect; enforceable at the type level for TS users. - Aspect composition: if aspects can compose other aspects, avoid deep wrapper chains that degrade runtime performance.
- Change detection: clarify how writes via aspects interact with
changed()and any futureChanged<T>-style filters.
Related Koota discussion
verybomb and JohannesKlaussDisorrder
Metadata
Metadata
Assignees
Labels
No labels