creatures caves welcome, guest
downloads   gallery   dev   community   creatchi   forum   mycaves
hack shack | script reservations | dev resources | dev forum


Randomly choose from A-Z?  on 3/14/2018 | 2 comments

     Is there a way to force something to choose randomly from A-Z, rather than 0-26?
- Malkin

Dear Malkin,
- Pilla
Visualisation techniques?  on 1/2/2018 | 1 comment | 2 likes

     How do you sketch out / visualise what a more complicated script, like a critter or plant timer script, will do?
- Malkin

Dear Malkin,
     Hey Malkin,

I don't have a specific way to sketch/figure out a complex agent, but for the sake of this answer I'll just write down my thought process for a random object instead.
Everyone has their own way to figure out how to code a complex agent, I have mine. For this example, I've decided on making a random tree. Enjoy!

Step 1 - Documenting
Write down what you want your object to do. How long should it live? What environment does it need? Will it influence the environment? Will it be seasonal? Be as detailed as possible. For now I'll make a tree that spawns delicious fruit.

- seasonal colors, leave color change every season
- During spring, it'll spawn flowers, during summer/fall - fruit
- It will live for 5 - 8 ingame years
- When dying, it will put some nutrients into the ground
- Only one tree per metaroom, will only grow in boggy soil.
- Minimum 2 fruits, maximum 4 per tree. A new fruit will always grow when there's less than 2 fruits. Depending on the nutrients/light/heat in the environment, a third and fourth fruit may grow.
- During the night, fruit/flowers will not drop
- Actions: Pushing/pulling the tree does nothing special, hitting the tree may drop some full grown fruit.

- Grows from a flower, hangs on the tree for one ingame day before falling off.
- Adds a dose of vitamin C
- Depending on the nutrients around the tree when the fruit was created on the tree, will give more or less "eaten fruit" stim
- Will spoil after three ingame days. Gives nutrients to environment.
- May grow into a tree if there are no other trees in this metaroom, and if there are sufficient nutrients around.
- Actions: pickup, eat

- Will close at night when hanging on the tree
- During spring, will fall off when fully grown. Summer/fall, it'll grow into fruit.
- Flowers will grow for 1 ingame day and bloom for 1 ingame day before falling off/growing into something else
- Gives some nutrients
- Actions: pickup, eat

- This is what happens when a flower/fruit has turned bad.
- It stays around for one ingame day, and when disappearing it will give nutrients to the environment.
- It's edible. Just not yummy. :P
- Actions: pickup, eat

...I could probably go more complex than this, but let's keep it semi-simple for now.

Step 2 - Commenting

Once you wrote down all of your objects and all of the requirements, you could make a small flowchart to visualize how the object itself needs to work. I personally don't use flowcharts, but sometimes with a very complex agent I fill the cosfile with comments before starting to code anything.

So, yeah, let's try my approach and create a small .cosfile. I make sure I have a species ID number ready, and I start writing comments directly into a cosfile. Take each object and write the initial scripts you will need for each object. Don't worry if you don't get all of them right away, you can still add them later.

** RESERVED ID: 36472


** This is a tree.
** This is fruit
** This is a flower
** This is detritus


** Tree creation
** Tree timer

** Fruit creation
** Fruit timer
** Fruit pickup
** Fruit eat

** Flower creation
** Flower timer
** Flower pickup
** Flower eat

** Detritus creation
** Detritus timer
** Detritus pickup
** Detritus eat

This is how my .cosfile looks now. In the install script, I'll write down the code I need to inject either object ingame, but I will comment it out later. I consider it very useful to have example injection scripts on top of the script, then if you need to create an object or write a script for something you can just copy the code with the correct classification numbers from there.

Occasionally, if I'm not in the mood to look up any CAOS at all but I want to have a basic idea ready, I write down some pseudocode in the comments to show what I actually want to achieve.

Step 3 - Code the absolute basics

Once you got your basic commented file down, you can start to create the scripts. I usually start coding the absolute basics first, making sure the object just works, whether or not the conditions are ideal. When I'm sure the basics work, I start adding in more and more requirements/cases/doifs.
For example, let's do the most basic code for the tree. The creation and timer script.

