Programs You'll Need
Script Station: 

Script Station Tutorials
Somewhat of an intro for script station, by Dr. Doofus orgainally

The following are some interesting objects and what they do. 

SocialInteractions.iff. 
This contains the scripts for all the normal Sim to Sim interactions like the simple hug, taunt, backrub, etc. 

HSDI.iff. 
This contains a lot of the same scripts but with more interactions that are used in Hot Date and Vacation, including the new kisses. There is a lot of duplication between these two files. Modifying either of the two above files would allow you to change normal Sim interactions look and act. Very fertile but touchy ground to work on. 

How are the two above used? Well, when a Sim wants to hug another Sim, the game creates a temporary invisible object of SocialInteraction. The SocialInteraction object is a kind of middle-man between the two Sims and coordinates the hug. If you think about it, that makes more sense to have one object coordinate two Sims than have two Sims trying to do things separately. That could easily become messy, couldn't it? After the hug or whatever action, the SocialInteraction object destroys itself (see below to see how that is done). It only exists temporarily, invisibly, to do an action. 

PersonGlobals.iff 
This is another very important file for social Sim-to-Sim interactions. It contains the startup routine (init and main) for all Sims. It also has the check trees for the different actions that decide which Sim to Sim interactions will be available on the pie chart at any time. It also contains more of the social interactions, for instance the Propose action. The MarriageHack.iff file that I made for hot date was a modified version of this file. 

Global.iff 
You can't modify this file in Vacation. If you do, the game tries to uninstall itself. I'd like to find a way around that. Global.iff has a number of routines that are common to all objects, such as the sabotage code that keeps you from using downtown objects on Vacation Island, as well as a number of more vital routines. 

All of the global files (files other than global.iff with the word global in their title) are interesting. They are common routines that are used by other objects. Global.iff is available to use by all objects. The others are called Semi-globals. The name of a semi-global file must be "included" into an object by an object to be used. An object can only use one semi-global file. 

For instance, if you look at any of the phone.iff files in Script Station, you'll see a reference at the very top left of the screen to PhoneGlobals.iff. The actual phone file has no behavior sections of its own but uses the behaviors in PhoneGlobals. 

If you look at the script numbers for the different behavior sections, you'll notice that most objects have numbers starting with 4096 and going up. Semi-globals have numbers from 8192 and up. Global.iff uses numbers from 256 and up. These files also contain their own string and BCON sections, so if you have trouble finding something that you know an object uses, for instance, a text message, you might have to look in global or semi-global files. 

Behavior.iff 
There is nothing executable about this as far as I can tell. It's not so much an object as it is a bit of flimsy documentation on the behavior of many built-in routines. Very interesting info, although not anything to actually hack. 

Here is a little documentation on built-in Script commands: 

Most objects require you to go to the "routing slot" before you use them. If you see a call to a routine like "Go to Routing Slot", that means that the Sim will be directed to go to the front of the refridgerator, or the side of the bed, or the front of the chair -- wherever it is that the rest of the object's behavior begins. 

Some objects create new objects at runtime. For instance, the guinea workbench will create gnome objects. It does this with a routine called "Create New Object Instance". Two of the parameters to this routine contain the four bytes of the object's GUID. One of the parameters tells where the object is supposed to be created. 6 means that it's created but doesn't show up visibly in the game in an exact spot, so you can figure out where to put it later. 

"Find Location For" is a routine that sometimes works with Create New Object Instance. It takes a parameter that describes what kind of free space to look for. I don' t remember all the parameters -- that info is in Behavior.iff somewhere. To see how these work together, look at the routine "Make Baby" in bedheart.iff (the vibrating bed). First it calls Create New Object Instance to create a cradle. Then it calls Find Location For to actually put the cradle in some empty location. And if it can't find a free location, "Make Baby" gives up and uses the next routine to destroy the cradle. 

To destroy an object (and remember not all objects are "things"), the game uses the "Remove Instance" command. It takes as its parameter a pointer to the object in (I think) "Stack Object ID". It deletes the object. This is how Vacation sabotage-code is able to make objects like the Dining Podium disappear at runtime. 

The game has multiple way of referring to objects. One way is with what's called the Stack Object ID. Stack Object ID is a pointer to a particular object. Some routines require you to set Stack Object ID to point to the object you want to mess with. For instance, "Remove Instance" requires a pointer to the object to be destroyed in Stack Object ID. 

When Stack Object ID is set to point to an object, you can refer to the variables inside that object as "Stk Obj's Attribute 6" or something like that. The important phrase there is "Stk Obj's" which means that we're referring to part of the object that Stack Object ID points to. 

There is also a "my" pointer. I'm not sure how this is set, but it seems to be the default pointer of the object whose thread has control. You can use the "my" pointer exactly like "Stk Obj's". For instance "my Attribute 6". WHEN YOU ARE MODIFYING OBJECTS (and hacking to do so), IT IS IMPORTANT TO REMEMBER HOW TO REFER TO THE OBJECT. 

The "Relationship" built-in routine is a mystery to me. I know what it's doing, but I don't know what the parameters mean. This is the routine that allows you to create new relationships and modify existing relationships between people. Or between people and objects. That last part surprised me. For instance, beds have relationships with the people that slept with them. When a Sim is choosing where to sleep, it will choose first the bed that it has the best relationship with. You might not see the bed in the thumbnails, but, yes, your Sim has a relationship with his bed! Interesting, huh? 

"Wait for Notify". This is a mysterious little built-in that is best not messed with. I believe that it is involved with handshaking between objects. In general programming (not just Simantics), a "Wait for notify" means that a thread is supposed to stop running and just sit there waiting for another object to send it a "notify" command saying, "you can proceed now." Changing the order of Notify and Wait for Notify in other areas of programming is often fraught with peril, so it would be wise not to mess with this. Although it would be very nice to understand more about it. Incorrect use of this could probably cause the game to lock up. See below for more about multi-threading. 

"Dialog". This built-in causes the game to stop and show a message on the screen in a little blue box. You've seen this before, for instance when you get a crank call and it says, "Do you canoe?" or "Congratulations! Enter a name for your new baby?" The parameters refer to the size of the dialog box, the title of the dialog box, the actual message, the size of the dialog box, whether it has an Okay or Cancel button or just an Okay button. There is some information about this in Behavior.iff. I don't recall off the top of my head all the parameters. 

"Animate Sim". This causes the Sim to use one of the animations. 

"Play Sound Event". This plays a sound. Note: according to somebody, I think Candall, some animations will play their own sounds. The references to the sounds are embedded in the animation files. 

"Idle". Sometimes you will see an object call a Global routine called "Global: idle". That's just a routine in global.iff that does a plain built-in "idle". I assume that the "idle" routine does nothing at all but sleep for a specified length of time. Some idles use very short periods of times, like a few seconds. Other times you will see very large numbers, which seems to indicate that Maxis just wanted the object to go to sleep and sit there and do nothing. See below for more about idle. 

A word about threads in The Sims: 

We know that The Sims uses cooperative multi-threading from things said in other documents and comments from Maxis. What does that mean? Well, it means that some objects are running by themselves like their own little tasks. You know what tasks are from using your taskbar. A thread is like a little mini-task that runs as part of a larger program. 

When objects are created, they often have a startup routine called something like "init," and a main routine, called something like "main." 

Most very simple objects will immediately go into a loop using the "Idle" routine; which basically means the object goes to sleep and becomes a static piece of inactive furniture. Other objects have slightly more complicated idle routines. They make themselves idle for one day, but at the end of the idle, they come back to life, depreciate their value in Simoleans, then go back to sleep. For most objects, such as furniture, you can totally ignore their "main" routines. 

Other objects stay alive and awake because they have things to do. For instance, NPC's. They have a job to do, and they do it. SocialInteraction is another example. It has its own thread to control and coordinate the interaction of two Sims. When two Sims hug each other, it's the SocialInteraction thread that is making them hug, not the threads of the two Sims. 

When you read the scripts for an object, you have to keep in mind WHO is going to use a particular script. You know that the object itself has a thread for doing things. The main thread for an object might call other routines. But SOME routines in an object are not going to be used by an object. They are going to be used by the object or Sim that is USING the object. 

For instance, Betty Newbie wants to go to sleep. Betty has her own active thread, and that thread will call routines inside the bed for her to climb into bed. The bed's thread will not be involved, in this case. It is Betty's thread that is using the "Get in Bed" routine. SO, remember, when you read a script, keep in mind, is this routine for the object, or for the Sim using the object. It's an important distinction. The bed can refer to itself using the "my" object, but I don't think Betty can. The code that Betty would use to change the bed would be very different from the code that the bed would use to change itself. 

How do I know all of this? Because I've wasted a lot of time studying the different objects using Mazelord's wonderful Script Station tool, and I've read the documents available at Bil Simser's site, as well as the tutorial by Dr. Forbush at NWU about Edith. 

That's all I have the time to disgorge right now. There's a lot more to any advanced hacking tutorial. There's also a lot I don't understand. I'd like to understand relationship and wait for notify better. I'd like to see better documentation of the calling parameters for things like the Dialog box. If somebody wants to contribute to the body of knowledge by working on that, please do. 

--------------------------------- 
ADDED! | 17th May, 2002 

Bahr thought I should include this, so if anybody pretties all this up in a tutorial, be sure to include the following. 

