Entry Points
An object does not automatically run everything in the BHAV section. The BHAV section houses an object's coding (the instructions for how it should work). As with all sets of instructions there needs to be a starting point, or as they are called in programming,"Entry Points". Our Sims objects have two types of Entry Points: There are the Interactions, triggered by sims or players, and there are those that the game runs automatically.
The TTAB and TTAs sections handle the Interactions
When you mouse over an object it checks the Tree Table (the "TTAB" resource) to see which interaction choices it is allowed to display. Each "check tree" (called "guard" tree, in Iffsnooper) for each item listed is run at this time but the bhavs listed as the "actions trees" will not run unless that interaction is actually picked.
The OBJF resource handles those that run automatically.
Every object should have at least three (3) 'functions' listed in the Object Function Table (OBJf). These are the Init, the Load and the Main:
-
The INIT function
Init is short for initial (or a variation on that word) and is run when the object's "instance" is very first created - when you first buy it from buy or build mode, or if, like a baby, it is created by some other means. The very first (initial) time it makes an appearance in the world.Placement and similar 'rules' are in this BHAV: "Yes, I may be placed on surfaces at this height.", "No, I may not be placed on water.", "A wall is not allowed on my left side", "I am not burnable", "I may not be stolen", "I generate light" ... That sorta thing.
-
The LOAD function
Each time the lot is loaded each of it's objects 'load' in again as well. This bhav gets run then. It's not used by hackers very often so it usually contains has a single line of nonsense code that does not matter one way or the other. This is also one of the two common places we would find the lines that check to see what expansion packs are installed (so the object knows if it is actually allowed in the game) -
The MAIN function
The heartbeat. The continued existence of the object. This bhav never stops running. So there is never an ending line in this behavior. It loops round and round itself, like a heartbeat, but can change it's loop a little depending on how the object how/if being used at the moment. A chair is a perfect example of this that we'll examine in a moment.
Some objects (usually older ones) do not have the OBJf as a separate resource.
If your item does not have an OBJf listed among the resources, you'll find this information in the OBJD resource. The OBJD has an OBJf section built into it that is sometimes used instead called
--- Old Function Table
You will find an example of this in the Cheap Dining Chair.
Clone a Cheap Dining Chair (found inside of diningchairs.iff) and open it up in your hacking program (IffPencil, in my case). Take a look inside of the OBJD scrolling down a ways to the "Old Function Table" section. You'll spot the Main (BHAV 4096), Init (BHAV 4104) and Load (Oh look - BHAV 4104 is used for that as well! How unusual!) as well as a few others that are specific to seating. Weird and wonderful stuff.
A detailed look at a Main BHAV
We have
1 my slot 0 Equals? 0 [Next 0, 2]
2 Stack Object ID Assign To: my slot 0 [Next 3, Error]
3 stack object's definition type Equals? 2 [Next 4, 0]
4 (priv: ) inc comfort [Next 5, Error]
5 (glob: ) idle (3c 00 00 00 00 00 00 00) [Next 1, Error]
LINE #0: (glob: ) idle (20 4e 00 00 00 00 00 00)
Main starts by idling. Simply being there doing nothing, existing in our little Sim world. Then after the idle time (which is the determined by the parameters your see in the parenthesis next to the word idle, by the way) it goes on to line 1 (as instructed in the true/false returns)
LINE#1: my slot 0 Equals? 0
Here it checks to see if slot 0 (zero) is unoccupied (has a value of 0. If it were full with something (like a Sim) it would have a value of 1) If it IS unoccupied it goes back to line #0 and idles for that set amount of time before once again returning to line #1 and checking to see if it's slot #0 is unoccupied. The chair does this constantly until one of the times that it checks to see if the chair is unoccupied the answer ("return") is a negative ("false") answer. When my slot 0 does not equal 0 then got to line 2.
LINE#2: Stack Object ID Assign To: my slot 0
Line two makes the contents of the Slot 0 the Stack Object. The Stack Object is the code's focus. It's the thing in the sentence "Hey bring me that thing".
LINE#3: stack object's definition type Equals? 2
Line Three checks to see if the Stack Object ("thing") is actually a "Type 2" object. A type 2 object is a Sim. If somehow the answer is no, and something other than a Sim got into that chair the False instruction is to go back to Line 0 and idle some more. Since there's not really a chance of that happening it's going to return a "True" and go on to Line#4 which is the private call "inc comfort"
LINE#4: (priv: ) inc comfort
A "private call" is when one BHAV is run "inside" of another BHAV. It is a little sub-set of instructions that the script is to follow before continuing on. A rather strange and inappropriate example would be putting your tennis shoes on. The whole act is "Putting Your Shoes On" but you might make "Tying your shoelaces" a private call. It's an act of it's own but is also part of this larger act.
Let's follow the code and head over to (priv: ) inc comfort.
To do this we must temporarily close our "main" BHAV and open that BHAV. The name of the BHAV is already displayed but since come objects have a LOT of BHAVs it's usually easier to locate the sub-routine by BHAV number. Highlight Line four and look at the "function" number displayed in the data section of the window. Unlike the "2" listed for most of the other lines this one says 4113, the BHAV number of our subroutine.
(priv:) inc comfort
BHAV# 4113 "inc comfort"
(Rewrite this bhav as well so we can see it a lot more clearly.)
The first couple of lines are the chair identifying itself (line 0 puts the chair's own GUID in Local Variable 0 for future use) and identifying the sim sitting in it (line 1 checks the id of the object (Sim) found in slot 0 and lets our bhav know that this is the "stack object" referred to later on in this bhav).
Line 2 checks if that GUID that was put in Local variable 0 is a specific one. The original file all of this coding came from has several chairs in it. You had to pick one of them when you cloned yours. So these "Test" lines are trying to figure out which one you cloned. As it happens it starts with the cheap dining chair and it's first try is our own GUID so the return is "true" and we move on to line 3 (a false return would send us to line 5, another GUID check)
Line 3 is stack obj's motives Comfort <= Constant 4097:6
Translation: Is the Stack Object's (the Sim is the Stack Object, remember) comfort motive below the value found in BCON 4097:6?
If so go to line 4. If it's not below that value then we are done here. The sim has reached the maximum comfort we want him to get from this chair. (end successfully)
Line 4 is stack obj's motives Comfort += Constant 4097:0
Translation: Raise the stack object's comfort by the value found in BCON 4097:0. Then we are done here (end successfully).
Once the code has run through the private call it returns to the Main BHAV to finish up there so lets do the same. If it succeeded in completing the "inc comfort" BHAV then it returns a "True" response (some subroutines will return "false". This one just happens to be one that always returns a "true" when it's finished). The instructions in line 4 say a true response leads to line 5
LINE#5: (glob: ) idle (3c 00 00 00 00 00 00 00)
After idling a little at line #5 the instructions loop us back up to line 1 where, once again, it checks to see if the chair is unoccupied. If so idle, if not go to line #2, #3, then #4 (increase comfort), and #5 (idle) and check again - never actually stopping at any time, always looping round and round itself. Which loop it takes all depends on whether slot 0 is occupied or not.