Maine Coon cat from the Petz games

Kalium's Petz

Great Dane dog from the Petz games

SCP / Personality Research Notes

May 2020 note: this page has been updated to correct errors and add new information.

New! I've created the SCP Reader to parse SCP files in accordance with what we currently know.

This page details some of my dabblings into taking apart the SCP file, which determines at least some aspects of a breed's personality. I started playing with these files after reading the Petz dev interview posted to the RKC boards, which uncovered a lot of fascinating information about how the game worked. Note that this page is full of speculation; do not take it as a tutorial for how to edit SCP files to create custom personalities, or indeed a tutorial for anything! As of the time of writing (mid 2019) the only way to edit a breed's personality is to give it an SCP from another breedfile, effectively transplanting the donor breed's personality. I cover how to do this in my tutorial Swapping breedfile personalities.

However if you're interested in speculation and experimentation, read on, and I fully encourage you to build upon this, mess about with your game, and share your findings. If you want to drop me a line about anything listed here, email me: kaliumlynx@protonmail.com.

More SCP research can be found on Reflet's script research page. If you want to dive in further, join us at the Petz Hacking and Modding Discord.


The SCP file

The SCP is a binary resource file found within petz breedfiles and resource DLLs. Every breed has its own unique SCP. There are also much larger "master" SCP files found within the catrez.dll and dogrez.dll files. My guess is that the master files control generic behaviour for a cat or dog, and the breed specific files are an additional override that give rise to that breed's unique behaviours. The game's mice also have SCPs, as do some toys and other objects. The structure of these files appears to be similar across all these instances. The file extension SCP is possibly short for "script" but nobody is sure.

We know that the game uses a finite state machine for the pets' AI, and the SCP presumably hooks up to that state machine to influence it and create personalities. The SCPs themselves do not appear to contain executable code - they seem to be references for the state machine to use when deciding what to do.

When opened up in LNZ Pro or another resource editor, the SCP will appear as hex code. Below is the SCP of a labrador dog in LNZ Pro:

Labrador SCP open in LNZ Pro.

Not very intuitive, but it is possible to see patterns in the data, and that is what I've been experimenting with in order to crack exactly what's going on in here.


Mouse SCP Breakdown

I chose to focus on the mouse SCP for study, rather than any of the dog or cat breeds. The reason for this is that the mouse has a simpler set of actions and a smaller SCP, but still enough to puzzle out what is going on. We know from the petz dev interview that the game characters all run on similar code, so the hope is that whatever can be learnt from studying the mouse SCP can be applied to the cat and dog files. In some spots I cross checked findings with some cat SCPs (both the master cat SCP and some individual breeds) to see how they held up.

The mouse's SCP file is found within the main petz resource DLL file, found in the Resource folder. If you're running Petz 4 like me it'll be called Petz 4 Rez.dll, else it'll be named according to your game version. Once in there, click SCP, then MOUSE. You can see that it looks a lot like the lab file:

Mouse SCP open in LNZ Pro.

Note: as with all editing, if you are going to try playing with SCPs, always make a backup of any files you're working with. This goes double for if you're editing the core resource files such as Petz 4 Rez.dll. Back them up in case of problems, and save yourself a resinstall if things go wrong.

There are three main sections in the mouse SCP, and these are present in all other SCPs throughout the game. For lack of any better names I have called them:
  • the header, which contains basic information about the file.
  • the actions, which appears to define what animations to play at a given point.
  • the scripts, the largest part of the file, that appear to denote what the creature should do for each action.

The Header

At the start of the file is a plaintext copyright notice, then the header begins immediately after. It is a set of several bytes that appear to contain general information about the SCP file as a whole.

Mouse SCP with header section highlighted.

A few general observations:

  • The first byte, 0b (dec 11), matches the number of unique values in the animation slots for the "repeating segments" further down in the file. It seems to be a count of animations that the mouse (or cat, dog, toy etc) has available.
    • I cross checked this byte with the same position in the cat SCPs. The main cat scp gives a value of 227, whilst the alley breed SCP has 299 and the orange shorthair 228 (values all given in decimal). This would seem consistent with the observation that the alley and oshie breeds have animations that other cats do not perform.
  • Next is a value of 05. I don't know what this is, but in catz it is a much larger number, 4f (dec 79). It may also be a reference to states or animations, as the cat would obviously have many more.
  • Finally there is 2c (dec 44). Cross checked with some cat breedfiles, this seems to be a count of "repeating sections" below.

Actions / Animation Pointers

I originally called this part the "repeating segments" because it consists of several blocks of data whose structure repeats over and over, but I've started using "actions" to be more in line with Reflet's research and what the data actually means. There are 44 segments/actions total in the mouse SCP, as noted above. Below is the first of these actions highlighted:

Mouse SCP with first repeating segment highlighted.

The structure of an action is consistent and is laid out as follows:

  • Sixteen bytes
  • FF FF
  • Six bytes
  • FF FF
  • Six bytes

The sixteen byte section starts out with a numerical value that counts upwards for each action - if you look at all the actions, you can see that they increment by 1 each time. So this is an id for the action - action 0, 1, 2, 3 and so on. Editing this value will cause the game to throw a data corruption error on loading.

Mouse SCP with action IDs underlined.

Note: if you're looking at a breed SCP as opposed to a master SCP (cat.scp, dog.scp, or the mouse shown here) then the IDs are not continuous. This is because breed SCPs act as an overlay - see Reflet's script research for more details.

The next value is usually 01 00, but in some cases it is a different, but still small, value. According to Reflet's research, this is the number of scripts associated with this action. We'll cover scripts later.

The next two values are the most interesting. They each contain one of eleven (in the mouse) unique values, from 00 00 to 0a 00. The two values may be the same or different. In the first action they are both 00 00, but if we highlight the second action instead we can see them more clearly, because they're both 07 00:

Mouse SCP second action highlighted and animation values underlined

These values are of special interest because they're the only values where I managed to get an effect by editing them. Changing the 07 00 to 01 00 caused the mice to levitate when they exited their holes, displaying the "being picked up by the tail" animation:

Mouse animating as if being picked up.

So it seems as if each of the values that can go into these slots corresponds to a different animation. I also had some interesting effects when I changed only one of the values rather than both. Here's a recording of what happened when I changed only the first value to 01 00. Notice that the mouse periodically lifts into the air using the start of the dangling animation:

Mouse animating as if being picked up.

I did some testing with breakpoints in a disassembler and found that only the animation is affected - it doesn't trigger the MouseDangling function inside the state machine, which does trigger when you pick it up. From this, I assume these values are animation pointers. (I would also like to stop here and give thanks to the Petz devs for their nice and descriptive state machine function names. Much appreciated.)

By contrast if you change only the second value, the mouse will periodically perform the end of the dangling animation, when it is dropped back to the ground:

Mouse animating as if being picked up.

So it appears as if the values are start and end points respectively. Unusually enough, setting both values to 01 00 does not make them perform the full animation, but has them lift upwards with a lesser frequency, rather than on periodic intervals as is the case with just one. And this is just the result of tweaking the one action. There is a lot more to be discovered here!

I did wonder if it was possible to insert new animations into the game using these segments. The mouse has an unused animation in which it explodes, which is a leftover from the grubs in the Oddballz game, which used a similar engine. The numbers used seemed to point to the animation file for the animation required - MOUSE1 is the lifted/dangling/drop back down animation, corresponding to 01 00. I tried changing one of the values to correspond to this unused animation, but this caused a crash when the mouse tried to come out of the hole and, presumably, perform the requested animation.

Since the SCP's header contains a count of unique animations, I changed that to reflect that there was one more animation in the list, and reloaded. This time there was no crash, but the mouse simply went about its business without performing the exploding animation. I think the reason for this is that the animations are also split, as we can see there is a start portion to the dangling animation where the mouse is lifted into the air, and an end portion where it drops back down. Presumably somewhere in the game are instructions for which frames are part of the start and end parts of the animation, and it plays the required ones depending on which of the two values you edit. I would guess that as the game doesn't know what the "start" and "end" segments are for the unused exploding animation, it just doesn't play it at all, but this is wild speculation.

Following the first FF FF value we have a six byte section. This doesn't seem to vary much, at least in the mouse. The first value is always 00 00. The second is either 00 00 or 01 00, so I suspect it may represent a boolean, but I can't say for sure. The third value is always 03 00. I have not yet been able to find any more information on what these sections do, but according to Reflet the 03 value comes into play if the two animation pointers above are the same. How is still unclear.

Finally after another FF FF value we have the second six byte section. This one contains a value that is variable, but it is always higher than the value 1 for the previous segment. So in the first segment it is 00 00, in the second 0c 00, in the third 14 00, and so on (note that petz binaries are little-endian). According to Reflet's search, this value points to the location of the script to excecute for this action - see Scripts, below.

Overall there is a lot of exciting stuff here, but still plenty to do. In general I think that the repeating segements map out which animation to play at which time, making it look like the animal is performing the right action for whatever it's supposed to be doing.

The Scripts section

This is the longest part of the SCP, several times longer than the repeating segments, and it comes right after that part. Here is the start of it in the mouse SCP:

Start of the hex 40 section in the mouse SCP.

You can see that it is not as structured as the repeating segments, but some patterns do occur. This section consists of short sequences of bytes separated by the value 40 in hex (visible on the right side as the @ symbol), hence the name I originally gave to this part: "hex 40 section". These sequences are of varying lengths, but usually two, six, or ten bytes, and occasionally more.

