SEARCH
NEW RPMS
DIRECTORIES
ABOUT
FAQ
VARIOUS
BLOG
DONATE


YUM REPOSITORY

 
 

MAN page from Mandriva 2009 cuyo-2.0-1mdv2008.1.i586.rpm

CUAL

Section: Games and Demos (6)
Updated: Dec 2006
Index 

NAME

Cual - Cuyo Animation Language

Cual is the main language used to describe the animations in cuyo.Strictly speaking it'sthe stuff between the << >> brackets in the level description files(xxx.ld).

On the other hand this man page aims at being a complete descriptionof how to write levels for cuyo. But it's still under construction.See the file "example.ld" to get an ideaof how the rest of the level description works. There's also a bit ofexample Cual code in "example.ld". And of course, all the existing levelsare examples.

Note that Cual is probably still very buggy. It has almost not been tested.(The existing levels work, but that's all.) So if strange things happen andyou're sure it's not your fault, tell me (cuyoAATTkarimmi.de).

 

HOW IT WORKS

The level description is organized in scopes. There is a global scope andevery level has its own scope, which is a subscope of the global scope.It is common practise to place each level in a separate file, which thenbasically starts by opening its scope and ends by closing it.

A scope is defined by

  name = {contents}
Here name is the name of the new scope and contents containsthe definitions that pertain to that scope. This is a sequence of definitionsof the form

  name = stuff
Here stuff can be {contents} as above, or it can be a singledatum, or it can be a comma-separated list of data. Inside such a list,

  datum * number
can be used as a shorthand for datum, ..., datum, i.e. annumber-fold repetition of datum. A datum can be an identifier,a string (enclosed by '"'), a word, or a number. In place of a number

  <expression>
can be used, where expression is an arbitrary expression made up fromliteral numbers, previously defined numeric data, and the operators+, -, -, *, / and %.

Apart from definitions, a scope can also contain cual definitions(see below). These have to be enclosed in << and >>.

Each blob has its own (main) Cual procedure which does the drawing and theanimation stuff. The procedure only depends on the kind of the blob, thatis, it is the same for blobs of the same kind. However each blob has itsown instance of the variables.

In every game step, the procedure of each of the blobs is called once.(There are 10 game steps per second.) It has to draw the blob eachtime, even if nothing has changed. (However, there's an internal routinein cuyowhich checks if the same is drawn as in the last step and which thensupresses the drawing.)

There may be other procedures associated to a kind of blob, which areexecuted at special events, for example when a falling blob lands.In contrast to the main procedure, these event handlers are not allowed todraw anything. See section "event handlers" for a list of the existing events.

The name of the main procedure of a blob (the one which draws the blob)is the name of the kind of the blob. Normally,that name is the word listed after pics= entry in the .ld file; butif that "word" contains a dot, only the part before the dot makes up the name. (E. g. with pics=redblob.xpm,greenblob.xpm, the names are "redblob" and "greenblob".)

The name of an event handler procedure is the name of the kind, followedby a dot, followed by the event name. (E.g. "redblob.land" for the landingevent of the redblob from above.)

[Explain the default procedures.]

 

LEVEL DATA

String valued data:

name
The name of the level.This appears in the list of levels as well as in the level intro.
description
This is an optional further description of the level in its intro.
author
The name of the level author(s) for credit at the beginning of a level.

Identifier valued data:

bgpic
Background picture (file name). If too small, placed at bottom.Defaults to none.
toppic
Appearance of the top border coming down (file name).Defaults to none.

Number valued data:

numexplode
The size that a group of blobs has to reach in order to explode.This is only the level-wide default. Each kind can override this.Whether the group does explode is also controlled by behaviour.See section VARIABLES AND CONSTANTS for details.
toptime
Time the border takes to come down, in 10th of seconds per pixel. Thedefault value is 50 (i.e. one pixel every five seconds).
topoverlap
Placement of toppic relative to the actual border.More precisely, number of pixels the lower border of the pictureis below the actual border.Defaults to the height of the picture.
topstop
When the border comes down at the end of the level, numberof pixels it should stop before the bottom. Set this to thesame value as topoverlap if you want your toppic to be comletelyvisible at the end.Defaults to 0.
chaingrass
If set to 1, chain reactions are neccessary to kill the grass.Defaults to 0.More precisely, chaingrass only controls the default forbehaviour for grass blobs.See section VARIABLES AND CONSTANTS for details.
mirror
If set to 1, the level appears upside-down.Defaults to 0.
neighbours
Determines in which directions the blobs can connect to each other in orderto form groups. This is only the level-wide default. Each kind can overridethis. See section VARIABLES AND CONSTANTS for values.Defaults to neighbours_rect.
randomgreys
The time between two randomly appearing greys in 10th of seconds.Use -1 for none at all, which is the default.
nogreyprob
The probability that a grey does not appear.See greyprob and colourprob in section KIND DATA for details.The default is 0.
falling_speed, falling_fast_speed
This is the vertical speed of the steered falling blobs.The unit is pixels per decisecond.The defaults are 6 and 32.
aiu_color, aiu_grass, aiu_grey, aiu_two_above, aiu_monochromic_vertical, aiu_height
Parameters for the AI-Player utility function.Default respectively to <10*(number of kinds)>, 20, 10, <aiu_color/2>,<aiu_color>, and 10.

Colour valued data (a colour is an RGB triple of numbers between 0 and 255):

bgcolor
The background colour. Defaults to white.
textcolor
Colour of any text. This includes the beginning-of-level information,message()s, and score. Defaults to a certain shade of dark grey.
topcolor
The colour of the top border comming down(where not determined by toppic).Defaults to a certain shade of light grey.

Other data:

startdist
Distribution of blobs at the beginning of the level.It is a list of strings, the format of whichis described in the section STARTDIST.
pics, greypic, startpic, emptypic
List of kinds. These can be either file names referring to the pictureto be used, or declarations of kinds that have to be defined later on.The different keywords (e.g. pics, emptypic) define different defaults.In fact, only the first three may be real lists,emptypic is limited to exactly one entry.In these lists, it is advisable to use "*" whenever possible.Besides being shorter to write, it also speeds up loading of the level.This is because cuyo does some initializations only once for each entrywith multiplier.
The intentions of these lists are normal blob kinds resp. grey blob kind resp.grass blob kind resp. nothing-blob. However, the only differences betweenpics, greypic and startpic arethe default values for behaviour, colourprob, goalprob,greyprob, versions and distkey (see there). All of thesecan also be set manually. Also, the default drawing code is different.(The default drawing code for startpic does not draw connections.)
kind
Each kind can have its own scope.See KIND DATA below for the entries of that scope.

 

KIND DATA

numexplode, chaingrass, neighbours
Defining these data in the scope of a kindoverrides the level-wide value for the kind.See section LEVEL DATA for a description of these data.
pics
A list of file names of pictures to be used for this kind.The nth entry can later be accessed in cual with pos=n-1.
colourprob
The probability that this kind appears as one of the two steered falling blobs.More precisely, this is a nonnegative integer weight.For determining the actual probability,the value is divided by the sum of the colourprobs of all kinds.This sum must be positive.The default is 1 for kinds declared with pics= and 0 for all other kinds.The probability is also used for "+" in startdist.For more details see section STARTDIST.
goalprob
This affects the semantics of "*" in startdistin the same way, as colourprob does for "+".The default is 1 for kinds declared with startpic=and 0 for all other kinds.
greyprob
The probability that this kind appears as a grey blob.This is similar to colourprob, but there is a difference:For greyprob, nogreyprob is included in the sum,so that it might happen, that no blob appears at all.There is a notable difference between a positive nogreyproband a positive greyprob in kind nothing,when several lines of grey blobs appear:In the latter case, empty blobs appear in the wall of greys, making holes.In the former case, the wall is made less high. Usually this is preferable.The default is 1 for kinds declared with greypic=and 0 for all other kinds.The value also affects the semantics of "-" in startdist.In this case, nogreyprob is not included in the sum.
versions
At the creation of a blob, its version variable is initialized.Usually, it is chosen at random from 0 to versions-1,but startdist provides the possibility to specify it exactly.See section STARTDIST for details.The default is 52 for kinds declared with startpicand 1 for all other kinds.
distkey
An alphanumerical key, which is used in startdist to identifythis kind of blob.The default is "A" for kinds declared with startpicand undefined for all other kinds.See section STARTDIST for details.

 

CUAL DEFINITIONS

Inside << >>, variable and procedure definitions are expected.
procname = code ;
Defines a "procedure". The next section describes how code looks like.
Example:
redblob = {

  schema16; 0*;

  1; A,B,C; *;
};
var varname1 [= def1 [: reapply]], varname2 [= def2 [: reapply]], ... ;
Defines variables with default values.If no default is specified, zero is used.See section VARIABLES AND CONSTANTS about themeaning of the default value and the optional suffix : reapply.
default varname1 = def1 [: reapply], varname2 = def2 [: reapply], ... ;
Changes the default for already defined variables.Again, the suffix : reapply is optional.This is useful to give to a single kind a different default for a variablethan to the other kinds.Also, the default of a system variable can be changed this way.
 

CODE

A code fragment can be one of the following:
{ code; code; ...}
Executes one command after the other.
code, code, ...
This is useful for simple animations.Executes exactly one of the commands:In the n-th call, the n-th command isexecuted. After the last command, the first one isexecuted again. However, if one of thecommands is "busy" (see section aboutbusieness), this one will be executed untilit stops being busy, and only after that,the next command will be executed.
procname
Executes the procedure procname, which has to be alreadydefined. The result is the same as if the code from procnamewould have been inserted in that place.
&procname
Executes the procedure procname; however, every instanceof such a procname is the same. This concerns busieness and thestate of an animation sequence. (See sections BUSIENESS and AMPERSAND-CALL.)
busy
Does nothing except being busy. (See section BUSIENESS.)
varname = expr
Sets the variable. See section "VARIABLES AND CONSTANTS" for details.
The same with +=, -=, *=, /=, %=, .+=, .-=.
Does what you would expect.[ varname = expr ] codeSets the variable varname to expr, executes codeand then resets the variable to the old value.
number
A shortcut for "file = number".
letter
A shortcut for "pos = number", where different letters mean different numbers:A: 0, B: 1, ..., Z: 25, a: 26, ..., z: 51
*
Draw the icon specified by the variableskind, file and pos.May also draw only a partof the icon, if specified by the variablequ(see section about variables and constants).
*@(position)
Like *, but draws the icon at some other position.This drawing is performed after all drawing by *.(See section about variables and constants for more details about @.)
@(position)*
Like *, but draws the icon at some other position.This drawing is performed before all drawing by *.(See section about variables and constants for more details about @.)
if expr if-arrow if-code ;

if expr if-arrow if-code else [else-arrow] else-code ;
The arrows can be either "->" or "=>".If you use "->" arrows, it does exactly whatyou would expect.
If the if-arrow is "=>",then once the expression getstrue, the if-codewill be executed every subsequenttime (without testing the condition),as long as it is "busy". For moredetails see section BUSIENESS.
If the else-arrow is "=>",then once the expression gets false, theelse-code will be executed every subsequenttime as long as it is busy.
The else-arrow may only be omitted, if the if-arrow is "->".Then the else-arrow also is "->".(But this might change in the future.)
switch {

  expr1 arrow1 code1 ;
  expr2 arrow2 code2 ;
  ...
}
The arrows can be either "->" or "=>".Does the same as:

  if expr1 arrow1 code1

  else if expr2 arrow2 code2

  ...
The last expr may be omitted to get anelse part without further condition.
bonus(expr)
The player gets expr bonus points.
message(String)
The string is displayed (blinking) on the screen.To be used together with bonus(...).
Example:
bonus(50);
message("You get 50 bonus points");
explode
Makes the blob explode. For the next 8 steps or so, theblob is still what it was before, but the explosion isdrawn over the graphics. After that, it's changed toa nothing-blob.
sound(Filename)
Plays the given sound file.

You can also omit the code completely.Then, of course, it does not do anything.This can be useful as part of ,-sequences.

There's a shortcut for drawing: You may omit the ";" betweena number, a letter and the "*". 

EXPRESSIONS

The only data type in cual is int. Bools are represented by 0 and 1,like in C. (And any number other than 0 is interpreted as true, ifa boolean is expected.)

Of course, variables, constants and numbers are expressions, andyou can use parentheses. There are the following operators:

The following operators exist (listed here in order of increasing precedence):
||Boolean or
&&Boolean and
==, !=, <, >, <=, >=Comparison
==..A special comparison
!Boolean not
+, -Add, substract
:Special operator
*, /, %Multiply, divide, modulo
&, |, .+, .-Bitwise and, bitwise or, setting of bits (same as bitwise or), unsetting of bits
-Unary minus
.Testing of bits (a.b is the same as a&b != 0)

/ and % work mathematically correct and do not make funny changeswhen the sign of the denumerator changes.More specifically a/bis the largest integer n such that bn<=a,and a%b is such,that (a/b)b+a%b = b. Examples:
13/5=2 # 13%5=3
-13/5=-3 # -13%5=2
13/-5=-3 # 13/-5=-2
-13/-5=2 # -13%-5=-3

The following are the special operators:

expr1 == expr2 .. expr3
Is true, if expr1 lies between expr2 and expr3.You may also omit one expr2 and expr3.(Then, it does the same as <= resp. >=.)The precedence imnplies that x==y==2..3 is the same as x==(y==2..3)and is neither (x==y)==2..3 nor x==(y==2)..3.Note that this operator mightchange in the future. (I plan to make something like"expr in set" in pascal.)
expr1 : expr2
Is true (that is, 1) with probabilityexpr1/expr2
neighbour_pattern
neighbour_pattern is a sequence of sixor eight characters 0, 1 and ?.It is true if the sequence fits to theneighbour sequence of the blob. The neighbour sequence is a string of "0"s and "1"swith a "1" for each neighbour of the same kind,starting above and going clockwise. This way,you get a string of "0"s and "1"s (six or eight, dependingon wether this level is in hex mode).
Example: 1???0??? is true iff theblob above this blob is of thesame kind and the blob below it is ofdifferent kind.
For an empty blob the semantics is slightly different:If in some direction there is no neighbour, because the field ends there,the entry in the neighbour sequence is 1 nevertheless.So for an empty blob 1???0??? is true, iff theblob above this blob does not exist or is empty as well,and the blob below this blob exists and is not empty.
If some blob changes its kind during a step, the expression will stilltest the neighbours as they were at the beginning of the step.(See the section about variables and constants for details.)

The following functions exist:

rnd(expr)
Returns a random value between 0 and expr-1
gcd(expr1, expr2)
Returns the greatest common divisor of expr1 and expr2
 

VARIABLES AND CONSTANTS

The following kinds of variables and constants exist:
-
User defined variables (see section "Definitions"). At the start of thelevel (or at the creation of the blob) the value is the default value youprovided.If you supplied the default with : reapply, the value of thevariable is also set to the default, whenever the kind changes.
-
System variables. These variables are always defined and have specialmeanings, e.g. file and pos. Some of them are read-only.
-
User defined constants. These are defined in the main .ld part, not incual (not inside << >>).
-
System constants. Some of them depend on properties of the level, some arereally constant.

Of each variable, there's one instance in each blob. Normally, you accessthe instance in your own blob, but with the following syntax, you can accessvariables of other blops:
  varname@@(x, y; side)
  varname@@(x; side)
  varname@@(; side)
  varname@(dx, dy; side)
  varname@(dx; side)
  varname@()
If x and y are given,these are absolute coordinates in the grid of blops,that is the variable is taken from the blob with loc_x=x and loc_y=y(see under system variables).
If only x is given, it specifies one of the two blobs that arecurrently falling. If there is only one such blob left, because the otherone got stuck on some tower, the remaining blob's coordinate is 0.Otherwise one of the two has coordinate 0, the other 1.The value x is interpreted modulo 2.
In the @ variants, the coordinates are relative to the current blob.
The variant @@(; side) refers to the semiglobal blob,the variant @() to the global blob (See section "The Global Blob").
The extra part ; side is optional and specifies the sideof the game. This is only meaningful in two-player mode.side = < specifies the left player,side = > the right player,side = = the player to which the current blob pertains,and side = ! the other player.
@() and @@() can also be given as @ respectively @@.

This can be done for both, reading andwriting variables. It also works for system variables (but not for constants).

In hex mode levels, for odd dx, dy should be a "half integer", thatis a number ending in ".5". This is the only place in Cual wherenon-integers appear.Especially, ".5" is not allowed in composite expressions.Therefore, also integer dy is always allowed.If a half-integer is expected and an integer is given, it is assumed to berounded to above, that is 5 then represents 4.5 and -5 represents -5.5.

Caution: With mirror=1 the absolute and the relative coordinates usedifferent coordinate systems. Handle with extreme care.

Accessing foreign variables is not as easy as it might look at first glance;it might easily introduce a dependence of the internal order of executionof the blob codes. For this reason,

-
reading variables with @ or @@always returns the value of the variable it hadat the beginning of the current step, that is, before any of theblob codes has been executed.
-
when writing variables with @ or @@,the write operation will only be executedat the end of the current step. (The write operations are stored ina kind of queue.)

This is also true if a blob accesses its own variables with @(0,0).

The operators +=, -=, etc.are also performed in the future if the lefthand side is an @-variable.(To be more precice, the right hand side iscalculated instantanousely.)

For illustration, look at the following six statements:

1) X += 1
2) X@(0, 0) += 1
3) X = X + 1
4) X = X@(0, 0) + 1
5) X@(0, 0) = X + 1
6) X@(0, 0) = X@(0, 0) + 1

