COB Author’s Guide
by
Sandra J.G. Linkletter
Version 1.31(WIP), 12/NOV/97

Table of Contents

1. Introduction 
	Questions and Answers .....................................................................................  2
	Acknowledgments .............................................................................................  3
2. Creating Objects
	Properties of Objects ..........................................................................................   4
	Parts of  a COB File ..........................................................................................    5
	General Guidelines ............................................................................................   6
3. Examples
	Creating a Simple Object ..................................................................................    8
	Animating Objects ............................................................................................  15
	Moving Objects .................................................................................................  18
	Creating Compound Objects
		Ordinary Compound Objects ................................................................  20
		Lifts ........................................................................................................ 24
		Vehicles ...............................................................................................  24
		Blackboards .......................................................................................... 25
	Altering Existing Scripts ...................................................................................  27
	One-Shot Scripts ................................................................................................ 28
	Removing Objects and Their Scripts ..................................................................  29
4. Programmer’s-Eye View of Albia ................................................................................. 30

Diagram 1 Picture of Albia with Rooms and Ground Level
Appendix 1 List of Known Objects by Stefan Kuske
Appendix 2 CAOS Reference by Mark Ashton
Appendix 3 COE Documentation

Introduction 

Questions and Answers

What is a COB?

A COB is an “object” that can be injected into a world run by a program named Creatures.  Creatures is an event-driven, object-oriented environment.

What is an “object”?

An object is anything you see on the screen.  Even the background got there originally as an injected object, or set of objects.  We’re not sure just how at this point, but someone will figure it out.

How do objects enter Albia?

A COB injector is available from CyberLife.  COE (by Alexander Lämmle) can also inject objects.  There are other COB injectors available, but the author has no first-hand experience with these.

When do objects enter Albia?

The Object Injector from CyberLife only works when there are selectable creatures in the game.  This is because COBs can also be used to inject chemicals into creatures.  Therefore CyberLife’s Object Injector will only work if a creature is selected, in case your COB injects some chemicals when it is installed.  If chemicals are injected without a selected target, Creatures will crash.  

COE will inject COBs at any time.  This means that you must know whether or not any chemicals are injected by your COB when it is installed, and avoid doing that when you do not have a creature selected.

What makes up a COB?

A COB has at least one file, with the file extension COB.  If there are graphics involved, there will be a file with the file extension SPR.  If there is sound involved, there will be one or more WAV files.  COBs can share SPR files, so not every COB need have it’s own SPR file when it is distributed.   The same thing is true of WAV files.  SPR files must be placed in the Images subdirectory in order for Creatures to find them.  WAV files must be placed in the Sounds subdirectory.

What tools are available for writing COBs?

COE supplies the most complete set of tools.  There is a sprite file editor included.  Individual sprites can be exported as BMP files, for editing with other graphics tools.  BMP files can be imported from other sources, as well.  Starting with COE version 1.5, the palette of any imported BMP file will be translated into the palette for Creatures.  Earlier versions of COE require that the colors be selected directly from the Creatures palette with an eyedropper tool.  COE will allow you to save the palette as a BMP file.  Registered copies of COE allow the use of COS files, a format invented by Alex.  COS files contain the same text as COB files, but are in a much more readable format and can contain comments.  Unregistered copies of COE can only edit in COB format.  This is possible, but more difficult since there can not be any comments or line feeds in COB format.  This was the format in which CyberLife originally wrote their routines before Alex supplied them with ability to use the COS format.  COE is a shareware program.  Basic sprite editing and COB injection functionality is available in the unregistered version.  Registration at the time of this writing is $25 US, and can be paid by check, money order, or credit card through a 3rd-party payment processing service called Kagi.  Visit http://www.kagi.com/ for more information on Kagi.

What programming language is used to write COBs?

COBs are written in Creatures Agent/Object Scripting (CAOS).  This programming language was created by Steven Grand of CyberLife, and continues to evolve.  The routines are stored in ASCII format in world.sfc, and parsed by Creatures.  All tokens in CAOS are exactly 4 alphanumeric characters long.  Think of yourself as programming an HP desktop calculator from the mid-70’s, and you will be in the right frame of mind.  This big difference is that you are programming an object for an event-driven system.

How do I write a COB?

Read the rest of this document.

Acknowledgments

Thanks to:

Daniel Ashton for proof-reading.  Any remaining errors and omissions are my fault.
Stefan Kuske for his COB Class Summary.
Mark Ashton for his CAOS Reference.
Alexander Lämmle for COE.
Steven Grand and CyberLife for Creatures.

CyberLife® is a registered trademark of CyberLife Technology Ltd.
Creatures™, Albia™, Norn™ and Digital DNA™ are trademarks of CyberLife Technology Ltd

Creatures Object Editor © 1977 Alexander Laemmle

© Copyright 1997 Sandra J.G. Linkletter, except where noted as excerpted from other work.

Creating Objects

Properties of Objects

Objects are identified by three numbers.  These are called family, genus, and species.  It is better to think of them as simply parts of a hierarchical classification system rather than as the true Linnaean terms.  There is a fourth number used to summarize these three.  It is called class number.  It can be calculated the hard way, or gotten from the class calculator in COE.

Objects have attributes and behavior.  Attributes define whether the object falls or floats, whether it is restricted to one room, whether creatures can see it, whether it can be picked up and carried, etc.  Behavior defines other interactions which are allowed with the hand and with creatures.

Objects can have graphics.  All objects with graphics have at least one sprite.  Animation is accomplished with multiple sprites.  Sprites are uncompressed graphical data, containing color information which references a palette supplied by the program controlling the sprite.  A sprite file (SPR) may contain sprites for multiple objects, but an object cannot have sprites in more than one sprite file.

Objects can make sounds.  Sounds are played from WAV files.  There is one sound per WAV file.  An object may use as many WAV files as you desire.

Objects have position.  Location consists of  X and Y coordinates, and also depth in the picture.  This last coordinate is called “plane”.  X and Y can change during the lifetime of the object.  Plane cannot change during the lifetime of the object.

Objects have three general-purpose numeric variables which can be used to retain information for the lifetime of the object  (static variables).  These are obv0, obv1 and obv2, and they are left free for use by the programmer.  Other numeric variables relating to objects have a specific purpose and will be discussed later.

Objects have one general-purpose object pointer variable, objp, which is retained for the lifetime of the object.  This is left free for use by the programmer.  Other object pointers variables relating to objects have a specific purpose and will be discussed later.

Some objects, called compound objects, have separate parts.  There can be no more than 10 parts in a compound object, but all compound objects must have one part (part 0).  Compound objects have position only for their parts, and not for the parent object.  The parent object takes the position of part 0.  The positions of all other parts are relative to part 0.  Some compound objects have additional required structures, such as a cabin for vehicles and lifts, and word lists for blackboards.  Compound objects also have “hotspots”, representing control knobs for either creatures or the hand.  Without these, the object cannot be activated.  Compound objects cannot be picked up or dropped, although with a work-around the hand can relocate blackboards and ordinary compound objects.  Vehicles do not take kindly to this process.

