Creating the Agent

Now that we know how classifiers work, we're ready to write our first line of code. The Banshee dolly isn't a Creature, doesn't have multiple parts (such as buttons), and you can't put things inside it, so it's what we call a "simple object". The CAOS Documentation tells us that the command to create a new simple object looks like this:

NEW: SIMP (command) family (integer) genus (integer) species (integer) sprite_file (string) image_count (integer) first_image (integer) plane (integer)

The (command) part tells us that the section before it, the bit that says "NEW: SIMP", is the command itself. "SIMP" is short for "simple object", which is the kind of object we want to create. So for the first line of our file, let's write that:

new: simp




We still need to give it a few properties it will use to make the agent. The other things listed on the line above are just placeholders for those properties, kind of like the blank spaces you see in a Mad Libs story. Let's take a look at them:


NEW: SIMP (command) family (integer) genus (integer) species (integer) sprite_file (string) image_count (integer) first_image (integer) plane (integer)

First, it wants the family, genus and species that the agent will use—its classifier, in other words. Each one of these placeholders is followed by (integer) to indicate that the value we put in needs to be an integer (a number). We already looked at classifiers in the last section, so we know the numbers we need to give it are 2 21 60659. Let's add that to our new: simp line in the CAOS Tool.

new: simp 2 21 60659




NEW: SIMP (command) family (integer) genus (integer) species (integer) sprite_file (string) image_count (integer) first_image (integer) plane (integer)

Now it wants the name of the sprite file. The (string) bit tells us that it is expecting a string, which is what we call content that isn't just a number—such as a word, a sentence, or in this case, a filename. Strings are always surrounded by double quotes.

I named my sprite file "bansheedolly.c16", but when listing filenames in Creatures you don't include the file's extension. So the value we need to put down (at least in my case) is "bansheedolly".

new: simp 2 21 60659 "bansheedolly"




NEW: SIMP (command) family (integer) genus (integer) species (integer) sprite_file (string) image_count (integer) first_image (integer) plane (integer)

"Image count" and "first image" are similar concepts.

The image count wants to know how many images the agent uses. In this case, the Banshee dolly uses 15 individual frames.

"First image" just indicates what is the first frame that the agent uses. It's asking because a sprite file can contain frames for multiple different agents, so the first frame for one agent might not be the first frame in the file. In this case, the sprite file is for this agent only. And if you look in SpriteBuilder, you will see that it starts counting at 0. So, we know that 0 is the number we add here.

new: simp 2 21 60659 "bansheedolly" 15 0




NEW: SIMP (command) family (integer) genus (integer) species (integer) sprite_file (string) image_count (integer) first_image (integer) plane (integer)

The last property is the agent's plane. The plane indicates how close the object will be to the foreground.

For reference, 0 is as far back as anything can go, while Creatures tend to have planes between 1000-6000, and Creature eggs around 5000. Overlays—scenery that appears in front of Creatures, such as archways—tend to have planes between 8000-8500.

I'm going with a value of 800, to make the Banshee dolly appear behind Creatures, since it's rather large. Keep in mind, though, that setting plane numbers is not an exact science and you're free to use whatever value you think looks good.


Having replaced all of the "placeholder" text with the correct values, we now have our first line of code, which should look something like this:

new: simp 2 21 60659 "bansheedolly" 15 0 800




Agent Properties

Now the game will know the basics about how to create the Banshee dolly: what classifier it uses and how to display it visually on the screen. But if we were to inject it now, all we would have would be a floating image. We need to tell it a little more information about what this agent is going to be like physically. Specifically, we need to address the following questions:

  • How does the world affect the object?
  • What can the player do to it?
  • What can Creatures do to it?
  • If it falls, how fast?
  • If it rests on the ground, will it pass through some kinds of barriers?
  • Is it slippery? Does it roll?
  • Does it bounce?

How does the world affect the object?
What can the player do to it?