Only 1) and 3) do the same; they simply increment X by 1.
Statement 4) sets X to one more than it was at the beginning of the step.
Statements 2), 5) and 6) cause the value of Xto be changed in the future (after thecurrent step): X is set to one morethan:
2) the value of X just before the change (that is, X is incrementedin the future),
5) the current value of X,
6) the value of X at the beginning of the step.

 

Some more details

-
Whenever you try to access a variable at a location which doesn't exist,you will get the default value.If default values depend on the kind,the default pertaining to the blob executing the code is used.This may change in the future.
-
Changing a variable which doesn't exist does nothing (and does notresult in an error).

 

The system variables

file
Specifies the file number from which to take the icon thatis drawn by "*". This variable is reset to 0 before the drawingprocedure is executed.
pos
Specifies the position in the file of the icon that is drawnby "*". This variable is reset to 0 before the drawingprocedure is executed.
kind
The kind of the blob. There are constants for the possiblevalues of this variable.If you change the kind, you should be aware of three things:
Expressions like "001???01" test the neighbour pattern atthe beginning of the current step. So the change ofthe variable kind will not be reflected.
In the current step, the program to draw the blob has alreadybeen invoked (in fact, the program which changed this variable);so in this step, the blob will still look like one of the oldkind. However, if things are drawn after the kind has been changed,icons from the new kind are taken.
Defaults of the new kind that are declares with : reapply are applied.This happens at the same time that kind changed.
version
Is assigned a hopefully distinctive value at the blob's creation.See versions in section KIND DATA for details.
qu
Tells "*" which part of the icon to draw. It's possible todraw the whole icon, or only one of its quarters. If a quarteris drawn, you may specify independently which of the quarters totake and atwhich position to draw it. Use the constants (see below).This variable is reset to "draw all" before the drawingprocedure is executed.
out1, out2
Set these Variables for debug output. The values will be printedon top of the blob. There variable are reset to "output nothing"before the drawing procedure is executed. (In fact, "output nothing"is one special big value.)
inhibit
Set this variable to a sum of the constants DIR_...; this willinhibit that this blob connects into the given directions. Thisis not for the graphics but for the calculation of theconnected components and the explosions.
behaviour
This is a bit field.Refer to "The Constants" below for the meaningful of its bits.The default is calculate_size+explodes_on_size for normal blobs,explodes_on_explosion+explodes_on_chainreaction for grey blobs,0 for the empty blob andgoalblob+explodes_on_explosion+explodes_on_chainreaction orgoalblob+explodes_on_chainreaction(depending on whether chaingrass is set) for grass blobs.

 