Objects have scripts, which define how they are injected, and how they respond to events after injection.  These scripts make up the COB file.  A single set of event scripts for an object applies to all occurrences of that object in the game.

Parts of a COB File

COB files consist of one or more scripts.  Scripts for more than one object may be combined into one  COB file, although this is not recommended because of the potential confusion.  The exception is when the objects are designed to work together, as do Mark Ashton’s Hives and Bees.

All scripts possess 10 general-purpose variables which retain information only during the execution of the script (dynamic variables).  These are var0 - var9.  These variables are left free for the use of the programmer.

Injection Script

These define an object being injected, if any.  This script must exist, even if it injects no objects.  Injection scripts can be used to delete existing objects and scripts, to execute one-shot scripts such as stim statements, or as dummy headers to alter existing scripts without actually injecting any new occurrences of the object.  We’ll examine those uses later.

Event Scripts

These define what happens, if anything, when an object is subjected to events such as pushing, pulling, dropping, etc.

Extra Scripts

These define how a creature acts when it is doing those events.  This is what makes a creature take an appropriate pose for eating, when it eats an object.  It can also enforce the logic of the situation, causing items to be picked up before they are eaten.

General Guidelines

You must choose a Family, Genus, and Species for your object.  The choices for Family are as follows:

0 = Special/Override Objects
1 = System Objects
2 = Simple Objects
3 = Compound Objects
4 = Creatures

For practical purposes, you will be choosing between simple objects and compound objects.  If you are advanced enough to program a creature, you are probably not in need of this document.  System objects are background scenery.  Special objects are, well, special.

The choices for Genus, within Families 2 and 3, are as follows.  You will recognize the descriptions as the nouns which are learned by creatures.

Family 2 (Simple Objects)
Genus
1	hand
2	button
3	water
4	herb
5	egg
6	food
7	drink
8	vendor
9	music
10	animal
11	fire
12	comfort
13	toy
14	bigtoy
15	weed
Family 3 (Compound Objects)
Genus
1	mover
2	lift
3	computer
4	slides
5	bang

Your choice of Family and Genus should be based on some level of consistency within those groups.  A creature will think of your object in terms of all the other objects, in that family and genus, which it has seen before.  If you program a food item and class it with weeds, a creature will be likely not eat it.  Or the creature will eat it, and learn to eat the deathcap mushroom as well.  So try to be somewhat consistent in your choice of  Family and Genus.

Species number is less restricted, but has another potential danger for the programmer.  If you accidentally choose the same Family+Genus+Species for your item as is used by another item, you will wipe out the other item when your item is injected.  For example, Family 1, Genus 6, Species 3 is Carrots.  If you inject a COB for a new food which uses the same numbers, Carrots as we have known them will disappear forever from that copy of Albia.  The existing examples of Carrots will continue to look like Carrots, but will act like your new food object.  CyberLife is programming from Species 1, upward.  It would behoove us to stay out of their way.  The more prolific COB programmers have staked out small territories at higher Species numbers.  A table of the known objects is given in Appendix 1.

It is courtesy to include a remover COB with your objects.  The user needs a way to remove your COB in the unlikely event that he or she does not like it.  Even more important, if your COB for some reason does not work well with the user’s Albia and the only way to recover is to evacuate the planet and start over, then you will have lost a fan forever.  Try to give the remover COB a name that will indicate both that it is a remover and what it removes.  For instance, to remove Blue Cheese, make a Blue Cheese Remover COB, not Cheese Death or The Mouse.   Those are cute names, but not helpful to a user faced with a directory full of COB files.

Every COB should be distributed with a readme file, BUT . . .  it should not be named readme.txt.  Information text files should be named in keeping with the COBs to which they refer.  For instance, a text file issued with Rain Storm should be named something like rain.txt or storm.txt.  In the information text file include such things as the Family, Species and Genus of your object, any required SPR and WAV files, where the object appears and how it is used, and whether or not there can be more than one of  your object in Albia at the same time.  Remind users of where the SPR and WAV files go.  Include instructions on contacting you with the congratulations you will so richly deserve for your creation.

Examples

Creating a Simple Object 

Injection Script

For purposes of demonstration, let’s create the food called “Cheese”.  The Family, Genus, and Species for this item is already defined as 2 6 1.  The  “class” for cheese is calculated by filling in the numbers in this formula, in hexadecimal.

1st byte = Family
2nd byte = Genus
3rd byte = Species
4th byte = 0

02060100

Convert this to decimal, using the Windows Calculator, and you get 33947904.  Alternatively, you can use COE to get the same number.  The class is set to this number by the following statement.

setv clas 33947904

Now we need Attributes and Behavior for the cheese.  The choices for attributes are below.

Carryable                            creature can pick up obj	1	
Mousable - Right Click       user can pick up obj	2	
Activateable - Left Click    can be activated by user	4	
Container                            carries other objs (vehicles only)	8	
Invisible                              creatures can’t see it	16	
Floatable                             normally floating on screen	32	
Wallbound                          limits movement to current room	64	
Groundbound                     movement only limited by ground surface	128	
	
NOTE: Wallbound OR Groundbound, can’t be both.	
Table excerpted from Mark Ashton’s CAOS Reference

The sum of  the chosen attributes is used in the COB.  If we want our cheese to be able to be picked up by both the hand and the creatures, and to fall to the floor of the current room when dropped, then we add 64+2+1 and get 67 for the attributes.  The attributes are set to this number by the following statement.

setv attr 67

Creatures can “push”, “pull”, “get”, “drop”, or “stop” an object.  The ability to “get” (and therefore “drop”) an object is defined in the object attributes statement.  The object behavior statement defines the abilities to “push” (act1), “pull” (act2) and “stop” (deac) an object.

Left Click - user interaction	Touch - creature interaction	
0	clicks have no effect	0	creature can take no actions	
1	monostable: clicks activate, further clicks have no effect until object is inactive again.	1	act1	
2	retriggerable monostable: clicks activate even if already active	2	act2	
3	toggle: 1st click activates, 2nd deactivates again	3	act1 act2	
4	cycle: 1st click activate1, 2nd activate2, 3rd deactivate	4	deac	
		5	act1 deac	
		6	act2 deac	
		7	act1 act2 deac	
Table excerpted from Mark Ashton’s CAOS Reference

One number is chosen from each column.  We don’t want the hand to “eat” the cheese, so the first number is 0.  If we want “push” to mean “eat”, then we set the second number to 1.  Setting the second number to 2 would mean that the cheese would have to be “pulled” to be eaten.  Setting the second number to 3 would imply that we plan to have two different things happening with cheese, depending on whether the cheese is “pushed” or “pulled”.  The rest of the values are combinations including “stop” as a verb.  To keep our cheese consistent with the existing cheese, we set the second number to 1.  Behavior is set with the following statement.  Notice that no setv is used in this statement.  This is not consistent syntax, but it is correct in this instance.

bhvr 0 1

