.NET Terrarium Version 2.0
Home | Usage Stats | Documentation | Charts |
 

Lab 1: Creating a Herbivore

Lab Objective 

The objective of this lab is to build a fully functional organism for Terrarium.  You will begin by creating a simple organism and then add more advanced functionality.  Once you are happy with the way it is performing, you can introduce it to the Terrarium Ecosystem and have it compete against other attendees’ organisms.

Exercise 1 – Create a Simple Herbivore

Create a Simple Herbivore

 

An animal is simply a class you write that derives from a special class (Animal) exposed by the Terrarium.  The code in this class gets executed by the game and controls the behavior and characteristics of your animal in the game.

 

In this exercise, you will create a simple Herbivore Animal in C#. You will use Microsoft Visual Studio .NET 2003 to create, compile, and run this lab.

 

Please substitute your name wherever you see the text <YOUR NAME> below since each animal introduced into the .NET Terrarium must have a unique name.

 

1.1  Create a new Terrarium Animal project in Visual Studio

·   Click Start->All Programs->Microsoft Visual Studio .NET 2003->Microsoft Visual Studio .NET 2003

·   Click File->New->Project

·   In the Project Types pane, click Visual C# Projects

·   In the Templates pane, click Terrarium Animal

·   Type <YOUR NAME> in the Name field.

·   Click OK

 

1.2  Add your name and email address to your animal. 

Update the AuthorInformation assembly attribute with your name and email address.

 

[assembly: AuthorInformation("Your Name", "someone@microsoft.com")]

1.3  Set the CarnivoreAttribute to false. 

The Carnivore attribute indicates that your animal is an Herbivore.  Set the CarnivoreAttribute to false.

 

  [Carnivore(false)]

 

1.4  Select an AnimalSkin for your animal. 

The AnimalSkin attribute defines what kind of creature your animal looks like.

 

[AnimalSkin(AnimalSkinFamily.Inchworm)]

1.5  Assign values to each of your animal characteristic properties.  The sum of the property values must not exceed 100.

 

[MaximumEnergyPoints(20)]

[EatingSpeedPointsAttribute(0)]

[AttackDamagePointsAttribute(12)]

[DefendDamagePointsAttribute(12)]

[MaximumSpeedPointsAttribute(16)]

[CamouflagePointsAttribute(10)]

[EyesightPointsAttribute(20)]

 

1.6  Add the targetPlant field to the MyAnimal class. 

Because your animal is a Herbivore, it eats plants.  targetPlant stores the reference to the plant your herbivore wants to eat.  Place this above the Initialize method.

 

// The current plant we're going after 

PlantState targetPlant = null;   

1.7  Subscribe to the IdleEvent. 

The IdleEvent is the last event fired on every turn.  This line tells the game engine to call the MyAnimal_Idle method each time the IdleEvent is fired.  Add the following line to the Initialize method.

 

Idle += new IdleEventHandler(MyAnimal_Idle);

1.8  Add the IdleEvent handler. 

This method provides most of the logic for your simple herbivore.  First, if your animal is ready to reproduce, it begins a reproduction cycle.  Next it attempts to eat.  If it already has a targetPlant, it walks to the targetPlant and begins eating.  If it doesn’t have a target plant, it tries to find one by scanning its surroundings.  Add the following two methods to the MyAnimal class.

 

// Fired after all other events are fired during a turn

void MyAnimal_Idle (object sender, IdleEventArgs e)

{

    try

    {

        // Reproduce as often as possible

        if (CanReproduce)

            BeginReproduction(null);

 

        // If we can eat and we have a target plant, eat

        if (CanEat)

        {

            WriteTrace("Hungry.");

            if (!IsEating)

            {

                WriteTrace("Not eating: Have target plant?");

                if (targetPlant != null)

                {

                    WriteTrace("Yes, Have target plant already.");

                    if (WithinEatingRange(targetPlant))

                    {

                        WriteTrace("Within Range, Start eating.");

                        BeginEating(targetPlant);

                        if (IsMoving)

                        {

                            WriteTrace("Stop while eating.");

                            StopMoving();

                        }

                    }

                    else

                    {

                        if (!IsMoving)

                        {

                            WriteTrace("Move to Target Plant");

                            BeginMoving(new MovementVector(targetPlant.Position, 2));

                        }

                    }

                }

                else

                {

                    WriteTrace("Don't have target plant.");

                    if (!ScanForTargetPlant())

                    {

                        if (!IsMoving)

                        {

                            WriteTrace("No plant found, so pick a random point and move there");

 

                            int RandomX = OrganismRandom.Next(0, WorldWidth - 1);

                            int RandomY = OrganismRandom.Next(0, WorldHeight - 1);

 

                            BeginMoving(new MovementVector(new Point(RandomX, RandomY), 2));

                        }

                        else

                        {

                            WriteTrace("Moving and Looking...");

                        }

                    }

                }

            }

            else

            {

                WriteTrace("Eating.");

                if (IsMoving)

                {

                    WriteTrace("Stop moving while eating.");

                    StopMoving();

                }

            }

        }

        else

        {

            WriteTrace("Full: do nothing.");

            if (IsMoving)

                StopMoving();

        }

    }

    catch (Exception exc)

    {

        WriteTrace(exc.ToString());

    }

}

 