The system read-only variables

turn
Is 1 resp. 2 if the blob is falling and just being turnedby the user and 0 otherwise.(1 in the first turning step, 2 in the second one.)Be aware that if the user presses the turn key fast severaltimes, some of these steps may be omitted. (Use the turn eventif you want to be sure that a program block is executed oncefor every turn.)
connect
Contains internal data. Will be removed. Probably.
size
The size of the component of the blob. (That is, how many blobsare connected.)
loc_x, loc_y
The absolute coordinates of the blob. (0,0) = top left corner
loc_xx, loc_yy
The absolute coordinates of the blob in pixels.This is not always the same as loc_x*32 and loc_y*32,particularly for the steered falling blobs.
loc_p
The player of the blob (1 or 2)
falling
true, if the blob is falling. (Falling in the sense of steeredby the player. Grey blobs are not falling in that sense.)
falling_fast
true, if the blob is falling fast, that is, the user pressedthe down key.
players
The number of players.
exploding
When the blob is exploding, the position in theexplosion animation (1 - 8); 0 else.
 

The Constants:

Constants for behaviour:
goalblob
Set goalblob if this blob should act like grass: You will haveto get rid of it to win the level and making this blob explode will givemore points.
calculate_size
When this bit is set, size will be regularly updated to the sumof weight in the connected component.
explodes_on_size
When this bit is set, a connected component explodes, when it has size>=numexplode.
explodes_on_explosion, explodes_on_chainreaction
When these bits are set, the blob explodes whenever an explosion, that wastriggered by explodes_on_size, happens in its neighbourhood.explodes_on_chainreaction refers to those triggering explosions,that are the second or later part of a chain reaction.explodes_on_explosion refers to the other ones.