The cheese sprites are in the SPR file named “food.spr”.  There are 3 sprites for cheese, starting at offset 3, in food.spr. 

To set the position, we can either have the cheese appear somewhere in Albia, or we can have it appear in the hand.  We still need to choose a plane for the cheese.  Plane zero is the back of the display.  Items cannot be seen when placed on this plane.  Presumably they are under the background sprites.  Plane 9000 is the front of the screen.  Let’s choose 3500, arbitrarily.

Now we have all the required information for a simple object, to be created by the command 

new: simp spritefile numberimages firstimage plane clone

where 

spritefile is the name of the file containing the sprites for cheese (food),  numberimages is the number of sprites used for this object (3), firstimage is relative to the beginning of the file (3), plane is the plane of the object (3500) and clone refers to whether this object shares the spritefile with all others of the same type, or whether it uses a copy of the sprite file (0 = no).

Object creation scripts must always start with the command inst.  This command causes the entire rest of the script to execute without interruptions.  This is very important in an event-driven system.  Otherwise an event (such as pushing the object) might get processed before the object is fully defined.  If you are very lucky this will do nothing.  Sometimes it results in partially defined objects that do not function correctly.  Most likely it will lock-up or crash the game.

All scripts should end with an endm command.  Sometimes this is not strictly necessary.  Get in the habit, and you will be better off.  It will help to contain mistakes.  COE will not correctly compile COS code if there are missing endm statements.

We code this in the following manner, in COS format.

* Example Cheese
inst
new: simp food 3 3 3500 0
setv clas 33947904
setv attr 67
bhvr 0 1
mesg writ targ 8
edit
endm

COS format uses one line per expression.  Tokens within an expression must be separated by single spaces.  Leading spaces and tabs are ignored.  Comments are indicated by a leading asterisk.

In COB format this is 

inst,new: simp food 3 3 3500 0,setv clas 33947904,setv attr 67,bhvr 0 1,mesg writ targ 8,edit,endm

COB format uses either commas or spaces as delimiters between expressions.  There must be no spaces between the commas and the expression following, if commas are used.  Tokens within an expression must be separated by single spaces.  All characters must be in lower case.  If you do not have COE, you can actually code in COS format in Notepad, save the file, add the trailing commas, delete the linefeeds and tabs, and then use cut-and-paste to insert the now-COB-formatted text into another compiler.  This is a lot of work, but at least you will have a saved copy in a more readable format.

At this point we have not written any code for handling events which might happen to the cheese.  This code already exists in Albia, so we could inject this COB just as it is, and get a new piece of ordinary cheese.

We slipped one unexplained statement into that installation code.  That was mesg writ targ 8.  This statement tells the object that it is entering the game.  Like the final endm, mesg writ targ 8 is a good habit to learn.  It ensures that the object handler gets the object going, once you have placed it.  Other messages, which we will use later, are 0 = activate1, 1 = activate2 , 2 = deactivate, 4 = pickup, and 5 = drop.  Notice that the message numbers do not always correspond to the event numbers.  CAOS is a new language that has evolved under the guidance of a small group of people and is not as consistent as established languages, which may in their beginnings have been nothing to brag about themselves.

If we want the cheese to appear without the hand, we can replace edit with a positioning command.  

The code

inst
new: simp food 3 3 3500 0
setv clas 33947904
setv attr 67
bhvr 0 1
mesg writ targ 8
mvto 4080 895
endm

or

inst,new: simp food 3 3 3500 0,setv clas 33947904,setv attr 67,bhvr 0 1,mesg writ targ 8,mvto 4080 895,endm

creates a new piece of cheese in front of the lemon trellis.  The X,Y coordinates of points can be found on the map generated by COE.  The X and Y coordinates are those of the upper left-hand corner of your object, so take that into consideration when deciding on a location.

An object injected with a mvto statement may not look just right until it is picked up and dropped for the first time.  The default pose for a new object is pose 0.  This is the first sprite in the file at the location which you specified in the new: simp statement.  The new piece of cheese, for example, appears initially in the pose for being carried.  To correct that, the pose must be set to the sprite for a piece of cheese on the ground.  This is pose 2.

The code

inst
new: simp food 3 3 3500 0
setv clas 33947904
setv attr 67
bhvr 0 1
mesg writ targ 8
pose 2
mvto 4080 895
endm

or

inst,new: simp food 3 3 3500 0,setv clas 33947904,setv attr 67,bhvr 0 1,mesg writ targ 8,pose 2,mvto 4080 895,endm

will cause the cheese to look correct.  It is still floating slightly off the ground.  This is a matter of fine-tuning X and Y, which you can try on your own.  This is also the last section where I will be writing the scripts in both COS and COB format.  By now you should know how to make COB code from COS code, even if you do not have a registered copy of COE.

Event Scripts and Extra Scripts

There are several events for which a script can be written.  The most commonly used are listed below.

0	deactivate
1	activate1
2	activate2 
4	picked up
5	dropped
7	enter scope
9	timer

17	extra activate1
18	extra activate2
19	extra deactivate

All event scripts and extra scripts start with the symbol scrp, followed by the Family, Genus and Species of the object, followed by the event number.

Let’s continue our example of the standard cheese.  The code in world.sfc for cheese includes routines for “push”, “get”, and “drop”.  These are the three things creatures can do with cheese.   The script header for cheese which has been pushed is scrp 2 6 1 1.  That for cheese which has been gotten is scrp 2 6 1 4, and that for cheese which has been dropped is scrp 2 6 1 5.   The complete code, as seen in world.sfc, follows.

Script for Activate1

This routine makes a chewing sound, injects chemicals into the creature, causes the cheese to appear to be dangling, makes the creature drop the eaten cheese, and removes the cheese from Albia.

scrp 2 6 1 1
snde chwp
stim writ from 10 255 0 0 35 250 34 10 57 150 0 0
pose 0
targ from
drop
kill ownr
endm

The snde statement supplies the sound of chewing.  The sound made is in the file chwp.wav, under the Sounds subdirectory.  

The stim statement is complex.  The format is as follows.

stim delivery significance neuron intensity features chem0 qty0 chem1 qty1 chem2 qty2 chem3 qty3

Delivery can have one of the following values:  shou (every creature within hearing), sign (every creature who is looking), tact (every creature who is touching) ,or writ object  (only the creature specified by object as described next).  Object (only for writ) can have one of the following values: targ (the current focus of the script), ownr (the creature whose script this is), from (the creature who caused this script to run), or norn (the currently selected creature).  Significance is usually set to 0, meaning that the significance neuron is not stimulated.  Neuron is usually set to 255, meaning no sensory lobe neuron is stimulated by this command.  Intensity is usually set to 0, meaning that the neuron not being stimulated.  Since no neuron is selected, this really doesn’t matter.  The above three items will make more sense if you have the Genetics Kit, but it is not really necessary to use them at a beginning level.  Features is equal to 4 if the event is sensed even when the creature is asleep.  There are a only a few objects using this byte.  Finally, there are four pairs of chem and qty.  These must all be present even if  they are set to 0.  The chemicals are those listed in the Genetics Kit, and are referred to by  a number between 0 and 255.  The amounts may range from 0 to 255.

 The targ from statement changes the focus of the script to the object from which came the “push”.  For cheese that can only be a creature.  Drop tells the creature to drop the cheese.  This is not the same as invoking the “drop” script for the object.  It merely tells the creature’s brain that the object is gone from the creature’s grasp.  Kill ownr tells the object handler in Creatures to kill the process handling ownr, which is the object to which this script belongs.  In this case, that is a cheese.  Notice that you could make a terrible mistake by saying kill targ.  Since targ is set to from, you would kill the creature.  If the creature is a grendel, well and good.  Otherwise you have will have killed a norn.  Always be sure of where the object pointer targ is pointing before you use targ in a statement.  When a script opens targ  is by default pointing at ownr.

