Wednesday, January 15, 2014

Generating arbitray In-game eggs from CAOS commands, while also investigating the Norn reproductive system.


Okay, so in a previous article we've seen how to generate .egg files from genomes with a custom tool.
Even if it may be a nice skill to add to your toolbox, it might not be the most practical everyday tool to inject genomes in your game.

Wouldn't it be more practical if we could directly create ingame eggs from arbitrary genomes/couples as if they were just laid ? This is not only possible but also quite easy.

Some available tools such as the Genome injector on the awesome CDR website already perform that feat. ( Be sure to check out the whole site, as it is definitely the single most complete and comprehensive resource on writing C1 and C2 custom programs )

From there we could go the easy way, as Chris conveniently included a detailed description of the CAOS magic involved in spawning C2 eggs from genomes in the readme file the genome injector ( thanks for that Chris ! ).

But I'll rather show you how you're supposed do find out that information by yourself when starting from scratch, as it will serve us better in the long run when investigating other undocumented game features.
We will be doing this for C1, as Chris' tool only seems to work on Creatures 2.

We will use the CAOS language,it's documentation and some external tools to try to understand what exactly happens during the whole Norn reproductive process, so we can mimic it with a custom and more practical tool.



Things you'll need

A couple of tools and docs will be necessary for us to investigate the standard breeding process:

- A way to execute CAOS commands ingame, to test and probe stuff.
  • I most exclusively use Chris' CCmdline tool for quick tests.It works with C1 and C2.
  • You could also use the CAOS injector tab of the corresponding game's genetic kit,
  • Or the CAOS console found in BobTweak for C2 ( along with some other useful tools, be sure to check that one out if you don't know about it ).
- Reliable CAOS documentation for C1 or C2
- An optional scriptorium browser for the appropriate game.
It will make things easier, but you could also use hand crafted CAOS commands to retrieve the scripts you're interested in.
- Some kind of Classification reference for the appropriate game, you'd better cross information from various sources as most are incomplete or contain mistakes.
- Optionally a genetics kit, if you're really starting from scratch and don't know much about Creatures yet.

How babies happen:

You didn't think you'd be asking about that once again in your life , did you ?
Well, it's all a matter of bees and flowers:





No seriously, in the Creatures games, babies or rather eggs, happen when Norns F**K.



I'm not being rude here, it really is the exact name for the CAOS command used to trigger "sperm donation" as it is poetically described in the C1 CAOS reference document.

We'll begin our investigation from the end of the reproductive chain as this is what is of most interest to us : generating eggs.

In Creatures, eggs are laid by the mother Norn when the pregnancy reaches its term.

The Genetics kit sheds some light on the process if you check out the description for the "Progesterone" chemical.

The description for this chemical reads "Produced progressively during pregnancy. When it reaches a threshold, it fires a receptor to cause the egg to be laid."

In game mechanics terms, this chemical thresholds trigger a hardcoded "involuntary action".
There's a few used involuntary actions in the game, such as sneezing, coughing, falling in a coma, laying an egg or ...dieing.

There's also some free slots available for you to use if you want to implement new involountary actions to make your Norns more interesting.

Once again, the Genetics kit is a good place to understand the process:
Open your C1 gen kit, load the mum1.gen genome, then navigate to the genes tab.
Order your genes by type, and navigate the "Receptor" section. ( not to be confused with the stimuli genes, some of which are also used during pregnancy )


Gene 159 is labelled as "start laying" and operates by reacting to progesterone levels as expected.


We can see how it triggers "Involuntary action 1" when progesterone levels get over the expected threshold. We now know that this action is the one associated with laying an egg ( we must note this as not all tools do map involuntary actions so explicitly ).

"Involuntary actions" as most other aspects of the game are managed by associated CAOS scripts.
By browsing the game scriptorium with one of our tools, we can find the associated script either by name ( if available ), or by trying to locate unique pieces of code that we expect to find.

For example, without any documentation available, we could look for scripts that contain references to the egg sprites, to the "new: gene" command, or to the Egg classifier (2 5 2).

The following script found as 4 0 0 65 will be our best candidate for the role.
( We can also note that the preceding and following scripts also seem to concern involuntary actions, with their references to sounds of sneezing, coughing and dieing.Which is a good indicator that we've found what we wanted.)

Here is a screenshot from the CKC's Script Archive applet, run in Scriptorium browsing mode, showing the EggLaying script known as 4 0 0 65.

Oddly enough, the egg laying script is classified as "Creatures->All Creatures -> Both sexes -> Lay an egg".
Meaning it's not a female specific behaviour. There's probably a good reason for that ( simplification ? possibility for new sexless species ?) but it won't really matter for our needs.

Let's rather take a look at the script and see what it does.
You can fetch the script with your favorite CAOS console tool by feeding it: "dde: scrp 4 0 0 65"


This is a slightly more readable version:



ltcy 1 255 255

doif carr ne 0
    stop
endi

doif baby gt 0
    pose 48
    wait 40
    setv var0 baby
    setv baby 0
    setv var1 posl
    addv var1 16
    setv var2 limb
    rndv var3 0 5
    mulv var3 8
    new: simp eggs 8 var3 2000 0 

    pose 0
    setv clas 33882624
    setv attr 64
    setv obv0 var0
    setv obv1 0
    subv var2 hght
    mvto var1 var2
    slim
    evnt targ
    tick 900
    dde: negg
    targ ownr
    stm# writ ownr 29
    wait 60
endi

done

endm



So what does all of this mean ?
With the help of the C1 CAOS guide, we can understand all of this:


ltcy 1 255 255

Is used to mean that the involuntary action should not retrigger before "255" delay.
This is to give time to the activating chemical do fade away and not lay more and more eggs at once


doif carr ne 0
    stop
endi


This stops the script if anybody is carrying the current object.
Probably to avoid bugs with creatures currently carried by the "edit" CAOS command, so they don't lay eggs while flying.



doif baby gt 0
....
endi


This bloc will be executed only if  "Baby" is set."Baby" contains the child moniker if current Norn is pregnant.
This means all of this only happens if a Creature is pregnant.
Even with a massive injection of Progesterone, an unfertilized Norn won't lay any egg.
This makes sense to me.
(This might also be an interesting spot to implement a new game mechanism such as the possibility for Norns to lay unfertilised eggs that could be later eaten? Come on, don't frown on me, you're doing the same for hens already.Yumm, scrambled Norn ovary byproduct with beacon !)

The contents of the DOIF bloc are the core of the egg laying process:

    pose 48        # Makes the creature Crouch for laying the egg
    wait 40        # Small delay
    setv var0 baby    # put the Baby's moniker in global variable Var0
    setv baby 0    # Clear the "Baby" flag from the norn, she's not pregnant anymore
    setv var1 posl    # Put the current creatures Left position in global variable var1
    addv var1 16    # Add 16 to the variable ( 16 is half a Norn, this centers the egg on the mother
    setv var2 limb    # Put the lower creature's limit in global variable var2, this "finds the ground"
    rndv var3 0 5    # Roll a 6 sided dice, and put result in var3
    mulv var3 8    # Multiply that value by 8 ( used to index imagefiles from 1-6 egg number later
    new: simp eggs 8 var3 2000 0 # Create a new egg,from "eggs" sprite, with 8 states,pick the appearance N°"var3"
    # From now on, following the "new:" command, targ is no longer the mother but the egg.
    pose 0         # Sets the egg sprite to the first one ( smallest )
    setv clas 33882624 # Sets the egg class for this egg
    setv attr 64    # Sets the egg attributes ( roombound )
    setv obv0 var0    # Puts the Baby moniker saved in global var0 inside the egg's onw obv0 variable
    setv obv1 0    # Puts 0 in obv1 local variable, ass we will see later, this will be the babies sex (0=random)
    subv var2 hght    # Subtracts egg height from found ground level ( Y axis is Top->Down )
    mvto var1 var2  # Places the egg correctly at mother's center, and groundlevel-eggsize
    slim        # Enables the egg "limits"
    evnt targ    # Triggers the "New egg" indicator in the status bar.
    tick 900    # Sets the egg's timer to 900
    dde: negg    # Updates number of natural eggs in the world
    targ ownr    # Targets back the mother
    stm# writ ownr 29 # Fires the 29 hardcoded stimulus in the mother
    wait 60        # small pause



Then we're only left with the cleanup:
done    # signal that we're done so the creature can resume normal life
endm    # Mandatory endmacro command




So what does all of this teach us ?
If we take out of the whole housekeeping stuff, and gameplay specifics from the script,
spawning a new egg boils down to running:

    new: simp eggs 8 <EggImageNumber*8> 2000 0
    pose 0         # This sets initial egg size,might start bigger
    setv clas 33882624
    setv attr 64  
    setv obv0 <MONIKER>  
    setv obv1 <SEX>  
    mvto <Xpos> <Ypos>  # Put the egg somewhere
    slim        # Enables the egg "limits"
    tick 900    # Sets the egg's timer to 900

    dde: negg    # Use if you want that egg to count as one egg in game stats.
  

We got rid of all uncontrolled stuff to replace it with our known wanted values.We also don't consider the new egg as a natural egg, so we don't update anything in the game interface.

We could also remove the "mvto" command, and add an "edit" one at the end of the script, so the newly injected egg ends up in the hand ( this won't disturb the egg if you don't spawn it starting at full size ) 

Additionally, we are still using a predefined and already existing (this is mandatory !) child genome moniker.
To generate one at runtime we might rather use the "new: gene" command such as in :
    new: gene tokn <MotherMoniker> tokn <FatherMoniker> obv0
or

    new: gene tokn <MotherMoniker> 0 obv0 
for mono parental child generation.

Before you get straight to making new eggs though, let's just see what happens to the newly laid egg.
The "tick 900" command in the original scripts, sets the egg timer value to "900" once laid.

You could further check the 2 5 2 9 ( Simple -> Eggs ->Norn Egg -> Timer ) script to see what happens once the egg gets into the world, but this is a much longer script.
I won't cover it in this article, but what happens next is that at regular intervals the egg grows in size.
Once the max size is reached, the next timer tick plays the "about to hatch" animation and sounds, and creates the new creature.
The last timer tick then destroys the remaining egg shell after some time.


Finally : generating your own ingame eggs

That's it ! we now know how to generate our own eggs.
Here are some CAOS snippets for the various creation scenarios you might want to use.

Remember we have control of all those parameters to get the expected behaviour:
  • We can pick mom and dad monikers at will ( or spawn eggs from one single moniker )
  • We can either create an egg for an existing moniker, or generate one from any random creatures couple ( even dead ones).We only need to have their .gen files ( The names of all .gen files map to the creature's monikers.)
  • We can spawn eggs at any state: small or grown.
  • We can choose the eggs sex or set it as random
  • We can control the Egg's appearance.
  • We can't control the eggs timer so it grows slower or faster, as this is reset in the timer script at each cycle.
  • We can spawn Eggs anywhere we want them, or make them user placable.

Yay! an egg out of nowhere from a CAOS command !


To make a random sex egg from a single genome ( here Purple mountain Norn ):

new: simp eggs 8 8 2000 0,pose 0,setv clas 33882624,setv attr 64,setv obv0 tokn 0XER,setv obv1 0,mvto 2682 870,slim,tick 900

To make a carryable egg from a single genome ( you can't put it in the incubator before it reaches it's max size yet ):

new: simp eggs 8 8 2000 0,pose 0,setv clas 33882624,setv attr 64,setv obv0 tokn 0XER,setv obv1 0,slim,tick 900,edit


To spawn a fully grown egg that will hatch as soon as dropped:

new: simp eggs 8 8 2000 0,pose 3,setv clas 33882624,setv attr 2,setv obv0 tokn 0XER,setv obv1 0,slim,tick 20,edit


To spawn a fully grown egg that will hatch quickly, from 2 parent genomes :

new: simp eggs 8 8 2000 0,pose 3,setv clas 33882624,setv attr 64,new: gene tokn 1WGR tokn 2YZL obv0,setv obv1 0,mvto 2682 870,slim,tick 20


Closing words

I hope this was interesting.Generating ingame egg files from arbitrary genomes can be an useful and practical addition to your Creatures mad scientist skillset.
Also contrary to the egg file generation mechanism shown in a previous article, this not only is more practical for everyday use but also works with C1.

All of these articles aren't purely coincidental. Once we've got all the bases covered, a future article will deal with massively and automatically mixing arbitrary genomes, and producing the corresponding eggs.

Basically, I will show you how to write a script that takes a set of Norn genomes, simulate them breeding for an arbitrarly high number of generations, and then import ingame some of the resulting children.
I use this possibility to check stability of my new genome/breeds over multiple generations, or to check long term compatibility when mixing various breed genomes.

If you want to know more about that, stay tuned !

Happy binary breeding!



 



2 comments:

  1. Using the Genetics Kit's CAOS injector function, I could not get "To spawn a fully grown egg that will hatch quickly, from 2 parent genomes" to work, even after I took out the commas. I used this code instead, partially generated by CrEd32:

    inst new: gene tokn 0isi tokn 1lmv var0 new: simp eggs 8 32 2000 0 pose 0 setv clas 33882624 setv attr 64 setv obv0 var0 setv obv1 0 mvto 2848 868 sys: cmra 2648 732 slim evnt targ tick 100 dde: negg wait 60 endm

    and that worked.

    ReplyDelete
  2. That's weird.
    What went wrong exactly ? Was it a syntax error ?Or did the egg not behave as expected?
    The code samples should work as is, by just replacing the monikers, without any other edits.

    ReplyDelete