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.
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.
·
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
Update the AuthorInformation assembly attribute with your
name and email address.
[assembly: AuthorInformation("Your
Name", "someone@microsoft.com")]
The Carnivore attribute indicates that your animal is an
Herbivore. Set the CarnivoreAttribute to false.
[Carnivore(false)]
The AnimalSkin attribute defines what kind of creature your
animal looks like.
[AnimalSkin(AnimalSkinFamily.Inchworm)]
[MaximumEnergyPoints(20)]
[EatingSpeedPointsAttribute(0)]
[AttackDamagePointsAttribute(12)]
[DefendDamagePointsAttribute(12)]
[MaximumSpeedPointsAttribute(16)]
[CamouflagePointsAttribute(10)]
[EyesightPointsAttribute(20)]
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;
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);
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;
}
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);
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());
}
}
Build the animal DLL by selecting Build | Build Solution
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.
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.
In this
lab, you’ve created a simple Herbivore, tested it in your local Terrarium.
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.
- 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
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);
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));
}
}
- 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
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.
In this
lab, you’ve modified your Herbivore to be able to detect when it is being
attacked and to respond to this attack.
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.
·
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
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);
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;
}
}
}
}
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());
}
}
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();
- 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
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.
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!
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.
Your
animal is now in the Ecosystem battling against dozens of other animals, where
your coding skills will determine its fate!