Provided by: cuyo-data_2.0.0brl1-1_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.

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

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

       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_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  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_up Is called when a player gets a row from the  other  side.
              Is only called for the semiglobal blob, though.

       row_down
              Is  called  when  a player gives a row to the other side.
              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.

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

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.

                                   2012-1-27                           CUAL(6)