// Looks for target plants, and starts moving towards

// the first one it finds

bool ScanForTargetPlant()

{

    try

    {

        ArrayList foundCreatures = Scan();

 

        if (foundCreatures.Count > 0)

        {

            // Always move after closest plant

            foreach (OrganismState organismState in foundCreatures)

            {

                if (organismState is PlantState)

                {

                    targetPlant = (PlantState)organismState;

                    BeginMoving(new MovementVector(organismState.Position, 2));

                    return true;

                }

            }

        }

    }

    catch (Exception exc)

    {

        WriteTrace(exc.ToString());

    }

    return false;

}

1.9  Subscribe to the LoadEvent. 

The LoadEvent is the first event fired on every turn.  This line calls the MyAnimal_Load method (defined in Task 1.7) each time the LoadEvent is fired.  Add the following line to the Initialize method.

 

Load += new LoadEventHandler(MyAnimal_Load);

1.10          Add the LoadEvent handler.

In the LoadEvent, your animal verifies the targetPlant still exists (it may have been teleported or eaten).  Add the following method to the MyAnimal class.

 

// First event fired on an organism each turn

void MyAnimal_Load(object sender, LoadEventArgs e)

{

    try

    {

        if (targetPlant != null)

        {

            // See if our target plant still exists (it may have died)

            // LookFor returns null if it isn't found

            targetPlant = (PlantState)LookFor(targetPlant);

            if (targetPlant == null)

            {

                // WriteTrace is the best way to debug your creatures.

                WriteTrace("Target plant disappeared.");

            }

        }

    }

    catch (Exception exc)

    {

        WriteTrace(exc.ToString());

    }

}

 

1.11          Build the animal DLL. 

Build the animal DLL by selecting Build | Build Solution

 

1.12          Introduce the Herbivore into the Terrarium in Terrarium Mode. 

Terrarium supports two game modes, Terrarium mode and Ecosystem mode.  In Ecosystem mode, your animal competes against animals submitted by other developers. 

 

Terrarium mode is the Terrarium test mode.  In Terrarium mode you can test your animal in a controlled environment.

 

Start the Terrarium by clicking Start->Programs->.NET Terrarium 1.2->.NET Terrarium 1.2.  The Terrarium 1.2 client will open in Ecosystem mode.

 

There are two modes that Terrarium 1.2 can run in.  The default is Ecosystem mode.  This is where everyone who is running the client in this mode participates together.  The peers will discover each other, teleport organisms to each other and report their statistics to the server.  This mode is the more interesting of the two.

 

The other mode is called Terrarium mode.  This is an “offline” mode that is perfect for testing your organisms.  In Terrarium mode, you are not communicating with other peers, so no teleportation occurs.  You also don’t report your statistics to the server.  You can save the state of the Terrarium whenever you like, create a new one to start fresh whenever, or open an existing one.  You can see how this mode really does aid in creating and testing your organisms.

 

For this exercise, we do not want to introduce the animal into the Ecosystem since the animal may not be advanced enough to survive long. Instead, we change into Terrarium mode and this allows you to test your animal before introducing it to the Ecosystem.

 

To switch to Terrarium Mode, click the New Terrarium button.  Enter Lab01 as the name and click Save.  This will restart the client in Terrarium mode.

 

New Terrarium

The next step is to add some plants into the Terrarium so that your Herbivore will have something to eat when it is introduced. To do that, click on the Add button, then click the Server List button and you will get a list of several animals that have already been introduced.

 

Add Animal

 

