Open krispya opened 1 month ago
My preferred approach would be to go for symmetry and enable bulk operations in all contexts. Examples:
isGold = trait();
// ------------------------------------------------------------------
// adding with `...trait[]` arg
myEntity.add(Contains(isGold));
// translates to
world.query(isGold).forEach(goldEntity => myEntity.add(Contains(goldEntity)))
// ------------------------------------------------------------------
// removing with `...trait[]` arg
myEntity.remove(Contains(isGold));
// translates to
world.query(isGold).forEach(goldEntity => myEntity.remove(Contains(goldEntity)))
// ------------------------------------------------------------------
// querying for a relation with `...trait[]` arg
world.query(A, Contains(isGold))
// translates to (pseudo code implementation)
containsGold = world.query(Contains(isGold))
world.query(A, Contains("*")).filter(e => containsGold.some(e2 => e2 === e.targetFor(Contains)))
This looks good to me. My monkee brain understands what is being expressed in each case.
When using relations in a query you can query for a specific target:
Or a wildcard, which matches any entity targeted by that relation:
The feature request is to extend this by passing traits which filters by any entity that is a target of the relation and also has the matching traits.
Challenges: We are currently using the same API for both adding relations as traits and querying entities. This mixes concerns in a way that feels unsafe. Either strong typing needs to address this or there needs to be some symmetry between adding relations and querying them.