Constants for kind:

<name of kind of blob>
For each kind of blob, there's one constant withthe name of that kind. Use it to check if ablob is of that kind using "kind@(x,y) == aKind"or to change to that kind using "kind = aKind".When kind is changed, behaviour is reset to the default for the new kind.
Sometimes it is neccessary to perform arithmetic on kinds,for example when several have been declared using the "*" multiplier.The values of the constants are succesive in the order, in which the kindshave been declared. When a name is used several times, the first use definesthe value. Example:
  startpic = apple, orange
  pics = orange, pear, apple * 3, banana
  greypic = pineapple
This initializes 2 kinds with the defaults for startpic,6 kinds with the defaults for pics, and 1 kind with the defaults for greypic.The value of the constant orange is 1 more than that of apple,pear is 2 more than orange, banana is 4 more thanpear and pineapple is 1 more than banana.We do not specify what these values actually are.
This constant also exists for the empty kind, if one has been declaredusing emptypic. In this case the value's relation to the other valuesis not specified at all.
global, semiglobal
Denote the kind of the global, respectively semiglobal, blob.
nothing
Is the same as the constant for the empty kind.Is provided, because sometimes, you don't havean empty kind, but you still need to test if ablob is empty.
outside
The value of kind if the coordinates are outsideof the game board.