For the purpose of this lab, and as is usual in the real world, there are several plant species you can choose from. Simply select any of the species of Type “plant” and click OK. This will introduce 10 plants of the type you selected to the Terrarium.

 

 

Add several more plants by selecting the plant in the drop down box and clicking the Insert button so you have a lot of plants in the Terrarium.

 

Insert Animal

 

Finally introduce your animal. To do this, click on Add button click Browse and browse to the dll you created (<YOUR NAME>.dll). This dll will be located in the Bin folder of your project.

 

You should see 10 instances of your creature in the Terrarium.  To add more, you can use the Combo Box and Insert button like you did with the plants.

Note

The base characteristics of your animal can't be changed when the code is running -- capabilities characteristics like: how fast it can move, how well it attacks, how large it gets, etc.  These are defined on your animal by applying special attributes to the class you create.  You can see the list of available characteristic attributes in the Attributes section of the Organism Documentation.  Some characteristics require points to be applied to decide "how much" of them you get.  Each animal has 100 points to divide among these attributes.  So, for example, you could decide that your animal will be really fast by applying many points to the MaximumSpeedPointsAttribute, but it won't have good eyesight since you’ll have fewer points left to apply to the EyesightPointsAttribute.

 

Once you've defined the characteristics your animal will have, then you write code that controls the behavior of the animal.  Look at the methods, properties and events on the Animal and Organism classes (Animal derives from Organism) in the Organism Documentation to see what you can do in your code.  These methods define all the actions your animal can take.  Note that many of the method names start with "Begin...".  These methods are asynchronous.  When you call them, code execution will return immediately from the method.  When the action completes, the corresponding event will fire on your organism to tell you it is done.

Lab Summary

In this lab, you’ve created a simple Herbivore, tested it in your local Terrarium.


Exercise 2 – Handling an Attacked Event

 

In this hands-on lab you will use the event model of the Terrarium to handle an Attacked event.  An Attacked event is fired when you are attacked by another animal. This is just one of the many events that you can handle, to see the full list, refer to the Organism Documentation.

 

Please substitute your name wherever you see the text <YOUR NAME> below since each animal introduced into the .NET Terrarium must have a unique name.

 

2.1  Open the animal you created in Exercise 1 (Simple Herbivore)

  • Click Start->All Programs->Microsoft Visual Studio .NET 2003->Microsoft Visual Studio  .NET 2003
  • Select File | Open | Project.  This will open the standard file open dialogue.
  • Browse to the folder where you saved the project in Exercise 1.
  • Click the file named <YOUR NAME> and then click Open.
  • If the source file does not open in the main window, double-click the MyAnimal.cs icon from the Solution Explorer window. The source then opens in the main window

2.2  Subscribe to the AttackedEvent. 

The AttackedEvent is fired when your animal is attacked by another animal.  This line tells the game engine to call the MyAnimal_Attacked method each time the AttackedEvent is fired.  Add the following line to the Initialize method:

 

Attacked += new AttackedEventHandler(MyAnimal_Attacked);

2.3  Add the AttackedEvent handler. 

When your animal is attacked, it first tries to defend itself against its attacker.  It then tries to run away from the attacker by moving to a random location on the game board.  Add the following method to the MyAnimal class.

// Fired if we're being attacked
void MyAnimal_Attacked(object sender, AttackedEventArgs e) {
  if(e.Attacker.IsAlive)
  {
    AnimalState theAttacker = e.Attacker;
    BeginDefending(theAttacker); //defend against the attacker
 
    WriteTrace("Run away to some random point");
    int X= OrganismRandom.Next(0, WorldWidth - 1);
    int Y= OrganismRandom.Next(0, WorldHeight - 1);
    BeginMoving(new MovementVector(new Point(X,Y), 10));
  }
}
 

2.4  Rename and Build the animal DLL.

  • Select Project Properties.  This will open the Project Properties dialog.
  • In Common Properties | General, change the Assembly Name field to <YOUR NAME>_Ex2 and click OK.

·         Build the animal DLL from within the IDE by selecting Build | Build Solution

2.5  Introduce the Herbivore into the Terrarium in Terrarium Mode. 

 

Terrarium supports two game modes, Terrarium mode and Ecosystem mode. 

 

In Ecosystem mode, your animal competes against animals submitted by other developers. 

 

Terrarium mode is the Terrarium test mode.  In Terrarium mode you can test your animal in a controlled environment.

 

