Wednesday, December 17, 2014

Investigating Creatures 1 Teleporters

Alright, despite having loads of stuff in store, maybe I'll take a break from gory reversing stuff for this post, before I loose all of my readers (yeah, something like "both of them") :)

So why not take this opportunity to study something more generic? what about investigating how C1 teleporters work?


A happy Norn family, ready for exploration of time and space.



It only requires a bit of CAOS reading and your favorite C1 CAOS tool.

 

Getting the information

As you probably know by now, in all creatures games, all things are classified in broader families addressable by a 3 number identifier.

In this classification, C1 teleporters belong to the "Compound objects -> Vehicle -> Teleporter" branch.
Translated into CAOS terms, this is the "3->1->1" classifier.

If in doubt you can use the following command to explore what a given classifier corresponds to:

rtar 3 1 1,sys: camt



"rtar" means "Select a random target among following identifier" , and "sys: camt" centers game camera on target.
You can use 0's in place of any of the numbers as a wildcard for "any".

Repeatedly running those commands can quickly get you through the objects you are looking for:

  • rtar 3 1 0,sys: camt will show you all kinds of vehicles
  • rtar 2 6 0,sys: camt will cycle you through all foods
  • rtar 2 6 4,sys: camt will do so specifically through all the lemons
  • ...
All Creatures objects also have a set of scripts associated with them.
Each possible action is mapped to a script handling what will happen when the corresponding action occurs ( Actions include, enabling, carrying ,dropping, clicking,timers...)

The action Number 2 corresponds to activation.
We can therefore recover the script associated with teleporter activation by issuing the following CAOS command:

 dde: scrp 3 1 1 2

Which means "Compound objects -> Vehicle -> Teleporter->Activate2"



And the command returns :

setv actv 0,gpas,snde telb,snde tele,part 0,anim [123456],part 1,anim [123456],over,doif posl lt 3000,doif posl lt 1500,tele 7730 456,else tele 3992 930,endi,else,doif posl lt 5000,tele 2880 740,else,tele 1180 600,endi,endi,part 0,anim [67890],part 1,anim [67890],endm


Making sense of the script

After a bit of formatting, we get the following:

setv actv 0
gpas
snde telb
snde tele
part 0
anim [123456]
part 1
anim [123456]
over

doif posl lt 3000
    doif posl lt 1500
       
        tele 7730 456
    else
        tele 3992 930
    endi

else
    doif posl lt 5000
        tele 2880 740
    else
        tele 1180 600
    endi
endi

part 0
anim [67890]
part 1
anim [67890]
endm


Let's comment this and take bits one by one :

setv actv 0    # Clears the "Active" flag on the object, see remark below
gpas        # "Get Passengers" : loads nearby creatures into the Teleporter's field
snde telb    # Plays the Zap sound
snde tele    # Plays the teleporting sound
part 0        # Sets part 0 of the teleporter as the target for further actions
anim [123456]    # Plays animation of teleporter part 0
part 1        # Sets part 1 of the teleporter as the target for further actions
anim [123456]    # Plays animation of teleporter part 1
over        # Waits until animation is over before continuing
        # Note that part 0 and 1 are run in parallel as only one
        # "over" command is used



doif posl lt 3000        #Enter this bloc if current object's left position is lower than 3000
    doif posl lt 1500    #Enter this bloc if current object's left position is lower than 1500
       
                # If both conditions are met ( posl <3000 and posl < 1500 )
        tele 7730 456    # Teleport to 7730 456
    else

                # Otherwise, If if only posl <3000 is true (i.e. 1500<posl<3000 )
        tele 3992 930    # Then teleport to 3992 930
    endi

else                # If object position is not lower than 3000, enter this part
    doif posl lt 5000    # If it is >3000 but < 5000
        tele 2880 740    # Teleport to 2880 740
    else            # Otherwise ( >3000 and > 5000 )
        tele 1180 600    #Teleport to 1180 600
    endi
endi

part 0        # Sets part 0 of the teleporter as the target for further actions
anim [67890]    # Plays animation of teleporter part 0
part 1        # Sets part 0 of the teleporter as the target for further actions
anim [67890]    # Plays animation of teleporter part 1
endm        # End Macro




The non-intuitive part here probably is usage of the "setv actv 0" command right at the beggining of the script.
This command means "Deactivate the current object".
Then how using it so early doesn't break anything?
In fact, this is needed to instruct the game engine that the object did finish being used so it can be activated again later.
Without this instruction, the game wouldn't know when the object is done doing it's thing and you could only clik it once in it's lifetime.
Using it early in the script doesn't hurt, as it doesn't interrupt the script execution.
You might want to use it later in the script to prevent multiple activations of the object before it's animation/action terminates.

Other than that here's not that much to it and things should be pretty clear with the above explanations.
However the way teleporters are handled is interesting.


Handling multiple teleporters in one script


We can see that all 4 game teleporters are treated as one unique object, and that this only script is used to make them all work.

The game uses the current object's "posl" (position of the left edge) as a means to know which of the four teleporters is the one running the script.

Basically, it checks if the object running the script is below the 1500 th pixel, or between 1500 and 3000, or between 3000 and 5000, or over 5000.

Approximate position of the world slices and the teleporters.



Those correspond to very rough slices of the world but why not ? there are only 4 fixed teleporters and they are significant distance apart, so this technique makes sense as a low computing power means of attributing the action to a given teleporter.