Let's assume the tree uses the image "pilla_tree_1", which contains 5 frames of a growing tree. The tree is fully grown when it reaches the 5th frame (so frame number 4).

** Tree creation
scrp 2 4 36472 10
** Attr: Suffer collisions (64) and physics (128 ) - 192
attr 192
** Bhvr: act1 (1), act2 (2), hit (8 ) - 11
bhvr 11
** Set the tick to 1/5th of an ingame day. A tree
setv va00 game "engine_LengthOfDayInMinutes"
divv va00 5
mulv va00 1200

** Tree timer
scrp 2 4 36472 9
** If the tree is not growing yet, grow the tree
doif pose lt 4
setv va00 pose
addv va00 1
pose va00
** If the tree is fully grown, spawn fruit
gsub spawnFruit

** Everything below this point are subroutines for the tree timer
subr spawnFruit

I now created a script for a tree that spawns fruit if it's fully grown, this are the basics of the script.

I use subroutines a lot to keep the code readable, it also allows you to add in the same subroutine in different spots in the code, while still allowing you to pick the initial variables needed for the subroutine.

Step 4 - Increase complexity

If you want to go more and more complex, you can addd in more and more requirements/cases/exceptions to the existing code. Right now it'll forever spawn fruit, it will never die, etc. If you want it to live for a specific duration, you'll have to add life variables and increase them every time a timer tick runs. If you only want it to grow on normal/boggy soil (or whatever), you can add in a doif that specifies that the soil has to be any of those types, etc.
As long as the basic code is working, you can keep on adding to it until it works exactly as you want it to work.

That's pretty much my thought process.


$$ - Pseudocode

Pseudocode? What dat? It's just some code YOU create. With pseudocode you're writing the code for something without worrying about using the wrong commands/no punctuation/... - You just have to think logically and think about how the object has to act, and write this down.

For example, here's some example pseudocode for the fruit once it dropped from the tree.

* if current age < total life:
** increase life of fruit
** if environment = boggy soil, dry soil, normal soil and if no other trees around
*** Grow into a tree
** End the if block
* Else if current age > total life
** If environment != water
*** Turn into detritus
** Else
*** Disappear
** End if block
* End if block

$$ - Flowcharts

Some people draw up flowcharts if they need to write complex code. I personally never use flowcharts as I'm better at reading code itself than a flowchart, but obviously this is not the case for everyone.
If you feel like you would be able to work better with flowcharts, then by all means make a flowchart. Just google some info about flowcharts to get started :)

$$ - Custom scripts

In case you would want another object to 'change' the initial object, I usually work with custom scripts. Let's make a fictional example: I want that the fruit which has dropped from the tree, when eaten, makes the tree drop some leaves. (This makes no sense whatsoever but it fits the example. Deal with it. :P)

So, yeah, in this case the fruit would have to send a message to the tree when eaten, a message that tells the tree to drop some leaves. For script numbers, you can usually safely pick any number over 1000. Let's use script number 1012 for the tree:

scrp 2 4 36472 1012
gsub dropLeaf

subr dropLeaf

I'm not doing any actual coding yet, just preparing the scripts we'll need. Now, script number 1012 has to be triggered when the fruit has been eaten, so we'll need to do the fruit script next. Also, for fun, I want the fruit to inject vitamin C.

scrp 2 8 36472 12
* Stim writ eaten fruit
* Chem vitamin C (optional)
* Send message 1012 to the tree to trigger the leaves

Now that I write down the utter basics for the fruit script, I realize the fruit needs to have the tree saved as an OV so the fruit can refer back to the tree. I'd go to the spawnFruit subroutine in the tree timer script and make sure the tree variable gets added to the fruit so the fruit can consistently refer back to the tree.

And like this you keep on writing, adding to and refining the code.

I hope my incoherent rambling somehow managed to answer your question! If you have any more questions, don't hesitiate to ask ;)

(Also, special thanks to Malkin for adding all the resource links!)
- Pilla
Peak of smell  on 7/25/2014 | 2 comments | 4 likes

     I'm playing around a bit with the genetics and wanted my breed to have their home where the light is. So I changed Stimulus to 'Reached Smell 1'. I thought it was that easy but I found the following problems:

- What to do with the instinct gene for the home? The light emitters classify as nothing but invisible. My solution now was to change them to 'weather' and set the instict to weather, too. Would changing of the emitters cause problems (with other agents maybe)?