Script for Picked Up

This routine causes the cheese to appear to be dangling while being held.

scrp 2 6 1 4
pose 0
endm

Script for Dropped

This routine causes the cheese to lie flat on the ground, and makes a dropping sound.

scrp 2 6 1 5
snde drop
pose 2
endm

Script for Extra Activate1

Extra scripts are scripts that will be followed by creatures which are acting on the object.  Creatures have different pose definitions from objects.  The poses of each creature are defined by it’s genome.  The Genetics Kit from CyberLife can give you more information on this topic.  

This routine causes a creature who considering  “pushing” a cheese to first drop everything else.  The relative importance of picking up the cheese is 3, compared to doing anything else.   The next three commands tell the creature to aim for the spot at which the object can be pushed (the whole object in this case, since it is a simple object), approach the object, and touch it.  A small delay is introduced in order to allow the user to see what is happening.  The object (the cheese), referred to as _it_, is then sent a message telling it that it has been picked up.  The object pointer _it_ refers to an object that is the focus of a creature’s attention.  In other words, _it_ is the object in the Creature’s View bubble.  At this point, the “get” script for the cheese is executed .  Another delay is introduced, and then the creature takes up pose 73, which is an eating pose.  Another pause for admiration of the artwork, and then the cheese is told that it has been pushed.  The “push” script for the cheese is executed.  An extra sound command is given here, as well.  I assume that this was originally generic code for a creature eating things, before additional sounds were introduced in the food object scripts.  Pose 74 is another eating pose.  Pose 12 is a standing pose.  The cheese is then told it has been dropped.  The “drop” script for the cheese is executed.  The importance of picking up this cheese is now set to 0.  After a small pause, the done command tells the creature’s brain to find something else to think about.

scrp 2 6 1 17
drop
impt 3
aim: 0
appr
touc
wait 4
mesg writ _it_ 4
wait 10
pose 73
wait 5
snde chwc
mesg writ _it_ 0
pose 74
wait 7
pose 12
wait 4
mesg writ _it_ 5
impt 0
wait 20
done
endm

Although I have been flippant about the pauses in this script, there can be some real reasons for issuing wait commands other than simple aesthetics.  Each of the commands in an object’s script is being executed in a lower-level language, using OS calls and accessing hardware of  unknown speed.  Stability of a script can sometimes be improved by inserting a few pauses, especially where a succession of commands involving other objects (such as stim) are being given.

Animating  Objects

In this example we will examine an animated object, and also the use of  scripts 7 and 9 to remove it automatically after a period of time.  Our example is the Xmas tree from the CyberLife Xmas add-on.  This object is injected with the following routine.  Notice that the statements for setting attributes and behavior are missing.  These default to 0.  In this case that is what we want, since the Xmas tree does not interact with anything.

inst
new: simp holi 4 6 3500 0
setv clas 34341632
mvto 2675 803
sys: cmra 2200 724
mesg writ targ 8 
endm

The one new statement in this routine is the sys: cmra statement.  This statement moves the “camera” to the coordinates X=2200, Y=724.  The camera is what the user sees.  So the tree is injected, and the user’s view pans to the tree.  The camera is moved to a different set of coordinates from the tree because the coordinates of the camera are it’s upper left-hand corner, and we want the tree to be more or less centered in the user’s view.

The object initialization code, invoked when the object enters the world, is

scrp 2 12 03 7
tick 324000
anim [012R]
endm

Two statements here are new.  The statement tick 324000 sets the objects timer to “go off” every 324000 ticks.  Ticks are about 1/10th of a second.  324000 ticks is about 9 days.  At the end of 9 days (gametime), the timer script, script 9, will be called.

The tree is animated by the statement anim [012R].  The numbers correspond to the poses of the object.  If you recall from the cheese example, pose 0 is the first sprite belonging to the object.  The poses are numbered sequentially thereafter.  The R indicates that the object should repeat the cycle from the beginning, until told to do otherwise.  In the case of the Xmas tree, this results in twinkling lights.  If you think back to our first example of a cheese, this animation would result in spinning cheeses.  It will continue to do this until it is selected again, by some other script call, and told to stop repeating that animation cycle.  One could program an on/off switch for the Xmas tree by adding a “push” script for this object.

The timer code, invoked whenever the timer goes off, is

scrp 2 12 3 9
kill targ
endm

This removes the tree at the end of 9 days of displaying in the Albia.  If you only run Albia a few hours a day, this is a very long time!

We mentioned above the possibility of programming an on/off switch for the Xmas tree.  Let’s do that now.   We’ll use one of the object-specific variable, obv0, to keep track of whether the lights are on or off.  Obv0 equal to 1 will mean that the lights are on, and obv0 equal to 0 will mean that they  are off.  Script 7 needs editing to properly initialize obv0.

scrp 2 12 03 7
tick 324000
anim [012R]
setv obv0 1
endm

Next we write the script for switching the lights.  We’ll use script 1, and switch the lights by pushing.  To use a single script to toggle the lights, we’ll use a doif structure.  A doif structure is as follows.

doif test
	<code executed if test is true>
else
	<code executed if test is not true>
endi

where test is a comparison between two values.  In this instance the two values are the variable obv0 and the number 0.  That means the first part of the doif structure will execute if the lights are off.  The second part of the structure, the part after the else statement, will execute if the obv0 is not equal to 0.  When the lights are off, and the tree is pushed, the animation is started.  Obv0 is set to 1  to indicate that the lights are now on.  When the lights are on, and the tree is pushed. the animation is stopped by setting the tree to a fixed pose.  Obv0 is set to 0 to indicate that the lights are now off.  In either case, the special-purpose object variable actv is set to 0.  This signals to the system that the object is deactivated and ready for another push.  If this statement was left out, the tree would only respond once to a push and then become inert.

scrp 2 12 3 1
doif obv0 eq 0
	anim[012R]
	setv obv0 1
else
	pose 0
	setv obv0 0
endi
setv actv 0
endm

One more thing needs to be changed before this will work.  This object was defined with an attribute and behaviors all 0.  We need to add the following lines to the installation script, after the setv clas statement.

User can activate: setv attr 4
User can push only, creature can do nothing: bhvr 1 0

Thus:

inst
new: simp holi 4 6 3500 0
setv clas 34341632
setv attr 4
bhvr 1 0
mvto 2675 803
sys: cmra 2200 724
mesg writ targ 8 
endm

Moving Objects

The example here is the Xmas Reindeer.  First the object is created.  All of the statements in this injection script should be familiar by now.

inst
new: simp holi 10 15 3500 0
setv clas 34212608
mvto 3200 865
sys: cmra 2900 724
mesg writ targ 8 
endm

Now the Reindeer is initialized, animated, moved, and eventually destroyed all without ever leaving the initialization (#7) script.  Because script 7 is called each time Creatures is started, the portion of the code that is the “true” initialization is enclosed in a doif structure.  In this case the doif structure is lacking the else statement.  That means that nothing special is done if the doif test fails.  The object variables obv0 through obv2 are always zero when an object is created.  Therefore the first time into script 7 obv1 will be zero.  The code inside the doif sets obv1 to the initial position of the leftmost edge of the sprite.  This is 3200, according to the mvto statement in the injection code.  400 is then subtracted from obv1.  Similarly, obv2 is set to 400 plus the current position.  These become the left-hand and right-hand limits for the motion of the Reindeer.

Next we use three loop structures to move the Reindeer.  A loop structure is as follows.

loop
	<code executed>
untl test

where test is a comparison similar to that used in the doif structure.  Our outer loop uses obv0 gt 100 as the test.  Within this loop, two more loops move the Reindeer  first left, and then right, using the mvby statement.  The animation changes according to direction, from 0246 to 1357.   With each complete left-right motion, obv0 is incremented.  After 100 times through the outer loop,  a fourth loop moves the Reindeer rightwards and upwards until the top of the Reindeer sprite is nearly off the screen.  Then the Reindeer object is deleted.

scrp 2 10 11 7
doif obv1 eq 0
	setv obv1 posl
	subv obv1 400
	setv obv2 posl
	addv obv2 400
endi 
loop 
	pose 8 
	anim [0246R] 
	loop 
		mvby -8 0 
	untl posl le obv1 
	pose 8 
	anim [1357R] 
	loop 
		mvby 8 0 
	untl posl ge obv2 
	addv obv0 1 
untl obv0 gt 100 
anim [1357R] 
loop 
	mvby 8 -2 
untl post le 20 
kill ownr 
endm

An important thing to remember about loops is that they will execute continuously, as long as the object exists, until their end condition is satisfied.  This may be forever, and in fact can even be defined as such by using an ever statement instead of an untl test statement.  These loops time-share with all other processes in Albia, and can add substantially to the load on the processor.  Therefore, if you fill Albia with spinning whirly-gigs floating from one end to the other, do not be surprised if Creatures slows down.

Creating Compound Objects

This group includes ordinary compound objects, and special compound objects.  The special objects include lifts, vehicles, and blackboards.  A compound object must have at least one part, part 0.  If either the hand or any creatures are to interact with a compound object, it must have controls defined by spot and knob commands.

Ordinary Compound Objects

new: comp spritefile numberimages firstimage clone

Firstimage is relative to the beginning of the file.  If the images for the compound object begin at sprite number 5, then firstimage=5 for the new: comp statement.  Clone refers to whether this object shares the spritefile with all others of the same type, or whether it uses a copy of the sprite file.  This might be used if the sprite file is going to be changed by events during the lifetime of the object.  I do not know what commands would change it, but they are probably in the DDE family of commands about which I know nothing. 

new: part part# relativeX relativeY firstimage plane

There must always be a part 0, with relative X and Y of 0, 0.  Firstimage is relative to the firstimage for the compound object.  Let’s continue the above example where the images for the compound object begin at sprite number 5.  If part 0 uses the first image for that object then firstimage=0 for the new: part statement.  There can be no more than 10 parts, numbered 0 - 9, in one compound object.

spot spot# left top right bottom

Spot numbers range between 0 and 5.  It is not important that any particular spot number correspond to any one knob, but the areas cannot overlap.  Defining a spot with position values -1,-1,-1,-1 removes the spot.

knob knob# spot#

Knob numbers range from 0 to 5 and are very specific in meaning.

knob#	meaning
0	creature push
1	creature pull
2	creature stop
3	hand push
4	hand pull
5	hand stop

Defining a knob with -1 for the spot number removes the knob.

Example

As an example, let’s make the slide show that is in the theater in Albia.  We’ll give it a different number, so our practicing won’t blow up the good one.  First we create the compound object as before.  Part 0 is the image of the upright shaft of the projection screen, with the tripod base.

inst
new: comp auvi 22 0 0
new: part 0 0 0 0 500

So far we have a compound object that uses 22 sprites from the sprite filename auvi.spr, starting at the first sprite (offset=0), and it is not a cloned object.  The obligatory part number 0 is the first image in the file, placed at object-relative co-ordinates 0 0, and in plane 500.  There are three more parts to the slide show.

new: part 1 27 0 4 505

This is the screen, placed at object-relative coordinates 27,0.  The images start at offset 4 in the file named auvi.spr.  It is placed in plane 505, slightly in front of  Part 0.

new: part 2 0 43 1 515

This is the projector, placed at object-relative coordinates 0,43.  The images start at offset 1 in the file named auvi.spr.  It is placed slightly in front of Part 1, leaving room for the pictures.

new: part 3 39 27 12 510

These are the pictures projected by the projector onto the screen.  They are placed at object-relative coordinates 39,27.  The images start at offset 12 in the file named auvi.spr.  They are placed in plane 510, slightly in front of the screen, but behind the projector.

Now we have to define the spots and knobs.  We need three spots for the scripts for the slide projector.

spot 0 55 7 127 47
spot 1 7 47 47 63 
spot 2 55 99 127 127

For those three spots, we need six knobs.  That’s three for the creatures, and three for the hand.

knob 0 0
knob 1 1
knob 2 2
knob 3 0
knob 4 1
knob 5 2

The number we will give our Tutorial Slide Projector is 3 4 212.  This is in my range of object numbers, so I can do this without worrying.  The behavior is defined as single clicks for the hand, and all three actions (push, pull, and stop) for the creatures.  The attributes are defined only as mouse-clickable.  Of the other attributes, only invisible can apply to ordinary compound objects.  We certainly do not want our new slide show to be invisible to the creatures!  The new slide projector will be moved to the cellar, between the still and the shower.  Be sure to define all the parts before moving the object.  Otherwise only the parts defined before the move will appear where you want them to be.

setv clas 50648064
bhvr 1 7
setv attr 4
mvto 1480 950
endm

Now the scripts, just copied straight out of Albia for this example.

scrp 3 4 212 1
part 1
anim [01234567]
snde sprg
over
part 2
anim [12R]
part 3
pose 9
stim sign 64 9 255 0 34 30 43 30 0 0 0 0
endm

This script begins with an animation of the screen being pulled open, accompanied by a kind of “sproing” sound.  The over statement forces the script to wait until this animation is over before proceeding.  Then the slide projector begins an animation of a flickering beam of light.  After this animation has begun (it has an R in it, so it will continue without pause until future notice), the slide image itself takes on a pose of a circle of light, as from an empty slide holder.  A stim command is issued to all creatures watching the screen being opened.

scrp 3 4 212 0
part 3
pose 0
part 2
pose 0
part 1
anim [76543210]
snde sprg
endm

This script sets the slide image to a pose with no graphics, turns off the slide projector, and rolls up the projection screen with another “sproing” sound.  In this case there is no over statement after the screen animation because there is no code after it needing to be delayed.

scrp 3 4 212 2
part 3
doif pose eq 0
	part 1
	anim [01234567]
	snde sprg
	over
	part 2
	anim [12R]
	part 3
	pose 9
	setv actv 1
	stop
endi
snde whir
part 3
setv var0 pose
addv var0 1
doif var0 gt 9
	setv var0 1
endi
part 2
pose 0
part 3
pose 0
wait 5
part 2
anim [12R]
part 3
pose var0
setv actv 1
stim sign 64 9 255 0 34 60 43 60 0 0 0 0
endm

This script, which is triggered by clicking on the projector, first checks to see that the projection screen is open.  It does this by checking the pose of  part 3, the slide image.  If the slide image is dark, then the screne must be closed.  If  the projection screen is closed, we go through the entirety of the screen opening script.  We then exit the script using the stop statement.  If the screen is already open, then the slide show can begin.

The slide advance begins with a whirring sound.  Var0 is set to the pose of part 3, and then increased by one.  The value of var0 is then checked to see if it is greater than 9.  If it is then the slide carousel has gone full circle and the image must be set back to the circle of light from the empty slide holder.  This is done by setting var0 back to 1.  The projector and the slide image display a momentary darkness, and then the new slide is displayed with the pose var0 statement.   A stim command is issued to all creatures watching the slide show.

If you enter all of this into COE, compile it and inject it, you will have a working slide show in the basement for your private party entertainment.  But what if you decide you want to move it to the garden for an afternoon’s entertainment for the kids?  Compound objects can’t normally be moved.  However, with a small programming trick we can move this one.  This trick will also apply to blackboard, but NOT to vehicles or lifts.

The first thing we must do is expand one spot.  This is better done with a spot near the upper left-hand corner of the object.  That is because the object will automatically shift itself in the grip of then hand until it is in that position, and it is disorienting to have this happen when you have grabbed the middle of the bottom edge, for example.  We will expand spot 0.  Replace this

spot 0 55 7 127 47

with

spot 0 0 7 127 47

To the beginning of the script for pushing, scrp 3 4 212 1, add the following code.  The purpose of this code will be explained below.

doif from eq pntr
	targ pntr
	setv var0 posl
	targ ownr
	subv var0 posl
	doif var0 lt 55
		edit
		setv actv 0
		stop
	endi
endi

First, test to see if the cause (from) of this event is the hand (pntr).  If it is, then process this section.  Make the hand the target.  Get it’s X coordinate (posl).  Set the target back to the object whose script we are processing (ownr, which is the slide show in this instance).  Subtract it’s X coordinate from that of the hand.  If the hand is closer to the left-hand edge than 55 pixels, then we want to move the projector rather than open the screen.   The edit command you have seen before.  The last thing to do is to set the projector back to a deactivated state with the setv actv 0 command.   The stop command says we are done with the routine and do not want to continue processing the “push”.  Notice that if the hand is to the right of the 55 pixel mark, then the routine continues and the hand can still open the screen.

You now have a movable slide projector and screen.  You can only move it when the screen is closed, but that’s reasonable enough.  It cannot be programmed to allow creatures to move it because it is not a “carryable” object and cannot be made into one.

Lifts

new: lift spritefile numberimages firstimage

new: cbtn spritefile numberimages firstimage plane

cabn left top right bottom

Lifts are made up of one lift object, and one call button object per floor.  The lift must have a cabin.  How the call buttons are tied to the lift, I do not know.

NO EXAMPLE POSSIBLE WITHIN MY EXPERTISE.

Vehicles

new: vhcl spritefile numberimages firstimage

The definitions for these arguments are as for the ordinary compound objects described above.  There is no clone argument for a vehicle.   The rules for declaring parts, spots and knobs apply exactly as above.  In addition, a vehicle must have a cabin for the passengers.  This cabin must be large enough to hold a creature.

cabn left top right bottom

The arguments left, top, right, and bottom are relative to the upper left-hand corner of Part 0, just as for spots.  To pick up passengers, you must use the command gpas and to eject passengers you must use the command dpas.  There is a special method for picking up a particular passenger, using spas target.

Vehicles must not be moved with the edit command.  Bad things happen.  The contents are left behind, trapped, and cannot be released by dpas because they are now outside the limits of the cabin.  Vehicles can be moved with the following pair of commands.

setv xvec X
setv yvec Y

Finally, there is a special command for teleporters.

tele X Y

This command teleports the passengers of the vehicle to the coordinates X,Y.  I have never successfully used this command, although it is how the existing teleporter system works.  I suspect teleporters must be teamed up and that passengers must be teleported into the cabin of an activated member of the system.

Example

For our example I am going to make a duplicate of the boat, launching from the right-hand side of the island.  This is a simple vehicle with few working parts.  I am going, in fact, to simplify it still further from the existing Albian code because they needlessly duplicated part 0 with part 3.

First we build our boat.  Part 0 of the boat is the body with the paddlewheel.  Part 1 duplicates the left-pointing arrow, but is colored to indicate a lit button.  Part 2 duplicated the right-pointing arrow, and is also colored to indicate a lit button.  The sprites are in the file names boat.spr, a file which contains 10 sprites.  We will put the boat on ubiquitous plane 3500, and the lit buttons slightly in front of the ones built into Part 0.  Here, then, is the first part of the code.

inst
new: vhcl boat 10 0
new: part 0 0 0 0 3500
new: part 1 8 61 6 3505
new: part 2 136 61 8 3505

The class of the object will be set to correspond to an object with Family 3, Genus 1, and Species 210.  The attributes will be set to a “container” that can be activated by the hand.  The behavior will be set to “retriggerable monostable” for the hand, and “push” plus “pull” for the creatures.  “Retriggerable monostable” is an intimidating way of saying that even though I’ve just pushed it and it is still active, I can push it again and it will respond.

setv clas 50450944
setv attr 12
bhvr 2 3

The cabin is then defined.

cabn 25 0 100 135

Two spots are defined to correspond to the buttons.

spot 0 136 61 156 80
spot 1 8 61 28 80

Four knobs are defined, two for the creatures and two for the hand.  Although the creatures don’t really need extra spots because they can push or pull at will, it is more realistic to have separate knobs for these functions.

knob 0 0
knob 1 1
knob 3 0
knob 4 1

The boat is then put into the water.

mvto 7825 590

endm

Now, the guts of the object code.  Pulling the boat will result in movement to the left, since that spot is one the left-pointing arrow.  The first doif structure tests to see if the boat is already docked when the Pull button is pressed.  If so, then motion is stopped and the boat is set to inactive.

scrp 3 1 210 2
doif posl le 7825
	inst
	setv xvec 0
	setv yvec 0
	setv actv 0
	stop
endi

If the boat is not already docked, then the boat gathers up passengers, gives the creature who pressed the button a little shot of excitement (boredom decrease), lights up the left-pointing arrow, dims the right-pointing arrow, animates the paddlewheel, starts the paddlewheel sound, and sets the motion to -900 in the along the x-axis (left).

gpas
stim writ from 0 -1 0 0 43 30 0 0 0 0 0 0
part 1 
pose 1
part 2 
pose 0
part 0
anim [543210R]
sndl padl
setv xvec -900
setv yvec 0

A loop structure tests about once every tick for position of the upper-lefthand corner of the boat.  When that corner has moved to a position less than or equal to 7825 on the x-axis the sound is faded, then ended.  Both arrow buttons are dimmed.  The motion of the boat is stopped, and the passengers are released.

loop
	wait 1
untl posl le 7825
fade
snde pade
part 0 
pose 0
part 1 
pose 0
setv xvec 0
setv yvec 0
setv actv 0
dpas

Lastly, after a wait of about 300 ticks the boat is told to act as if it has had it’s Push button pressed.

wait 300
mesg writ targ 0
endm

Pushing the boat will result in movement to the right, since that spot is one the right-pointing arrow.  A  test for position is carried out as before, this time with respect to 8200.  The highest value possible for the x-axis is 8351, and we don’t want our boat to fall off  the edge of the world, numerically speaking.  The entire push routine is a mirror image of the pull routine.  This portion will pick up and drop off passengers out in the ocean, because of the wrap-around in the coordinate system which prevents this simple looping movement routine from continuing to the other shore.  More on this later.

scrp 3 1 210 1
doif posl ge 8200
	inst
	setv xvec 0
	setv yvec 0
	setv actv 0
	stop
endi
gpas
stim writ from 0 -1 0 0 43 30 0 0 0 0 0 0
part 2
pose 1
part 1
pose 0
part 0
anim [012345R]
sndl padl
setv xvec 900
setv yvec 0
loop
	wait 1
untl posl ge 8200
fade
snde pade
part 0
pose 0
part 2
pose 0
setv xvec 0
setv yvec 0
setv actv 0
dpas
wait 300
mesg writ targ 1
endm

These two routines make the creatures move appropriately for pressing the buttons.

scrp 3 1 210 17
impt 3
aim: 0
appr
touc
mesg writ _it_ 0
endm

scrp 3 1 210 18
impt 3
aim: 0
appr
touc
mesg writ _it_ 1
endm

Well, that boat is interesting and allows us to let our creatures play in the surf like little holy persons, walking on water.  But what if we wanted to go all the way to the opposite shore?  Let’s look at the right-hand limit.  We want to stop the boat the the watchtower.  The value of posl at that spot will be in the low hundreds.  If we substitute that in the first doif structure, the boat will stop before it has even begun to move!  What can we do?  What we do is add another doif structure, choosing a test point that is between the two ends of the ferry run outside of the boat’s path.  Changing the test to

doif posl gt 625
	doif posl lt 7600
		inst
		setv xvec 0
		setv yvec 0
		setv actv 0
		stop
	endi
endi

accomplishes our goal.  Likewise the movement loop must be adapted.  The following code will move the boat properly to the watchtower.

loop
	wait 1
	doif posl ge 625
		doif posl lt 7600
			setv obv0 1
		endi
	endi
untl obv0 eq 1

Obviously the routine for pulling must have mirror image changes.  Substitute 

doif posl le 7825
	doif posl gt 7600
		inst
		setv xvec 0
		setv yvec 0
		setv actv 0
		stop
	endi
endi

and

loop
	wait 1
	doif posl le 7825
		doif posl gt 7600
			setv obv0 1
		endi
	endi
untl obv0 eq 1

in the proper places.

Now the boat goes to the watchtower.  But wait!  Although dpas ejects the passengers to the nearest floor, there is no way to get into the boat at the watchtower.  Now what?  Now we add magic to out boat.  Change the y-axis motion statements immediately before each loop.  For pulling make the motion statements

setv xvec -900
setv yvec 50

and for pushing make the motion statements

setv xvec 900
setv yvec -50

Now our boat will fly.

Blackboards

new: bkbd spritefile numberimages firstimage backgroundcolor chalkcolor aliascolor textX textY

Spritefile is the file containing all of the sprites for this object.  Numberimages is how many sprites belong to this object.  Firstimage is the offset into the file, of the first sprite for this object.  Backgroundcolor, chalkcolor, and aliascolor are all one byte values from 0 to 255.  For the background I suggest using 0, which is invisible.  I suggest doing this because the blackboard text area has a ragged bottom edge that does not look good in visible color.  Another part behind the blackboard can supply the color.  Chalkcolor and aliascolor (color of the cursor) are a matter of taste and can be gotten by trial and error.  TextX and textY are the co-ordinates of the upper left-hand corner of the text area relative to the upper left-hand corner of the blackboard object.

bbd: word blackboardoffset creaturevocaboffset [word]

Blackboards can only hold 16 words each, with offset values from 0 to 15.  The current vocabulary of creatures is 80 words long, with offset values from 0 to 79.  These vocabulary positions correspond to specific area of the brain.  Offsets 0-15 are verbs.  Offsets 16-55 are nouns.  These nouns in turn correspond to specific object numbers.  Offsets 56-71 are drives.  Offsets 72-79 are special words.  I do not know if there is a length limit on the words.  The word must be enclosed in square brackets as shown. 

The word list for the computer in Albia is as follows.

bbd: word 0 9 [sleep]
bbd: word 1 74 [look]
bbd: word 2 1 [push]
bbd: word 3 2 [pull]
bbd: word 4 3 [stop]
bbd: word 5 72 [yes]
bbd: word 6 73 [no]
bbd: word 7 4 [come]
bbd: word 8 5 [run]
bbd: word 9 6 [get]
bbd: word 10 7 [drop]
bbd: word 11 75 [what]
bbd: word 12 10 [left]
bbd: word 13 11 [right]
setv obv0 0

An important point in the usage of blackboards is that the object variable obv0 always points to the word that will be displayed with the blackboard display or edit commands.  If you set obv0 to a value outside the range of 0-15 at any time, the blackboard object will crash.  Therefore if you are looping through a blackboard list, do not use obv0 as your counter.  The example loops below demonstrate the potential problem.

This WILL crash:

setv obv0 0
loop
	<do stuff with bbd>
	addv obv0 1
until obv0 gt 15

This WILL NOT crash:

setv obv1 0
loop
	setv obv0 obv1
	<do stuff with bbd>
	addv obv1 1 
until obv1 gt 15

bbd: edit action

Setting action to 1 turns on the editing.  Turning on the editing (unfortunately) deletes the word in order to free the area for typing.  Setting action to 0 ends the editing.

bbd: show action

Setting action to 1 displays the word on Part 0, starting at the co-ordinates set in the blackboard creation statement.  Setting action to 0 erases the word.

bbd: emit action

Setting action to 1 reads the word aloud to all creatures within hearing range.  The word appears in a speech bubble above the blackboard, to signify that the word has been read aloud by the blackboard to the creatures.  Setting action to 0 allows only those creatures who are looking at the blackboard to receive the word as input.  No speech bubble appears above the blackboard.  It is as if the creatures were reading silently, each for themselves.

Example

Let’s make an underground cave extension of the computer in Albia.  

7800,960

I AM SO TIRED OF BLACKBOARDS!!!!
Altering Existing Scripts

If you want to alter the behavior of an existing object, you can inject a new version of the script in question.  You must make a dummy injection routine to go with it.  The following pair of routines would change the sound that cheese makes when it hits the ground.

Injection

inst
endm

Event

scrp 2 6 1 5
snde bang
pose 2
endm

To examine existing scripts inside Albia, you can use COE.  You can also do it by hand with much patience.  The script numbers are present in reverse order in Albia, somewhat before the macro code itself.  You can read the macro code, since it is in ASCII.

One-Shot Scripts

One-shot scripts are most often used to inject chemicals into a creature.

Injection

inst
stim 0 255 0 0 240 255 241 255 242 255 243 255
endm

This injection will immunize a creature against the first four diseases in Albia.  Injections such as these are useful when you want to preserve a valued creature at all costs.  Just remember that by preserving a creature who may have a poor immune system you may be weakening your breeding stock.  This can be justified if the creature has other exceptional qualities that you want to preserve in spite of the other possible danger.

A more interesting project is the filling in of two of the three Black Holes in Albia.  In a later section the you can read about the rooms in Albia, and what the causes such things to a happen.  For now, just create the following script.

Injection

inst
room 23 6550 682 7160 701 1
endm

Injecting this will close the two Black Holes present at the ends of the docks at the Tree and on the left-hand side of the Island, which were caused by a misdefinition of room 23.

Removing Objects and Their Scripts

Objects should always be distributed with removers.  The remover should not only remove the object (or objects), but also all of the scripts associated with the objects.  This is done in the following manner, for our cheese sample.

Injection

inst
enum 2 6 1
kill targ
next
scrx 2 6 1 1
scrx 2 6 1 4
scrx 2 6 1 5
scrx 2 6 1 17
endm

The scrx statements must go last if you are removing multiple objects.  This might happen if you are removing a drink machine and all of it’s drinks, or an entire set of encyclopedia.

Programmer’s Description of Albia

Albia is a flat, rectangular world measuring 8352 x 1200.  There are 9000 visual layers in which objects can move.  The coordinate system runs from X=0, Y=0 in the upper left-hand corner, to X=8351, Y=1199 in the lower right-hand corner.  Layers are numbered 0 to 9000, from back to front.  0 is behind the background scenery and does not display.  The background scenery of Albia is formed of 58 columns of  8 sprites, each measuring 144 x 150 pixels.  These 464 sprites are in back.spr.

There are two sorts of physical constraints to falling in Albia.  These are groundbound and wallbound.  An object may be bound by the floor of a room (wallbound), or by the bottom of the world (groundbound), but not both.  There are also ground level points defined in Albia, but these must be invoked explicitly by the programmer.

There are 261 ground level definitions, of 32 pixels each in length.

These are summarized below.

X		Y
Begin	End
0	671	688
672	767	587
768	991	592
992	1023	591
1024	2783	590
2784	2815	600
2816	2847	648
2848	2879	696
2880	2911	720
2912	3007	736
3008	3039	760
3040	3359	921
3360	3423	923
3424	3551	925
3552	3647	927
3648	4255	929
4256	4639	760
4640	4767	928
4768	4959	927
4960	5023	799
5024	5279	671
5280	5311	703
5312	5343	727
5344	5855	927
5856	6079	664
6080	6143	672
6144	6271	680
6272	6335	684
6336	6559	692
6569	8351	694

Rooms are defined by 5 parameters.  These are left boundary, top boundary, Right boundary, bottom boundary, and room type.  Albia comes with  26 rooms numbered 0 through 25.  The parameters for these 26 rooms follow.  There is an error Room 15, generated I suspect by an attempt to close the Black Hole of the Sunken Statue.

Room	Left	Top	Right	Bottom	Type
0	701	453	1494	594	Indoors
1	810	683	1530	787	Indoors
2	760	310	1073	434	Surface
3	1635	234	2813	589	Surface
4	1255	987	3215	1097	Indoors
5	1731	802	2174	931	Indoors
6	2435	608	2967	738	Indoors
7	2242	757	6335	927	Surface
8	4527	944	5355	1099	Indoors
9	4211	367	6154	526	Surface
10	5919	544	6554	664	Surface
11	7157	542	7948	663	Surface
12	7158	343	7772	457	Surface
13	7602	731	8090	963	Indoors
14	1637	661	2177	787	Indoors
15	-1815	725	-1295	1138	Undersea
16	7178	751	7562	884	Indoors
17	652	865	1116	1101	Indoors
18	7560	988	8149	1095	Indoors
19	5879	966	6087	1142	Indoors
20	3271	970	4519	1146	Indoors
21	7818	679	8458	695	Surface
22	142	681	796	698	Surface
23	6599	682	7111	701	Surface
24	1529	854	1637	873	Surface
25	3259	1070	4507	1150	Indoors

There is attached a map of Albia to 1/4 scale (generated in COE) to which the existing rooms have been added in magenta, and the existing ground levels in chartreuse.

Rooms can be connected vertically, by lifts, or horizontally, by movers.  Teleporters supply spot-to-spot movement between rooms.  There is otherwise no way that a creature can move from room to room.  If a non-floating object that is wallbound falls in a spot where there is no room defined at any point on the vertical line through that object, the sprite ceases to exist but the object does not.  This includes creatures, who then become “ghosts” in Albia.  To prevent this from happening, be sure to have a room defined at some vertical position for every horizontal position.

There are environmental variables for wind and temperature in Albia, but these parameters are not currently active.  There is no environmental variable for light intensity.  Fudging can be done by using ground level as a direct sunlight/no direct sunlight indicator, as was done in Shitake Mushroom Logs.

Diseases in Albia are controlled by the executable.  They can occur in random outbreaks, or they can be injected by objects such as the Cave Flies.  The antigens follow a saw-toothed pattern of increase that does not begin decreasing until the concentration of antibodies is higher than the concentration of antigens.  All toxins present in a creature will follow this cycle if it’s status is “Sick”.  Therefore it is not wise to use the unassigned toxins for your own purposes, as the executable will seize control of any toxins present if the creature falls ill.

Diagram 1 - Rooms and Ground Level in Albia

See ALBIA.BMP at web site.

Appendix 1 - Script Numbers for Objects

See Stefen Kuske’s list at web site.

Appendix 2 - Complete Listing of CAOS

See Mark Ashton’s CAOS Reference Document at web site.

Appendix 3 - COE Documentation

See ??? at web site.