HOW ACTIONS WORK: CHECK TREES AND TEST TREES. 

If you ever used a program like Blueprint MenuEditor to enable objects downtown, you probably remember seeing a list of the actions on the right side of the screen that the object uses. 

Each object that has actions has a thing called the TTAB or Tree Table, which contains the names of the different actions and certain properties of the action, such as whether visitors to you house can do it, children can do it, and how tempting it should be to Sims. 

That's old stuff. If you want to hack, you might want to know more about this. If you look at an object in Script Station, there is a little box, center right, titled "Interaction Sections". In there, you'll see zero or more entries. One of those is the Tree Table for the object you are working on. You might have to do some guessing to figure out which one to use, because often there is left-over irrelevant garbage in there too. 

Once you find it, double click on it, and you'll see something that looks a little similar to MenuEdit. If you click on a single action, you'll notice something new. In the center of the screen, there are two values, the Check Tree, and the Action tree, associated with that action. 

The action tree is the number for a BHAV section (or routine, or whatever you want to call it) that is on the left side of the main ScriptStation screen. THAT is where this particular action takes place! For instance, I'm looking at the aquarium right now (Aquarium1.iff). I have included a pic to show what I mean. There are seven actions listed on the left. The one second from the top is called Watch Fish. The Action Tree for Watch fish is 4101. And look to the left at the highlighted section 4101. It's called Watch Fish also! So that is where the behavior associated with Watch Fish takes place. I can double click on Watch Fish and monkey with it if I want. In this example, we were lucky that Watch Fish had the same name as the action we see in the pie menu. Sometimes they have different names and the only way to track them down is to look for the number in the action tree. 

If you look at the pic, you'll see there is also a curious number there called the Check Tree. The check tree is the number of the section that determines whether or not your Sim even gets to see this action available in the pie menu during the game. For instance, when the aquarium is healthy, the "Watch Fish" action should be available. When you have ignored the aquarium and the fish died, the "Watch Fish" action shouldn't be on the pie menu, but "Clean and Restock" should. The check tree is the section that determines whether these actions are available. 

Going back to the picture, the check tree for Watch Fish is #4101. That's listed on the left under the name "Watch Fish test". You will quite frequently see routines with the word "test" in them -- they are usually a check tree. 

Check tree routines return a value of TRUE if the action should be available. They return a FALSE if the action shouldn't be available at this moment in time. If we were to double-click the "Watch Fish test" routine, we would see that it basically figures out if the fish are still alive, and returns a TRUE value if they are. Otherwise it returns FALSE. 

That's enough information to get you started with 90% of the actions in the game. There are other actions that are more difficult to track down. 

At some point, you might wonder, where are the check trees and action trees for Sim to Sim interactions? 

The tree table for all Sim to Sim interactions are kept in PersonGlobals.iff. If you look in the tree table there, you'll see it all -- hugs, kisses, slaps, taunts. It's all there. Most of the check trees test to see if you are in the right mood to perform a certain action. If your Sim is not in the mood to kiss somebody, the Kiss tests will return false, and you won't see that option in the pie menu in the game. 

Most of the Sim to Sim interactions work by creating a SocialInteractions object. (kept in SocialInteractions.iff) The action trees in PersonGlobals create a SocialInteractions object. They then call the appropriate routine in SocialInteractions by using a built-in routine called "Run Tree by Name". After that, PersonGlobals cleans up by deleting the SocialInteractions object. As I explained earlier, SocialInteractions is an invisible, temporary dummy object that is only created when two Sims interact, and is deleted shortly thereafter. 

So that's Sim to Sim interactions. There are other interactions that are more difficult to track down. For instance, if your Sim is in the love tub (LoveTubHD.iff), and you want him to Cuddle with another Sim, the "Cuddle" option appears in the pie menu. But you won't see "Cuddle" anywhere in the tree table for the love tub! So where is the Cuddle action? 

The game is able to create new actions at run time using another built-in primitive routine called "Add/Change the Action String". I'm not sure what all the parameters are, but you can see this at work in the lovetub, in the routine #4126 "Join Text". The names of the missing actions (wash, cuddle, kiss, play) are in text strings in #302. The "Add/Change the Action String" routine adds these actions to the pie menu after two Sims have sat down. I'm not sure exactly how this works, or how the action tree and check tree addresses are set up. If anybody can provide more info, please do! 

CHECK TREE ADS: 

Actions have advertising values that tempt Sims into performing them. For instance, in the aquarium object, the "Watch Fish" action has an advertisement of "Fun 1..10." Bil Simser has a description of what advertisements are on the BluePrint webpage, so you might want to read that for more info. Basically, these are just numbers for creating temptation and steering Sims to make right choices. The Fun advertisement of "Watch Fish" doesn't give the Sim any fun -- the object itself does that in the scripts -- but it does lead the Sim trying to choose what to do next that the aquarium should give it fun. The higher the Fun advertisement, the more likely that a Sim with a low Fun motive will choose to use it. 

Behavior scripts can change their ad trees at run time. You might see objects that change their ads with a statement like "my Check Tree ad range 3 :AssignTo 0". The 3 means motive 3, (which I think is comfort) and the 0 means that this object will not tempt anybody with comfort. You can see this kind of thing happening in the lovetub after a second person gets in. The check tree ads are modified so that a third person doesn't waste time trying to enter the tub. I'm not sure how this change is undone so that the ads are reset to their normal value. 

ADDING NEW ACTIONS TO AN OBJECT: 

This takes a little work but it can be done. I've done it before. I made a bookcase called the Encyclopedia Simmanica that Ikbod is going to recolor. I used the cheap pine bookcase as the base object and added new actions to it, so you could study any skill -- not just cooking and mechanical. 

Here's how you can do it. All of the following assumes that you already have the check tree and action tree routines ready to run and just want to "plug them in" to the object so they can be used. (Obviously that's the bulk of the work). 

The first step is to add a new entry to the tree table. If you click on the tree table in Script Station, there is a button on the bottom right of the tree table screen that says "Add". If you click on this, Script Station adds a new dummy action to the object with the name "New Interaction". 

Then change the Check Tree field so it points to your Test routine. You can leave it 0 if you want the action to always be available. 

Change the Action Tree field so it points to the section where the actual action begins. 

Set up your advertisements so they tell the Sim what to expect from the object, enable it for visitors or children as you wish, and you are done. 

--------------------------------- 
ADDED! | 17th May, 2002 

OBJECTS THAT COOPERATE. 

Some objects cooperate with each other. For instance: 

1. The robot butler object (Robot.iff) cooperates with it's docking station (RobotDock.iff). 

2. The NPC controller that schedules the visit of the different NPCs at home (NpcController.iff) cooperates with the Maid (maid.iff), gardener (gardener.iff) and thief (thief.iff). 

3. The Hot Date bar (bar.iff) cooperates with all kinds of things, including the barmaid (NPCBarmaid.iff). 

4. The Stripper (EntertainerFemale.iff) cooperates with the cake (EntertainerCake.iff). 

Generally, whenever an NPC comes with an object, there is some kind of cooperation involved, and even if there is no other object, such as with the maid, there is an INVISIBLE object somewhere telling the NPC when to do its job. These cooperations cause problems when you clone and NPC or one of the objects that it interacts with. 

Most objects in the game have what is called a GUID. The GUID is a number (usually shown in hexadecimal) that the game uses to identify the type of an object -- whether it's a stove or a sofa or the maid or the gardener. When you clone an object using Transmogrifier, the GUID of the new cloned object is changed so that there won't be a conflict with the old GUID. This way you can, for instance, have more than one stove in the catalog. The game uses the GUID's to find objects of certain types and to tell the difference between different kinds of objects. 

So when you clone something like the Robot NPC, you change it's GUID. But this creates a problem because the robot's docking station only knows how to create objects of a certain GUID type -- the original robot. You might think, "Well, I'll just get around that by cloning the docking station, too!" You do that and you still have the same problem -- the new docking station only creates the old-style Robot. 

The docking station and the robot have to cooperate with each other, and they identify each other by their GUID's. The cloned docking station uses the old robot GUID inside the code. That has to be changed by hand to the new GUID of the new robot. And the new robot has to be modified so it uses the GUID of the new docking station. You have to be thorough about it and hunt down ALL references to the old GUID's. 

That means getting your hands dirty going through the code with something like Script Station, or using search mode of a hex editor. I believe there might be a third party program out there that can try to do it for you in one step.

Often used codes, quick tips
Getting money

Function: 0019 : 25
Parameter0: 0703 : 1795
Parameter1: 2328 : 1000 *How much money you get
Parameter2: 0002 : 2
Parameter3: 0000 : 0

The chaching sound
Function: 0017 : 23
Parameter0: 012C : 300
Parameter1: 0000 : 0 
Parameter2: 0000 : 0
Parameter3: 0000 : 0

Making a money sign above head
Function: 0002 : 2
Parameter0: 0001 : 1
Parameter1: 000A : 10 *How much money appears above head
Parameter2: 0500 : 1018
Parameter3: 0712 : 1810

Playing an animation
Function: 002C:44
Parameter0: 0002:2
Parameter1: 0000:0
Parameter2: 2000:8192
Parameter3: 0000:0
2 is the animation that will play, 44 is the basic of the code, the actual animate.