Understanding other small bits:

We now know the broad lines of how all of this works, but we need to also get into the details to be able to say we fully mastered the teleporters inner workings.

What we might want to understand now is :
  • Which teleporter is which ? 
  • How is the animation played on the remote teleporter when the Norn arrives while the target teleporter is never mentioned in the script 
If we read out script " 3 1 1 1"  ("Compound objects -> Vehicle -> Teleporter->Activate1"), with :

dde: scrp 3 1 1 1

We can see :


This means:

enum 3 1 1            # For each 3 1 1 object (teleporter)
    mesg writ targ 1    # Run it's #1 action (activate)
next
endm


Therefore, when one teleporter is activated, all of them fire, running the same animation.


To know which teleporter is which, we can simply use the "sys: cmra x y" command with the coordinates of the four teleport targets and see where we land.

( the "tele" command teleports a creature to a given position, the "sys: cmra" one only moves the game cam to given coordinates)

We get the following results :
  • 7730 456 is the island bridge
  • 3992 930 is the garden
  • 2880 740 is the nursery
  • 1180 600 is the light house
 Notice how the X values for each of the teleporters fall within the world slices we identified earlier:

1180<1500<2880<3000<3992<5000<7730


Messing with the teleporters.

Now we fully understand how all of this works, why not mess a bit around with the teleporters?
Let's change their behaviour, and instead of having them work in pairs, make any teleporter send the creature to a random teleporter among the three other (we could also simply permute them,or make them teleport Norns to other places, not necessarily other teleporters).

Lets do it like this :

setv actv 0    # Clears the "Active" flag on the object
gpas        # "Get Passengers" : loads nearby creatures into the Teleporter's field
snde telb    # Plays the Zap sound
snde tele    # plays the teleporting sound
part 0        # Sets part 0 of the teleporter as the target for further actions
anim [123456]    # Plays animation of teleporter part 0
part 1        # Sets part 1 of the teleporter as the target for further actions
anim [123456]    # Plays animation of teleporter part 1
over        # Waits untill animation is over before continuing
        # Note that part 0 and 1 are run in parallel as only one
        # "over" command is used

rndv var0 0 2    # Roll a 3 sided dice ,results are 0-2 inclusive



doif posl lt 3000       
    doif posl lt 1500    # If source is the lighthouse
       
        doif var0 eq 0       
            tele 7730 456 # go to Island
        endi
        doif var0 eq 1       
            tele 3992 930 # go to the Garden
        endi
        doif var0 eq 2       
            tele 2880 740 # go to the Nursery
        endi   

    else             # If source is the Nursery
        doif var0 eq 0       
            tele 7730 456 # go to Island
        endi
        doif var0 eq 1       
            tele 3992 930 # go to the Garden
        endi
        doif var0 eq 2       
            tele 1180 600 # go to the light house
        endi

       
    endi

else               
    doif posl lt 5000    # If source is the Garden
        doif var0 eq 0       
            tele 7730 456 # go to Island
        endi
        doif var0 eq 1       
           
tele 1180 600 # go to the light house
        endi
        doif var0 eq 2       
            tele 2880 740 # go to the Nursery
        endi

       
    else            # If source is the Island bridge
        doif var0 eq 0       
            tele 3992 930 # go to the Garden
        endi
        doif var0 eq 1       
            tele 2880 740 # go to the Nursery

        endi
        doif var0 eq 2       
            tele 1180 600 # go to the light house
        endi


    endi
endi

part 0        # Sets part 0 of the teleporter as the target for further actions
anim [67890]    # Plays animation of teleporter part 0
part 1        # Sets part 0 of the teleporter as the target for further actions
anim [67890]    # Plays animation of teleporter part 1
endm        # End Macro


We can now put all of this on one horribly long line, and install the script by using "scrx" to remove the preceding, and "scrp" to install the new one:


scrx 3 1 1 2,scrp 3 1 1 2,setv actv 0,gpas,snde telb,snde tele,part 0,anim [123456],part 1,anim [123456],over,rndv var0 0 2,doif posl lt 3000,doif posl lt 1500,doif var0 eq 0,tele 7730 456,endi,doif var0 eq 1,tele 3992 930,endi,doif var0 eq 2,tele 2880 740,endi,else,doif var0 eq 0,tele 7730 456,endi,doif var0 eq 1,tele 3992 930,endi,doif var0 eq 2,tele 1180 600,endi,endi,else,doif posl lt 5000,doif var0 eq 0,tele 7730 456,endi,doif var0 eq 1,tele 1180 600,endi,doif var0 eq 2,tele 2880 740,endi,else,doif var0 eq 0,tele 3992 930,endi,doif var0 eq 1,tele 2880 740,endi,doif var0 eq 2,tele 1180 600,endi,endi,endi,part 0,anim [67890],part 1,anim [67890],endm


This will sure help lazy Norns to spread around the world more efficiently :)
Making an emergency cob that teleports a Creature back in the kitchen is left as an exercise for the reader.

See you soon !




2 comments:

  1. That was awesome. I'm enjoying your blog. I know it's not actively updated, but I am glad it still exists.

    ReplyDelete
  2. (Late) thanks for your comment :)
    Indeed, I've unexpectedly stopped working on it one day, but I don't consider it over yet.
    There's still plenty of stuff waiting to be done!

    ReplyDelete