Skip to content

One Ring to Find Them

Neofox: floof_mug MMMH, REAL CODE

This RUNS! Playful premises aside, this is a functioning showcase of fennecs principles.

Get comfy, grab a cup of Java CoffeeScript Visual J# whatever, and get your paws dirty playing around in the code! It's good fun!

All .csproj and .cs files are over here on Github!

Premise

In this example, we'll recreate the forging of the Rings of Power in the Land of Mordor, as told in the legendary story.

We'll use the Object Link system to model the binding relationship between the One Ring and the other Rings it rules.

First, we group spawn Entities for each of the other Rings and its Bearer, and link all of them to our singleton instance of the One Ring.

Then, we bind them all in darkness with a Stream<>.For runner.

Recipe

cs
using fennecs;

if (!Console.IsOutputRedirected) Console.Clear();

var world = new World();

world.Entity() // Three Rings for the Elven-kings under the sky,
    .Add(new RingBearer("elven"))
    .Add(Link.With(OneRing.Instance)) // One Ring to rule them all,
    .Spawn(3);

world.Entity() //Seven for the Dwarf-lords in their halls of stone,
    .Add(new RingBearer("dwarven"))
    .Add(Link.With(OneRing.Instance)) // One Ring to find them,
    .Spawn(7);

world.Entity() //Nine for Mortal Men doomed to die...
    .Add(new RingBearer("human"))     // ("Human Rings"? I like it!)
    .Add(Link.With(OneRing.Instance)) // One Ring to bring them all, 
    .Spawn(9);

// Use our Palantir to find all Rings linked to the One Ring
var ringsOfPower = world
    .Query<RingBearer, OneRing>(Match.Plain, Link.Any)
    .Has(Link.With(OneRing.Instance)) // and in the darkness bind them.
    .Stream();

// Use the Query to corrupt the Ring Bearers
ringsOfPower.For((Entity ring, ref RingBearer bearer, ref OneRing link) =>
{
    bearer = bearer with { corrupted = true };
    link.CallOut(ring, bearer);  // it calls out to its master!
});

Console.WriteLine("\nDirected by: Peter Foxen");

// The Ring Bearer component represents the owner of a Ring of Power.
internal record struct RingBearer(string race, bool corrupted = false);

//But they were, all of them, deceived, for another ring was made!
internal class OneRing
{
    // Of course it's a GoF singleton! It's straight out of Mordor!
    public static readonly OneRing Instance = new();
    // No, we can't "make another", precious.
    private OneRing() { }
    // Sample interaction for linked Entities to use
    public void CallOut(Entity ring, RingBearer bearer)
    {
        if (bearer.corrupted)
            Console.WriteLine($"{ring} corrupted its {bearer.race} bearer!");
    } 
}
txt
E-00000001:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its elven bearer!
E-00000002:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its elven bearer!
E-00000003:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its elven bearer!
E-00000004:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its dwarven bearer!
E-00000005:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its dwarven bearer!
E-00000006:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its dwarven bearer!
E-00000007:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its dwarven bearer!
E-00000008:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its dwarven bearer!
E-00000009:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its dwarven bearer!
E-0000000a:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its dwarven bearer!
E-0000000b:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its human bearer!
E-0000000c:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its human bearer!
E-0000000d:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its human bearer!
E-0000000e:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its human bearer!
E-0000000f:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its human bearer!
E-00000010:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its human bearer!
E-00000011:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its human bearer!
E-00000012:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its human bearer!
E-00000013:00001 <fennecs.Identity>
  |-<RingBearer>
  |-<OneRing> >> O-<OneRing>#0202C666 corrupted its human bearer!

Directed by: Peter Foxen

In this example:

  1. We define the RingBearer and OneRing components to represent the bearers of the Rings and the power of the One Ring respectively.
  2. We refer to a singleton instnace of OneRing to represent the One Ring.
  3. We create Entities for each group of Rings (Elven, Dwarven, and Human) using the EntitySpawner, adding a RingBearer component and a Link to the One Ring for each.
  4. We create a Query to find all RingBearer Entities that are linked to our OneRing instance (the One Ring).
  5. We use the Query's For method to iterate over the linked Rings and corrupt their bearers, updating the corrupted flag in the RingBearer record.

This example showcases the expressive power of fennecs' Object Link system. By establishing Links from the Rings to the One Ring, we are able to easily query and manipulate all Entities bound to it. The One Ring's influence is modeled directly in the ECS architecture.

The use of records for the RingBearer component allows us to cleanly update the corruption status of each bearer in a single line of code within the For loop.


Congratulations!

Neofox: thumbsup ONE DOES NOT SIMPLY FINISH A TUTORIAL Neofox: evil

One For to bring them all, and in the darkness bind them

In the land of fennecs, where the foxes play.

fennecs is released under the MIT License. Neofox is released under the CC BY-NC-SA 4.0 License.