Parameter Numbers
Parameter 2= 
0 BUDGET_SUBSTRACT
1 BUDGET_SUBSTRACT | BUDGET_TEST
2 BUDGET_ADD
3 BUDGET_ADD | BUDGET_TEST
4 BUDGET_UNKNOWN

Parameter 3= 
0 MISC_EXPENSE
1 JOB_INCOME
2 MISC_INCOME
3 FOOD_EXPENSE
4 BILL_PAYMENT
5 MAINTENANCE_EXPENSE
6 PURCHASE
7 ARCHITECTURE
8 UNKNOWN_TYPE
9 UNKNOWN_TYPE

Add cooking skill

1
Function : 0002 : 2
Parameter0: 000A : 10 'The cooking skill...below is the list that shows what number is what skill
Parameter1: 0000 : 0
Parameter2: 0300 : 768
Parameter3: 1912 : 6418

2
Function : 0002 : 2
Parameter0: 000A : 10 'The cooking skill...below is the list that shows what number is what skill
Parameter1: 03E8 : 1000 'add one skill....I might have changed this to all skills when i was doing something. So it might be 100. 
Parameter2: 0500 : 1280 
Parameter3: 0712 : 1810

4? not sure it add this one.
Function : 0002 : 2
Parameter0: 0000 : 0
Parameter1: 0000 : 0
Parameter2: 0500 : 1280
Parameter3: 0719 : 1817

10 - cooking skill
11 - charisma skill
12 - machanical skill
15 - creativity skill
17 - body skill
18 - logic skill

I still don't know if this works, because i've never checked it....it was all from fooling around. But if you explore you can find out how it works and add skill. I don't really know if you can decrease a skill 
I don't really know how to add dialogs and making random things happen. :P

Random Numbers
The code for random primitive:

Function - 0008 - 8

Param 0 - The number of the location in which the random number will be returned (Temporary storage 0, My attribute 3 and so on)

Param 1 - The sort of location in which the random number will be returned (Temporary storage 0, My attribute 3 and so on) - listed in STR# section 132 in Behavior.iff

Param 2 - The max random number

Param 3 - What Param 2 is - Literal Value, My attribute and so on - listed in STR# section 132 in Behavior.iff

Examples:

Random Number 0 - Literal Value 100 into Temporary Storage 1
0008 - 8
0001 - 1
0008 - 8
0064 - 100
0007 - 7

Random Number 0 - Constant Value 4096:7 into Stack Obj's Attribute 3
0008 - 8
0003 - 3
0001 - 1
0007 - 7
001A - 26

Recently, I've noticed that the random primitive seems to generate numbers from 0 to the number you specify minus one. So as an example, random number 0-3 can only result 0, 1 or 2 - never 3. 

Some useful code tips and starters
Routing Slot
-------
Most objects require you to go to the "routing slot" before you use them. If you see a call to a routine like "Go to Routing Slot", that means that the Sim will go infront of the object. Example, go infront of refridgerator, or the side of the bed, or the front of the chair -- wherever it is that the rest of the object's behavior begins.
Object Instance
-------
Some objects create new objects at runtime. For instance, the guinea workbench will create gnome objects. It does this with a routine called "Create New Object Instance". Two of the parameters to this routine contain the four bytes of the object's GUID. One of the parameters tells where the object is supposed to be created. 6 means that it's created but doesn't show up visibly in the game in an exact spot, so you can figure out where to put it later. More in the forum

Object Instances Cont
-----------
"Find Location For" is a routine that sometimes works with Create New Object Instance. It takes a parameter that describes what kind of free space to look for. I don' t remember all the parameters -- that info is in Behavior.iff somewhere. To see how these work together, look at the routine "Make Baby" in bedheart.iff (the vibrating bed). First it calls Create New Object Instance to create a cradle. Then it calls Find Location For to actually put the cradle in some empty location. And if it can't find a free location, "Make Baby" gives up and uses the next routine to destroy the cradle.

Remove Instance
-----------
To destroy an object (and remember not all objects are "things"), the game uses the "Remove Instance" command. It takes as its parameter a pointer to the object in (I think) "Stack Object ID". It deletes the object. This is how Vacation sabotage-code is able to make objects like the Dining Podium disappear at runtime.

Remove Instance Cont
-----------
The game has multiple way of referring to objects. One way is with what's called the Stack Object ID. Stack Object ID is a pointer to a particular object. Some routines require you to set Stack Object ID to point to the object you want to mess with. For instance, "Remove Instance" requires a pointer to the object to be destroyed in Stack Object ID.

Stack Object ID
------------
When Stack Object ID is set to point to an object, you can refer to the variables inside that object as "Stk Obj's Attribute 6" or something like that. The important phrase there is "Stk Obj's" which means that we're referring to part of the object that Stack Object ID points to.

My Pointer
-------
There is also a "my" pointer. I'm not sure how this is set, but it seems to be the default pointer of the object whose thread has control. You can use the "my" pointer exactly like "Stk Obj's". For instance "my Attribute 6". WHEN YOU ARE MODIFYING OBJECTS (and hacking to do so), IT IS IMPORTANT TO REMEMBER HOW TO REFER TO THE OBJECT.

Wait For Notify
-------
"Wait for Notify". This is a mysterious little built-in that is best not messed with. I believe that it is involved with handshaking between objects. In general programming (not just Simantics), a "Wait for notify" means that a thread is supposed to stop running and just sit there waiting for another object to send it a "notify" command saying, "you can proceed now." Changing the order of Notify and Wait for Notify in other areas of programming is often fraught with peril, so it would be wise not to mess with this. Although it would be very nice to understand more about it. Incorrect use of this could probably cause the game to lock up. See below for more about multi-threading.

Dialogs
-------
This built-in causes the game to stop and show a message on the screen in a little blue box. You've seen this before, for instance when you get a crank call and it says, "Do you canoe?" or "Congratulations! Enter a name for your new baby?" The parameters refer to the size of the dialog box, the title of the dialog box, the actual message, the size of the dialog box, whether it has an Okay or Cancel button or just an Okay button. There is some information about this in Behavior.iff. I don't recall off the top of my head all the parameters.

Animate Sim
----------
This causes the Sim to use one of the animations.

Playing Sounds
----------
This plays a sound. Note: according to somebody, I think Candall, some animations will play their own sounds. The references to the sounds are embedded in the animation files.

Idle
-----
Sometimes you will see an object call a Global routine called "Global: idle". That's just a routine in global.iff that does a plain built-in "idle". I assume that the "idle" routine does nothing at all but sleep for a specified length of time. Some idles use very short periods of times, like a few seconds. Other times you will see very large numbers, which seems to indicate that Maxis just wanted the object to go to sleep and sit there and do nothing. See below for more about idle.

Goodies

The Comfort Level:

--------------------------------------------------------------------------------

A bit where and how to add comfort to an object.

The BCONs areas are listed in the box on the bottom right of the screen. You are able to change the comfort for the Maxis white dining chair (the Parissiene Chair) by changing the section that they call #4097 Tuning Comfort. 

About Sounds:

--------------------------------------------------------------------------------

Some animations will play their own sounds. The references to the sounds are embedded in the animation files. Example, Found in the animations included with the Pepsi Machine download, It wasn't in the actual animation cfp file, but in the cmx.bcf that accompanied. If you look, you will see a string of the following:

.sound.a2o-someanim

where the first "." is hex byte 05 and the second "." (following the word "sound") is variable depending on the length of the animation's name. In this case, it would represent 12, since "a2o-someanim" is 12 letters/bytes long.

I've only ever seen them in the pepsi animations, but this possibility may prove invaluable if we figure out how to implement them in our own animation files.

Mains:

--------------------------------------------------------------------------------

Can you just include the Main from the other object? No. You can't have two mains. You would have to combine the mains together into one main, and the same with the init's. That would mean carefully splicing a lot of code back and forth and understanding well what it all does. 

Strings:

--------------------------------------------------------------------------------

Strings can be included. If there is an address conflict -- say that both objects use a message #301:2, one that says "Congratulations on your marriage!" and one that says, "You just earned a Cooking Skill point!" then obviously you have to renumber one of them, and that means going back through all the spliced in code and changing references to the old string location to point to the new one. You would have to do the same thing with the names of the animations and sound files and BCONS. 

Skills:

--------------------------------------------------------------------------------

If you're trying to change the skills that a bookcase allows you to earn, you don't need to mess with the main and init routines. I think they don't do much anyway. What you want to do is hunt through the other routines ("read book" may be the important one, but not sure") and look for the place where it increases "mechanical" and "cooking". Once you find all references to that, you can change them to something else like "charisma" or "logic". It means a lot of hunting. To change the type of skill, open the line of code in expert edit mode, and fiddle with the numbers until you see the "mechanical" change to "charisma" in the gray box at the bottom. I know, that's kind of a dorky way to do things, but it's what I had to do. There's a number that represents cooking, one for charisma, one for logic, etc... you have to experiment to find the one you want.

SimAntics Language
These pages will help you understand the script language called "SimAntics", which is used in the game "The Sims" by Maxis. Just like all other languages it takes time to understand it. You will be guided and taught how to program SimAntics here. 

Click one of the articles below or download the examples! 

General: 
IFF files 
Strings 
Bit compression 
Character files 