To switch to Terrarium Mode, click the New Terrarium button.  Enter Lab01 as the name and click Save.  This will restart the client in Terrarium mode.

 

New Terrarium

The next step is to add some plants into the Terrarium so that your Herbivore will have something to eat when it is introduced. To do that, click on the Add button, then click the Server List button and you will get a list of several animals that have already been introduced.

 

Add Animal

 

For the purpose of this lab, and as is usual in the real world, there are several plant species you can choose from. Simply select any of the species of Type “plant” and click OK. This will introduce 10 plants of the type you selected to the Terrarium.

 

 

Add several more plants by selecting the plant in the drop down box and clicking the Insert button so you have a lot of plants in the Terrarium.

 

Insert Animal

 

Finally introduce your animal. To do this, click on Add button click Browse and browse to the dll you created (<YOUR NAME>.dll). This dll will be located in the Bin folder of your project.

 

You should see 10 instances of your creature in the Terrarium.  To add more, you can use the Combo Box and Insert button like you did with the plants.

Lab Summary

 

In this lab, you’ve modified your Herbivore to be able to detect when it is being attacked and to respond to this attack.


Exercise 3 – Communication

 

In this hands-on lab you will use the animal’s Antenna property to communicate with other animals.  The state of the antenna is visible to all animals.  By changing the value of the antenna your animal can communicate with the other animals in the Ecosystem.  In this lab, you will update your animal to signal when another animal is blocking a target plant.  In response, the blocking animal will move out of the way, giving your animal access to the target plant.

 

Please substitute your name wherever you see the text <YOUR NAME> below since each animal introduced into the .NET Terrarium must have a unique name.

 

3.1  Open the animal you created in Exercise 1 (Simple Herbivore)

·         Click Start->All Programs->Microsoft Visual Studio .NET 2003->Microsoft Visual Studio  .NET 2003

·         Select File | Open | Project.  This will open the standard file open dialogue.

·         Browse to the folder where you saved the project in Exercise 2.

·         Click the file named <YOUR NAME> and then click Open.

·         If the source file does not open in the main window, double-click the MyAnimal.cs icon from the Solution Explorer window. The source then opens in the main window

3.2  Subscribe to the MoveCompletedEvent. 

The MoveCompletedEvent is fired when your animal has stopped moving.  This line tells the game engine to call the MyAnimal_MoveCompleted method each time the MoveCompletedEvent is fired.

Add the following line to the Initialize method:

 

MoveCompleted +=new MoveCompletedEventHandler(MyAnimal_MoveCompleted);

 

3.3  Add the MoveCompletedEvent handler.

There are two reasons an animal will complete its move event; the animal has reached its destination or its path is blocked.  If the animal’s path is being blocked, we want to signal the blocking animal to move out of the way.  The signal we use is the antenna value of 13.  Add the following method to the MyAnimal class.

// Fired when we've finished moving.

private void MyAnimal_MoveCompleted(object sender, MoveCompletedEventArgs e)

{

    // Reset the antenna value

    this.Antennas.AntennaValue = 0;

   

    // If we've stopped because something is blocking us...

    if (e.Reason == ReasonForStop.Blocked)

    {

        WriteTrace("Something's blocking my way.");

        if (e.BlockingOrganism is AnimalState)

        {

            AnimalState blockingAnimal = (AnimalState)e.BlockingOrganism;

            if (blockingAnimal.AnimalSpecies.IsSameSpecies(this.Species))

            {

                // Signal to our friend to move out of our way.

                WriteTrace("One of my friends is blocking my way.  I'll ask him to move.");

                this.Antennas.AntennaValue = 13;

            }

        }

    }

}

3.4  Add the logic to move out of the way when blocking our friends. 

On every turn, we need to look around for animals signaling they’re being blocked.  The ShouldIMoveForMyFriend method looks for animals signaling “13.”  If any are found, the animal moves out of the way of the blocked animal.  Add the following method to the MyAnimal class.

// Routine to move out of the way when blocking our friends.

void ShouldIMoveForMyFriend()

