Provided by: cuyo-data_2.1.0-1build1_all bug

NAME

       Cual - Cuyo Animation Language

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

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

       Note  that  Cual is probably still very buggy.  So if strange things happen and you're sure it's not your
       fault, tell me (cuyo@karimmi.de).

HOW IT WORKS

       The level description is organized in sections.  There is a global section and every level  has  its  own
       section,  which  is  a  subsection of the global section.  It is common practice to place each level in a
       separate file, which then basically starts by opening its section and ends by closing it.

       A section is defined by name = {contents}.  name is the name of the new section and contents contains the
       definitions  that  pertain  to that section.  This is a sequence of definitions of the form name = stuff.
       Here stuff can be {contents} as above, or it can be a single datum, 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. a
       number-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 from literal numbers, previously defined numeric data, and the operators +, -, *, / and %.

       Definitions can also depend on versions.  See section VERSIONING below.

       Apart from definitions, a section 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 the animation stuff.  The
       procedure only depends on the kind of the blob, that is, it is the same  for  blobs  of  the  same  kind.
       However each blob has its own instance of the variables.

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

       There may be other procedures associated to a kind of blob, which are executed  at  special  events,  for
       example  when  a  falling  blob  lands.   In contrast to the main procedure, these event handlers are not
       allowed to draw 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; but if 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, followed by a dot, followed by the event
       name.  (E.g. "redblob.land" for the landing event 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.

       explosionpic
              Appearance of the explosions (file name).  Has a default.

   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 number of game steps.  Each  game  step  lasts  80ms.   The
              default value is 50 (i.e. one pixel every four seconds).

       topoverlap
              Placement  of  toppic  relative  to the actual border.  More precisely, number of pixels the lower
              border of the picture is below the actual border.  Defaults to the height of the picture.

       topstop
              When the border comes down at the end of the level, number of pixels it  should  stop  before  the
              bottom.   Set this to the same value as topoverlap if you want your toppic to be comletely visible
              at the end.  Defaults to 0.

       chaingrass
              Must be 0 or 1.  If set to 1, chain reactions are necessary to kill the  grass.   Defaults  to  0.
              More  precisely,  chaingrass only controls the default for behaviour for grass blobs.  See section
              VARIABLES AND CONSTANTS for details.

       mirror Must be 0 or 1.  If set to 1, the level appears upside-down.  Defaults to 0.

       randomfallpos
              Must be 0 or 1.  If set to 1, the initial fall position is randomized horizontally.   Defaults  to
              0.

       neighbours
              Determines  in which directions the blobs can connect to each other in order to form groups.  This
              is only the level-wide default.  Each kind can override this.  See section VARIABLES AND CONSTANTS
              for values.  Defaults to neighbours_rect.

       hexflip
              In  hex  mode,  determines  whether  the  even or the odd columns are shifted upwards.  By default
              (hexflip = 0), the odd columns are shifted. 1 means: shift even columns  of  player  1;  2  means:
              shift even columns of player 2; 3 means: shift even columns of both players.

       randomgreys
              The  expected  time between two randomly appearing greys in game steps (80ms).  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.

       aiu_color, aiu_grass, aiu_grey, aiu_two_above, aiu_monochromic_vertical, aiu_height
              Parameters  for the AI player's utility function.  Default respectively to <10*(number of kinds)>,
              20, 10, <aiu_color/2>, <aiu_color>, and 10.  See section THE AI UTILITY FUNCTION for details.

   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 which
              is described in the section STARTDIST.

       pics, greypic, startpic, emptypic
              Lists  of  kinds.   These  can  be  either  file  names  referring  to  the picture to 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 and cuts down memory usage.
              This is because cuyo does some initializations only once for each entry with 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 between pics, greypic and startpic are the
              default values for behaviour, colourprob, goalprob, greyprob, versions and  distkey  (see  there).
              All  of  these  can also be overridden individually.  Also, the default drawing code is different.
              (The default drawing code for startpic does not draw connections.)

       kind   Each kind can have its own section.  See KIND DATA below for the entries of that section.

KIND DATA

       numexplode, neighbours
              Defining these data in the section of a kind overrides 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 file=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 startdist in 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 nogreyprob and 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 1.

       distkey
              An alphanumerical key, which is used in startdist to identify this kind of blob.  The default is A
              for  kinds  declared  with  startpic and 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 the meaning 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 variable than  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 is executed. After the last command, the first one is executed  again.   However,  if
              one  of  the  commands is "busy" (see section BUSIENESS), this one will be executed until it stops
              being busy, and only after that, the next command will be executed.

       procname
              Executes the procedure procname, which has to be already defined.  The result is the  same  as  if
              the code from procname would have been inserted in that place.

       &procname
              Executes  the  procedure  procname;  however, every instance of such a procname is the same.  This
              concerns busieness and the state 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 ] code
              Sets the variable varname to expr, executes code and 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 variables kind, file and pos.  May also draw only  a  part  of  the
              icon, if specified by the variable qu (see section VARIABLES AND CONSTANTS).

       *@(position)
              Like *, but draws the icon at some other position.  This drawing is performed after all drawing by
              *.  If *@ is used from several blobs, the further order  of  drawing  is  not  specified.   It  is
              guaranteed,  however,  that  at  any  given  time  this order is the same for all positions.  (See
              section 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  *.   If  @*  is used from several blobs, the further order of drawing is not specified.  It is
              guaranteed, however, that at any given time this order  is  the  same  for  all  positions.   (See
              section 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 what you would
              expect.  If the if-arrow  is "=>", then once  the  expression  gets  true,  the  if-code  will  be
              executed every subsequent time (without testing the condition), as long as it is "busy".  For more
              details see section BUSIENESS.  If the else-arrow is "=>", then once the  expression  gets  false,
              the  else-code  will  be executed every subsequent time 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.  This is equivalent to setting it to true.

       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, the blob is still what it was before, but the
              explosion is drawn over the graphics.  After that, it's changed to a nothing-blob.

       lose   The players immediately lose the level.

       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 ";" between a 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, if a boolean is expected.)

       Of course, variables, constants and numbers are expressions, and you can use parentheses.  There are  the
       following operators (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 changes when the sign of the numerator changes.
       More specifically, if b is positive, then a/b is the largest  integer  n  such  that  n*b<=a.   If  b  is
       negative, then a/b is the largest integer n such that n*b>=a.  In both cases a%b is such that (a/b)*b+a%b
       = a.  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 of expr2 and expr3.  (Then,
              it  does  the  same  as  <=  resp.  >=.)   The  precedence  implies 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  might  change
              in the future. (I plan to make something like "expr in set" in Pascal.)

       expr1 : expr2
              Is true (that is, 1) with probability expr1/expr2

       neighbour_pattern
              neighbour_pattern is a sequence of six or eight characters 0, 1 and ?.  It is true if the sequence
              fits to the neighbour sequence of the blob.  The neighbour sequence is a string of "0"s  and  "1"s
              with 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, depending on wether this level is in hex mode).

              Example: 1???0??? is true iff the blob above this blob is of the same kind and the blob  below  it
              is of different 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 the blob 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 still test the neighbours as they
              were at the beginning of the step.  (See the section 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 CUAL DEFINITIONS).  At the start of the level (or at the creation
          of the blob) the value is the default value you provided.  If you supplied the default with : reapply,
          whenever  a blob's kind changes, the value of the variable is also set to the default of the new kind.
          There is a subtlety: This only happens if the new value of kind is in fact different from the old one.

       —  System variables.  These variables are always defined and have special meanings, e.g.  file  and  pos.
          Some of them are read-only.

       —  User defined constants.  These are defined in the main .ld part, not in cual (not inside << >>).

       —  System constants.  Some of them depend on properties of the level, some are really constant.

       Of each variable, there's one instance in each blob.  Normally, you access the instance in your own blob,
       but with the following syntax, you can access variables 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  The system variables).  If only x is given, it
       specifies one of the two blobs that are currently falling.  If there is only one such blob left,  because
       the  other  one  got stuck on some tower, the remaining blob's coordinate is 0.  Otherwise one of the two
       has coordinate 0, the other 1.

       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 side of 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 and writing variables.  It also works for system  variables  (but  not
       for constants).

       In  hex mode levels, for odd dx, dy should be a "half integer", that is a number ending in ".5".  This is
       the only place in Cual  where  non-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 be rounded to above, that is 5 then represents 4.5 and -5 represents -5.5.

       Caution: With mirror=1 the absolute and  the  relative  coordinates  use  different  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 execution of the blob codes.  For this reason,

       —  reading variables with @ or @@ always returns the value of the variable it had at the beginning of the
          current step, that is, before any of the blob codes has been executed.

       —  when  writing  variables  with  @  or  @@, the write operation will only be executed at the end of the
          current step.  (The write operations are stored in a 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 left hand side is an @-variable.  (To
       be more precice, the right hand side is calculated 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 X to be  changed  in  the  future
       (after the current step): X is set to one more than:

       2)     the value of X just before the change (that is, X is incremented in 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 not result in an error).

       [Add explanation of time slices; roughly:
          @-access  of variables in reality don't access the value at the beginning/end of the game step, but of
          the time slice.  The call of the main procedure of all blobs happens in the same time slice, but  each
          other kind of event has its own time slice.]

   The system variables
       file   Specifies  the  file  number  from  which to take the icon that is drawn by "*".  This variable is
              reset to 0 before the drawing procedure is executed.

       pos    Specifies the position in the file of the icon that is drawn by "*".  This variable is reset to  0
              before the drawing procedure is executed.

       kind   The  kind  of  the  blob.   There  are constants for the possible values of this variable.  If you
              change the kind, you should be aware of three things:

              —  Expressions like "001???01" test the neighbour pattern at the beginning of  the  current  step.
                 So the change of the variable kind will not be reflected.

              —  In  the  current  step, the program to draw the blob has already been invoked (it might even be
                 the program which changed this variable); so in this step, the blob will still look like one of
                 the old kind.  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 declared with : reapply are applied.   This  happens  at  the
                 same time that kind changed, but only if the new kind is different from the old one.

       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 to draw the whole icon, or  only  one  of
              its  quarters.  If a quarter is drawn, you may specify independently which of the quarters to take
              and at which position to draw it.  Use the constants (see below).  This variable is reset to "draw
              all" before the drawing procedure is executed.

       out1, out2
              Set  these  Variables  for  debug  output.   The values will be printed on top of the blob.  These
              variable are reset to "output nothing" before  the  drawing  procedure  is  executed.   (In  fact,
              "output nothing" is one special big value.)

       weight When  calculate_size  is  set in behaviour, size will be regularly updated to the sum of weight in
              the connected component.  The default is 1.

       inhibit
              Set this variable to a sum of the constants DIR_...; this will inhibit  that  this  blob  connects
              into  the given directions.  This is not for the graphics but for the calculation of the connected
              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,       floats        for        the        empty        blob        and
              goalblob+explodes_on_explosion+explodes_on_chainreaction   or   goalblob+explodes_on_chainreaction
              (depending on whether chaingrass is set) for grass blobs.

       falling_speed, falling_fast_speed
              These variables are only used in the semiglobal blobs.  They define  the  vertical  speed  of  the
              steered falling blobs.  The unit is pixels per game step.  The defaults are 6 and 32.

   The system read-only variables
       time   The number of time steps since the level was started.

       turn   Is  1 resp. 2 if the blob is falling and just being turned by 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
              several  times,  some  of  these steps may be omitted.  (Use the turn event if you want to be sure
              that a program block is executed once for every turn.)

       connect
              Contains internal data.  Will be removed.  Probably.

       size   The size of the component of the blob.  (That is, how many blobs are connected.)

       basekind
              The value of the constant generated for the name of the kind of the blop.  Example:

                pics = orange, pear, apple * 3, banana, apple

              Here, all four kinds apple have the same value for basekind, and this value is apple.

       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  or it is a preview of a falling blob.  (Falling in the sense of
              steered by the player.  Grey blobs are not falling in that sense.)

       falling_fast
              True, if the blob is falling fast, that is, the user pressed the down key.

       informational
              True, if the blob is one of the info-blobs at the side of the  game  area.   In  this  sense,  the
              previews of the falling blobs also count as info-blobs.

       players
              The number of players.

       exploding
              When the blob is exploding, the position in the explosion animation (1 to 8); 0 else.

              Currently,  there  is  one  exception: if the explosion has been triggered by the explode command,
              then exploding will have value 1 only after the current game step [more precisely: time slice; fix
              that].   Reason:  when  reading exploding@(x,y), we maybe don't know yet that the other blob calls
              explode.

   The Constants:
       Constants for behaviour:

       goalblob
              Set goalblob if this blob should act like grass: You will have to get rid of it to win  the  level
              and making this blob explode will give more points.

       calculate_size
              When  this  bit  is  set,  size  will  be  regularly updated to the sum of 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  was  triggered  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.

       floats When  this  bit is set, the blob keeps its vertical position even if there is an empty blob below.
              This bit has no effect on the steered falling blobs.

       Constants for kind:

       <name of kind of blob>
              For each kind of blob, there's one constant with the name of that kind. Use it to check if a  blob
              is  of that kind using kind@(x,y) == aKind or to change to that kind using kind = aKind.  See kind
              under The system variables for the side-effects of setting kind.

              Sometimes it is necessary to perform arithmetic on kinds,  for  example  when  several  have  been
              declared  using  the  *  multiplier.   The values of the constants are successive in the order, in
              which the kinds have been declared.  When a name is used several times, the first use defines  the
              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 than pear 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 declared using  emptypic.   In  this
              case the value's relation to the other values is 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 have an
              empty kind, but you still need to test if a blob is empty.

       outside
              The value of kind if the coordinates are outside of the game board.

       Constants for neighbours:

       neighbours_rect
              A blob connects up, down, left, and right.  This is the default.

       neighbours_horizontal
              A blob connects left and right.

       neighbours_vertical
              A blob connects up and down.

       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 complete picture".

       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 quarter SRC and draw it at position DST.

       Miscellanious constants:

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

VERSIONING

       Sometimes it is necessary to define a level slightly differently for different purposes.  For example you
       might  need to decrease numexplode for the two-player version lest it becomes unplayable.  The difficulty
       settings from cuyo's main menu provide another example.

       This is done by qualifiing a definition with the versions it should apply to.  It is best explained by an
       example:

         numexplode = 8
         numexplode[2] = 6
         numexplode[1,hard] = 10

       This  specifies  that normally numexplode should be 8.  In two-player mode it should be 6.  In one-player
       hard mode it should be 10.  Here the specifiers 2 for two-player mode, 1 for one-player mode and hard for
       hard  mode  are  used.   Along  with  easy for easy mode these are all predefined specifiers intended for
       levels.  Additionally (and for internal purposes), there are specifiers for the level tracks: main,  all,
       game, extreme, nofx, weird, and contrib.

       Furthermore,  you can make up and use your own specifiers.  In order for them to take effect, though, you
       have to give cuyo additional information about the current version.  This is done  on  the  command  line
       using the --version option.  For example

         cuyo --version=hard,geek

       Specifies  both  hard  version  (you  can  change  that  in  the  menu)  and version "geek", which is not
       predefined.

       There are several constraints to be observed:

       —  All versions of a definition must be made before the first use of the thing defined.  As sometimes  it
          is  not  obvious  where  the  defined  thing  is used (for example startpic uses a previous greypic by
          assigning successive numbers to kinds), it is best to group all these versions into one block.

       —  A given version also applies to every more specialized version, for which no definition is given.   In
          the above example, numexplode is set to 6 in two-player hard mode and in two-player easy mode as well.

          All  resulting  conflicts must be resolved.  For example, if you make a definition for [2] and one for
          [hard], you must also make a  definition  for  [2,hard]  (or,  equivalently,  for  [hard,2]),  because
          otherwise it would be ambiguous which of the two former should apply in two-player hard mode.

       —  Cuyo  knows  that  easy  and  hard  exclude  each  other.  Consequently, it is unnecessary (and indeed
          prohibited) to give an [easy,hard] definition, even if both [easy] and [hard]  are  given.   The  same
          holds for 1 and 2, and for level tracks.

       —  Furthermore,  cuyo  knows that 1 and 2 are exhaustive: There is no mode which is neither single-player
          nor two-player.  (The human-versus-AI mode  counts  as  two-player  as  far  as  cual  is  concerned.)
          Therefore,  if there are definitions for both, it is unnecessary, (and again illegal) also to define a
          version without any of both.  For example, if [1,de] and [2,de]  are  given,  [de]  must  be  omitted.
          Alternatively,  you  could  of  course  give  [1,de]  and  [de]  or  [de] and [de,2].  The level track
          specifiers are exhaustive as well.

BUSIENESS

       (No, not Business ;-)

       Busieness is a concept to make it easier to implement simple animated sequences which  are  triggered  by
       certain events.  Each code fragment has an internal 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 not all of the commands have been executed.

       —  code1 ; code2 is busy as long as at least one of code1 and code2 are busy.

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

         switch {
           1:100 => {B*, C*, D*, E*};
           -> A*;
         };

       This  code  fragment  normally draws the icon at position A (0).  But in each step, with a probability of
       1/100, an animation sequence consisting of icons B, 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/100 that A is
       drawn again.  But with the double arrow, the switch statement won'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 global blob (for the whole game, not
       one for each player), which, well, isn't really a blob, but behaves a bit like it.  It has its own set of
       variables,  and it can have a program which is run once every step.  To define such a global program, use
       global=code.  However, the global variables do exist even if you don't define global code.   See  section
       VARIABLES  AND  CONSTANTS 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 life, just before the first time its main drawing
              routine is called.

       turn   Is called for falling blobs each time they are rotated.

       land   Is called when the steered blob lands (just after it landed).

       changeside
              Is called when a blob moves from one player to the other, just after the blob has arrived  at  the
              new player.

       connect
              Is called when the connection of blobs is recalculated.

       row_up Is called when a player got a row from the other side, after everything is finished and just after
              the loc_y of all blobs has been decreased by 1.  Is only called for the semiglobal blob, though.

       row_down
              Is called when a player gives a row to the other side, before anything visible happens,  but  just
              after  the  loc_y  of  all blobs has been increased by 1.  Is only called for the semiglobal blob,
              though.

       keyleft, keyright, keyturn, keyfall
              Are called when the player presses the left, right, turn or fall key.  Are  only  called  for  the
              steered  falling  blobs and the semiglobal blob, though.  (Note that, in contrast to turn, keyturn
              is called even if the steered blob cannot be rotated due to some obstacles, and also if  there  is
              no steered blob.)