Is there maybe another, easier way to tell the instinct that they get their comfort when following the light 'smell'?

- How does 'Reach Smell X' work anyway? Is it triggered when a certain amount of CA is reached or the maximum of the room or the total worlds? (Like, if I install a new room that has a new light maximum would their home location change?)

- Would there be a way to 'invert' it? To set 'darkness' as their home?
- Luzze

Dear Luzze,
     The way Creatures detect and interact with smells is a bit funky. I know what you're going through, because I've tried to do similar things in the past.

I'm not sure exactly how "reached smell X" works on its own, but I can tell you that if you want your Norns to approach something, the smell in question needs to be associated with an agent type. Norn brains are set up to run primarily on interactions with physical agents. For the most part, a smell is essentially just a "billboard" that tells the Norn where to find an agent of a given type.

One way in which you can see this limitation in action is what I call "oblivious Norn syndrome" (or ONS for short). If you create an object that smells like food, but is either invisible or just some other type of agent, Norns will pace around that agent but completely ignore it. Even if the agent is some other edible object, like a piece of fruit, they will still ignore it! Their brains connect "food smell" to "food agents", so they will keep doggedly looking for a piece of food until they are either sufficiently distracted by something else, or until they die.

This kind of behavior (expecting an agent to be associated with a smell) extends to Norn Home Smell too: there is a specific, visible agent called "Norn Home" which Norns approach when homesick, and this agent is what produces Norn Home Smell. If Norns can't see the Norn Home agent, or if the smell emitter is a different agent type, they will fall right into ONS: pacing back and forth helplessly as they look for something they either can't see or don't recognize.

Now here's something that might be able to help you: Norns only know that the "Norn Home" agent is what produces Norn Home Smell because the game stores associations between smells and the agents that emit them. In Docking Station at least, you can change or create new associations using the CACL command. The structure of the command, as depicted in the CAOS Documentation, looks like this:

CACL (command) family (integer) genus (integer) species (integer) ca_index (integer)

So if (for example) I wanted to make the Hand smell like food, I could run this command:

CACL 2 1 1 8

You can have your Norns approach light more effectively if you tell the game that the "light smell" is linked to a certain agent type, and tell them to approach that agent. I'm not sure the inverse would be possible, though, since "darkness" even in the game is simply an absence of the "light smell".
- Ghosthande
Nested DOIF?  on 4/13/2014 | 1 comment

     Have you ever used nested DOIFs? (DOIFs inside DOIFs) When would you recommend using them? Do you have any tips on how to work with nested DOIFs effectively?
- Malkin

Dear Malkin,
     I use nested conditions all the time: in CAOS, in PHP, Javascript, and ColdFusion (which is, interestingly, more similar to CAOS in some ways than it is to other web-related languages). The correct answer is: whenever it seems more efficient to do so. In general, which method you use isn't a matter of optimization, but basic logic that depends entirely on the circumstances: your script won't do what you want it to if you use the wrong method.

But there are definitely some times when it's better to nest them, and some times when it isn't. The most common alternative to nesting conditions is to link them, like this:

DOIF condition 1
(do something)
ELIF condition 2
(do something)
ELIF condition 3
(do something)
(do something)

It's all essentially one "block" of conditions. If the first condition isn't true, it will automatically try the second, then if that isn't true it will try the third, etc.

Nesting conditions, as you know, looks like this:

DOIF condition 1
(do something)
DOIF condition 2
(do something)
ELIF condition 3
(do something)
(do something)

There are a few ways in which humans use conditions that computers don't, and this "language bias" is the most counterproductive when using conditions, because our experience speaking English (or German, or Chinese) influences how we expect CAOS to work. For instance, I see a lot of new programmers write stuff like this:

DOIF the sky is blue
(do something)
ELIF the grass is green
(do something)
(do something)

Because we all think the same way and make the same initial assumptions when learning to code, you'll see people do this kind of thing in any programming language that uses conditions. The problem is that computers--regardless of what language you're using to communicate with them--don't like subject changes in the middle of condition blocks. Since the first DOIF is referring to the sky, the game expects that the next condition in the block will also relate to the sky. Even though the basic structure looks correct to the human eye, the code above won't work consistently because it relies on forcing the game to "think" in a way it wasn't designed to. This is the kind of situation in which we need to use nested conditions. The code above becomes much more stable and reliable when we "phrase" it properly:

DOIF the sky is blue
(the sky is blue, so do something)
DOIF the grass is green
(the sky is not blue BUT the grass is green, so do something)
(the sky is not blue AND the grass is not green, so do something)

Now the game will know for sure that we only care about the color of the grass if the sky is blue. If we want to check the color of the grass and take different actions depending on both the sky and grass color, we can duplicate the grass-related condition block like this:

DOIF the sky is blue
DOIF the grass is green
(the sky is blue AND the grass is green, so do something)
(the sky is blue BUT the grass is not green, so do something)
DOIF the grass is green
(the sky is not blue BUT the grass is green, so do something)
(the sky is not blue AND the grass is not green, so do something)

Or we can use variables to "tally up" the results of our conditions, like this:

DOIF the sky is blue

DOIF the grass is green
ADDV VA00 10
ADDV VA00 20

(the sky is blue and the grass is green)
(the sky is blue but the grass is not green)
(the sky is not blue but the grass is green)
(the sky is not blue and the grass is not green)

Which one you use depends entirely on the situation: if you're only combining two conditions, the first method is certainly more straightforward at a glance. But if you're combining more than two conditions (perhaps you want to check if the sky is blue, if the grass is green, and if there's a mild breeze) that method will double in complexity with each condition added, which can get messy very quickly. The second method has an advantage in that situation, because the final condition retains the same structure no matter how many conditions are involved.

It also makes it easier to use the same action for different conditions, because you can do fun stuff like this:

(the sky is blue and the grass is green)
ELIF VA00 EQ 12 OR VA00 EQ 22
(the sky is blue but the grass is not green, OR the sky is not blue and the grass is not green)
(the sky is not blue but the grass is green)

There's a lot that could be said about conditions and how to use them, but any method depends on what works best for your agent and what makes the most sense to you. I think that's why I find conditions one of the most fun and interesting aspects of coding.
- Ghosthande
Correct BHVR, No Script?  on 11/13/2013 | 4 comments

     What happens if I set a bhvr that allows an agent to be interacted with, but I don't give that agent a corresponding interaction script? What does the creature experience when they interact with such an agent?
- Malkin

Dear Malkin,
     It depends on the script in question. A C3/DS agent cannot have a BHVR that includes edibility but no eat script, for example: the agent will error when the user attempts to inject it, well before any creature could try to interact with it.

It may not seem that way, but this is true for all script types; I actually discussed this with AquaShee a while back and he was able to determine that scripts that appear to be optional, such as the pickup script, only appear to function that way because the game has a hidden "global default" pickup script that it uses if there is no pickup script for a specific agent.

So really, there is never not a script to match an agent's BHVR, either because it causes an error or because there really is a script involved. A creature that interacts with a "scriptless" agent experiences whatever stimulus exists in the default script.

The only time I can think of when a creature might receive literally no stimulus for an action is if an agent's creator does write a script for a certain interaction, but does not include any stimulus. CFE breeds appear to feel disappointment and/or boredom when an action provides no feedback and will eventually give up, but non-CFE breeds don't have this feature and may continue to try to perform the same action until they exhaust themselves.
- Ghosthande
Patch Plants  on 11/7/2013 | 1 comment | 1 like

     Are patch plants easier to create than regular agents, since they're a sort of addition to an already created agent (i.e. the garden box)? Or do they basically entail the same amount of coding and work to create?
- Rascii

Dear Rascii,
     In my opinion, they're both pretty much equal, though patch plants may be slightly more difficult the first time around since you have to get familiar with Garden Box coding and variables. Beyond that, patch plants and regular plants are generally the same: a coder still needs to write an install script, it is just "nested" inside a GB script. The other scripts, including the timer script and remove script, are basically identical.

So from my experience (mostly helping others--I have yet to finish a patch plant of my own) the Garden Box is definitely not a "shortcut" for people who want easier plants, but those who are new to plant creation aren't in for much if any extra difficulty, and coders who are already familiar with making regular plants will find that patch plants aren't intimidating at all once you start. :)
- Ghosthande
Drag and Drop in C3/DS  on 10/28/2013 | comment | 1 like

     Most (if not all) actions in the Creatures series are point and click-based, but I was wondering if drag and drop actions are also possible. Since C3 and DS have user interface elements in-game I thought it wouldn't be too surprising if the engine supports it. Do you know if drag and drop actions are supported?