Old articles: 
Tweaking with the Neighborhood 
OBJD 
CTSS 
BMP_ 
TTAs 
STR# 
FWAV 
FAMI 
FAMs 
NBRS 
Downloads 
You can also download sample files which are part of the articles. The source code may be used in any programs you make. The author is not responsible for any bugs! You're not allowed to distribute it to others unless you've got explicit permission from the author. 

File Size Last update 
ParseIFF.zip 6 Kb October 23, 2001 
IFFFile.zip 9 Kb December 15, 2001 

ParseIFF.zip: This VB6 module contains more information than covered in the IFF files article, like the OBJD section and the BMP_ section, but the resource map and iff files loader are fully supported. The module is part of a program Judson Hudson is programming (http://www.simprograms.com) and the module is the IFF reader I've adapted for his program. Please note that the reader can only be used to load files, as it doesn't allow for "unsupported" sections to be read. 

IFFFile.zip: These C++ class files contain the IFF editing set used in IFF Pencil. It works perfectly and you're allowed to use it as well, if you mention my name somewhere in the program (like in the About Box). This module can load and save any IFF file and supports the .CAR compressed file format, which actually is a IFF file compressed. The compression module is in this file as well. 

It is recommended that you start with the first topic and end with the last, but you can use this site for reference as well. 

FINISHED 
Chapter 1 SimAntics Basics 
Chapter 1.1 Subroutines 
Chapter 1.2 Structure of a BHAV section 
Chapter 1.3 Private, Global and Semi-global scope 
Chapter 1.4 Primitives 

SimAntics Basics 

As a language, SimAntics has grammar and words. To write SimAntics, you will need to know the grammar in the first place. The grammar of SimAntics is quite simpel, fortunately. In this chapter we will discuss the basics without digging in the code itself. At the end of this chapter, you will understand what BHAV and GLOB sections are. You will know the difference between private, global and semi-global scope and you'll know how the scripts are stored in the IFF file. 

1.1 Subroutines 

SimAntics scripts are used to make an object live and interact with the sims like in real life. In the IFF files (the files which contain information about objects and such things) there are often dozens of BHAV sections. Every BHAV section contains exactly one SimAntics subroutine. Such a subroutine is called by other subroutines or by The Sims to simulate an interaction or a part of an interaction. 

Every subroutine has an identification number. This number is used by other subroutines to identify the subroutine they want to have started. Subroutines also have a name. This name can be something like "main" or "load" or something like "Eat Interaction" or "process". Some names are also used for identification purposes by other subroutines. However, this is only used when the script trying to start that subroutines doesn't know it's ID number. 

1.2 Structure of a BHAV section 

Below you can see an example of a BHAV section. 

02 80 02 00 00 00 00 00 02 00 00 00 02 00 01 FD 00 00 0B 00 00 05 0A 03 17 00 FE FD 05 00 00 01 03 00 00 00 

Every "line" of the script takes exactly 12 bytes: 

02 80 02 00 00 00 00 00 02 00 00 00 
02 00 01 FD 00 00 0B 00 00 05 0A 03 
17 00 FE FD 05 00 00 01 03 00 00 00 

Every lines is made of a WORD (=2 bytes) containing the next instruction, two BYTES containing the next lines and 4 WORDs used by the instruction. Actually, these are not seperate WORDs but just bytes, but it is easier to work with WORDs. 

Note that once you call something a WORD, the two bytes are reversed. That's how the Intel processor works with 2-byte values. Also, I do something different with the very first line. 

8002 02 00 00 00 00 00 02 00 00 00 

0002 01 FD 0000 000B 0500 030A 
1014 FE FD FFFF FFFF FFFF FFFF 

The first 12 bytes are called a header. This header contains information about the subroutine. The first two bytes of the header are always the same. The next byte contains the number of lines in the BHAV section. I don't know anything about the rest of the header. 

As you can see, the first line (that is line 0, all subroutines start at line 0) executes instruction 2, with parameters 0000, 000B, 0500 and 030A. When the result of that instruction is True (often indicates success) then the subroutine continues at line 1 (that's the second line). However, when the result is False (often indicates failure or an error) then the subroutine jumps to line FD (in decimal, that is 253 or -3). 

When a program jumps to FD, FE or FF the subroutine quits giving the result to the calling subroutine. FE means "True" while FF means "False" and FD "Error". I'm not sure but I think that returning "Error" has the same result as returning "False" ??! Is this correct or causes returning "Error" the calling subroutine to return "Error" as well? It is possible that using FD crashes the Sims lets it hang, please try it out. 

If the first instruction returns True the second instruction is executed. The second instruction is 1014 with all parameters set to FFFF (that's 65535 or -1). If that instruction returns "True" then the subroutine will quit returning "True" as well. If the instruction returns "False", however, then the subroutine will quit returning "Error". 

1.3 Private, Global and Semi-global scope 

Every subroutine has a so-called scope. Subroutines with a global scope are available in every IFF file and are defined in SIMS\GameData\Global\Global.iff. In this file, there are hundreds of subroutines which subroutines in all other files can use. Examples are "move forward n tiles" to let the sim move forward and "idle hours" to let the subroutine wait for hours. The number of tiles and hours are parameters. The ID numbers of these subroutines are between hexadecimal 100 and 1000 (or 256 and 4096 in decimal). 

A subroutine can call a global script by setting the function to the ID number of the subroutine and the parameters to whatever is needed by the subroutine. 

There are also subroutines with a private scope. These subroutines are stored in the IFF file of the object. Their ID number range is from hexadecimal 1000 to 2000 (or 4096 and 8192 in decimal). These subroutines are not available in other IFF files, but they can be called by using the name of the subroutine. More about that follows later. 

In the example used in chapter 1.2 the second line calls a private subroutine with the ID number 1014 (or 4116 in decimal). 

There are also subroutines which are used by some IFF files but are not required by all. In the IFF file, there is often a GLOB section which contains the filename of the IFF file containing the subroutines this IFF file needs. Examples are "DoorGlobals", "DoorGlobals.iff", "CarGlobals" and "PersonGlobals.iff". Sometimes the .iff extension is included, sometimes not. The files are stored in the same directory as Global.iff. The semi-global subroutines work the same way as global subroutines but they have their ID numbers higher or equal to hexadecimal 2000 (or 8192 in decimal). 

Not all files have a GLOB section. In that case, the subroutines in that IFF file can't call semi-global subroutines. 
1.4 Primitives 

Like every computer languages, every subroutine uses a basic instruction set in the end. These instructions are called Primitives in SimAntics, and they serve a similar function as the instruction set of the Pentium. There is a primitive for calculating things, a primitive to update the object's graphic, a primitive to create an object, a primitive to move or destroy an object, and so on. The global-scope subroutines are merely tools which make it easier to access the primitives. 

The ID numbers of primitives are from 0 to 100 (in decimal, that's 0 to 256). They are not stored in any IFF file, but in the main executable of The Sims, just like the instruction set of the Pentium being stored in the processor while the programs and the Windows subroutines are stored in the memory or harddisk. 

There are currently 50 primitives in The Sims. A list of the primitives follow below with links to chapter 3. 

IFF Files 

IFF basics 
An IFF files is basically a container file. This is a file which contains other files. An example of such a file, which you can call an archive as well, is the ZIP file. An IFF file is just like a ZIP file: it contains other files. In IFF files, the files are not compressed like ARJ or ZIP files. The files aren't files either. The files are called sections. Sections have a 64-byte name and a 4-byte "extension". This extension specifies the type of the section. Unlike ZIP files, all sections in one file are more-the-less dependent of each other. All sections form one unique object, or define the neighborhood, or do something else like that. 

For more information about the relationship between sections in an "object" IFF file, consult my article about Object IFF Files. 

Introduction to the Resource Map 
Just like other archive files, some IFF files have a so-called resource map: a section which tells the programs loading the IFF file what sections are in the file and where they begin etc. The Resource Map is present in some IFF files, but not in all. That's because there are currently two versions used by The Sims: version 2.0 WITHOUT Resource Map and version 2.5 WITH Resource Map. 

File format basics 
Every IFF file starts with a 64-byte header: 

00000000 4946 4620 4649 4C45 2032 2E30 3A54 5950 IFF FILE 2.0:TYP 
00000010 4520 464F 4C4C 4F57 4544 2042 5920 5349 E FOLLOWED BY SI 
00000020 5A45 0020 4A41 4D49 4520 444F 4F52 4E42 ZE. JAMIE DOORNB 
00000030 4F53 2026 204D 4158 4953 2031 3939 3600 OS & MAXIS 1996. 

or 

00000000 4946 4620 4649 4C45 2032 2E35 3A54 5950 IFF FILE 2.5:TYP 
00000010 4520 464F 4C4C 4F57 4544 2042 5920 5349 E FOLLOWED BY SI 
00000020 5A45 0020 4A41 4D49 4520 444F 4F52 4E42 ZE. JAMIE DOORNB 
00000030 4F53 2026 204D 4158 4953 2031 0001 7031 OS & MAXIS 1..p1 

The 2.0 IFF file has a 64-byte string (=array of characters) with some null-bytes here and there. The 2.5 IFF file starts with "IFF FILE 2.5" and ends with a 4-byte pointer to the Resource Map. This pointer is a place in the IFF file, where 0 is the beginning of the file. 

The pointer is stored in high-to-low order. This means, that the most significant bytes (the higher bytes) are stored first, then the less significant bytes. Usually, values are stored in low-to-high order, like hex 11 22 33 44 stored as "4433 2211" and hex 12345678 as "7856 3412". In this case, these values are stored as "1122 3344" and "1234 5678" (these spaces is just to make it easier to follow). After the header, all sections are stored. Between two sections, there sometimes appear so-called padding bytes. These bytes between multiple sections have the value of hex A3 and are to be ignored. 

Size Name Description 
4 bytes sType Type / extension of the section, e.g. "OBJD" or "FAMI" or "BMP_" 
4 bytes drLength Size of the section, header included 
2 bytes wrID Identification number of section. Should be unique in every type 
2 bytes wrUnk Unknown value, probably something with readonly stuff 
64 bytes sName Name of the section 

All values are in high-to-low order stored. One can see the sType value as a 4-byte number. That number is stored in high-to-low order. In a programming language, you can compare the 4-byte-number drType with the numeral equavalent of "OBJD" instead of comparing a string with "OBJD", which takes much more time. 

The wrID identification number can be shared by sections of different types. But one may not have to type "BHAV" sections both having wrID set to 4096. One of these sections won't be able to be used in such cases. But one may have "OBJD" with wrID 5000 and "TTAB" with wrID set to 5000 as well. 

As you see, the section header is exactly 76 bytes long. After the header follows the section-specific data. 

One of the sections will be of type "rsmp". (Yes that's not the same as "RSMP", which doesn't exist!) This section is the Resource Map. My programs usually don't use the pointer in the IFF file header, but encounter the "rsmp" section while screening the IFF file for undocumented sections. The reason for this is that there are IFF files with multiple Resource Maps (yes they exist! these IFF files are not cleaned up correctly) or that there are Resource Maps pointing to non-existing sections (again: not cleaned up well after deleting sections). I think the routines Maxis and some other programmers use don't save the file completely, but only mark deleted sections as type XXXX and add a new Resource Map at the end of the file, to prevent long save times. My program is designed to load the whole file and save the whole file. While loading an IFF file, the *whole* file is stored in memory and the file on the hard drive can even be deleted without the program losing any data. 

The Resource Map section format 
This table describes the data of the section, thus everything *after* the 76-byte header! 

Size Name Description 
8 bytes sEmpty Contains zero-bytes 
4 bytes sMagic Always "pmsr" so every loader knows this is indeed a valid Resource Map. 
4 bytes dLength Should be the length of the section, but is often zero. Don't trust this value! 
4 bytes dTypes Number of section types used in this file 

Please note that all these values are in low-to-high order! 

After these values, a number of type entries are stored, which list the sections of that type in the file: 

Size Name Description 
4 bytes sType The low-to-high order equavalent of the type (like "DJBO" or "IMAF" or "BATT"). 
4 bytes dSections Number of section definitions following 

Now, all sections of type sType will follow: 

Size Name Description 
4 bytes dPosition Position of this section in the file. For the section length, consult its header at that position 
2 bytes wID Identification number of section. Should be unique in every type 
2 bytes wUnk Unknown value, probably something with readonly stuff 
x bytes szName Name of the section (terminated zero) 

These values are all in low-to-high order. The sName string has an undefined size. Thus, the reader doesn't know the length of the string. This string terminates with zero, however, like: "6566 6700 ABC." is the string "ABC" plus a zero byte. So, the reader just reads the name until it reaches zero. After this zero, the next section definition begins. 

Sometimes there is a padding-byte between two section definitions. This byte is placed if and only if the current position (thus the byte after the zero-byte) is at an odd (=non-even) position relative to the beginning of the section. 

In short, if the beginning of the section were memory location 0 and the current byte is byte 457, then the alignment byte will be placed, so that the next section definition or type list starts at byte 458. The reason: alignment. When looking for a certain section type, a program doesn't have to compare at every single byte, but at every two bytes. This makes the routines faster. The alignment byte is always hex A3. 

I hope you now understand the IFF file format and the Resource Map format. Any questions left? Feel free to contact me! 

A sample Visual Basic module which loads IFF files and can display can be downloaded at the download page. 

Example 
This is an example of a resource map. Study it closely! 

00011550: 00 72 73 6D-70 00 00 03-66 00 00 00-10 00 00 00 .rsmp...f....... 
00011560: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00 ................ 
00011570: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00 ................ 
00011580: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00 ................ 
00011590: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00 ................ 
000115A0: 00 00 00 00-00 70 6D 73-72 F0 07 00-00 0E 00 00 ....pmsrð....... 
000115B0: 00 66 4A 42-4F 01 00 00-00 CA 04 00-00 A7 41 10 .fJBO....Ê...§A. 
000115C0: 00 00 A3 23-52 54 53 02-00 00 00 EF-26 00 00 81 ..£#RTS....ï&..� 
000115D0: 00 10 00 61-32 6F 00 5A-27 00 00 82-00 10 00 63 ...a2o.Z'..‚...c 
000115E0: 32 6F 00 42-41 54 54 01-00 00 00 C5-27 00 00 81 2o.BATT....Å'..� 
000115F0: 00 10 00 43-6C 6F 63 6B-20 2D 20 41-6C 61 72 6D ...Clock - Alarm 
00011600: 20 74 72 65-65 20 74 61-62 6C 65 00-A3 73 41 54 tree table £sAT 
00011610: 54 01 00 00-00 15 29 00-00 81 00 10-00 00 A3 50 T.....)..�....£P 
00011620: 52 47 44 07-00 00 00 34-3C 00 00 80-00 10 00 41 RGD....4<..€...A 
00011630: 6C 61 72 6D-20 43 6C 6F-63 6B 20 64-72 61 77 20 larm Clock draw 
00011640: 67 72 6F 75-70 00 A3 96-3E 00 00 81-00 10 00 41 group.£–>..�...A 
00011650: 6C 61 72 6D-20 43 6C 6F-63 6B 20 64-72 61 77 20 larm Clock draw 
00011660: 67 72 6F 75-70 00 A3 78-42 00 00 82-00 10 00 72 group.£xB..‚...r 
00011670: 69 6E 67 69-6E 67 00 5A-46 00 00 83-00 10 00 72 inging.ZF..ƒ...r 
00011680: 69 6E 67 69-6E 67 00 BC-48 00 00 84-00 10 00 72 inging.¼H..„...r 
00011690: 69 6E 67 69-6E 67 00 9E-4C 00 00 85-00 10 00 72 inging.žL..…...r 
000116A0: 69 6E 67 69-6E 67 00 00-4F 00 00 86-00 10 00 72 inging..O..†...r 
000116B0: 69 6E 67 69-6E 67 00 54-4C 41 50 03-00 00 00 E2 inging.TLAP....â 
000116C0: 52 00 00 00-00 00 00 00-A3 3E 56 00-00 01 00 00 R.......£>V..... 
000116D0: 00 00 A3 9A-59 00 00 02-00 00 00 00-A3 32 52 50 ..£šY.......£2RP 
000116E0: 53 07 00 00-00 F6 5C 00-00 80 00 00-00 41 6C 61 S....ö\..€...Ala 
000116F0: 72 6D 20 43-6C 6F 63 6B-20 67 72 61-70 68 69 63 rm Clock graphic 
00011700: 00 3E 80 00-00 81 00 00-00 41 6C 61-72 6D 20 43 .>€..�...Alarm C 
00011710: 6C 6F 63 6B-20 67 72 61-70 68 69 63-00 C4 93 00 lock graphic.Ä“. 
00011720: 00 64 00 00-00 70 68 6F-6E 65 00 6E-A5 00 00 65 .d...phone.n¥..e 
00011730: 00 00 00 70-68 6F 6E 65-00 E4 B6 00-00 66 00 00 ...phone.ä¶..f.. 
00011740: 00 70 68 6F-6E 65 00 70-C8 00 00 67-00 00 00 70 .phone.pÈ..g...p 
00011750: 68 6F 6E 65-00 F6 D9 00-00 68 00 00-00 70 68 6F hone.öÙ..h...pho 
00011760: 6E 65 00 56-41 48 42 07-00 00 00 CE-DB 00 00 00 ne.VAHB....ÎÛ... 
00011770: 10 10 00 6D-61 69 6E 00-A3 6E DC 00-00 02 10 10 ...main.£nÜ..... 
00011780: 00 53 65 74-20 41 6C 61-72 6D 20 54-45 53 54 00 Set Alarm TEST. 
00011790: A3 DE DC 00-00 07 10 10-00 55 6E 73-65 74 20 41 £ÞÜ......Unset A 
000117A0: 6C 61 72 6D-20 54 45 53-54 00 A3 4E-DD 00 00 06 larm TEST.£NÝ... 
000117B0: 10 10 00 55-6E 73 65 74-20 41 6C 61-72 6D 00 E2 ...Unset Alarm.â 
000117C0: DD 00 00 01-10 10 00 53-65 74 20 41-6C 61 72 6D Ý......Set Alarm 
000117D0: 00 76 DE 00-00 03 10 10-00 70 72 6F-63 65 73 73 .vÞ......process 
000117E0: 20 72 69 6E-67 00 A3 1E-E0 00 00 05-10 10 00 69 ring.£.à......i 
000117F0: 6E 69 74 20-74 72 65 65-00 5F 50 4D-42 03 00 00 nit tree._PMB... 
00011800: 00 EE E0 00-00 D0 07 10-00 43 61 74-61 6C 6F 67 .îà..Ð...Catalog 
00011810: 00 D0 01 01-00 A0 0F 10-00 53 70 65-65 63 68 00 .Ð... ...Speech. 
00011820: A3 52 05 01-00 70 17 10-00 53 70 65-65 63 68 00 £R...p...Speech. 
00011830: A3 4E 4F 43-42 01 00 00-00 D4 11 01-00 00 10 10 £NOCB....Ô...... 
00011840: 00 54 75 6E-69 6E 67 20-56 61 6C 75-65 73 00 54 .Tuning Values T 
00011850: 4F 4C 53 01-00 00 00 26-12 01 00 80-00 10 00 00 OLS....&...€.... 
00011860: A3 56 41 57-46 03 00 00-00 0E 13 01-00 01 00 10 £VAWF........... 
00011870: 00 00 A3 6B-13 01 00 02-00 10 00 00-A3 CC 13 01 ..£k........£Ì.. 
00011880: 00 03 00 10-00 00 A3 44-4A 42 4F 01-00 00 00 2D ......£DJBO....- 
00011890: 14 01 00 A7-41 10 00 43-6C 6F 63 6B-20 2D 20 41 ...§A..Clock - A 
000118A0: 6C 61 72 6D-00 53 53 54-43 01 00 00-00 A2 05 00 larm.SSTC....¢.. 
000118B0: 00 D0 07 10-00 00 A3 - - .Ð....£ 

Strings 

What are strings? 
A problem when dealing with data formats are strings. Strings are arrays of characters which are the texts used in the game (e.g. "Baby" or "Bookshelf"). Because the length of the string is very variable, one can't just reserve 16 bytes for a string, but needs to save it in an effective way... having 100 strings of different length and reserving 64 bytes per string (some 60 bytes long, others 5 bytes etc.) is very inefficient. This article describes the way The Sims saves strings. 

"Basic" strings 
One way to save a string is called Basic. It is called that, because the programming language Basic saves strings the same way. First, the length is written, followed by all characters of the string (not terminated with a zero byte). 

The disadvantage of this type of saving strings is that the length must be calculated when saving the file and also takes 2 or 4 bytes in the file. Also, there is no language byte. 

Zero terminated strings 
The other way The Sims saves strings (and this one is used most) is by first writing one byte containing the language and then writing the whole string ending it with a zero byte (0x00) to indicate the string has ended. All C++ string management subroutines use this type of storing strings in memory (except for that language byte). 

One disadvantage is that, since the string length isn't saved, the length has to be computed when the file is loaded. Personally, I use the MFC class CString to handle it. 

Developer/translator notes 
Usually, a Zero terminated string is directly followed by another string terminated zero without a language byte and alignment bytes between the strings (For more information about alignment bytes, read the "IFF files" article). This string is used by the translators and developers as a reference of the purpose of the string and how to translate it. 

Languages 
Every Common string starts with one byte containing language information. As far as I know, there are 15 languages used in The Sims: 
0x01 USEnglish 
0x02 UKEnglish 
0x03 French 
0x04 German 
0x05 Italian 
0x06 Spanian 
0x07 Dutch 
0x09 Swedish 
0x0E Portuguese 
0x0F Japanese 
0x10 Polish 
0x11 Traditional Chinese 
0x12 Simplified Chinese 
0x13 Thai 
0x14 Korean 

Bit compression 

Bit compression 

Introduction to Bit Compression 
The Sims uses an uncommon way of compressing. This type of compression is used in, among others, the TTAB (Tree table, Interaction menu section), ObjM (used in house??.iff) and CARR (used in Careers.iff) sections. I've written two algorithms which decompresses and compresses the sections. When decompressing, one has to know whether it's decompressing/compressing a 4-byte, 2-byte or 1-byte value. 

Algorithms for 4-byte values: 

Read algorithm 

1) Read one bit --> if 0 then value = 0 and quit subroutine 
2) Read two bits --> 0...4 and read the table (For 4 bytes: [0]=6, [1]=11, [2]=21, [3]=32) 
3) Read n bits (n is the value off the table) and store in "value" 
4) Expand the most significant (very first) bit read (thus make all higher bits than bit 5/10/20/32 have the same binary value as that bit) 
5) Return the value 