THE LIFE OF A BLOB

       Normal  blobs  come  into  life  at  the beginning of the game, or they fall into life: either as colored
       blobs, steered by the user, or as grey blobs.  More precisely, the steered blobs already come  into  life
       when  they  appear  as  the  preview.   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  into  an  empty  blob.   That's important for the variables: The empty blob still has all the
       variables set to the values they had before; only its kind is  different.   Empty  blobs  are  everywhere
       where  there's  no other blob.  (However, the falling blobs steered by the user are 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.   Empty  blobs  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 below it stops existing when the grey blob arrives and a new empty  blob  starts  existing
       when  the  grey  blob  moves on.  There is only one situation in which empty blobs move: When a 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 blobs in 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, except the last which is special.  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 10 describes both players.  Hence, each character describes 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 character 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 the
              character, specifies the blob's kind.  The difference between the character and the  distkey  then
              specifies the blob'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 has distkey  =  "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).

       %      An info blop with the version set according to the level-wide neighbours.

       &      An info blop with the version set according to the level-wide chaingrass.

       The last line may have length 4, 8, 10, or 20.  If it has length 10 or 20, it is just a  normal  line  as
       above.  Otherwise it describes the informational blops next to the field.  In case of length 4, the first
       entry describes the blop which depicts the number of greys.  The second entry describes  the  blop  which
       depicts  the  number  of  grass  blops.   The  third  entry  describes  the blop which depicts connection
       information.  The fourth entry describes the blop whoch  depicts  chaingrass  information.   In  case  of
       length  8,  the  above holds for the left player.  The remaining 4 entries then describe the same for the
       right player, but in reversed order.  The default is "-*%&&%*-" (or equivalently "-*%&").

       As seen above, startdist can reference 62  kind/version  combinations  directly  (and  more  at  random).
       Because  this  might  at  some  time not be enough, the multichar extension has 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 number multiplied by
       10 or by 20.  Every multicharacter combination starting with ".", "+", "-", or  "*"  is  treated  as  the
       corresponding  character  in  single-character  format.   All other character combinations are treated as
       numbers in base 62 representation.  Here, "A" to "Z" are digits with decimal value 10 to 35, and  "a"  to
       "z"  are  digits with decimal value 36 to 61.  Leading spaces are allowed instead of zeroes (however, the
       all-space string is forbidden).  The maximal distkey which (as a number) is not larger  than  the  number
       given  in  startdist,  specifies  the  blob's  kind.  The difference between the startdist number and the
       distkey then specifies the blob's version.  In the case of multichar distkeys, the default  for  distkeys
       of 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 neighbouring blobs of the same kind.  "Neighbouring", of course, refers to the
       neighbours entry.  inhibit and the calculate_size bit of behaviour have  no  effect  (these  are  mutable
       during  the  lifetime of blobs, while at the time of startdist processing, no blob's lifetime has 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 to set 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 of the .ld files:

       —  Outside of everything; that code is accessible from every level coming after 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 a kind, every blob in that level will have that variable.  The only effect of
       defining the variable in the section of a kind is that this kind is the only 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 used in both cases,  so  the  animation  will  simply  continue.   (Removing  the
       ampersands from example 2 will turn the behaviour to the one of example 1.)

THE AI UTILITY FUNCTION

       When  deciding  how to place the steered falling blobs, the AI player tries to maximize a certain utility
       function.   Its  value  is  the   sum   of   the   values   for   both   steered   falling   blobs   plus
       aiu_monochromic_vertical  in  case  both  blobs  have the same color and they get placed vertically.  The
       value for a single blob is the sum of the following:

       —  For each new neighbour of blob, the neighbour utility.

       —  aiu_two_above, if the blob is two above a blob of same kind.

       —  aiu_height*20/(the blob's y coordinate).

       The neighbour utility for a single new blob and a single one of its new neighbours  is  the  sum  of  the
       following:

       —  aiu_color, if the neighbour has the same kind as the blob.

       —  aiu_grass, if the neighbour fulfills behaviour.goalblob.

       —  aiu_grey, if the neighbour fulfills behaviour.explodes_on_explosion.

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 the way I would like, and in other situations I don't know how Cual should behave.

                                                   2014-10-25                                            CUAL(6)