- eprillios

Dear eprillios,
     Hmm, that's an interesting question.

I've never specifically tried to make something drag-and-droppable, so I can't say for sure that there's no way to do it. I'm not aware of any specific commands for it, however. I do know that you can run a line of code to make the hand pick up an agent when it is clicked on, but I don't think that's quite the same thing. Sorry I can't be of more help! :)
- Ghosthande
Pigment Bleeding  on 8/18/2013 | 1 comment | 3 likes

     Hi, I've been trying to stop my genetic norns that i'm making from changing colors as they get older. Is there any way that I can get rid of the pigment bleeding?
- HavenHerbaven

Dear HavenHerbaven,
     I'm not an expert on genetics, usually sticking to the "caotic" side of development, but I can empathize with what you're dealing with; pigments are tricky to work with.

There is a tutorial here which may be of use, although I must warn you that--despite what the tutorial says--you must not delete any of a Norn's genes. Deleting genes simply leads to slider syndrome when that Norn breeds with others that have normal genes.

Fortunately, you can literally "turn off" a gene without having to delete it. Each of a Norn's genes has a special toggle; in the Genetics Kit this appears as a check box at the top of the gene editing window, which says "Do not express (carry)". If this box is checked, the gene still exists in the Norn's genome, but lies dormant. Its effects should not be observable on the Norn.

I hope this helps as a starting point and wish you the best of luck with your project!
- Ghosthande
ATTs and Breeding  on 5/26/2013 | comment

     First off, thank you for the advice concerning spriting/lighting/etc earlier! I've since made some headway on the breed I'm working on (despite a few setbacks), but I've gotten stuck on a worry of mine.

I know from experience that breeding creatures with different sprites will sometimes get you weird, disjointed/dismembered creatures if they're using certain breed sprites in combination with other breed sprites.

While I'm not worried about ATTs becoming a problem with pure-bred creatures, I'm worried that my breed would become prone to this problem when crossbred, and I want to try and prevent the problem before I've made too much progress.

What do you know about how ATTs interact with other ATTs from other breed slots? Can a problem like this be easily fixed?

Thanks again!
- Leporidae

Dear Leporidae,
     Each Norn body part has an ATT which tells it where its joints are. So a Norn head has a "neck joint", and a Norn body also has a "neck joint", and the game positions the head on the body by lining them up with one another. Easy, right? I'm sure you probably know that much already. The reason some breed combinations "go wrong" is that in the past, not all creators were consistent about making sure the joints were in the same relative place on each body part, compared to other breeds.

A Norn with (for example) a neck joint located 10 pixels too far down can still look visibly normal in the game, when both its head and body ATTs match up with each other. But when you get a crossbreed with that breed's head and another breed's body, bad things will happen. Its head ATT specifies that the neck joint is 10 pixels further down than usual, but its body ATT specifies that the neck joint right where it's supposed to be. As a result, the Norn winds up with a floating head.

If your breed has the same proportions as an official breed and are positioned the same way on their sprites, you can just copy an official breed's ATTs and avoid the whole issue. If not, that's okay too! As long as you can get the hang of how ATTs work in general, I don't think making your breed compatible with others will be too difficult. But I do strongly recommend using a graphics program like Photoshop, Gimp, or even Paint to keep track of where connection points are located on the sprites--not just for your breed, but for one of the official breeds too, so that you can get an idea of where joints are supposed to go.

And finally, you can always use the Genetics Kit to test hybrids in-game. I had a lot of concerns about how Gaius crossbreeds would look, for example, because he's built so weird. Because the Genetics Kit allows you to specify species/breed slot for each body part, and then create an egg in-game, it's a breeze to gengineer a test subject with any combination of body parts you want.

