|C2 Caos - Unravelling the Humble Ant |
| 2/19/2016|| 8|
This post is intended to instruct the reader on some of the more obscure CAOS scripting found within the C2 Anthill and Ant agents. I won't be going through the entire thing, but I wanted to share the notes I took while learning how these agents behave. Maybe you'll find it helpful to read along?
There's a most curious chunk of code within the Ant's Timer script (2 17 1 9), that at first, I couldn't make heads or tails out of.
It's a big chunk of an even bigger script. At first glance, my immediate questions were: What is it doing with such huge numbers as 4176 and 8352? And what's this unnamed "256" script it's triggering with a mesg wrt+? I was curious enough to try to find out what on earth all this code was managing.
It turns out, this is controlling how an ant carries a piece of detritus back to its home. Here's how I figured it out.
OVs and VARs - Follow the Breadcrumbs
An important first step towards understanding CAOS written by someone else, is knowing what each variable in the script represents. So we have to read the code like a machine would: starting at creation, watching the variables be created, seeing which parts of the script will be triggering in what order, and how the variables are changed over time.
The first line of this chunk of code presents us with our first question:
What is ov04? Right away, we know that this whole section of code is ONLY triggered if ov04 equals 1. This OV is a pretty big deal, apparently.
If you're already confused, here's a brief primer on how variables work in Creatures 2.
OVs are variables shared across all scripts belonging to the agent. In other words, you can set an OV variable in the agent's creation script, and can later reference it in a different script, such as the Timer, or Activate 1, or Drop (etc). These variables are not automatically visible to other agents, however.
VARs (or VAs, once you need to go higher than 9) are temporary variables that are only visible in the script they're created in. Every script can create its own VARs, but one script cannot access a different script's VARs. Also, these variables - being temporary in nature - are deleted once the script is no longer using them.
So again: What IS ov04? Searching through the rest of the ant's Timer script, I came across several mentions of it. It seems that the Timer will check its value a couple of times, but if it doesn't find anything, it'll default to 0. The next time the Timer script fires, it will see ov04 now equals 0, making one of those earlier checks relevant:
This is directly above our big chunk of code that's checking for ov04 to equal 1. But here, it's checking for the same variable to equal 0. Interesting...
The Logical Sequence of Events
So, ok. Let's figure this out. Here is a fresh new ant. His Timer script just triggered for the first time ever. All of the ov04 checks were bypassed, because ov04 has no value yet, not even 0. Then the script sets it to 0. The Timer script runs again, and this time, ov04 equals 0! The above code suddenly matches the check, and it proceeds to do stuff!
First, it creates a new temporary variable, var0, and sets it to 0. It then 'enums' (cycles) through every Detritus (2 11 0) object in the world.
**Protip: When you enum through a category, '0' is a wildcard. So here, we're enumerating through every kind of Detritus, no matter what it is- dead fruit, dead insects, anything.**
If a Detritus object exists, it checks to see if var0 is still 0. Let's assume it is, for now.
Next, it checks to see whether the ant is physically touching this Detritus. If not, it keeps cycling through Detritus, eventually exiting this loop if the ant isn't touching any of them. But if it IS touching one, it does some more checking to ensure this Detritus isn't preoccupied or otherwise unavailable, then the ant sends a "I just picked you up!" message to the Detritus (which, in turn, forces it to be picked up by the ant), and finally sets var0 to 1.
And then this happens:
ov04 is set to 1. That means that the next time the Timer script triggers, our big chunk of code (that we were originally looking at) is finally set into action, and this other chunk of code is no longer firing.
So, from this we can determine that ov04 is a flag, of sorts. ov04 simply means, "is the ant carrying detritus?" because it only equals 1 when that condition is true- otherwise, it equals 0.
That's... the first line of the mystery solved. Phew. Only one line?! Well, it may seem like a lot of effort to understand one variable, but it was an important one.
An Ant's Place in the World
The next big mystery is this:
Now we have a new temporary variable being created: var0. It's being set to whatever ov03 is. Searching through the script, this is the only mention of ov03 anywhere, meaning that its value isn't being set here. But if it's never being set, why is it checking the value?
Well, it is being set- just not in this script. It's an OV. This must mean that some other script is setting its value. The most logical place to look is wherever the ant is being created. What creates ants...? The Anthill!
And here it is, within the Anthill's Timer (2 16 1 9) script:
Here is where all ants are born. And if you look carefully, you can see ov03 being set to var1, which at the top of this section is being set to the Anthill's posr (Position Right). Also make note of ov02, which is being set to var0, which is the Anthill's posl (Position Left).
Now you might recall that I said OVs are shared between an agent's scripts, but not between different agents. That's kind of true, but in some instances, this rule can be kinda broken.
When an agent spawns another agent, it uses the new: command. This enables it to write the Creation script of the new agent. You would think, then, that this script belongs to the Anthill- but no, it actually belongs to the ant. Once the ant has been created, it owns all of the various attributes and OVs that were bestowed upon it.
And because it belongs to the ant, any OVs created here can be accessed by the ant's other scripts.
We can ignore the rest of that code for now. We just came for the ov03 and ov02. They are the Right and Left positions of the ant's parent Anthill.
So, here's what's happening. ov02 and ov03 are being compared to the ant's current position. Some arcane math is employed, involving the world's wrap-around point and the global positioning coordinates (it may as well all be Greek to me, but if you can understand it, good for you) to figure out which direction the ant should take to travel back home.
To be honest, I'm a little foggy about this myself. But to cut a long story short, ov03 is used to set var0 to a number representing the total distance back to his Anthill in one direction.
...and ov02 is used to set var1 to a number representing the total distance back to his Anthill in the other direction.
Then some weird math is used to determine which of these directions is the shorter route home. ov00 is set to 1 or 0 depending on this result, which is fed into the ant's movement subroutine to determine which direction he should travel in. And then it stops the rest of the script- this will become important very shortly!
But, it's time for a quick recap. Here's what we've learned so far:
In other words, the majority of it is messing around with coordinates, and trying to figure out the best direction to travel home while carrying a piece of Detritus. Blech, how boring. But, I suppose, necessary. After all, machines aren't as smart as people think. They don't automatically know any of this- you have to be meticulous and specific in every possible detail. And God help you if you're not a Mathematician!
But here's where the script does something really, really cool.
You see, if var0 is less than 0, the script enters that doif, makes the ant move a bit, and then stops. It doesn't continue reading the script- it goes right back to the beginning. And if var1 is greater than 0, the same thing happens.
var0 and var1 essentially trap the ant inside these doifs until it reaches home. Because until it reaches home, one of these checks is ALWAYS going to be true.
Only when it returns home does the script move on. And from that point, the script is making the assumption that the ant and its Detritus are currently touching the Anthill.
That becomes critically important as we examine the next major section:
Delivering the Goods
This 'enums' (cycles) through all the Detritus in the world again. But at this point, the ant is already carrying some Detritus. And, as we know, he's reached home. So it cycles until it finds the Detritus that this ant is carrying, and destroys it. The Detritus was successfully delivered!
It also sets var0 to 1, which immediately triggers the next part of the script:
var0 is 1, so now it cycles ('etch') through all Anthills the ant is currently touching. If it finds one - and it should - then a message is sent to the Anthill to run its '256' script. Another temporary variable, var1, is played with here as a failsafe to make sure these actions don't occur more than once.
...Tells the script that the ant is no longer carrying a Detritus, and to exit this part of the script.
And that is the entire chunk of code decyphered.
If you're still wondering what that message of '256' to the Anthill was, the short answer is that the Anthill has a special non-standard script with the number 256. It's only ever activated this way, by an ant delivering Detritus.
When triggered, the 256 script manages the 'energy' of the Anthill, growing it and spawning new ants when the food level rises.
Agents can have an enormous number of custom scripts, beyond the usual "Activate", "Eaten", "Dropped" etc that most objects have by standard. This allows you to create unique agent-to-agent interactions, as long as you know which of their uniquely-numbered scripts to trigger.
But that's an entirely different chunk of code for another day...
| 12/14/2019|| 1|
That was awesome! I am trying to wrap my head CAOS scripting, and this was super helpful, so thank you.
| 12/14/2019|| 1|
Awesome analysis. It's amazing how much coding work goes into something that appears simple on the surface (ants, of all things)!
| 12/16/2019|| 1|
I saw the thread title and thought to myself "oh cool, someone else is doing a code breakdown like I used to do!"
Then I saw my own name.
Oh, my. I didn't even notice this post was bumped from 2016...