Skip to content

Paying a Visit to Old Friends

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

To settle an old score, we need to get even with five former friends Entities... we need to find those that wronged us, and wrong them right back in their face.

We create the Entities and define the Relation (struct Betrayed) they have with us, and also ours (struct Grudge) with them. We include a plain Component (struct Location) as useful data to everyone involved.

Next, we query for the Relation, say hello, and unalive interact with the Entities in a Stream<>.For. This removes our Grudge for them.

Recipe

cs
// KillBill.cs (type declarations at bottom of file)

using fennecs;

if (!Console.IsOutputRedirected) Console.Clear();
Console.WriteLine("Directed by: Trentin Quarantino");
var random = new Random(2003);

// The world is a stage. 
var world = new World();

// This is us. Here and now.
var us = world.Spawn().Add<Location>("here");

// Ok, let's maybe not spend 4 years in a coma!
// Thread.Sleep(TimeSpan.FromDays(365 * 4));

// They were five. This is how it went:
for (var i = 0; i < 5; i++)
{
    var them = world.Spawn()
        .Add<Location>("wedding chapel")
        .Add<Betrayed>(us);

    // And just in case, we will never forget.
    us.Add<Grudge>(them);
}

// We query for their Locations; to pay them a visit;
// and their Entity Id. It's a surprise tool that will help us later!
var betrayingVipers = world.Query<Location>()
    .Has<Betrayed>(us)
    .Stream();

Console.WriteLine($"As we said, there were {betrayingVipers.Count} of them.");

// They went into hiding around the world.
betrayingVipers.For((ref Location location) =>
{
    location = $"hideout 0x{random.Next():x8}";
    Console.WriteLine($"One hides in {location}.");
});

Console.WriteLine();
Console.WriteLine($"We are still {us.Ref<Location>()}, though.");

// Has<>(Match.Entity) is the same as saying HasRelation<>()
Console.WriteLine();
Console.WriteLine($"Do we hold grudges? {us.Has<Grudge>(Entity.Any)}.");
Console.WriteLine("This is us (and our grudges): \n" + us);

// Choose your weapon:
//    query.Despawn();
//    query.Truncate(0);
// -> visiting each entity personally
betrayingVipers.For((Entity them, ref Location theirLocation) =>
{
    Console.WriteLine();
    
    ref var ourLocation = ref us.Ref<Location>();
    ourLocation = theirLocation;

    // Knock knock.
    Console.WriteLine($"Suddenly, in {theirLocation}:");
    Console.WriteLine($"Oh, hello {them}!");
    Console.WriteLine("Remember us?"); 
    Console.WriteLine($"They do. They remember everything! " + 
                      $"They admit their Betral is {them.Has<Betrayed>(us)}!");
    
    // Get our revenge.
    them.Despawn();
});

world.GC();

// Survey the aftermath.
Console.WriteLine();
Console.WriteLine($"Now, there are {betrayingVipers.Count} of them.");
Console.WriteLine($"Let's get out of {us.Ref<Location>()}.");
us.Ref<Location>() = "traveling";

// We satisfied our grudges.
Console.WriteLine($"Any more grudges? {us.Has<Grudge>(Entity.Any)}.");
Console.WriteLine("This is us now:\n" + us);
Console.WriteLine($"We'll be {us.Ref<Location>()} for a while.");


# region Components
// "tag" (size-less) component, used here to back a Relation
internal struct Grudge;


// "tag" (size-less) component, used here to back a Relation
internal struct Betrayed;


// A Location Component wrapping a string.
internal readonly struct Location(string there)
{
    public static implicit operator Location(string location) => new(location);
    public override string ToString() => there;
}
# endregion
txt
Directed by: Trentin Quarantino
As we said, there were 5 of them.
One hides in hideout 0x12736da2.
One hides in hideout 0x4474dd11.
One hides in hideout 0x6ba4d3ab.
One hides in hideout 0x0acc04c4.
One hides in hideout 0x441796fe.

We are still here, though.

Do we hold grudges? True.
This is us (and our grudges): 
E-00000001:00001 <fennecs.Identity>
  |-<Location>
  |-<Grudge> >> E-00000002:00001
  |-<Grudge> >> E-00000003:00001
  |-<Grudge> >> E-00000004:00001
  |-<Grudge> >> E-00000005:00001
  |-<Grudge> >> E-00000006:00001

Suddenly, in hideout 0x12736da2:
Oh, hello E-00000002:00001 <fennecs.Identity>
  |-<Location>
  |-<Betrayed> >> E-00000001:00001!
Remember us?
They do. They remember everything!They admit their Betral is True!

Suddenly, in hideout 0x4474dd11:
Oh, hello E-00000003:00001 <fennecs.Identity>
  |-<Location>
  |-<Betrayed> >> E-00000001:00001!
Remember us?
They do. They remember everything!They admit their Betral is True!

Suddenly, in hideout 0x6ba4d3ab:
Oh, hello E-00000004:00001 <fennecs.Identity>
  |-<Location>
  |-<Betrayed> >> E-00000001:00001!
Remember us?
They do. They remember everything!They admit their Betral is True!

Suddenly, in hideout 0x0acc04c4:
Oh, hello E-00000005:00001 <fennecs.Identity>
  |-<Location>
  |-<Betrayed> >> E-00000001:00001!
Remember us?
They do. They remember everything!They admit their Betral is True!

Suddenly, in hideout 0x441796fe:
Oh, hello E-00000006:00001 <fennecs.Identity>
  |-<Location>
  |-<Betrayed> >> E-00000001:00001!
Remember us?
They do. They remember everything!They admit their Betral is True!

Now, there are 0 of them.
Let's get out of hideout 0x441796fe.
Any more grudges? False.
This is us now:
E-00000001:00001 <fennecs.Identity>
  |-<Location>
We'll be traveling for a while.

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