I do love that I can open C3/DS cos scripts and get the initial injection code, rather than having to backwards engineer it as in C1 and C2. Given how complicated many of the objects in C3/DS are, this sort of modification may well have been impossible without this small change in code accessibility! Here's the initial shark script - with a lot of unnecessary empty lines removed. Actually, this whole script seems to contain a lot of unnecessary stuff, such as a reps loop that runs once, or object variables that are set but never referenced. It feels very much like code that was never cleaned up after they got it functional.
Search This Blog
Amazing Technicolor Sharks
Grand Botanical Overhaul I: Cacti
I've recently begun my most ambitious project yet: the Grand Botanical Overhaul for Creatures 2. The plan here is to do something similar to my Creatures 1 Herb Update, to improve consistency in plant behaviors and streamline their use for creatures, while also including some quality of life improvements for the player. This includes:
- Including launchers for the plants that don't have them
- Making sure the main plants (pear, triffid, trumpet, aubergine, tomato, and acorn) have proper life cycles including plants, fruits, seeds, and detritus. This includes fixing any bugs in their life cycle.
- Ensuring that anything inedible is invisible - both plants that are naturally inedible and plants that simply aren't ready to eat yet.
- Implementing behavior similar to my updated C1 Herbs: creatures eat directly off the plant, hand pushes plant to pluck the fruit.
- Reclassifying harmful members of edible classes into badplants.
As I go through this process, I'm thoroughly analyzing the code for each plant, so this will be a series of in-depth looks at the CAOS involved. I will be going into the changes I've made, but won't put anything up for download until the project is finished. I'm beginning with the cacti - technically badplants, but still in need of some fixes.
I'm a One-Woman QA Department
Things have been slow working from home lately and I finally decided I was utterly fed up with... well, pretty much everything that's wrong with Creatures 2. So with the help of Bella the Beta Norn, I set out to fix as much of it as possible, which turned out to actually be quite a lot.
You're gonna need a bigger better boat.
I began with my archnemesis: the boats. I've previously expressed my gripes with the boats, especially the light ocean one:
"Not only do creatures constantly get stuck in it, not only are the controls located where you can't click on them when the boat is occupied, but the boat itself is completely pointless because it leads to a small, dead end patch of island with no food on it."
I initially "solved" this problem by just deleting the boat, but did not release a COB for it because the hard part would be re-creating the boat. I started work on that, and then I figured, the dark ocean boat isn't so bad but it's still an annoyance, so I should go ahead and fix that too. So at that point, why settle for just deleting the light ocean boat? If I'm replacing the dark ocean boat, I might as well replace the other one too.The scriptorium makes the event scripts for any official object trivial to obtain, but with COBs like this, the hard part is always in restoring the original object as part of the COB removal script - while event scripts are easy to rip from the game, the injection/creation script is generally a mystery, and that's where a lot of important values are set: initial values for object variables, attr and bhvr values, and various physics traits. With complex objects like the boats, you need to create the parts in the correct order, too.
Topsy Turvy Toxic World
So, last session I said that "while I like Toxic Norns well enough, it's a huge hassle to keep and interbreed them with other Norns" and that got me thinking. I'm not going to attempt keeping Toxics in the main world, but I realized I could easily have a separate world for them. So I created the Mire, dropped the Ettin and Grendel eggs into the water, and started spreading nastiness around the whole world.
Of course, a world full of one breed of plain Norns wouldn't be that much fun, and I was curious about how colortrue creatures worked, so I cracked open a genome and whipped up a colortrue Toxic Norn. I'm sure there are better varieties out there currently that can interbreed with other colortrues (at least as well as any Toxic could interbreed), so I'm not going to put this variety up for download, but it was interesting to see how simple the edits really are. The pigment genes are just moved around so they fall under different organs, their mutations are turned off, and they're unlinked from age/gender. There are four of each color channel, and the base creature of any color has all four of a given channel set to the same value.
I'm not a big fan of the overlay look of high pigment values, so I stayed in the middle as I created six Norns: three male, three female. The males each have one color channel that is higher (set to 192 instead of 128), and the females each have one color channel that is lower (set to 64 instead of 128). And of course, I created a new name generator catalogue for this world too! From left to right, these are Foulvenom (magenta), Acidfilth (yellow), Witchphlegm (green), Rotgut (blue), Ruinbile (red), and Slimestump (cyan). I definitely prefer the look of the females with the lowered channels, so hopefully we'll see colors leaning toward the middle over time.
Bees, Beelacanths, and Flies, Oh My!
Having finished my improved version of the bees and hives update, as well as my improved beelacanth, I'd like to go into detail about the changes I've made to the code, which means lots of rainbow-highlighted CAOS scripts. If anybody reading this post happens to be colorblind, I apologize in advance. To the anonymous commenter who wanted more CAOS code: you're welcome.
Bee nightmare script, annotated
[Originally written July 12 2021]
I started by examining the
official beehive upgrade script. It includes scripts for both bees and hive. I
started first with the hive, and found that most of the scripts are fairly
simple. The push script looks complex and frightening at first, but on closer
inspection they’ve just crammed multiple statements into the same line. Split
up for readability and annotated, the script is long but not so frightening.
The biggest problem here is that this is the push script, which should feed the creatures in accordance with similar vendors, but instead it dispenses bees. I suspect this is so that you get bees upon clicking the hive, so when I swap the scripts, I’ll either have to disable that feature or find a way to conditionally react differently to the hand.
Then I moved on to the bees themselves. Whoever wrote this monstrosity should be keelhauled.
Thanks, I hate it! I went through and added linebreaks and indentation for readability, then annotated the whole thing. You're welcome.
scrp 2 10 3 7 loop anim [01R] rndv var0 0 1 doif var0 eq 0 doif obv0 le 0 gsub hunt endi doif obv0 ge 2 wait 10 gsub hive endi rndv var0 -1 1 addv obv0 var0 else rndv var3 10 20 reps var3 rndv var0 -10 10 rndv var1 -1 -5 mvby var0 var1 rndv var4 1 4 wait var4 repe endi ever subr hunt anim [01R] setv var0 posl setv var3 post rtar 2 4 14 doif targ ne 0 setv var1 posl setv var4 post setv objp targ targ ownr setv var6 var1 setv var7 var4 subv var1 var0 subv var4 var3 setv var5 var1 doif var5 lt 0 negv var5 endi doif var5 lt 2100 divv var1 200 divv var4 50 reps 50 reps 4 rndv var2 -5 5 mvby var1 var2 repe rndv var2 -2 2 mvby var2 var4 repe else divv var1 600 divv var4 60 reps 60 reps 10 rndv var2 -5 5 mvby var1 var2 repe rndv var2 -5 5 mvby var2 var4 repe endi setv var0 posl setv var3 post subv var6 var0 subv var7 var3 divv var6 30 divv var7 30 reps 30 mvby var6 var7 repe targ objp doif touc targ ownr gt 0 rndv var9 0 5 doif var9 eq 0 mesg writ targ 1 endi targ ownr addv obv0 1 endi endi targ ownr reps 20 rndv var0 -5 5 rndv var1 -5 5 mvby var0 var1 repe retn subr hive anim [01R] setv var0 posl setv var3 post rtar 2 8 1 setv var1 posl setv var4 post setv objp targ targ ownr subv var1 var0 subv var4 var3 setv var5 var1 doif var5 lt 0 negv var5 endi doif var5 lt 2100 divv var1 200 divv var4 50 reps 50 reps 4 rndv var2 -5 5 mvby var1 var2 repe rndv var2 -5 5 mvby var2 var4 repe else divv var1 600 divv var4 30 reps 30 reps 20 rndv var2 -5 5 mvby var1 var2 repe rndv var2 -5 5 mvby var2 var4 repe endi setv var0 posl setv var3 post targ objp setv var1 posl setv var4 post targ ownr subv var1 var0 subv var4 var3 divv var1 10 divv var4 5 reps 5 reps 2 mvby var1 0 repe mvby 0 var4 repe setv obv0 0 retn endm | ENTER SCOPE SCRIPT Endless loop {Flap wings animation Pick random choice of 0 or 1 If choice is 0 {if obv0 is 0 or less (obv0 = fullness) {run the hunt subroutine } if obv0 is 2 or more {wait for 10 run the hive subroutine } Pick random value adjust obv0 accordingly }else (if choice is 1) {pick random number of repetitions For that many times... {pick random vertical value pick random horizontal value move by that amount pick random amount of time wait that amount. } } } HUNTING SUBROUTINE (when bee is hungry) flap wings animation record x position record y position target random beelacanth if target exists {record x position of plant record y position of plant set object pointer to point to this plant target bee again save plant x position save plant y position find x distance to plant find y distance to plant record soon-to-be-absolute x dist to plant if it's less than 0 {negate it to make it positive } If absolute distance is less than 2100 {divide x distance by 200 divide y distance by 50 for 50 repetitions {for 4 repetitions {pick random value between -5 and 5 move toward plant in x, random y } pick random value between -2 and 2 move toward plant in y, random x } }else (absolute distance is more than 2100) {divide x distance by 600 divide y distance by 60 for 60 repetitions {for 10 repetitions {pick random value between -5 and 5 move toward plant in x, random y } pick random value between -5 and 5 move toward plant in y, random x } } record new x position record new y position find new x distance to plant find new y distance to plant divide x distance by 30 divide y distance by 30 for 30 repetitions {move toward plant } Target beelacanth If the beelacanth touches the bee {pick random value between 0 and 5 if that value is 0 {beelacanth pull script } target bee again add 1 to obv0 } } target bee for 20 repetitions {pick random value pick random value move by random values } end subroutine HIVE SUBROUTINE (when bee is full) flap wings animation record x position record y position pick random beehive record beehive x position record beehive y position set pointer to beehive target bee again find x distance to beehive find y distance to beehive save soon-to-be-absolute x distance if it's negative {negate it to make it positive } if absolute x distance is less than 2100 {divide x distance by 200 divide y distance by 50 for 50 repetitions {for 4 repetitions {pick random value move toward beehive in x, random y } pick random value move toward beehive in y, random x } }else (distance is more than 2100) {divide x distance by 600 divide y distance by 30 for 30 repetitions {for 20 repetitions {random value move toward hive in x, random y } random value move toward hive in y, random x } } find new x position find new y position target hive get hive x position get hive y position target bee again find new x distance find new y distance divide x distance by 10 divide y distance by 5 for 5 repetitions {for 2 repetitions {move toward hive in x, no y change } move toward hive in y, no x change } set obv0 to 0, bee is no longer full end subroutine end script |
Not long after I had a new version of the bee and hive upgrade: one where the bees are a new type of object, and where the hive behaves similarly to other vendors (getting the hand to get different results than creatures was just a matter of a simple doif from eq pntr statement in the push script, where I triggered the pull script instead). Also, I made two versions; normally the bees at the hive have eyes but the ones that roam do not, and I made a version where they all have eyes.
Of course, the updated hive and beelacanth go hand in hand, so next on my to-do list is updating the unruly beelacanth, and I won't be releasing the beehive update until that's done!
A brief look into variants
[Originally written November 23 2020]
I had previously been dismissing any mutation that just changed a variant number, on the assumption that the variant system wasn’t actually implemented fully in C3/DS, and that the value was completely meaningless. But it started gnawing at me, so I decided to test it by engineering a genome where colors are linked to variants, then hatching several eggs of that genome. The result was a rainbow of Norns, proving that while the default genome doesn’t use variants, the script is still in the game. Further, it turns out that the CFF genome does use variants (to determine whether a creature is an angry drunk, a happy drunk, etc).
Well, I haven’t been paying attention to my creature’s variant changes, so I decided to go through and check each genome, but it turned out that all of my creatures have only had variant changes in their pigment bleed genes, so there’s nothing to be concerned about. This does make me think, however – I’ve seen a few notable color rotation/swap mutations crop up over the years but almost always had trouble getting offspring to inherit them. If variant mutations are this common in the pigment bleed genes, it may be that the mutations I’d seen were variant-linked, and therefore appeared not to pass on because the children weren’t the right variant.
Lop Ear Norns
[Originally written September 19 2020]
I found a thread on Reddit that gave me an idea. Or rather, it showed me an idea that Wafuru of Mernorn and Kai Norn fame came up with and never actually made into a breed.
A bit of photoshopping later and I had some concept art. I’ve done COBbling, I’ve done genetic engineering, and I’ve done sprite overhauls… I think it’s about time I make my own breed from scratch. As much as I’d like to work in Creatures 3, the one glaring omission in my otherwise quite broad artistic skills is 3D modeling, so until I jump into Blender, new breeds with fancy sprites are a no-go there. Creatures 1 and 2 on the other hand, have more “painterly” art styles, which I can work with.
I made sure not to just copy Wafuru's art directly, but rather just use it as inspiration. No plagiarism intended, only standing on the shoulders of a Creatures 2 giant! For one thing, my Lop Ear Norns have wildly different tails and no spots. The color schemes are also a bit different, though similar, and the hairstyles are different (though the presence of hair at all is definitely inspired by the original artwork). Also, the males have horns. I feel they’re different enough to not qualify as stealing Wafuru’s work, though if I ever complete them and actually consider putting them up for other people to enjoy I’ll attempt to make contact just to be sure.
Of course, this may end up being far too ambitious a project for me – I remember how much work just revamping the Frog Norns was, and this will involve a lot more hand-drawing and intensive editing.
[Originally written November 21 2020]
I have finally finished making my first from-scratch breed, and have received permission from Wafuru to distribute the Lop Ear Norns! They are both a visual and genetic breed, having some edits to their genome as well as fancy new sprites. I’ve set all of their Pigment and Pigment Bleed genes to neutral values, so the colors you see in this image are the colors you get. Additionally, they have the following changes to their genome, which in theory should make them a touch less aggressive and a bit more skittish than the average Norn.
Organ: “Creature”, Tissue: “Sensorimotor”, Locus: “Involuntary Action 5(pass out)”. Chemical: “Sleepiness”.
Digital: Output = 0 + 255 if Signal > 230.
Organ: “Creature”, Tissue: “Sensorimotor”, Locus: “Involuntary Action 5(pass out)”. Chemical: “Sleepiness”.
Digital: Output = 0 + 255 if Signal > 200.
Lops are slightly quicker to pass out from exhaustion.
Stimulus: “Creature slaps me”, Signficance: “128”. Reaction: “I’ve been slapped”, Intensity: “255”. Detected while asleep.
+64 Pain, +32 Fear, +16 Anger.
Stimulus: “Creature slaps me”, Signficance: “128”. Reaction: “I’ve been slapped”, Intensity: “255”. Detected while asleep.
+64 Pain, +45 Fear, +0 <nothing>.
Stimulus: “I’ve been hit”, Signficance: “127”. Reaction: “IT has hit me”, Intensity: “255”. Detected while asleep.
+80 Pain, +48 Fear, +16 Anger.
Stimulus: “I’ve been hit”, Signficance: “127”. Reaction: “IT has hit me”, Intensity: “255”. Detected while asleep.
+80 Pain, +60 Fear, +0 <nothing>.
Lops don’t get mad when hit, they just become frightened.
Stimulus: “I’ve been pushed”, Signficance: “127”. Reaction: “IT has pushed me”, Intensity: “255”. Detected while asleep.
+32 Pain Increase, +32 Fear Increase, +47 Need for Pleasure Increase, +0 Anger Increase.
Stimulus: “I’ve been pushed”, Signficance: “127”. Reaction: “IT has pushed me”, Intensity: “255”. Detected while asleep.
+25 Pain Increase, +35 Fear Increase, +47 Need for Pleasure Increase, +0 <nothing>.
Stimulus: “I’ve been pushed”, Signficance: “127”. Reaction: “IT has pushed me”, Intensity: “255”. Detected while asleep.
+16 Pain Increase, +16 Fear Increase, +64 Need for Pleasure Increase, +64 Anger Increase.
Stimulus: “I’ve been pushed”, Signficance: “127”. Reaction: “IT has pushed me”, Intensity: “255”. Detected while asleep.
+10 Pain Increase, +20 Fear Increase, +64 Need for Pleasure Increase, +20 Anger Increase.
Stimulus: “I’ve been pushed”, Signficance: “127”. Reaction: “IT has pushed me”, Intensity: “255”. Detected while asleep.
+0 Pain Increase, +0 Fear Increase, +48 Need for Pleasure Increase, +32 Anger Increase.
Stimulus: “I’ve been pushed”, Signficance: “127”. Reaction: “IT has pushed me”, Intensity: “255”. Detected while asleep.
+0 <nothing>, +0 <nothing>, +48 Need for Pleasure Increase, +10 Anger Increase.
First of all, those gene names sound so indignant, I love them. You SHOVE Miette? You push her body like the shopping cart? Oh! Jail for Hand for one thousand years! In all seriousness, I felt bad when I discovered this gene, as I’d never realized that trying to scootch my creatures hurt them (or simply upset them in adulthood). Lops are more willing to go with the Hand’s guidance, resulting in less pain, and their timid nature makes them less angry, but also makes them slightly more afraid until they get used to it in adulthood.
When… “Drive i/ps” “FEAR” and “General Sensory i/ps” “IT is approaching” …and you “Retreat frm it”: +127 Reward.
When… “Drive i/ps” “FEAR” and “General Sensory i/ps” “IT is approaching” …and you “Retreat frm it”: +155 Reward.
When… “Drive i/ps” “ANGER” and “General Sensory i/ps” “IT is approaching” …and you “Hit it”: +127 Reward.
When… “Drive i/ps” “ANGER” and “General Sensory i/ps” “IT is approaching” …and you “Hit it”: +70 Reward.
Lops are more likely to flee than fight back.
When… “Stim source i/ps” “<ID 11>(detritus)” …and you “Eat it”: +66 Punishment.
This one is just a general life improvement; I noticed Norns had an instinct to not eat weeds, but couldn’t find one for detritus, so I made a version to avoid detritus.
Happy little genes
[Originally written October 6 2020]
While at this point I’ve more or less given up on figuring out the formula for exact RGB values produced by color rotations and swaps, I do want to dive a little deeper into the genetics side of it. What if you have more (or fewer) bleed genes? What about regular pigment genes?
In my previous exploration of color rotations, I found that the three bleed genes produce the final rotation output by means of the formula Floor((((0.5 * Gene1) + (Gene2) + (2 * Gene3)) / 4) + 16) = Actual Value.
I tried deleting the third gene and did some more experimentation.
Visual | ![]() | ![]() | ![]() | ![]() | ![]() |
---|---|---|---|---|---|
Gene 1 | 210 | 170 | 128 | 180 | 255 |
Gene 2 | 180 | 220 | 255 | 235 | 255 |
Actual | 174 | 184 | 191 | 194 | 223 |
Using the same formula structure I concluded that this is calculated as Floor(((Gene1 + (2 * Gene3)) / 4) + 32) = Actual Value.
Based on the relationship between the formulas, I would then expect that a single rotation gene would be calculated as Floor(((2 * Gene) / 4) + 64) = Actual Value. Indeed, when I created a creature with only one pigment bleed gene set to rotation 200, I got a creature with a total rotation value of 164 out of it.
Extrapolating from this, would adding a gene result in the formula Floor((((0.25 * Gene1) + (0.5 * Gene2) + (Gene3) + (2 * Gene4)) / 4) + 8) = Actual Value? I created a Norn with a fourth gene placed before the normal three, in the configuration 255/128/128/128. As expected, the reported rotation was 135. I think I’ve cracked the entire formula!
Do normal pigment genes work the same way? For each of the three colors, a creature has four genes. One of these is labeled “at birth” for each color but the rest (except for red) also switch on at birth; perhaps during development they intended these to turn on at different stages of life. Red is a bit of an oddball, because three of the genes for this color switch on at birth… but the fourth is tied to gender and turns on at adolescence. Why only red? That’s a question only the creators could answer. All I can do is figure out how the numbers are calculated. I decided to leave red alone for the time being and created some Norns with various edits to their blue genes, and swiftly concluded that this is far less complicated than bleed genes – the game simply averages the values.So… what about those genes that switch on later? Do they replace values, or do they simply get added into the mix? I created some creatures to test both bleeds and regular pigments. One had rotation genes set to 255/255/128 for embryo genes and 255/128/255 for adolescence genes. As a baby, her rotation value is 175. If the genes get replaced, the adolescent value would be 207, but if they get added in, it would be 213. I also created two creatures with their embryo red genes set to 20/100/150 and their adolescence gene set to 255 – one male, one female. I created both because if the genes got replaced, the order could matter. Their childhood red value was set to 90; if the gene got added in, it would become 131; if the gene replaced one other, it would be 168, 141, or 125 depending on which gene it replaced. And of course it would be 255 if it replaced all of them. Indeed, the bleed creature came out at 207, while the pigment creatures came out at 255, meaning that once a new coloration gene kicks in, it replaces the ones from previous life stages.COBbling rampage
[Originally written September 6 2020]
Emboldened by my success with the lemons, I’ve expanded my to-do list:
- Fix the coconuts. Playing with the shells shouldn’t cause pain, and I’ve noticed that creatures don’t seem to be able to eat the pieces.
- Fix the medicinal herbs. They don’t seem to go invisible when used up, thus causing the same kind of confusion about pushing not always working as the standard food. Also, I find it incredibly annoying that I’m not able to simply pick sprigs and carry them where I need them. That was the one thing the Playstation game did right!
- Fix the beelacanth. First of all, the plant contains small amounts of glycotoxin. In a herb. What were the developers thinking?! Secondly, the seed has unpredictable effects. Third, I want to bring its behavior into line with the updated medicinal herbs.
- Make a cheese vendor. Both to give me a source of cheese and to put my COBbling skills to the test.
But eventually world-breaking bugs gave way to oddly-placed objects, and once these were ironed out (turned out I’d forgotten to reset the target of the script to the owner after changing it and was pulling coordinates from the hand instead of the plants), I had a functional herb update pack! The herbs now become invisible when they’ve lost their usable sprig, so creatures aren’t tempted to keep pushing them. As an added bonus, clicking on the herb will pull the sprig off and drop it on the ground nearby – essentially, I’ve made the herbs double as vendors for their sprigs.
My plan initially was to take on the beelacanth next. The beelacanth is considerably more complicated than the standard herbs, and behaves quite differently. I’ve got a pretty good grasp on most of its behavior from annotating its code, and after some observation and testing courtesy of Bob (who had some nasty run-ins with the bees), I’ve concluded that it is perhaps too complex. I don’t mean for my level of skill (although that seems to be true right now too), I mean it’s confusing for the creatures.For instance, pushing a herb eats the sprig directly (and with my updates, hides the plant). With the beelacanth, pushing it eats the whole plant, except when there’s a fruit. In that case, the fruit pops off and the creature is left confused as to why he couldn’t eat the plant. There also appears to be a case for creatures pollinating plants by pulling them – but no other herb has a pull script. And there also seems to be code that can make the plant jettison its own seeds, based on a counter… but for one thing, the interaction of this counter with the timer means that if my calculations are correct, it would take several hours for this code to fire, and the counter doesn’t get reset! Similarly, the seeds can “go bad” after a while and cause different effects, but the creatures can’t distinguish a good seed from a bad one.
It’s all very impressive in theory and I don’t downplay its importance in paving the way for complex ecosystems in later games, but it just does not work well in the context of Creatures 1.
But I was having some issues updating the beelacanth, so I decided to move on to the coconut. I have searched on the internet for a fix for this, or even an explanation, and I can find nothing – but I have never seen a creature successfully eat a coconut. After looking through the code, I found, and fixed, the issue… and it turned out to be a oneliner. This is the “pick it up” script for the coconut piece, and the second line marks it as active. The problem? “Active” means creatures can’t use it again (which includes pushing it) until it goes inactive. I removed this line, and also changed a couple lines so that pushing the whole coconut slightly relieves boredom (in line with other toys, which the coconut is classified as) and no longer causes pain, and soon Betty was happily knocking down, cracking open, and eating coconuts.The beelacanth isn’t that important to me right now, since it’s an optional item that I don’t usually include in my worlds. What is important to me is cheese! I feel confident making my own COB from scratch now, even if just a simple, immobile vendor – a cheese plate that sits in the kitchen. If pushed by the hand, it would generate a piece of cheese. It would be tempting to do the same when pushed by a creature, but I want to be consistent with other vendors, of which there are officially four:
- Beehives – feeds honey directly when pushed (or is it pulled? If the latter, I will have to fix it…).
- Carrot vendor – feeds carrot directly when pushed.
- Hootch still – doesn’t do anything when pushed by anyone, and should probably be made invisible.
- Shee Seed Launcher – the odd one out, as it has a function but it doesn’t feed directly (I’ll have to fix this when I get around to finishing the beelacanth edits).
Therefore, the cheese plate should also feed directly. Besides, it’s easier to teach a creature that vendors produce food if they get fed from pushing it. Pushing the vendor and then the food is a bit of a leap of logic I don’t think creatures can make.
Step one was the artwork. This part was easy thanks to the C1 Photoshop palette and my existing pixel art skills. Importing it into a sprite was a bit of a struggle but once I had it saved in the correct bit depth and the correct size (apparently the dimensions need to be multiples of 4), that was done. Step two was choosing an ID. Nothing was listed on the wiki for 2 8 10, so that’s what I’m going with. Step three was coding. This object has only three scripts (the third is not shown; it’s just script 17 copied directly from the cheese item included in the game). The effect when eaten is also copied directly from cheese.
The coding wasn’t completely bug-free – being used to real programming I put an “endif” in there, which CAOS did not like. But surprisingly, that was the only hiccup. Once that was fixed, I had a functional cheese plate, and Bob was helping himself to as much cheese as he wanted!
Lemon Merengue Python
[Originally written September 4 2020]
Ready to dig into my next project, I located the lemon script, and as my means of deciphering it, I sort of translated it into pseudo-Python. What can I say? I have a degree in computer science, so the easiest way for me to understand code is to translate it into other, more familiar code. Even for those who aren’t well versed in programming, it should be somewhat easier to read.
So the question is, just what is obv0? A look in the developer reference tells me this is a generic object variable, which is stored in the object and exists outside the scope of the scripts. So what’s it do here? My best guess, based on that script, is that obv0 for the lemon flags it as eaten (1) or not (0). This will need to be modified to remove the pain increase, and possibly to make the lemon invisible after being eaten.
Next up is the drop script. This appears to use some clever bitwise operations. For those who are not programmers, this means that it’s doing stuff with the numbers written in binary, one digit (bit) at a time. The ATTR values may look rather random, but they’re not – they’re powers of two, which means something magical happens when they’re written in binary!
Description | ATTR value | Binary |
---|---|---|
Creature carriable | 1 | 00000001 |
Hand carriable | 2 | 00000010 |
Hand activatable | 4 | 00000100 |
Can carry things | 8 | 00001000 |
Invisible | 16 | 00010000 |
Floats on screen | 32 | 00100000 |
Limited to room (wallbound) | 64 | 01000000 |
Limted only by ground (groundbound) | 128 | 10000000 |
Each one is indicated by a 1 sitting in a different slot. So when you add the ATTR values together to set the attributes, you’re really setting a bunch of binary flags. For example, an attribute of 6 is created by adding 2 and 4 (hand carriable and hand activatable), the meaning of which isn’t immediately clear… but in binary, it's 00000110 – readable quite easily as long as you know what each slot corresponds to; both the hand carriable slot and the hand activatable slot are “on” (in other words, set to 1). Bitwise And (andv in CAOS, & in Python) and Bitwise Or (orrv in CAOS, | in Python) create a number by doing something in each slot based on the two inputs: for And, if both inputs have a 1 in that slot, the output has a 1, and otherwise it outputs a 0; for Or, if either input has a 1 in that slot, the output has a 1, and otherwise it outputs a 0. For example:
0111 AND 1010 | 0111 AND 0011 | 0111 OR 1010 | 0001 OR 1000 |
0010 | 0011 | 1111 | 1001 |
This script, if the obv0 variable is 1 (the lemon has been eaten), Ands the attributes with 252 (11111100) and then Ors it with 16 (00010000). Essentially, this means that, first, both of the carriable flags are turned off, and then the invisible flag is turned on. It then waits a moment and moves the lemon somewhere else, and starts a timer.
Which leads us to the timer script. When the timer’s up, it generates a location somewhere on the lemon trellis, puts the lemon there, marks it as uneaten, and does some bitwise operations to turn off invisibility and turn back on carriability.So if it didn’t go straight back to the trellis, where did it go? Based on the coordinates of the trellis I’ve confirmed the (0,0) coordinate is located in the upper left corner of this image, which is to be expected given that that is apparently a rip of the background straight from the game engine.
The drop script moves the eaten lemons to (571, 1084), which is precisely here. Because apparently hiding the eaten lemon behind a rock is easier than simply using an invisible sprite? And suddenly, flying lemons make sense. I’ll have to fix that when I make my tweaked lemon.And the final scripts for the lemon are “extra activate 1” and “extra activate 2” – which appear to be scripts intended for the creatures themselves? At any rate I don’t think I need to bother with them now.
So to sum it all up, the problems with the lemon are:
- An eaten lemon remains visible until dropped. That means it has the same problem as the carrot seedlings: a creature eats it, thinks it still has food in its hands, and then is confused when it can’t eat it.
- When dropped, an eaten lemon is hidden behind a rock until it’s ready to be moved back to the trellis.
- Lemons cause pain when eaten, teaching creatures that eating hurts. Not good!
I feel like this will probably be my usual workflow for this process – build the framework in BoBCoB because of its friendly interface, and then go to CrEd32 for the serious editing and debugging work.
I struggled for a while with various issues, slowly hammering out all the problems. I couldn’t get the lemons to inject in their invisible state correctly, so I made them inject as ready-to-eat fruits. I had issues with lemons hopping back to the trellis when dropped uneaten, fixed by fiddling with attributes. I had issues with lemons occasionally hopping to places they shouldn’t – I corrected this with a redundant script (the invisible lemon gets put on the upper left corner of the trellis, and then it gets moved to a randomized location on the trellis when it becomes visible again) so that even if one script misfires, the other will get it where it needs to go. I had issues with lemons not being visible or grabbable when they should or vice versa.I got it into a decent state but went back and changed my mind – why should I stick to the original lemon recycling model? Jessica’s carrot proves that you can just delete and recreate objects, and indeed if I was programming this game from scratch today that’s exactly what I’d do! So I went back and cleaned it up even more. In the end, Betty the Beta Norn and Bob the Beta Grendel did their jobs very, very well, and I was satisfied with the results of the beta test.
A crash course in COBbling
[Originally written September 4 2020]
Having the day off work, I decided it was as good a day as any to jump into the COBbling pool. I fully expect to break things in my reckless charge into mucking around in the game’s scripts, so instead of using my main world, I decided to insulate myself and experiment within the safety of a VM. I tossed Creatures 1 into Ye Olde XP Box, imported the female Purple Mountain Norn that comes with the game, and named her Betty – Betty the Beta Tester. I then set up my camera points for easy navigation, and injected Grendel Friendly and the Grendel Button, and Jessica’s carrots. After teaching Betty her verbs, and the words “food” and “hand” and teaching her to eat, I briefly exported her to make a backup copy of her file. This way if things go horribly wrong, which I expect them to, I’ll be able to simply reimport her and not have to deal with re-teaching her. I plan to do the same with the Grendel when he shows up.This was a rather speedy world setup since I just want a bare-bones playground for testing CAOS and COBs, so I imported Betty again after copying her file, then exited the game to set up the editor. I first tried CrEd32, but it gave me a bunch of registry errors, and I didn’t feel like mucking around in the registry if I didn’t have to. So I spun up BOBCOB instead. This one appeared to work, but I immediately ran into some issues where autoscript and other features were mysteriously grayed out – I soon realized that it apparently couldn’t find the game. I suspect this is because the Albian Years are in a different place than older tools expect. Well, whatever; it’s a VM, so I’m throwing all caution to the wind. Worst comes to worst, I’ve copied Betty and the C1 installer to a USB so I can spin a whole new VM up if needed. So I ended up mucking around in the registry anyway. A few hacks later and it was working just fine – anything that’s under HKEY_LOCAL_MACHINE\SOFTWARE\Gameware Development\Creatures 1\1.0\ needs to be copied into an identical entry in HKEY_LOCAL_MACHINE\SOFTWARE\Millennium Interactive\Creatures\1.0\ and you’re good to go! With that I was able to extract the default carrot scripts. Time to dive in!
There are five scripts associated with the carrot. All begin with “scrp 2 6 3 #” where # is some number. 2 6 3 is the designation of the carrot itself, and the number seems to indicate what action the script is for.
This right here is the push script! Thankfully, I don’t have to decipher it all by myself, thanks to Jessica’s helpful post. Even without the post, a good chunk of this is quite familiar to me as a programmer, such as the if/endif block (doif/endi in CAOS apparently).I likely could have figured out the pose and snde (sprite frame and sound) bits myself without much trouble using the official guide (which she also helpfully linked), but I am grateful for the explanation of that fourth statement!
I wasn’t expecting to get ramped up this quickly but I already feel pretty confident. I hope Jessica doesn’t mind, but I’m going to start by cracking open her improved carrots; comparing them to the originals should give me a pretty good idea of how the sorts of changes I need to make are implemented.
It looks like she’s done away with the if statement, which makes sense given that her carrots are invisible until they’re edible. She’s left the stimulus portion of the stim command alone, but altered some of the chemicals. It still plays a sound, and now it goes to pose 8 (Jessica’s custom stub) rather than reverting to a seedling.Then it performs the rest of the script instantaneously. That 7th command, new: simp ucrr 9 0 500 0, creates a new object using the image file ucrr, which contains 9 images, and it starts on image 0. It exists on plane 500, and does not create a cloned image gallery (whatever that is).
The next line sets that new object to class 33948416. Having fixed my registry issues I can now use CrEd32’s classifier calculator, and indeed this is the value for the carrot. The next line sets its attributes to 80: invisible (16) + wallbound (64). After that, is the behavior set. The first number is its behavior to the mouse and the second is its behavior to creatures. The 0 is “no effect” and the 1 means it can be pushed by creatures. Of course, that shouldn’t matter because it is invisible to them.
The next two lines are quite obvious to me without even looking them up – they’re generating random numbers between two endpoint numbers (presumably the bounds of the garden) and saving them into variables! Then the mvto line uses those variables as coordinates to place the new carrot in the garden. Finally, it sets the timer for 200 ticks (for the growing script) and kills the original carrot item. Makes sense to me.
The only other part I’d like to take a good look at is the injection script. The second, third, and fourth lines go through and destroy each existing carrot. The reps/repe lines form a pair that is essentially a for loop: everything between reps and repe gets repeated, in this case 10 times.The rest of it should look familiar, since it’s the “make new carrot” code also featured in the push script. The only difference is that the tick value is much lower – the carrots grow much faster when you inject them for the first time than they do when regrowing. Since the code is in the reps 10 block, it produces 10 carrots.
That was quite insightful… I think I’m ready to do my own COBbling!
The Frog Project
[Originally written August 21 2020]
Although I’m not really going to play my C2 world until I get my KVM switch to enable me to easily switch over to the NUC, I’m already thinking about what I want to do with it. One thing I’ve decided on is that I’m going to use Frog Norns for the first time; I’ve never used them before due to their ties to the pond and incomplete sprite set. This time, I’ve downloaded Don’s update that keeps the Frogs from dying if they leave their pool, and NornenMeister’s extended sprite set.However, while the sprite set is certainly nice, much better than what Cyberlife gave us, it’s still… insufficient. Based on what I’m seeing in Nornpose, there are issues with part positioning for the baby and child sprites; looking at them in SpriteBuilder reveals that they don’t match the dimensions used by the Emerald and Hebe Norns. Further, there are no old or senile sprites, and the females are differentiated only by their eye color. So I’ve decided to embark on a rather ambitious quest to bring the Frog Norns up to par with the other official breeds.
Fix the body data.
This is likely to be the most daunting part of the project.While NornenMeister has saved me a lot of work by making the sprites to begin with, I’m going to have to manually edit each and every one of the baby and child sprites to fit the same dimensions and positioning as the Hebe Norns. I'll just have to do the male sprites which I can then recolor for the females. Still, the males for these two life stages alone are going to be about 520 images if I’ve done the math right! But once the sprites fit the standards, I can just copy-paste the Hebe body data onto the Frog Norns.Update: It turns out NornenMeister’s sprites aren’t scaled quite right, so it takes almost as much work to fix them as to just scale down the adult sprite myself, and I get better results that way. Also, the body data for the tail sprites might take a little more work, because it turns out the tail positions/dimensions don’t match across Hebe and Emerald Norns either.
Differentiate the females.
This will actually probably be a simple flat recolor like making them a different shade of green – easily done with a photoshop batch job. If I'm feeling ambitious, I might add some extra details to the female sprites. I’d like to make them look like red-eyed tree frogs: orange hands and feet and red eyes, maybe white bellies and perhaps even a bit of blue on their sides.Create old and senile sprites.
The old sprites are the same size as the adult sprites, and the senile sprites are the same size as the child sprites. Therefore this, too, will just be a matter of batch-recoloring in photoshop and copying the Hebe body data.
I’ve got a lot of editing to do. Did I mention I’ve never dabbled in creatures sprite files or body data before?
[Originally written August 26 2020]
The Frog Project is moving much quicker than expected. I’ve finished reworking the baby male sprites and body data; while I have not tested them in-game, I still have C2 installed on my Windows 10 machine, even if I can’t effectively run the game there, so I’m using it along with NornPose to check that the files are readable and connect correctly. I like my results so far!
Compare a Hebe Norn for reference on the left, NornenMeister’s Frog Norns in the middle, and mine on the right:
Again, by no means do I intend to disparage NornenMeister's work. It's much more than Cyberlife gave us, but it's just got some room for improvement. My Frog Norns have smoother sprite scaling, and aren’t so disjointed because they use the same body data as Hebes except in their tails, which admittedly could be polished some more.
I had a little trouble getting the sprites to read back into the program, but once I figured out how to cut entire sheets, it got a lot easier. That’ll also make recoloring the females much easier, since everything’s already in one big file. While I was at it, I also fixed the sprites where the original artist forgot that Frog Norns have rounded ears, and the ones where the cheek fur hadn’t been recolored correctly. While I initially intended to leave the official adult male sprites alone, I did carry these over.
[Originally written August 29 2020]
Having finished making the child sprites for the Frog Norns, I loaded them into NornPose to check on my work. While it’s going well overall, the longer I work on these sprites, the more convinced I become that the originals were phoned in by an intern. In addition to having unfinished sprite sets and art mistakes, I keep finding sprites that haven’t been cleaned up – rows or columns of duplicated pixels, excessive black haloing…
And even after reworking the tails again I found that they still didn’t look good, and it turned out the tail base had simply been lifted from the Emerald Norns. The tail tip had weird jagged transparent areas at the base, among other problems. So I decided, once again, “fine, I’ll just make my own!” I used the upper arm sprite as a starting point for the tail base, and edited the tail tip to have a reasonably shaped base. Then I resized these for child and baby sprites, and made new body data for the third time.So then, despite my initial intention to leave the official sprites alone, I just had to go in and fix those too, to get rid of the weird excessive shadows and wonky pixels. But, aside from a handful of sprites left to fix, this means I’m almost done with my base sprites! At this point, it’s just a matter of running a couple batch recolors!
[Originally written September 2 2020]
On the 31st, I finished constructing my Frog Norns!
But my KVM wasn’t set up yet – the preview above was made with NornPose. Today I finished hooking everything up, so I installed a few things I’d downloaded, injected some fixes and cobs that come with the Albian Years, used the world state adjuster to activate the powerups, and verified that everything was good to go. I exited the game, put my Frog Norns in place, and launched the game once more! No crash, that’s a good sign! I dropped a Frog Norn egg into the world, and held my breath as the incubator did its work!Oh. Oh no. Back to the editor!
After following the internet’s advice and manually re-saving all 140 sprite files, I created a new test world and hatched a couple new Frog Norns. But they still didn’t look quite right. I wondered at first if I’d somehow screwed the sprites up again, but I wasn’t sure this wasn’t how they looked normally. After all, I’d never used Frog Norns before. So I looked on the internet and found a screenshot showing an unaltered example.Turns out that’s the expected appearance – the lightbulb went on, and I opened the Genetics Kit. Sure enough…
Gene | Sex | norn.gen | frog.gen |
---|---|---|---|
391 392 395 396 411 418 425 432 434 436 438 442 444 445 447 449 453 454 459 462 464 466 467 | B B B B B B B B B B B B B B F F F M M M B F M | 174 red 76 green 198 blue 106 red 60 red 196 red 86 green 41 green 110 green 200 blue 44 blue 225 blue 128 rot 128 swap 128 rot 128 swap 128 rot 128 swap 0 rot 128 swap 128 rot 0 swap 128 rot 128 swap 255 rot 128 swap 128 rot 255 swap 128 rot 128 swap DNE 128 rot 128 swap DNE 128 rot 128 swap DNE | 0 red 255 green 0 blue 0 red 0 red 0 red 255 green 255 green 255 green 0 blue 0 blue 0 blue 128 rot 128 swap DNE 128 rot 128 swap DNE 128 rot 128 swap DNE 0 rot 128 swap DNE 128 rot 0 swap DNE 128 rot 128 swap DNE 255 rot 128 swap DNE 128 rot 255 swap DNE 128 rot 128 swap DNE 128 rot 128 swap DNE 128 rot 128 swap DNE |
So I tried again, with the bleed genes unaltered from the basic Frog, but with the pigment genes all set to neutral values, and bingo! I’m not sure how well this will interbreed, pigment wise, but I plan to use this as my basic Frog Norn genome.
Ursula's New Groove: a pose gene case study
[Originally written August 2 2020]
Thanks to a genetic engineering tutorial and a tool called Nornimator that allows me to pose creatures, I was able to (mostly) unlock the secrets of pose genes. Animation cycles (like walking) are determined by gait genes, which are lists of poses to string together. The pose genes in turn consist of a 16-character string like this: X12020322222311X. For readability, I may split these strings up into sections. With the exceptions of the first and last characters, each one indicates an angle for a body part. The first one indicates the direction the creature is facing, and the last one, as far as I can tell, is unused. Likely it’s either a remnant of Creatures Village or a result of the “sacredness” of powers of two in computer programming.The valid characters for each slot are as follows, mostly according to the tutorial. It didn’t mention 4, but I saw it in a pose that I knew had the creature’s head facing the camera when its body was not, so while I haven’t seen 5-7, I assume that it would just be the same angle pattern repeating but with the head facing the player. I’ve also seen ? for the head slot, but I don’t really understand what it means.
Slot | Char. | Meaning |
---|---|---|
Direction | 0 | Away from camera |
1 | Facing camera | |
2 | Right | |
3 | Left | |
X | Same as it was before | |
? | Toward object of interest | |
! | Away from object of interest | |
Body Parts | X | Same as it was before |
0 | Far down | |
1 | Down | |
2 | Level | |
3 | Up | |
Head | 4 | Facing camera, far down |
5 | Facing camera, down | |
6 | Facing camera, level | |
7 | Facing camera, up | |
? | Unknown |
Armed with this new knowledge, I cracked open Ursula the Dancing Grendel’s genome to find out why she’s a member of the Ministry of Silly Walks. According to a gene comparison report, she has no gait mutations compared to a standard Jungle Grendel, though she does have two additional special gaits inherited from the Banshee Grendels. She does, however, have several mutated pose genes, which I did not want to write another complicated data table for. The important thing is, nearly all of her pose changes are in the arms, body, or head. The only leg position mutations are in her slapping and eating poses. None of these should make her do her funky dance walk.
But what she does have is a single pose with an age category mutation. Essentially, creatures have three normal walk animations – the baby crawl they’re born with, the adult walk they get when they become a child, and the shuffle they get when they become old. Ursula has a mutation that caused her to get Pose 3 of her old age walk early, upon reaching adulthood, but the other three poses involved in the walk cycle won’t change to match until she actually becomes old.
As I decoded, built, and then photoshopped an animation out of the poses, I discovered that Ursula’s problem is much more severe than I thought; her ability to move at all must have come from uneven terrain (allowing her to use the uphill and downhill gaits), as she can’t really move forward at all on level ground. She’s definitely a special needs creature.


