From Creatures Wikia

Jump to: navigation, search
Editnorn This article is about a project that is in development.
Information may change significantly as the project progresses.

Kaos is a high level language designed by bdonlan to make writing agents easier. The Kaos compiler then translates this high level language into CAOS. Currently, it is still in an early stage of development, but is already capable of automatically compiling complex expressions involving the use of TARG and such attributes as BHVR.

For the Haskell source code (currently still under significant development), visit the project page on Google Code.
For an easy testing and using of kaos visit [1] an Kaos editor (an geany modification).
KAOS_HOWTO with examples.

An [2] DEMO how to use kaos, with metaroom,monitor,plant,weather...


Editnorn Some information in this article seems to be inaccurate and should be fixed..
More information may be available in the talk page.

Kaos borrows its syntax primarily from the C family of languages.

Comments are the same as c,c++ 
 one line to end //
 multiline /*  ..... */

The overall structure of a Kaos file is a series of install, remove, and/or agent blocks. Here is an example of all of them:

install {
       agent it = newsimple (2, 21, 47494, "rubber ball", 1, 7, 5000);
        it.attributes = 214;
        it.behaviour = 0;
        it.acceleration = 5;
        it.elasticity = 25;
script (2, 21, 47494,1) {agent a=owner;numeric y;
       y=a.YVelocity-20 ;
remove {
    enum  (3, 21, 47494) {|p| p.kill();}    


This is the output file test.k.cos:
new: simp 2 21 47494 "rubber ball" 1 7 5000
attr 214
bhvr 0
accg 5
elas 25
mvto 6100 9200
scrp 2 21 47494 1
targ ownr
setv VA00 vely
subv VA00 20
velo VA00 0

enum 3 21 47494
kill targ


Additionally, if you only need a single install block, you can simply place its code in the top level:

print("Hello, world!\n");


At the top level, you may define macros like so:

 macro rvalue(numeric arg1, agent arg2, string arg3 = "default value") returning numeric { ... }
 macro set lvalue(...) { ... }
 macro iterator loopconstruct(...) { ... }

The returning keyword sets the return type, and is valid only on rvalue macros. Macros using this can set their return value by writing to the return variable like so:

 define plusone(numeric v) returning numeric {
   _return = v + 1;

lvalue macros are passed their new value as their first argument, eg:

 define set printme(numeric v) {
 install {
   printme() = 42;

Iterator macros are called with a block of code, and may invoke it by calling the yield function, optionally passing it values:

 define iterator(numeric) loop(numeric times) {
   numeric index = 0;
   do {
     index = index + 1;
   } until(index >= times)
 install {
   loop(10) { |i| print ("Loop number "); print(i); print("\n"); }

Macros cannot recurse, nor can they call macros which have not been defined before them. You can also use a block of code:

define poke(agent obj)  { obj.XVelocity = obj.XVelocity + 5; };

When the macro has no arguments, the parenthesis may be omitted:

define numeric pi = 3.14;
install { 
  print("Two pies are ", pi * 2, "\n");

Macro definitions must be done in the toplevel of a script using install, agent, and/or remove blocks; something like this is (currently) forbidden:

define string hello = "Hello world!";


Kaos expressions may use the standard arithmetic operators *, /, +, -, with the normal precedence and associativity:

print("The Answer is: ", 40 + 2, "\n");

OVxx variables may be accessed with the [] operator:
First at the top

ovar numeric age_of_agent[1];

then in scripts

agent a;

There are also a set of primitive functions for accessing CAOS opcodes such as RAND and the OUT* functions. They have a syntax like the following:

print("And the die roll is: ", getRandom(1, 6), "\n");

Some functions work on objects:


Kaos automatically takes care of TARG, so you can do things like:

agent a;
a.behaviour = pointer.attributes + owner.XVelocity;;

This compiles to:

  targ avar pntr 47
  setv va00 attr
   targ ownr
  addv va00 velx
  targ norn
  bhvr va00


Local variables are declared with a statement like one of the following:

number fortytwo = 42;
object maria = norn;
string yum = "pizza";

Once a variable has been declared, it can be accessed simply with its name. Assignment is done with the = operator:

number meaningoflife;
meaningoflife = 42;
print("The Answer is: ", meaningoflife, "\n");
meaningoflife = meaningoflife * 2;
print("Twice the answer equals ", meaningoflife, "\n");

Variables are lexically scoped to the curly-braces-delimited block they are declared in. It is possible to mask them, like so:

numeric foo;
foo = 42;
print ("foo = ", foo); // prints 42
  print(foo); // 42
  foo = 24;
  print(foo); // 24
print(foo); # 42

Global (GAME and EAME) variables may be accessed in two ways. They can be aliased to a named lexical variable:

// GAME variable
game number "engine_debug_keys" keys;
keys = 1;

// EAME variable
engine string "engine_clone_upon_import" clone;
clone = 1;

Or they may be accessed with a function:

game("engine_debug_keys") = 1;
engine("engine_clone_upon_import") = 1;

The former method should be preferred, as it tells the Kaos compiler what the type of the variable is, avoiding costly and complex runtime checks. However, if the name of the variable is computed at runtime, use of the function form is unavoidable.

Conditional statements

The Kaos if statement looks something like this:

if foo == bar {
} else {

The conditional statements can be built out of the operators ==, !=, <=, >=, <, and >. These all work on two expressions. In addition, if you simply put a bare expression where a conditional is expected, it will be interpreted as (expression) != 0.

In addition to comparing expressions, you can merge the results of the comparison with the && (and) and || (or) operators, as well as negating a conditional by prefixing a !. For internal reasons, while using parenthesis is allowed in a conditional, it is not recommended on the right side of an && or || as the resulting CAOS will be inefficient.

Note that unlike many other languages, Kaos conditional expressions do not short-circuit - all subexpressions will always be evaluated.

Looping constructs

Do...while and do...until loops are supported with the following syntax:

do {
  // code
} while condition

do {
  // code
} until condition

do {
  // code
} forever

  for (x = 42; x > 24; x = x - 1) {
    # ...

Note that at this time there is no way to escape a do { ... } forever loop. It is primarily included for completeness.

In addition there is the enum loop, with the following syntax:

enum variable (family, genus, species) {
  // code

In this, variable is assigned the value of each agent with the specified classifier (0 being accepted as a wildcard for any field).


The initial implementation of Kaos was as a perl compiler, but since then bd_ found Haskell, and now the currently actively developed implementation of Kaos is the Haskell implementation. Currently there is no public release; if you are interested in testing it please contact bd_.

Personal tools