Provided by: cuyo-data_2.~-1.2.brl1-1ubuntu2_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.  It has almost not been
       tested.  (The existing levels work, but that's  all.)   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.

       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  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 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 52 for kinds
              declared with startpic and 1 for all other kinds.

       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 to get an else 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,  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.

       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.  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 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.)

       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,      0      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
       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.)

       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
              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.

       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.

       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_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 the specifiers that cuyo uses
       by itself.

       Additionally, 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.

       -- 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].

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 the user presses
              the 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 the blob 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 fall into 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 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.  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).

       In   this   way,   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.)

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.

                                   2010-4-16                           CUAL(6)