ALL ABOUT CAOS VARIABLES!!!

So CAOS has all these variable setting/getting commands, and is pretty damn intimidating (numbers!!!!! oh god!!!!) when it comes to variables in general. Here's a table you're probably going to be referring to a lot for a bit:

  (numbered) Script variables Numbered object variables Named object variables Singleton variables Catalogues
Get VA##
(va00, va01...)
OV## MV## AVAR agentpointer index NAME "varname" MAME "varname" GAME "varname" EAME "varname" READ "tag" index
Set

SETV

SETS

SETA

No command; Catalogues are handwritten outside the game
Scope This script TARGeted agent OWNR of script; same vars as OV## Agent described by pointer TARGeted agent OWNR of script; same vars as NAME This world This game session This installation of the game
Destructor ENDM (death of THIS ITERATION of containing script)

KILL (death of containing agent)

KILL (death of containing agent) KILL (death of containing agent) KILL (death of containing agent) DELN "varname"

KILL (death of containing agent)

TARG OWNR DELN "varname"

KILL (death of containing agent)

DELG "varname"

Closing the world

Deleting the world

DELE "varname"

Closing the game engine

Uninstalling the game

Uninstalling/wiping the game/catalogues folder
Enumerator

No

REPS 100
ADDV VA00 1
AVAR OWNR VA00 ...
REPE

No

REPS 100
ADDV VA00 1
AVAR agent VA00 ...
REPE
NAMN No No EAMN SETV VA00 REAN "tag"
REPS VA00
READ "tag" VA00
ADDV VA00 1
REPE
Useful for Anything you have no reason to use again outside the script Information that persists with the agent

Information that needs to persist between runs of a script

Getting OV## vars of 'parent' when doing something else with TARG, or when TARG is uncertain Pseudo-arrays

Var ops when you can't/don't want to deal with changing TARG

Iterating over OV## of an agent (!!!!!!!!), since there's no other command that addresses a variable without explicitly stating the ##

Setting variables that are self-documenting; much nicer for use across more sprawling code Getting/setting NAME vars of 'parent' when doing something else with TARG, or when TARG is uncertain Setting variables that need to be consistent between many objects, eg. creator location Game settings to destroy on exit, like (theoretically) volume control Catalogues; help files, metadata, etc.
Notes Beware using this in timer scripts; they'll be wiped every time the agent TICKs. Usually you want OV## instead. If you ever change TARG, you may want to get in the habit of using MV## instead where applicable for clarity.   You can fake an array with this; using multiple objects you could fake a linked list. You can't fetch these values with AVAR.

You can fake an array with this, too.

      Beware GOG changes to filesystem

Also, there's about a jillion different variable types, and if you're a 16 year old rediscovering the game, you might have never encountered the concept of a 'typed' variable at all. Crash course: If you fudge them and try to put one type where another type should go, the engine gets mad. Like, crash-to-desktop hope-you-saved-your-game mad. There's conversion commands for most of the important ones; use them. Also, integers (1, 2, 3) and floats (1.5, 3.14, ...) aren't the same type, but are gotten and set by the same commands.

* indicates the function performs conversions in some or all circumstances

Uninitialized variables behave (and return as) like integers set to 0, on a cursory examination.

type name integer float string simple agent mouse cursor agent compound agent (uses PART) vehicle/cabin creature
TYPE result 0 1 2 3 4 5 6 7
Indirect operation (returns new var modified/based somehow from input var(s)) ACOS
ASIN
ATAN
COS_
SIN_
SQRT


SINS

The entire 'agent' section in the CAOS guide is a start;
most operations require that the agent be TARG first.

Direct operation
(changes an input var IMMEDIATELY, with no SETV etc.)
ABSV
ADDV
DIVV
MODV
MULV
NEGV

Bitwise:
ANDV
NOTV
ORRV

Shared with integer:
ADDV*
DIVV
MULV*
NEGV
ABSV
ADDS
CHAR
LOWA
Generation RAND NEW: SIMP NEW: COMP NEW: VHCL NEW: CREA
NEWC
Examination
(returns some property of var)
TYPE TYPE STRL
TYPE

The entire 'agent' section in the CAOS guide is a start;
most operations require that the agent be TARG first.

Conversion
(always indirect)
ITOF FTOI STOF

UNID

Checking if a variable is empty or if it's never been set (uninitialized)

There will come a point where you need to check if a variable is empty, or if it's uninitialized (never been set at all). These are similar but aren't the same thing in CAOS, so here's the quirks.

Uninitialized variables will work as integer 0 for most purposes; however, TYPE will correctly recognize them as uninitialized, returning 0.

Agents are a special case. You'd think AGNT would be perfect for making sure a target agent exists, but it's meant to be used with UNID; it's much more expedient to use TYPE to make sure a given variable is a valid, non-null agent before trying to use it.

If you need an empty string to check against (eg. using any of the many commands that take one string and output the next related string as output, and you might be checking the string before the command has run), you'll need to initialize it with SETS [...] ""; otherwise it'll behave as a number, 0, and your script will start screaming about unexpected types.

Should I use an integer or a float?

If you absolutely need a float, use a float.

Otherwise, use an integer.

How to make a direct operation indirect??

setv va00 1   setv va01 va00   addv va01 2   outs "va00: "   outv va00   outs " ... va01: "   outv va01
> va00: 1 ... va01: 3

In this particular context 'va00' is taken as 'copy the content of va00, please' and not 'a pointer to va00 please'

Your code will likely include a lot of temporary variables like this. Personally I delegate VA # OV 51-69 to them, just to keep things consistent.

What about the other way around?

*sigh*

setv va00 1.5   setv va00 sin_ va00   outv va00
> 0.026177

How to get a random float?

Glad you asked

setv va00 1   setv va01 rand 0 99   mulv va01 0.1   addv va00 va01

This will produce a number between 1.0 and 1.99

MULV and ADDV perform implicit integer-to-float conversions FOR SOME REASON. Generally anywhere in the docs you see 'variable' and not 'integer' or 'float' specified with one of these commands, it's worth testing to see if there's implicit conversion.

What's 'bitwise'?

OK, so in binary, these numbers look like this:

1 2 4 8 16 32
0000 0001 0000 0010 0000 0100 0000 1000 0001 0000 0010 0000

And these numbers look like this:

5 (4 and 1) 100 (32, 64 and 4) 23 (16, 4, 2, and 1)   and so on  
0000 0101 0110 0100 0001 0111     and so forth.

If you're keeping track of a small number of on/off flags -- say, 8 or so -- paying attention to the binary forms of these numbers might be a lot faster and simpler than storing a whole bunch of options in different variables.

Pay attention to the numbers the behavior and attribute flags ask you to sum up for their respective options.

The weird 'SETA'

SETA initially confused me, since I was, like most people, confused by pointers. Agent variables are pointers to an agent somewhere in the world. Be careful with using them, as if they point to an agent that's already been KILLed, or is otherwise incapacitated, well...

It works well with TARG and ENUM. Comb the game CAOS if you're still unsure.

Okay, but should I use the named variable commands or the numbered ones?

It doesn't matter, but here's my rule of thumb:

If you'll be referring to it later in the script, use named.

If you'll be using and discarding it, the way you'd use, say, i for an iterator in other languages, use numbered.

AVAR can't be used on named variables, so if you'll be doing anything that looks like an array, prepare to deal with numbered variables

There IS a slight performance difference between the two, so if you're making an agent that needs to run as quickly as possible your options may be limited. (TODO: measure said difference and state it here.)