Reflet has done some deep diving into this part and found that it is a list of commands, possibly function calls with optional parameters. A more in-depth look at this section is forthcoming.


Other sources of personality

When testing SCP swapping, I created orange shorthair catz with alley cat scps. When I tested my "alley-oshies" I noticed that although they had the alley personality, they still had aspects of the oshie personality such as trembling when they walked. This made me think that there must be some other factors within a breedfile that affected the pet's personality and the SCP was not the full story. Here's some speculation.

Traits

Among the relevations from the Petz dev interview was the trait system. Each breed, toy, etc in the game contains a list of adjectives that describe it, which the state machine then references to decide what a pet should do next (e.g. "go to the food, because it has the Tasty trait and you're hungry"). You can't see it in LNZ Pro, but it's visible near the start of the file when viewed in a hex editor. Here's the Labrador's trait list, but it looks the same for any breed of dog or cat - the same list is also found inside toy files, clothes, and even playscenes:

Labrador trait list.

Obviously not all these traits are applicable to a pet, since they are shared across all resources, but some of them are, and you can see how they would influence their personality. However nobody is yet sure of where in the file these traits are applied, but if that could be cracked it could lead to the possibility of custom personalities rather than swapping around existing ones. It appears that the traits are set somewhere within the executable code within the breedfile, which is currently not editable.

Credit for trait research goes to the Petz Modding and Hacking Discord group, who put together much of this information.

Much trait research comes from studying individual .pet files. Some traits have been known about for a long time - the "sleepy sickness", "trickster", and "trotter" characteristics all correspond to traits, although this was not known until the trait system was revealed in the dev interview. Trait values range from 100 (strongest) to 0 (weakest). Some breeds will always have 100 or 0 in a particular trait. With others it varies but the numbers will cluster around an average, meaning that different breeds will have different overall personalities but individuals will be slightly different. For example all Orange Shorthairs have low Confidence, but some are lower than others. Each pet appears to have dominant and recessive trait set, so an individual cat may display low Dogginess (the "trickster gene"), but have a high recessive value, meaning their child may have high Dogginess and perform tricks.

Dogz and catz share the same trait list, and traits can be passed down from parents to offspring. Each individual pet actually carries two trait sets, a dominant set and a recessive one. This means that they can be passed on like genes in real life, and may skip a generation.

  • Liveliness
  • Playfulness
  • Independence
  • Confidence: a low value produces the shivering seen in Orange Shorthairs and some Chihuahuas. Conversely a high value will produce chest puffing and strutting as seen in Bulldogs, which all have 100.
  • Naughtiness
  • Acrobaticness: this is the "trotter" gene, and will produce trotting behaviour if set to 0. This is the case in all Sheepdogs tested.
  • Patience
  • Kindness: a high value produces "sleepy sickness" as seen in the Chinchilla Persian.
  • Nurturing
  • Finickiness: set high in Siamese and Poodles, although it is the SCP that appears to control their characteristic poses. This is set to 0 in all other dog breeds and is variable in cats.
  • Intelligence
  • Messiness: set to 100 in all tested Alleys.
  • Quirkiness
  • Insanity: typically 0, but high in Chinchilla Persians.
  • Constitution: presumably this controls how easily the pet gets sick.
  • Metabolism: probably controls the speed at which the pet gets hungry.
  • Dogginess: this is the trickster gene, and is obviously always high in dogs. Cats with a high value in this trait will perform tricks.
  • LoveDestiny
  • Fertility
  • LoveLoyalty
  • Libido
  • OffspringSex

Default Factors

In the Dogz 1, Catz 1, and Oddballz games, which ran on a different engine, there was a section in the LNZ files called [Default Factors]. This section dictated the pet's personality along several axes, such as fear, energeticness, etc. It was possible to specify things such as the central value and how much a pet's personality would vary from that point. Very exciting stuff that could let you create true custom personalities! Unfortunately it did not carry forward into the newer games, but in a couple of spots in the Petz II files, there they are:

Default Factors inside a Petz II Calico.

Here's the Default Factors section hiding inside a Petz II Calico LNZ, with some handy comments to tell you what each number does. You can also find them inside the Petz II mice (look inside Catz II Rez.dll for those). Sadly they don't seem to do anything - the Calico's DFs are set to what appear to be generic values rather than anything that would give the cat its usual personality, and changing them or putting them in other breeds doesn't appear to make any difference. It seems they were left over from development and never intended to be used.

So what happened to them? I can guess that personality details were removed from the LNZ for separation of concerns - the LNZ details what the breed looks like, not personality. Are they still set, but elsewhere in the file? Were these rolled into the traits system? We just don't know, but they're a fascinating lead.