Interactions between the agent, the world around it, and the pointer are determined by that agent's attributes (often abbreviated ATTR, after the command that is used to set them). What does the CAOS documentation have to say about ATTR?

ATTR (command) attributes (integer)

There's that (integer) bit again. Attributes are represented by numbers, but instead of setting each attribute separately, you combine the values of all the attributes you want the agent to have. There are a lot of possible attributes an agent can use, but for now I'll stick with the basic ones that are common to most agents:

# Nickname Does what?
2 "Mousable" The pointer can pick up the agent.
4 Activateable The pointer can click on the agent.
64 Suffer Collisions The agent reacts to room boundaries—it will bounce off the ceiling, walls and floor instead of passing through them.
128 Suffer Physics The agent falls with gravity. When you use this for an agent, be sure you use "Suffer Collisions" too, or else the agent will fall through the floor and vanish outside the metaroom!

When we combine 2 + 4 + 64 + 128 we get a sum of 198, so that is the number we use for our ATTR:

new: simp 2 21 60659 "bansheedolly"
attr 198




What can Creatures do to it?

How a Creature interacts with the agent is defined by the agent's behaviors, or BHVR, also named after the command that sets it. The BHVR command is very similar to ATTR: the numbers for different behaviors are added up to get the value you use for your agent. Some of the more common behaviors, which we'll be using for the Banshee dolly, are as follows:

# Script name Does what?
1 Activate 1 ("Push") Allows Creatures to push the agent.
2 Activate 2 ("Pull") Allows Creatures to pull the agent.
8 Hit Allows Creatures to hit the agent.
32 Pick Up Allows Creatures to pick up (and drop) the agent.

Our code should now look something like this:

new: simp 2 21 60659 "bansheedolly"
attr 198
bhvr 43




If it falls, how fast?

For agents that respond normally to gravity, the speed at which they fall is referred to as their acceleration, and it's set using the ACCG command. A value of 4 is pretty natural-looking for most objects. A value of zero means the object will just (usually) stay put in midair. Negative values will make the agent float upward like a balloon!


If it rests on the ground, will it pass through some kinds of barriers?

The ability to pass through barriers is known as permeability, which is set using the command PERM.

Basically, there are some parts of the ship where objects have the option of falling through the floor. A few examples are the apples in the Norn Terrarium, which fall through the treehouse floor and land on the ground below, or the Snotrock, which falls through elevator shafts even though Creatures don't. Values for PERM range from 0 (falls through all surfaces that allow it) to 100 (never falls through any surfaces).

I usually set PERM to 100 for agents just so that people can put them in treehouses if they want. You definitely want to make sure you set it to something, since the default value is 0.


Is it slippery? Does it roll?

The ability to slide or roll are handled by the same property, referred to as friction, set with the command FRIC.

"Sliding" in Creatures games can be considered any kind of movement that does not involve vertical hopping. A hedgehog ambling along or a ball rolling across the ground are both technically sliding, they just have animations that give them the appearance of moving in different ways. FRIC values also range from 0 (slides a lot) to 100 (never slides). A ball that rolls, or a wet bar of soap, would probably have FRIC set to 0. Agents you wouldn't expect to be slippery can have values ranging from 75-100, depending on the object type; sometimes skidding a little can make an agent look a little more realistic.


Does it bounce?

The last property we need to set is elasticity, set with ELAS, which handles bounciness. Again, a value of 0 means the object will basically never bounce, while a value of 100 means it will rarely stop bouncing.


When we add all our agent properties to the code, we should end up with something that looks like this:

new: simp 2 21 60659 "bansheedolly" 15 0 800
attr 198
*bhvr 43
accg 4
perm 100
fric 80
elas 10

Notice that I have put an asterisk (*) in front of the BHVR command. This symbol comments out the line in question, telling the game to pretend it isn't there. This is because we'll be injecting the agent into the world soon. We don't want the game to try to look for the dolly's scripts just yet, because we haven't written any.


