Ghosthande's Hungry Critter Tutorial--er, Walkthrough
This isn't a tutorial so much as a walkthrough of what an eating subroutine looks like. Specifically, it's a generic subroutine I adapted from the Snotrock when I was making my own critters, with explanations as to how everything works.

This is a basic timer script that calls one of two subroutines. Ideally a critter will have a condition at the beginning of the timer script asking what the hunger level is. Conditions should be nested for best results, and listed in order of immediacy. For this critter, hunger is defined by the variable ov02 (ov01 is its lifespan). Both start at 100 when the critter is born and decrease little by little as it moves about. If a variable reaches a certain level--say, 25 or 30--the timer script calls the appropriate subroutine. The timer script might look something like this:

scrp 2 12 60699 9
         doif ov01 lt 1
                  gsub die
         else
                  doif ov02 le 30
                           gsub food
                  else
                           gsub normal
                  endi
         endi
endm


You can see what I mean by nested: instead of having multiple elif's all on the same level, the conditions are nested inside one another. It may not seem necessary, but it's actually better to do this way.

By the way, it's a good rule of thumb to always make sure a major subroutine like this ends in a blanketing "else" statement. That way you don't need to specify every single condition possible, and there is always a default for the critter to fall back on. If your critter winds up in a condition that doesn't have an action specified for it and you don't have a backup blanketing statement, the critter will simply not do anything, effectively going into a coma until you either delete it, change its status manually through CAOS, or it gets eaten or something.

Now, on to the food subroutine:

subr food
         rnge 1000
         seta ov99 null


The critter is looking for food within a range of 1000, which is pretty generous. And as far as I know it is the highest number allowed by the game. A lower range will decrease the likelihood that the critter will find food, but it is more desirable for critters that move slowly--there's no point in going after a food item that will be gone by the time the critter gets there. Norngirl's caterpillars only have a RNGE of about 200 for this reason.

The variable ov99 is going to be the critter's "other agent reference".


         inst
         esee 2 6 0


This line asks, can you see any of this object type (in this case, leaves)? ESEE automatically takes RNGE into account. The number 0 is a wildcard, meaning that this critter will search for any kind of leaves, regardless of their species number.


                  doif targ ne null


Always make sure that the targ isn't equal to null before you try to do anything with it. And if the critter itself falls into the classifier you're searching for, add "and targ ne ownr" to the end of that condition, or your critter will literally try to chase and/or eat itself!


                           setv va02 posx
                           seta va99 targ

                           targ ownr
                           setv va02 va02
                           seta ov99 va99


The variables va02 and va99 are the temporary position and temporary agent reference, respectively. I say temporary because right now we're saving these variables in the leaf, but we want the critter to have them. So the three lines below that target the ownr (critter) and transfer the variables.


                           loop
                                    doif posx gt va02
                                             velo -5 -5
                                             wait 5
                                    elif posx lt va02
                                             velo 5 -5
                                             wait 5
                                    endi
                           untl touc ownr ov99 eq 1 or ov99 eq null


We have a lot of things happening here. This is the "walking" chunk. It checks to see if the critter's posx (horizontal position) is greater or less than the variable we saved: remember that Creatures uses the cartesian coordinate system, so if posx is greater, that means the critter is to the right of the leaf. This code basically says, "if posx is greater than va02, move back so posx decreases. If posx is less than va02, move forward so posx increases." We want those numbers to be the same.

This section loops until one of two conditions are true: either ownr (the critter) is touching ov99 (the leaf), or ov99 doesn't exist.


                           doif ov99 ne null
                                    sndc "chwp"
                                    kill ov99
                                    addv ov02 30


Now we check to make sure that leaf is still there, kill the leaf, and add 30 to the critter's hunger level.


                           else
                                    gsub normal
                           endi
                  else
                           gsub normal
                  endi
         next
retn


Thus ends the subroutine. Notice that I tacked a "gsub normal" at the end of my conditions, as an alternative if the leaf isn't there: this way the critter will wander around randomly if it hasn't found food. If the critter wanders around a little, it will hopefully find a place with more food.



Back to BBW