Constants for neighbours:

neighbours_rect
A blob connects up, down, left, and right. This is the default.
neighbours_diagonal
A blob connects diagonally.
neighbours_hex6
When used in the level-wide neighbours, this sets hex mode.A blob connects up, down, left with a slight upwards shift,left with a slight downwards shift, right with a slight upwards shift,and right with a slight downwards shift.
neighbours_hex4
When used in the level-wide neighbours, this sets hex mode.A blob connects left with a slight upwards shift,left with a slight downwards shift, right with a slight upwards shift,and right with a slight downwards shift.
neighbours_knight
A blob connects in knight moves (Two forward and then one sideways.Forward is one of up, down, left or right.Sideways is perpendicular to forward. This makes a total of eight directions.).
neighbours_eight
Combines neighbours_rect with neighbours_diagonal.
neighbours_3D
A more obscure mode created especially for 3D.ld.When used in the level-wide neighbours, this sets hex mode.A blob connects up, down, two (but not one) to the left, and two to the right.In even columns it also connects right with a slight upwards shift.In odd columns it also connects left with a slight downwards shift.
neighbours_none
A blob does not connect at all.

Constants for qu:

Q_ALL
Value for qu, which means "draw the completepicture".
Q_TL, Q_TR, Q_BL, Q_BR
Values for qu. "TL" means draw top-left quarter,etc. (See the "*" command in the Code section.)
Q_SRC_DST
SRC and DST may be TL, TR, BL, BR. Take quarterSRC and draw it at position DST