Placing the Agent

If you were to try to inject the Banshee dolly right now, it wouldn't show up. That's because we haven't specified where in the world it should be injected.

The Creatures games use cartesian coordinates to describe where things are. The uppermost left corner of the world is considered position "0 0" (zero pixels from the left, zero pixels from the top) and any other location is measured by its horizontal and vertical distance from that point.

If you use the keystroke Ctrl + Shift + X, you will see two numbers appear next to your cursor. These numbers tell you the coordinates of the pointer's outstretched fingertip. This is an easy way to find the coordinates for any location in the game... just hover the cursor over that location and the numbers will tell you exactly what the coordinates are. Hitting Ctrl + Shift + X again will make the numbers disappear once you're done.

Useful note: when an agent is moved somewhere, the game doesn't center it on the coordinates provided—it moves the agent so that the upper left corner of the sprite is positioned there. So the whole agent will be slightly down and to the right of the point you specified.

Next we just need to know how to move the agent there. There are actually two commands we can use: MVTO and MVSF.

MVTO ("move to") is very exact in how it functions: it moves the agent right where you tell it to. But it will try to move it to that location even if doing so would put the agent halfway through a wall. This kind of thing will cause an error for most agents, so it's best to only use MVTO for ones that don't Suffer Collisions. The Banshee Dolly does, so MVTO is probably not appropriate.

MVSF ("move safely") will check to make sure the whole agent can fit in the space you're trying to put it in, and if there's a boundary intersecting that space, it will move the agent slightly to a "better" position. This is great because it prevents the kind of errors you might get with MVTO. I recommend using MVSF for any agent that does Suffer Collisions.

Both of these commands take the same variables: the horizontal and vertical coordinates, just like they appear next to the cursor. So if I were to move the Banshee dolly to the DS incubator area, I might use the command "mvsf 427 9245".

But where do we really want to put it? There are multiple places where you might want an agent to appear:

  1. Make it appear next to the Creator where it was injected.
    If your agent only works for Creatures 3 or Docking Station, but not both, then you're golden. All you need to do is use one of the commands listed above to put the agent somewhere in the vicinity of the game's Creator machine.

    If you want your agent to be able to inject into both games, it won't be quite so easy. There are multiple variables that are supposed to help you determine which game a person is using, or where the game's Creator is located, and a lot of tutorials will tell you to use one of those. It seems like an easy solution, but none of these variables are reliable across all versions of C3/DS. More users have switched to making their agents appear inside the inventory in order to get around this issue.
  2. Move it to some other location in the world.
    This is very straightforward, but I don't recommend making an agent appear away from the creator unless you really can't help it. Most people expect that when they inject an agent, it will appear somewhere they can see it. If it appears out of sight, say in another metaroom, they won't automatically know what has happened—they may assume it just didn't inject correctly.

    But what if, for example, you make an agent that's too big to fit next to the Creator? Or what if it's something that isn't supposed to be carried, like a new cheese machine in some other part of the ship? In cases like that, you can move the player to where the agent was injected to ensure that they see it. You can use the command CMRP to center the player's viewpoint on a certain set of coordinates. It takes coordinates just like MVTO, except it moves the player, not an agent.
  3. Make it appear inside the inventory.
    AquaShee introduced another alternative in his CAOS Chaos tutorials, which is to inject the agent straight into the player's inventory. This is one of the best possible places to put a new agent, since it ensures that wherever the player happens to be—even if they leave the Creator to go attend to their Creatures—the agent will be handed right to them. I'm not going to go into how the code works, because it's a bit more technical than we want to get into for our first agent. But the code to do it looks like this:

    seta va00 targ
    enum 1 2 11
    spas targ va00
    doif ov00 = 0 and clac = 0
    mesg writ targ 0
    endi
    next



    Of course, there are a few agents this method won't work for. Very large objects won't fit in the inventory, and some agents aren't meant to be picked up. But, those exceptions aside, it is usually the best option.
  4. Make it appear being held by the pointer.
    The final option is to make the pointer pick up the agent automatically, so that it appears to just poof into existence in the pointer's grasp. There aren't a whole lot of circumstances in which you'd want to do this instead of putting it in the inventory, but it is possible; that's how the Creatures Christmas stocking is injected, since it cannot be placed on the ground. The code to do this with your own agent looks like this:

    mesg wrt+ pntr 1000 targ null 0