Write algorithm 

Note:every write operation is bit-by-bit! 
1) If the value is equal to 0, write 0 and quit, else write 1 
2) If bit 5 and higher are all 0 or 1 then Temp = 0 
3) Else if bit 10 and higher are all 0 or 1 then Temp = 1 
4) Else if bit 20 and higher are all 0 or 1 then Temp = 2 
5) Else Temp = 3 
6) Write Temp (2 bits) 
7) Write n bits containing bits 0...n of the value, where n = 6/11/21/32 

Tables 

Bit 1 Bit 2 4-byte 2-byte 1-byte 
0 0 6 5 2 
0 1 11 8 4 
1 0 21 13 6 
1 1 32 16 8 

Character files 

Character files, what are these? 
Character files are IFF files which contain information about the very sims themselves, which are called characters. These IFF files often have a filename like user00024.iff or something similar and contain information specific to the character's body. All information about its body, head, name and even the icon in the queue is stored in this IFF file. Any information about interests, family, personality and skills and other mental things are not stored in this file, but in the Neighborhood.iff file. 

The contents of a character file 
Every character file has about the same contents. Some of the sections are always identical, others are not. 

Type ID Name Description 
BHAV 4096 Main Always the same 
BHAV 4097 init tree Always the same 
BHAV 4098 load tree Always the same 
BHAV 4099 init traits Always the same 
BMP_ 2002 faces The face of the character 
BMP_ 2003 rel. images The faces of the character in different moods 
BMP_ 2004 thumbnail The queue icon of this character 
BMP_ 2005 speech_med Used in the speech balloons 
BMP_ 2006 speech_large Used in the speech balloons 
BMP_ 2007 web_image Not always present! Image used in the HTML pages 
CTSS 2000 Contains the name of the character, sometimes in multiple languages 
GLOB 128 Semi-global file Always the same 
OBJD 128 user00032 - Twistie Contains object information about this character 
SLOT 128 Always the same 
STR# 200 bodystring Contains the information about the body & head of the character 
STR# 300 Behavior editor string set Always the same 
STR# 304 suit names Always the same 