Miscellanious constants:

DIR_XX
To be used with the variable inhibit to prevent the blobconnecting in the given directions. XX can beU, D, L, R (horizontal and vertical); UL, UR, DL, DR (diagonal);UUL, UUR, DDL, DDR, LLU, LLD, RRU, RRD (knight); F, B (3d)
 

BUSIENESS

(No, not Business ;-)
Busieness is a concept to make it easier to implement simple animatedsequences which are triggered by certain events. Each code fragment has aninternal state which tells if it is busy.
-
Normal statements like assignments are never busy.
-
A chain of commands separated by "," is busy as long as notall of the commands have been executed.
-
code1 ; code2 is busy as long as at least one ofcode1 and code2 are busy.

Here's an example of how to use busieness for an animation which appearsat random intervals:

switch {

  1/100 => {B*, C*, D*, E*};

  -> A*;
};

This code fragment normally draws the icon at position A (0). But in eachstep, with a probability of 1/100, an animation sequence consiting of iconsB, C, D and E is started. With a normal arrow ("->") after the "1/100",after the step in which B has been drawn, the probability would be 99/100that A is drawn again. But with the double arrow, the switch statementwon't switch back to A until the animation has terminated.

(Btw: It doesn't matter if there's a "->" or a "=>" before the "A*";A* isn't busy anyway.) 

THE GLOBAL BLOB

Apart from the normal blobs which you can see on screen, there's one globalblob (for the whole game, not one for each player), which, well, isn't reallya blob, but behaves a bit like it. It hasits own set of variables, and it can have a program which is run once everystep. To define such a global program, use "global=code". However, the globalvariables do exist even if you don't define global code. See section"Variables" on how to access them.Note that the global blob is always executed before any of the normal blobs.
There are also semiglobal blobs. There is one for each player.These are programmed with "semiglobal=code". 

EVENT HANDLERS

The following events exist:
init
Is called only once, when the blob gets into live, just before the firsttime its main drawing routine is called.
turn
Is called for falling blobs each time the user pressesthe turn key.
land
Is called when the steered blob lands.
changeside
Is called when a blob moves from one player to the other, just after theblob has arrived at the new player.
connect
Is called when the connection of blobs is recalculated.
row_up1, row_up2
Is called when player 1 resp. 2 gets a row from the other side.
row_down1, row_down2
Is called when player 1 resp. 2 gives a row to the other side.
keyleft, keyright, keyturn, keyfall
Is called when the player presses the left, right, turn or fall key.Is only called for the steered falling blobs and the semiglobal blob, though.
 

THE LIFE OF A BLOB

Normal blobs come into life at the beginning of the game, or they fallinto life: either as colored blobs, steered by the user, or as grey blobs.When a blob moves (by gravitiy or when rows go from one player to another),it takes its variables with it.When a blob explodes, it does not stop existing. Rather, it transforms intoan empty blob. That's important for the variables: The empty blob stillhas all the variables set to the values they had before; only its kindis different. Empty blobs are everywhere where there's no other blob.(However, the falling blobs steered by the user is in some sense "above"everything else; there are empty blobs beneath them.)

The life of empty blobs is different from the one of normal blobs. Emptyblobs are not affected by gravity, and they often start or stop existing.For example, when a single grey blob is falling down, the empty blob belowit stops existing when the grey blob arrives and a new empty blob startsexisting when the grey blob moves on.There is only one situation in which empty blobs move: Whena row moves from one player to the other, and everything moves up resp. down,the empty blobs move, too. 

STARTDIST

The format of the startdist field is rather complicated.On the plus side, this means that many things can be done with little effort.We first describe the single-character format, which,at the time of this writing, has sufficed for all needs.After that, we describe the general format as an extension.

Every line of the startdist describes one row of blobsin the level's initial state.The lines are aligned to the bottom and the topmost lines come first(normal reading order).Each line must contain exactly 10 or exactly 20 characters.In a line of length 20 the first 10 characters describe the left player,the second 10 characters describe the right player. A line of length 10describes both players.Hence, each character described one blob.The semantics are:

.
An empty blop.
+, -, *
A blop chosen at random according to colourprob,respectively greyprob, respectively goalprob.The value of nogreyprob has no influence.
0..9, A..Z, a..z
These characters denote a specific kind.If the key matches the distkey of some kinds,the first of these is chosen.More generally, these characters are ordered such that "9" comes before"A" and "Z" comes before "a".In this order, the maximal distkey, which does not come after thecharacter, specifies the blob's kind.The difference between the character and the distkey then specifies theblob's version.
Example 1:In the special case, where the character exactly matches a distkey,version is set to 0.
Example 2:Suppose kind apple has distkey = "A", kind orange hasdistkey = "O" and no further distkeys exist.Then the character "C" denotes an apple with version=2,the character "N" denotes an apple with version=13,the character "O" denotes an orange with version=0,the character "S" denotes an orange with version=4,the character "a" denotes an orange with version=12,and the character "8" does not denote anything (and hence is illegal).

In this way, startdist can reference 62 kind/version combinationsdirectly (and more at random).Because this might at some time not be enough, the multichar extensionhas been introduced.In this case, each blob is described by more than one character.However, the number of characters per blob must be the same for all keys.Hence, the lengths of startdist lines then must be this numbermultiplied by 10 or by 20.Every multicharacter combination starting with ".", "+", "-",or "*" is treated as the corresponding character in single-characterformat. All other character combinations are treated as numbers in base 62representation. Here, "A" to "Z" are digits with decimal value 10to 35, and "a" to "z" are digits with decimal value 36 to 61.Leading spaces are allowed instead of zeroes (however, the all-space stringis forbidden).The maximal distkey which (as a number) is not larger than the numbergiven in startdist, specifies the blob's kind.The difference between the startdist number and the distkeythen specifies the blob's version.In the case of multichar distkeys, the default for distkeysof kinds declared by startpic= is 10 in decimal.

For blops whose kinds are chosen at random (i.e. characters "+","-", "*" in single-character startdists),cuyo tries to make these as different as possible.That means, by a certain heuristic, cuyo minimizes the number of neighbouringblobs of the same kind. "Neighbouring", of course, refers to theneighbours entry. inhibit and the calculate_size bit ofbehaviour have no effect (these are mutable during the lifetime ofblobs, while at the time of startdist processing, no blob's lifetimehas started yet). So the only way to influence the unneighbouring(if you really wish to do so), is by setting neighbours appropriately.(Of course, this possibility is even more limited, when you intend toset the calculate_size bit during the blob's lifetime.) 

WHERE DO I PUT THE CUAL CODE?

Cual procedures and variables can be defined in different sections ofthe .ld files:
- Outside of everything; that code is accessible from every level comingafter that definition.
- In the section of a level.
- In the section of a kind.
This basically does what you expect. However, there's one thing you might want to know: Even if you define a variable inside akind, every blob in that level will have that variable. The only effectof defining the variable in the section of a kind is that this kind is theonly one which can access it. 

AMPERSAND-CALL

To explain a bit what calling a procecure with an & means, here two examples:

Example 1:
<<
myblob = {

  ...

  switch {

    myvar -> { 0A*; 1; A,B,C,D; *; 2A*};

          -> { 0B*; 1; A,B,C,D; *; 2B*};

  };
};
>>

Example 2:
<<
anim = {1; A,B,C,D; *};

myblob = {

  ...

  switch {

    myvar -> { 0A*; &anim; 2A*};

          -> { 0B*; &anim; 2B*};

  };
};
>>

The difference between these examples is what happens when myvar changes.In example 1, the animation "A, B, C, D" will restart at the beginning(because the two animations are different ones); in example 2, the"same" animation is usedin both cases, so the animation will simply continue.(Removing the ampersands from example 2 will turn the behaviour to theone of example 1.) 

SEE ALSO

cuyo(6) 

BUGS

Probably a lot. The following are just a few known ones:

There are several problems with busieness and that stuff.There are several situations in which Cual doesn't behave in theway I would like, and in other situations I don't know how Cual shouldbehave.


 

Index

NAME
HOW IT WORKS
LEVEL DATA
KIND DATA
CUAL DEFINITIONS
CODE
EXPRESSIONS
VARIABLES AND CONSTANTS
Some more details
The system variables
The system read-only variables
The Constants:
BUSIENESS
THE GLOBAL BLOB
EVENT HANDLERS
THE LIFE OF A BLOB
STARTDIST
WHERE DO I PUT THE CUAL CODE?
AMPERSAND-CALL
SEE ALSO
BUGS

This document was created byman2html,using the manual pages.