In all cases, the code that moves an agent into the world should appear directly after the commands that control its properties. In most agents, that forms the end of the install script.

I plan on going the traditional route and injecting the Banshee Dolly into the inventory, so my finished install script looks like this:

new: simp 2 21 60659 "bansheedolly" 15 0 800
attr 198
*bhvr 43
accg 4
perm 100
fric 80
elas 10

seta va00 targ
enum 1 2 11
spas targ va00
doif ov00 = 0 and clac = 0
mesg writ targ 0
endi
next




Injecting the Agent

Now we get to see one of the best reasons to use the CAOS Tool: it makes it super easy to test .COS files in your game. Make sure your game is running, and that the steps outlined above (eg. turning Autokill off) have been followed.

Then, with your game ready and running and the .COS file open in the CAOS Tool, click the "Inject Install Script" button.

Congratulations! If everything has gone correctly, you now have a Banshee Dolly in your game. We can't do much to it right now since it doesn't have scripts yet, but we're off to an excellent start.


Removing the Agent

At this point, we could just hover the pointer over the dolly and use the "kill hots" cheat to remove it from the world. But as we begin adding scripts, we're going to want to be able to remove the scripts too—Creatures 3/Docking Station won't overwrite scripts that already exist in the scriptorium, so we have to remove them whenever we want to reinject them. So the next thing we're going to want to write is the Banshee dolly's remove script.

The remove script goes at the very bottom of the .COS file, underneath everything else. It begins with the line RSCR which tells the game, "everything from here on out is part of the remove script".

rscr

So what do we want our remove script to do? There aren't any event scripts for us to remove yet, but we can make it remove the Banshee dolly itself. To do that, we'll use a block called ENUM. ENUM enumerates through all agents of a given type: it seeks out each one, no matter where it is located in the world, and you get to specify what it does to those agents.

The ENUM command has a pretty simple format: it just says "ENUM" followed by the classifier of the agent it's supposed to look for. Below ENUM we write a line that says NEXT, which means "I'm finished with this one agent... let's find the next one on the list". Once it has gone through all the agents it can find, it will automatically move on to any code after the "NEXT" line.

Once we write the ENUM block, our remove script should look like this:

rscr
enum 2 21 60659
next

The only thing it needs to do when it finds a Banshee dolly is to delete the dolly. To do this we'll use the KILL command, just like when you "kill hots" an agent under the pointer. The Banshee dolly will be instantly removed from the world.

But we don't want to use HOTS because that only targets whatever is under the pointer when the code runs. If someone were removing the Banshee dolly using the Creator machine, the thing under the pointer wouldn't be the Banshee dolly—it would be the Creator machine!

So instead we're going to use a variable called TARG. When a chunk of code is targeting a specific agent, that targeted agent can be referred to using TARG. The ENUM block automatically sets TARG to the object it just found, so we can kill that object by writing "KILL TARG".

Our remove script should now look like this:

rscr
enum 2 21 60659
kill targ
next

You can now click the "Inject Remove Script" button on the CAOS Tool (or hit F12). Your remove script will run and the Banshee dolly will be removed from the world. Great!


Onward to Part 4!

Creatures is © Gameware Development. Breeders Beware is a non-profit fansite run by Ghosthande and is not affiliated with Gameware, nor intended to infringe upon their copyright in any way.