Object Links
A special type of Relation is the Link, which associates a non-entity Object as the secondary key
in the Type Expression that forms the relationship.
As opposed to Entity-Entity Relations, Links use the Link's target as the backing data.
This allows us to group Entities by a non-Entity object, such as a string, a game engine's Node, or even an entire Physics Simulation they need to interact with.
Because the Link's target is the backing data, the Link resolves bidirectionally at enumeration time - the Entity that is linked to the object will have full access to the object (not just the "data" instead) - because the object is the data.
Creating & Removing Links
Bank chase = new("Chase"); // Bank is a class / reference
Bank targo = new("Targo"); // Bank is a class / reference
// Components can BE an object and be considered a Relation to that Object
// ... as opposed to just "having a bank: chase"
// bob has two Bank relations (each backed a reference to the object)
bob.Add(Link.With(chase)); // bob banks at chase (Type Bank->chase)
bob.Add(Link.With(targo)); // bob also banks at targo (Type Bank->targo)
Querying Links
// Specific link, fixed query
var customersOfChase = world.Query<Bank>(chase).Compile();
// Wildcard link, fixed query
var customersOfAnyBank = world.Query<Bank>(Link.Any).Compile();
// Wildcard target, specific exclusion, fixed query
var customersOfAnyBankExceptChase = world
.Query<Owes>(Link.Any)
.Not<Bank>(chase)
.Compile();
// All Entities, specific exclusion, fixed query
var entitiesExceptCustomersOfChase = world
.Query()
.Not<Bank>(chase)
.Compile();
// All Entities, wildcard exclusion, fixed query
var unbankedEntities = world
.Query()
.Not<Bank>(Link.Any)
.Compile();
// Wildcard target, specific exclusion, stream filter
var ent (itiseExceptCustomersOfChase = world
.Query<Bank>(Link.Any)
.Stream() with // do this on-the-fly where needed
{
Exclude = [Component.SpecificLink<Bank>(chase)]
};
Removing Links
bob.Remove<Bank>(chase); // bob no longer banks at chase
bob.Remove(chase); // type inference works here, too
Caveats
BEWARE of FRAGMENTATION
Use Object Links and Relations sparingly to group larger families of Entities. The difference to a reference type Component is that an entity can have any number of Object Links or Relations of the same type. This means that for n
different linked Objects or target Entities, up to n!
Archetypes could exist at runtime were you to attach all permutations of them to Entities at runtime.
Naturally, only Archetypes for actual constellations of Links and Relations on Entities will exist, so it is entirely up to your code. Great power, great responsibility.