Conclusion 
As you see, there are just a few section character-specific. These can be divided into 4 categories: images, name, object-information and body-information. The object-information part which is with each character different is only the Global User ID. The rest of the section is always the same. 

Application 
This information can be used to change the head or the body of your sim if you get bored, but want to keep the mental properties you worked so hard on developing. It can also be used to repair damaged character files. I did this once for someone who sent me a mail having this problem. It turned out that the bodystring part of the file, which is the most important one, was overwritten and deleted. I wrote a tutorial for him to repair that fix doing a transplantation sort of thing by making a new character with the same body properties and copying these properties to the old file. This tutorial will be found on the IFFEdit site (it's the Expert Edit tutorial). 

Tweaking with the Neighborhood 

Short introduction 
To understand the information, you need to have read all parts about the Neighborhood.iff file (FAMI, FAMs and NBRS). 

I've had many difficulties saving the Neighborhood.iff file. These difficulties resulted in a couple of bugs which caused a lot of trouble and a crashing The Sims. To prevent other programs and hex editing folks to have the same problems, I'll tell you some about how to correctly save the Neighborhood.iff file. One things you should have done already, is saving all sections. When experimenting with the file, I first started replacing the NBRS section, which worked eventually. Then, I'll now guide you though the dark foggy mazes of the Neighborhood.iff file. (Why is my nickname Mazelord anyway?) 

How The Sims loads the file 
The Sims doesn't use the Resource Map, for some strange reason. I don't know why they implemented it, but they read the whole file and generate their own resource map in memory (I do that too for the 2.0 files and recently for 2.5 files with a bad RSMP pointer). It turns out that the order in which the Neighborhood editor is saved is very important. I don't know exactly how they load the file, but it must be a strange way! 

Sorting the inner NRBS 
First, the NBRS section must be sorted. My programs assign a unique relation tag to every character, starting by 1. Then, I save the highest number for the DWORD after 'srbn'. Then I sort the characters in ascending order (thus starting by 1) on relationtag. 

Note: my programs save after 'srbn' the highest relationtag + 1 and after all characters an extra DWORD:00000000. I don't remember exactly why I did that, but it worked eventually. 

Correcting the FAM? IDs 
The highest Family number must also have the highest ID. So I sort the FAMI sections by Family number, changing the FAMs sections and FAMh sections too (actually, my program generates a new FAMs section and has the contents of the FAMh section saved in the CFamily structure). Note that family 0xffffffff must have ID=0! That family is the template family. 

The correct order 
I worked on this most. I've spent countless hours hex editing Neighborhood.iff files and eventually things went clear. First, the NGBH section is saved, followed by the NBRS one. Then all families are stored. First, we take every FAMI, FAMs and FAMh sections with the same ID together. Then we sort them with the highest ID first. Then we just save them beginning with the FAMI section with the highest ID, followed by the corresponding FAMs and, if there is one, the FAMh section. After saving all these sections, we end with TATT. My program doesn't save other sections, so if you got your comments saved as a STR#, don't expect it to survive my surgery. 

Adjusting the language byte of the FAMs section 
There was still one problem! It turned out that if The Sims saves which section has last been edited. To prevent The Sims from crashing, all language bytes in the FAMs section must be set to 1 (USEnglish). 

OBJD 

Hex dump of an OBJD section 

00000040 4F42 4A44 0000 0124 41AA 0010 426F 6F6B OBJD...$A...Book 
00000050 7368 656C 6620 2D20 5265 7472 6F00 0000 shelf - Retro... 
00000060 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
00000070 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
00000080 0000 0000 0000 0000 0000 0000 8A00 0000 ................ 
00000090 0400 9001 0100 0000 0000 8300 0000 0400 ................ 
000000A0 0000 0000 0000 0000 BC7A 1942 0000 0000 .........z.B.... 
000000B0 8E03 0000 0000 0000 0100 0000 0000 0000 ................ 
000000C0 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
000000D0 0000 8800 0900 0000 6C01 8000 4000 D007 ........l...@... 
000000E0 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
000000F0 0000 0000 0000 0000 0000 0000 0000 FFFF ................ 
00000100 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
00000110 0000 0000 0000 0000 2F71 DC5C 0000 0000 ......../q.\.... 
00000120 0000 0000 0100 0000 0000 0000 0000 0000 ................ 
00000130 0000 0000 0000 0000 0000 0300 0000 4300 ..............C. 
00000140 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
00000150 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
00000160 0000 0000 4F42 4A66 0000 00D8 41AA 0010 ....OBJf....A... 

Offset HEX data Name Description 
0 8A00 0000 Version Which version of the OBJD section 
4 0400 Initial stack size How large the stack is (used in the BHAV sections) 
6 9001 Base graphic ID of first DGRP section 
8 0100 Number of graphics Number of DGRP sections 
10 0000 Old tree id (main) See below 
12 0000 Old tree id (gardening) See below 
14 8300 Tree table ID Which tree table to use, FFFF if the OBJD is a subsection 
16 0000 Interaction group I have absolutely no idea... 
18 0400 Type What kind of a object this is (see below) 
20 0000 Master ID The local ID of the master section (if this = subsection) 
22 0000 Sub index Which subsection this is 
24 0000 Old tree id (wash hands) See below 
26 0000 Anim table ID I have absolutely no idea yet... 
28 BC7A 1942 GUID The Global ID of this section 
32 0000 Disabled If set to 0001, this object doesn't appear in the Catalog 
34 0000 Old tree id (portal) See below 
36 8E03 Price How much it'll cost to buy this object 
38 0000 Body strings ID I have no idea... 
40 0000 Slots ID I have no idea... 
42 0000 Old tree id (allow intersection) See below 
44 0100 Unused Well... just as it says 
46 0000 Unused Well... just as it says 
48 0000 Old tree id (prepare food) See below 
50 0000 Old tree id (cook food) See below 
52 0000 Old tree id (place on surface) See below 
54 0000 Old tree id (dispose) See below 
56 0000 Old tree id (eat food) See below 
58 0000 Old tree id (pickup from slot) See below 
60 0000 Old tree id (wash dish) See below 
62 0000 Old tree id (eating surface) See below 
64 0000 Old tree id (sit) See below 
66 0000 Old tree id (stand) See below 
68 0000 Sale price This seems to be not used... 
70 8800 Initial depreciation How much the value will decrease immediately after it's bought 
72 0900 Daily depreciation How much the value will decrease daily 
74 0000 Self depreciation If this is 0001, then the BHAV sections take care of the depreciation 
76 6C01 Depreciation limit Until which value the value will be decreased 
78 8000 Room flags See below 
80 4000 Function flags See below 
82 D007 Catalog strings ID Which CTSS section will be used for the text in the Catalog 
84 0000 Is global sim object I have got a clue, but I don't get it completely... 
86 0000 Old tree id (init) See below 
88 0000 Old tree id (place) See below 
90 0000 Old tree id (user pickup) See below 
92 0000 Wall style The wall style of the object (see below) 
94 0000 Old tree id (load) See below 
96 0000 Old tree id (user place) See below 
98 0000 Object version Version number of the object 
100 0000 Old tree id (room changed) See below 
102 0000 Motive effects ID Well... I don't know 
104 0000 Old tree id (cleanup) See below 
106 0000 Old tree id (level info request) See below 
108 0000 Catalog popup ID I don't know 
110 0000 Old tree id (serving surface) See below 
112 0000 Level offset ??? 
114 FFFF Shadow See below 
116 0000 Number of attributes I don't know 
118 0000 Old tree id (clean) See below 
120 0000 Old tree id (queue skipped) See below 
122 0000 Front direction Which direction the front direction is (see below) 
124 0000 Old tree id (wall adjacency changed) See below 
126 0000 MT lead object ??? 
128 0000 Dynamic sprites base ID The ID of the first SPR2 section 
130 0000 Number of dynamic sprites Number of SPR2 sections 
132 0000 Chair entry flags Which side of the chair is the entry side (see below) 
134 0000 Tile width How close people can walk to the object (unit: 1/16 tile, should be an even number) 
136 0000 Inhibit suit copying ??? 
138 0000 Build mode type Like function and room flags, see below 
140 2F71 DC5C Original GUID Global ID of original object 
144 0000 0000 Suit GUID ??? 
148 0100 Old tree id (pickup) See below 
150 0000 Thumbnail graphic Which DGRP section is used for the thumbnail in the Catalog 
152 0000 Shadow flags See below 
154 0000 Footprint mask ??? 
156 0000 Old tree id (dynamic multi-tile update) See below 
158 0000 Shadow brightness 0000 = normal, the larger the brighter 
160 0000 Old tree id (repair) See below 
162 0000 Wall style sprite ID The custom wall style sprite ID 
164 0000 ratingHunger The Hunger rating (catalog value) 
166 0000 ratingComfort The Comfort rating (catalog value) 
168 0000 ratingHygiene The Hygiene rating (catalog value) 
170 0000 ratingBladder The Bladder rating (catalog value) 
172 0000 ratingEnergy The Energy rating (catalog value) 
174 0300 ratingFun The Fun rating (catalog value) 
176 0000 ratingRoom The Room rating (catalog value) 
178 4300 Skill flags Which skills will be improved (catalog value), see below 
180 0000 Number of type attributes ??? 
182 0000 Misc flags See below 
184 0000 0000 Type Attr GUID ??? 
188 0000 Unused 
190 0000 Unused 
192 0000 Unused 
194 0000 Unused 
196 0000 Unused 
198 0000 Unused 
200 0000 Unused 
202 0000 Unused 
204 0000 Unused 
206 0000 Unused 
208 0000 Unused 
210 0000 Unused 
212 0000 Unused 
214 0000 Unused 

The 'Old tree id' attributes are used to identify the BHAV section used to load / init / etc. the object. They're often 0000, that indicates not used. 

Flags can be hexadecimal added (0x8+0x4=0xC; 0xC+0x2+0x1=0x10) 

Room flags Function flags Build Mode Type 
0001 = Kitchen 0001 = Seating 0000 = None 
0002 = Bedroom 0002 = Surfaces 0001 = Door 
0004 = Bathroom 0004 = Appliances 0002 = Window 
0008 = Living room 0008 = Electronics 0003 = Stair 
0010 = Outside 0010 = Plumbing 0004 = Plant 
0020 = Dining room 0020 = Decorative 0005 = Fireplace 
0040 = Misc. 0040 = Misc. 0006 = Column 
0080 = Study 0080 = Lighting 0007 = Pool 

Misc flags Chair entry flags Skill flags 
0001 = Hard to click 0001 = Front 0001 = Cooking 
0002 = Clear attributes with tutorial reset 0002 = Front right 0002 = Mechanical 
0004 = Right 0004 = Logic 
0008 = Back Right 0008 = Body 
0010 = Back 0010 = Creativity 
0020 = Back Left 0020 = Charisma 
0040 = Left 0040 = Study (children) 
0080 = Front Left 

Wall Style Front Direction Shadow flags 
0000 = None 0000 = Front 0001 = Thumbnail has shadow 
0001 = Normal 0002 = Right 0002 = Shadow on runtime (not used) 
0002 = Fence 1 0004 = Back 
0003 = Door (Front?) 0006 = Left 
0004 = (Door Back?) 
0005 = Door Left 
0006 = Door Right 
000C = Fence 2 
000D = Fence 3 
000E = Fence 4 
000F = French door 
0016 = Custom 

Type 
0002 = Character 
0004 = Buy Object 
0008 = Build Object 
The rest is unknown 

Note that all HEX values are in Intel order (see Resource Map page), thus you'll need to reverse it and convert it to decimal to 'understand' some values. The last few unknown values are probably there in case Maxis decides to add a few attributes and such. I've just copied this information out of the Behavior.iff file (definition labels section) and most attributes are still not clear to me. Any tips/explanations? Please mail me! 

CTSS 

Short introduction 
To understand the information, you need to have read the part about strings and the part about section relationships. 

The Sims stores text information about the object which is used in the Catalog (Buy/Build mode) in the CTSS section. The CTSS section is a section like other sections which main purpose is storing multiple strings, like TTAs and STR#. 

String format used 
In CTSS, there is only one type used: Common type. This is because CTSS sections are only used to be displayed in the game, and therefore need the language byte. 

CTSS format 
First WORD: Unknown. Appears to be FDFF or FEFF. I think it's purpose is to determine what to do on failure. The FF one always means return FALSE and is returned if there is a failure. The FD or FE byte is the return value on success. This is used in the BHAV section too. 

Second WORD: Number of Strings following. 

The rest: For each language, two Common strings with notes: the first is the name of the objects, the latter is a description of the objects. 

If there are no strings for a certain language (as is often the case for UKEnglish) then the default language is used (USEnglish). 

BMP_ 

Short introduction 
To understand the information, you only need to have read the Section relationships part. 

The format 
Simple: an uncompressed bitmap file. I just save the section to a file on the harddisk, then read it using LoadImage() and deleting the file afterwards. I don't have found a way yet to read the bitmap directly from the IFF file. 

What it's used for 
There are in an ordinary object file three BMP_ sections. The one named 'Catalog' is responsible for the button used in the catalog (Buy/Build mode). The two others, both named 'Speech', are probably used as icons in the upper left of the screen. I don't know exactly about the small one, however. Maybe it is used in the think balloons... 

TTAs 

Short introduction 
To understand the information, you need to have read the part about strings and the part about section relationships. 

The Sims stores text information about the so-called pie menu (the menu you see when you clicked the object) in the TTAs section. When editing a TTAs section, it is very important to keep the strings at the same position. I don't mean position in the file, but that the 2nd string remains the 2nd string and the 5th string isn't deleted so that the 6th string becomes the 5th string. There is one simple reason for that: the TTAB sections references to these strings as 1st, 2nd, 3rd etc. The TTAB section is the section determining the main behaviour of the object and determines the look of the pie menu. But now, I'll tell you about TTAs, which looks like CTSS. 

String format used 
In TTAs, there is only one type used: Common type. This is because the strings in the TTAs sections are used to be displayed in the game, and therefore need the language byte. 

TTAs format 
First WORD: Unknown. Appears to be FDFF or FEFF. I think it's purpose is to determine what to do on failure. The FF one always means return FALSE and is returned if there is a failure. The FD or FE byte is the return value on success. This is used in the BHAV section too. 

Second WORD: Number of Strings following. 

The rest: For each language, one Common string with notes, which is the text displayed in a button of the pie menu. 

If there are no strings for a certain language (as is often the case for UKEnglish) then the default language is used (USEnglish). 

STR# 

Short introduction 
To understand the information, you need to have read the part about strings and the part about section relationships. 

The Sims stores text information used in the game (mostly dialog boxes) as well as used by the scripts in the STR# section. This section is only used by the BHAV sections and are very important, since they aren't only the dialog box texts but also contain information BHAV uses. 

String format used 
STR# displays text in the game, like TTAs, but also uses text for internal purposes (which are described later this article) and therefore use Basic format as well as Common. Strangely, Basic format is not often used for these internal purposes, but for developer comments added. For internal purposes (BHAV) is often the Common format used, with just one language (USEnglish), probably because of the first WORD. 

STR# format 
The First WORD is not there in a Basic STR# section. That's how I know what type of STR# section I'm dealing with: if the highest byte in the WORD is FF, then it's a Common type section, else it's a Basic type, and the read value is the number of strings following. 

First WORD: Unknown. Appears to be FDFF or FEFF. I think it's purpose is to determine what to do on failure. The FF one always means return FALSE and is returned if there is a failure. The FD or FE byte is the return value on success. This is used in the BHAV section too (and appears in CTSS and TTAs too). 

Second WORD: Number of Strings following. 

The rest: In case Common: for each language, n Common strings with notes. In case Basic: n Basic strings (without notes, btw). 

If there are no strings for a certain language (as is often the case for UKEnglish) then the default language is used (USEnglish). 

Internal purposes 
The a2o, a2c, a2a, c2c etc. STR# sections (these were names) are used by BHAV to tell which animation should be displayed. The strings are the names of animations and are defined animation.ndx file which points to an other file containing the filename. 

The "Call Named Tree prim string set" STR# section contains the strings used to call a BHAV section knowing the name of it. These BHAV sections are often in other IFF files (e.g. JobFinder.iff contains named BHAV sections used by the computers and the newspaper). 

The "Suit primitive strings" STR# section contains names of skins in the GameData\Animation directory. (see notes of a2o etc. sections). 

Most other sections either contain strings displayed in the game or strings referring to animations and such. 

FWAV 

Short introduction 
To understand the information, you need to have read the part about section relationships. 

The Sims stores information about sounds in the FWAV sections. The string is the name of a sound and references to the .hot files in the SoundData directory, which contains a lot of information and the filename of the sound. 

FWAV format 
Most easy format! Just a zero terminated string (A number of characters closing with a 0x00 byte). 

FAMI 

Short introduction 
To understand the information, you need to have played The Sims once FPRIVATE "TYPE=PICT;ALT=wink.gif". 

The Sims stores information about every family, whether having a house or not, in the FAMI, FAMs and FAMh sections. I don't know anything about the FAMh section, but the FAMI section will follow now. 

FAMI format 
The format is not difficult. It is simply a couple of DWORDs followed by an array of DWORDs: 

Position Contains 
0000 Unknown number, possibly current language when the family was made. 
0004 'IMAF' 
0008 House lot number 
000C Family number 
0010 Family cash 
0014 Net Worth 
0018 Friends 
001C Unknown 
0020 Member count 

After that, the Character IDs of the members follow. This will be explained in the NBRS section. 

I don't know what unknown is... if you've got any idea, drop me a mail and I'll consider it. 

FAMs 

Short introduction 
To understand the information, you need to have read the part about section relationships. 

This section contains the name of the family. 

FAMs format 
This section is identical to TTAs, with one exception: there is only one string, in one language (should be set to 1, see 'Tweaking with the Neighborhood') and with an often empty note. 

NBRS 

Short introduction 
To understand the information, you need to have played the Sims more than once. 

The Sims stores information about all characters in The Sims, except for the information about the 'object' sim, such as look , but interests and relationships, jobs and skills and such, in the NBRS section (NBRS = NeigBouRS). 

NBRS format 
This is quite a difficult format. 

It is basically a header followed by an array of character information. 

Position Means 
0000 Unknown number, zero at my PC 
0004 Some ID number, same as the second DWORD of the NGBH section 
0008 'SRBN' 
000C DWORD Number of characters (or better: highest relationtag) 

After that, all characters are stored. There are two types of characters: short and long. The short is, well, short and the longer one contains far more information about the character. 

Every character starts with DWORD:00000001, then DWORD:00000004, and then a zero-terminated string containing the character filename followed by an alignment byte (0xA3) if needed. Then, one of the following cases occur. By reading the file, I find the 0xffffffff value to know what I'm dealing with. 

Short: 
Position Means 
0000 Zero 
0004 Zero 
0008 Relation tag (see relationships later) 
000A Character ID (This is the Character ID the FAMI section references to 
000E always 0xffffffff, I use this value to know if the section is short or long. 
0012 Number of relationships 

Long: 
Position Means 
0000 Zero 
0004 Type: always 5 or 6 (my program sets new characters to 6). I think 5 means inactive and 6 means talkable too or something like that, but I'm not sure 
0008 Zero 
000C Nice 
000E Active 
0010 Unknown (always zero) 
0012 Playful 
0014 Outgoing 
0016 Neat 
0018 DWORD Unknown (always zero)Nice 
001C Cooking 
001E Charisma 
0020 Mechanical 
0022 DWORD Unknown (always zero) 
0026 Creativity 
0028 Unknown (always zero) 
002A Body 
002C Logic 
002E 54 unknown bytes (always zero) 
0064 Politics 
0066 Weather 
0068 Sports 
006A Leisure 
006C Scifi 
006E Travel 
0070 Flowerpower 
0072 Babies 
0074 Beauty 
0076 Spookystuff 
0078 Career path 
007A Career level 
007C DWORD Age (09 = Child, 1b = Adult) 
0080 Race (01 = Light, 02 = Dark, 03 = Medium) 
0082 DWORD Unknown (Color?) 
0086 DWORD Unknown (Perhaps skin related) 
008A DWORD Gender (0 = Male, 1 = Female) 
008E If ghost, the lot on which to haunt 
0090 Haunt level (if 1 --> ghost) 
0092 Unknown (zero) 
0094 20 unknown bytes (zero) 
00A8 Relation tag (see below) 
00AA DWORD Character ID 
00AE Unknown value, always oxffffffff 
00B2 Number of relationships 

Then, an array of all relationships follow: 

Position Means 
0000 DWORD Unknown value, always DWORD:00000001 
0004 Relationtag of friend/enemy 
0006 Unknown value, always WORD:0000 
0008 DWORD Type (1 means 1 DWORD following, 2 means 2 DWORDs following) 
000C DWORD Strength (from -100 up to 100 inclusive) 
0008 DWORD inLove (1 means love, 0 means no love) this value is not included in Type 1 relationships (my program saves only type 2 relationships, btw.) 

After the relationships, just continue reading until BYTE:01 00 00 00 04 00 00 00 is found, which indicates the next character. Do this until the position pointer exceeds the section length.

•