I hope this answer has been helpful; ATTs aren't always easy to explain without visuals, but hopefully they don't seem too scary. :)
- Ghosthande
Timer Scripts With Pushes  on 5/26/2013 | comment

     What are some tips and tricks you can use to make a plant or critter timer script (growing/fruiting plant, mobile critter) that also allows the item to be interacted with (pushed, pulled, hit, eaten), and easily 'resume its place' in the timer script?
- Malkin

Dear Malkin,
     If you followed the same learning curve I did, your first introduction to timer scripts might have been the Basic Plant Script on the Creatures Wiki. A lot of my early agents started out with timer scripts like that: just a line of subroutines, or even just the code itself laid out sequentially. This is fine at first, because this system works great for things that aren't interactive, like plants.

A timer script runs automatically every few ticks (depending on what you set the agent's TICK to). It will automatically be interrupted if another script is called (eg. if a Creature activates its Push Script), and when the timer script next runs, it starts over from the beginning. This means that if you have a plant with a timer script like the one in the tutorial above, it's going to want to restart the whole Grow -> Live -> Seed -> Die sequence every time it gets interrupted. This can cause errors in a lot of ways... say, if the plant tries to "grow" when it's already an adult, it may try to grab an out-of-range sprite.

One easy way to prevent a timer script from being interrupted is to LOCK the agent at the beginning of the script, and UNLOCK it at the end. Then if a Creature or another agent tries to interact with it, it just says "sorry, no can do!" and goes on with its timer. The downside is that the more often the timer script is running, and the longer it takes to run, the less often the agent is open for interactions. And if the whole script runs in one iteration of the timer script, as with the Basic Plant, the agent will essentially be locked for its entire existence (which is why I don't write timer scripts that way anymore). Since Norns don't understand the concept of an agent being "locked", this is a major downside.

The most surefire way to keep track of where an agent "left off" is to use OVxx variables to keep track of what it was doing last. If you're dealing with something like a plant growing or wilting, you can simply check the agent's pose, eg. "doif pose lt (whatever the final pose is)". Of course, this pose will probably change if you end up adding sprites later. And if you ever want to re-use the same code for another agent, that agent might have a different number of sprites. So it's easier to set an OVxx variable with that number when you first create the agent, and then have the agent check "doif pose lt OVxx".

Variables are even more useful if you're dealing with something that doesn't always follow a set pattern of behavior, such as a critter. A critter might wander randomly, interact with Creatures, look for food, play with nearby toys, or any number of other behaviors, often depending on less predictable factors like whether it's hungry or what's going on in its environment.

To do this, you first set a permanent (OVxx) variable as soon as the critter "decides" to do something--eg. as soon as it realizes it's hungry and starts looking for food--and reset that variable to "empty" as soon as the critter is finished doing that thing. Then, at the beginning of the timer script, you check that variable. If the variable is set to a certain action, you go straight to that subroutine. If it isn't set, you let the critter go through the normal process of what it wants to do next.

Using variables this way for critters can be overdone, though. Say, if I have a critter that gets interrupted by a Creature when it's in the process of looking for a mate. Being played with so much leaves it starving, but it ignores the food near it because its last action wasn't "find food". But because it's now starving, it dies before it can reproduce. You may end up seeing some strange behavior if you don't have a set "hierarchy" to prioritize your critter's actions.

If you use reference variables, it's also important to re-check them at the beginning of the timer script to make sure they're still "valid". For instance, let's say that I have a critter that seeks out and eats leaves, as described in the Hungry Critter Tutorial.

In the tutorial, the Hungry Critter only uses a temporary variable to reference the leaves it finds, which means that it "forgets" what it was looking for if the timer script is interrupted. If I want to use an OVxx variable so it can pick up the hunt where it left off, I need to remember that the leaf might not exist anymore by the time the critter gets around to looking again; it might have rotted, been eaten, autokilled, or simply moved. Yes, moved: I've had situations where a Creature carried a food item into another metaroom, and the critter that wanted to eat it spent the rest of its life trying to "follow" that food item! A lot of things can happen while your critter is distracted. [ntongue]
- Ghosthande

prev | 1 | 2 | next

hack shack
script reservations
dev resources
active projects
dev forum
log in
lost pw
0 online
creatures caves is your #1 resource for the creatures artificial life game series: creatures, creatures 2, creatures 3, docking station, and the upcoming creatures family.

contact    help    privacy policy    terms & conditions    rules    donate    wiki