{

    try

    {

        ArrayList foundAnimals = Scan();

 

        if (foundAnimals.Count > 0)

        {

            foreach (OrganismState organismState in foundAnimals)

            {

                if (organismState is AnimalState)

                {

                    AnimalState visibleAnimal = (AnimalState)organismState;

 

                    // Only move if the animal is one of our friends (IsSameSpecies).

                    if (visibleAnimal.Species.IsSameSpecies(this.Species))

                    {

                        // If the animal's antenna value is 13, it means they're blocked (see the MoveCompletedEvent method).

                        if (visibleAnimal.Antennas.AntennaValue == 13)

                        {

                            // We're blocking our friend, so we should move.

                            WriteTrace("I'm blocking one of my friends.  I should move.");

 

                            int newX = this.Position.X - (visibleAnimal.Position.X - this.Position.X);

                            int newY = this.Position.Y - (visibleAnimal.Position.Y - this.Position.Y);

 

                            BeginMoving(new MovementVector(new Point(newX, newY), 2));

                            return;

                        }

                    }

                }

            }

        }

    }

    catch (Exception exc)

    {

        WriteTrace(exc.ToString());

    }

}

3.5  Call the ShouldIMoveForMyFriend() method at the end of each turn. 

At the end of every turn, we need to call the ShouldIMoveForMyFriend method to unblock any of our friends.  Since the IdleEvent is fired on each turn, add a call to the ShouldIMoveForMyFriend method at the end of the MyAnimal_Idle method.  Add the following method call as the last line of the MyAnimal_Idle method.

ShouldIMoveForMyFriend();

 

3.6  Rename and Build the animal DLL.

  • Select Project | Properties.  This will open the Project Properties dialog.
  • In Common Properties | General, change the Assembly Name field to <YOUR NAME>_Ex3.
  • Build the animal DLL from within the IDE by selecting Build | Make Solution

3.7  Introduce the Herbivore into the Terrarium in Terrarium Mode. 

Terrarium supports two game modes, Terrarium mode and Ecosystem mode. 

 

In Ecosystem mode, your animal competes against animals submitted by other developers. 

 

Terrarium mode is the Terrarium test mode.  In Terrarium mode you can test your animal in a controlled environment.

 

To switch to Terrarium Mode, click the New Terrarium button.  Enter Lab01 as the name and click Save.  This will restart the client in Terrarium mode.

 

New Terrarium

The next step is to add some plants into the Terrarium so that your Herbivore will have something to eat when it is introduced. To do that, click on the Add button, then click the Server List button and you will get a list of several animals that have already been introduced.

 

Add Animal

 

For the purpose of this lab, and as is usual in the real world, there are several plant species you can choose from. Simply select any of the species of Type “plant” and click OK. This will introduce 10 plants of the type you selected to the Terrarium.

 

 

Add several more plants by selecting the plant in the drop down box and clicking the Insert button so you have a lot of plants in the Terrarium.

 

Insert Animal

 

Finally introduce your animal. To do this, click on Add button click Browse and browse to the dll you created (<YOUR NAME>.dll). This dll will be located in the Bin folder of your project.

 

You should see 10 instances of your creature in the Terrarium.  To add more, you can use the Combo Box and Insert button like you did with the plants.

 

To test the new functionality, increase the population of your animal by clicking the Insert button.  Notice that when one of your animals is blocked from a food source, the blocking animal moves out of the way.

 

Lab Summary

 

Your Herbivores are now talking to each other.  You could now take communication and combine it with the attacked event logic.  Maybe you can have your herbivore signal to all of his friends that he is being attacked and they should all come and help.  Or they should all run away!


Exercise 3 – Introduction into the Ecosystem

 

In this hands-on lab, you will introduce your animal into the Terrarium Ecosystem. The Ecosystem is what makes the Terrarium such an interesting game. You get a chance here to match your animal making skills against others. If you run this on a machine on the Internet, the Ecosystem is the Internet and other any Terrariums on the Internet will be able to safely exchange Animals with your Terrarium.

Start the Terrarium by clicking Start->All Programs->.NET Terrarium 1.2->.NET Terrarium 1.2

The Terrarium will open in Ecosystem mode.

 

To introduce your animal into the Ecosystem, click on the Introduce Animal button,

 

Introduce Animal

 

Browse to the dll you created (<YOUR NAME>_Ex3.dll). This dll will be located in the Bin folder of your project. After selecting your animal, click Open, your animal will be introduced into the Ecosystem, you should be able to see 10 of your animals on the screen.

You can only insert an animal once into the Ecosystem, so make sure you’ve tested it thoroughly in Terrarium mode before introducing it.

Lab Summary

 

Your animal is now in the Ecosystem battling against dozens of other animals, where your coding skills will determine its fate!

 

 
 

.NET Terrarium 2.0 Server Updated 05/13/2008