Provided by: cuyo-data_2.1.0-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.

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

       randomgreys
              The  expected  time between two randomly appearing greys in game steps (80ms).  Use
              -1 for none at all, which is the default.

       nogreyprob
              The probability that a grey does  not  appear.   See  greyprob  and  colourprob  in
              section KIND DATA for details.  The default is 0.

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

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

       bgcolor
              The background colour.  Defaults to white.

       textcolor
              Colour  of any text.  This includes the beginning-of-level information, message()s,
              and score.  Defaults to a certain shade of dark grey.

       topcolor
              The colour of the top  border  comming  down  (where  not  determined  by  toppic).
              Defaults to a certain shade of light grey.

   Other data
       startdist
              Distribution  of blobs at the beginning of the level.  It is a list of strings, the
              format of which is described in the section STARTDIST.

       pics, greypic, startpic, emptypic
              Lists of kinds.  These can be either file names referring  to  the  picture  to  be
              used,  or  declarations  of  kinds that have to be defined later on.  The different
              keywords (e.g. pics, emptypic) define different defaults.  In fact, only the  first
              three may be real lists, emptypic is limited to exactly one entry.  In these lists,
              it is advisable to use * whenever possible.  Besides being  shorter  to  write,  it
              also  speeds  up  loading of the level and cuts down memory usage.  This is because
              cuyo does some initializations only once for each entry with multiplier.

              The intentions of these lists are normal blob kinds  resp.  grey  blob  kind  resp.
              grass  blob  kind  resp. nothing-blob.  However, the only differences between pics,
              greypic and startpic are the default values for  behaviour,  colourprob,  goalprob,
              greyprob,  versions  and  distkey (see there).  All of these can also be overridden
              individually.  Also, the default drawing code is different.  (The  default  drawing
              code for startpic does not draw connections.)

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

KIND DATA

       numexplode, neighbours
              Defining these data in the section of a kind overrides the level-wide value for the
              kind.  See section LEVEL DATA for a description of these data.

       pics   A list of file names of pictures to be used for this kind.  The nth entry can later
              be accessed in cual with file=n-1.

       colourprob
              The probability that this kind appears as one of the  two  steered  falling  blobs.
              More  precisely,  this is a nonnegative integer weight.  For determining the actual
              probability, the value is divided by the sum of the colourprobs of all kinds.  This
              sum must be positive.  The default is 1 for kinds declared with pics= and 0 for all
              other kinds.  The probability is also used for + in startdist.   For  more  details
              see section STARTDIST.

       goalprob
              This  affects  the  semantics of * in startdist in the same way, as colourprob does
              for +.  The default is 1 for kinds declared with startpic=  and  0  for  all  other
              kinds.

       greyprob
              The  probability  that  this  kind  appears  as  a  grey  blob.  This is similar to
              colourprob, but there is a difference: For greyprob, nogreyprob is included in  the
              sum,  so  that  it  might  happen  that no blob appears at all.  There is a notable
              difference between a positive nogreyprob and a positive greyprob in  kind  nothing,
              when  several lines of grey blobs appear: In the latter case, empty blobs appear in
              the wall of greys, making holes.  In the former case, the wall is made  less  high.
              Usually  this is preferable.  The default is 1 for kinds declared with greypic= and
              0 for all other kinds.  The value also affects the semantics of - in startdist.  In
              this case, nogreyprob is not included in the sum.

       versions
              At  the  creation  of  a blob, its version variable is initialized.  Usually, it is
              chosen at random from 0 to versions-1, but startdist provides  the  possibility  to
              specify it exactly.  See section STARTDIST for details.  The default is 1.

       distkey
              An  alphanumerical  key,  which is used in startdist to identify this kind of blob.
              The default is A for kinds declared with  startpic  and  undefined  for  all  other
              kinds.  See section STARTDIST for details.

CUAL DEFINITIONS

       Inside << >>, variable and procedure definitions are expected.

       procname = code ;
              Defines a "procedure".  The next section describes how code looks like.  Example:

                redblob = {
                  schema16; 0*;
                  1; A,B,C; *;
                };

       var varname1 [= def1 [: reapply]], varname2 [= def2 [: reapply]], ... ;
              Defines  variables  with default values.  If no default is specified, zero is used.
              See section VARIABLES AND CONSTANTS about the meaning of the default value and  the
              optional suffix : reapply.

       default varname1 = def1 [: reapply], varname2 = def2 [: reapply], ... ;
              Changes  the default for already defined variables.  Again, the suffix : reapply is
              optional.  This is useful to give to a  single  kind  a  different  default  for  a
              variable  than  to  the other kinds.  Also, the default of a system variable can be
              changed this way.

CODE

       A code fragment can be one of the following:

       { code; code; ...}
              Executes one command after the other.

       code, code, ...
              This is useful for simple animations.  Executes exactly one of the commands: In the
              n-th  call,  the n-th command is executed. After the last command, the first one is
              executed again.  However, if one of the commands is "busy" (see section BUSIENESS),
              this  one will be executed until it stops being busy, and only after that, the next
              command will be executed.

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

       &procname
              Executes  the procedure procname; however, every instance of such a procname is the
              same.  This concerns busieness and  the  state  of  an  animation  sequence.   (See
              sections BUSIENESS and AMPERSAND-CALL.)

       busy   Does nothing except being busy.  (See section BUSIENESS.)

       varname = expr
              Sets the variable.  See section VARIABLES AND CONSTANTS for details.

       The same with +=, -=, *=, /=, %=, .+=, .-=.
              Does what you would expect.

       [ varname = expr ] code
              Sets  the  variable  varname to expr, executes code and then resets the variable to
              the old value.

       number A shortcut for file = number.

       letter A shortcut for pos = number, where different letters mean different numbers: A:  0,
              B: 1, ..., Z: 25, a: 26, ..., z: 51

       *      Draw  the icon specified by the variables kind, file and pos.  May also draw only a
              part of the icon, if specified by  the  variable  qu  (see  section  VARIABLES  AND
              CONSTANTS).

       *@(position)
              Like *, but draws the icon at some other position.  This drawing is performed after
              all drawing by *.  If *@ is used from several blobs, the further order  of  drawing
              is  not specified.  It is guaranteed, however, that at any given time this order is
              the same for all positions.  (See section VARIABLES AND CONSTANTS for more  details
              about @.)

       @(position)*
              Like  *,  but  draws  the  icon  at some other position.  This drawing is performed
              before all drawing by *.  If @* is used from several blobs, the  further  order  of
              drawing  is  not specified.  It is guaranteed, however, that at any given time this
              order is the same for all positions.  (See section VARIABLES AND CONSTANTS for more
              details about @.)

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

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

                if expr1 arrow1 code1
                else => if expr2 arrow2 code2
                ...

              The last expr may be omitted.  This is equivalent to setting it to true.

       bonus(expr)
              The player gets expr bonus points.

       message(String)
              The string is displayed (blinking)  on  the  screen.   To  be  used  together  with
              bonus(...).  Example:

                bonus(50);
                message("You get 50 bonus points");

       explode
              Makes  the blob explode.  For the next 8 steps or so, the blob is still what it was
              before, but the explosion is drawn over the graphics.  After that, it's changed  to
              a nothing-blob.

       lose   The players immediately lose the level.

       sound(Filename)
              Plays the given sound file.

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

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

EXPRESSIONS

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

       Of course, variables, constants and numbers are expressions, and you can use  parentheses.
       There are the following operators (listed here in order of increasing precedence):

              ||     Boolean or

              &&     Boolean and

              ==, !=, <, >, <=, >=
                     Comparison

              ==..   A special comparison

              !      Boolean not

              +, -   Add, substract

              :      Special operator

              *, /, %
                     Multiply, divide, modulo

              &, |, .+, .-
                     Bitwise  and, bitwise or, setting of bits (same as bitwise or), unsetting of
                     bits

              -      Unary minus

              .      Testing of bits (a.b is the same as a&b != 0)

       / and % work mathematically correct and do not make funny changes when  the  sign  of  the
       numerator changes.  More specifically, if b is positive, then a/b is the largest integer n
       such that n*b<=a.  If b is negative, then a/b is the largest integer n such  that  n*b>=a.
       In both cases a%b is such that (a/b)*b+a%b = a.  Examples:

       13/5=2       13%5=3
       -13/5=-3     -13%5=2
       13/-5=-3     13%-5=-2
       -13/-5=2     -13%-5=-3

       The following are the special operators:

       expr1 == expr2 .. expr3
              Is true, if expr1 lies between expr2 and expr3.  You may also omit one of expr2 and
              expr3.  (Then, it does the same as <=  resp.  >=.)   The  precedence  implies  that
              x==y==2..3   is   the   same  as  x==(y==2..3)  and  is  neither  (x==y)==2..3  nor
              x==(y==2)..3.  Note that this operator might change in the future. (I plan to  make
              something like "expr in set" in Pascal.)

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

       neighbour_pattern
              neighbour_pattern  is a sequence of six or eight characters 0, 1 and ?.  It is true
              if the sequence fits to the neighbour sequence of the blob.  The neighbour sequence
              is  a  string  of  "0"s  and  "1"s  with a "1" for each neighbour of the same kind,
              starting above and going clockwise.  This way, you get a string of  "0"s  and  "1"s
              (six or eight, depending on wether this level is in hex mode).

              Example:  1???0??? is true iff the blob above this blob is of the same kind and the
              blob below it is of different kind.

              For an empty blob the semantics is slightly different: If in some  direction  there
              is  no neighbour, because the field ends there, the entry in the neighbour sequence
              is 1 nevertheless.  So for an empty blob 1???0??? is true, iff the blob above  this
              blob does not exist or is empty as well, and the blob below this blob exists and is
              not empty.

              If some blob changes its kind during a step, the expression  will  still  test  the
              neighbours  as  they were at the beginning of the step.  (See the section VARIABLES
              AND CONSTANTS for details.)

       The following functions exist:

       rnd(expr)
              Returns a random value between 0 and expr-1

       gcd(expr1, expr2)
              Returns the greatest common divisor of expr1 and expr2

VARIABLES AND CONSTANTS

       The following kinds of variables and constants exist:

       —  User defined variables (see section CUAL DEFINITIONS).  At the start of the  level  (or
          at  the  creation  of  the  blob)  the value is the default value you provided.  If you
          supplied the default with : reapply, whenever a blob's kind changes, the value  of  the
          variable  is  also  set to the default of the new kind.  There is a subtlety: This only
          happens if the new value of kind is in fact different from the old one.

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

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

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

       Of each variable, there's one instance in each blob.  Normally, you access the instance in
       your own blob, but with the following syntax, you can access variables of other blops:

         varname@@(x, y; side)
         varname@@(x; side)
         varname@@(; side)
         varname@(dx, dy; side)
         varname@(dx; side)
         varname@()

       If x and y are given, these are absolute coordinates in the grid of  blops,  that  is  the
       variable is taken from the blob with loc_x=x and loc_y=y (see under The system variables).
       If only x is given, it specifies one of the two blobs  that  are  currently  falling.   If
       there  is  only  one  such  blob  left, because the other one got stuck on some tower, the
       remaining blob's coordinate is 0.  Otherwise one of the two has coordinate 0, the other 1.

       In the @ variants, the coordinates are relative to the current  blob.   The  variant  @@(;
       side)  refers  to the semiglobal blob, the variant @() to the global blob (See section THE
       GLOBAL BLOB).  The extra part ; side is optional and specifies the side of the game.  This
       is  only  meaningful in two-player mode.  side = < specifies the left player, side = > the
       right player, side = = the player to which the current blob pertains, and  side  =  !  the
       other player.  @() and @@() can also be given as @ respectively @@.

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

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

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

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

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

       —  when writing variables with @ or @@, the write operation will only be executed  at  the
          end of the current step.  (The write operations are stored in a kind of queue.)

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

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

       For illustration, look at the following six statements:

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

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

       2)     the value of X just before the change (that is, X is incremented in the future),

       5)     the current value of X,

       6)     the value of X at the beginning of the step.

   Some more details
       —  Whenever you try to access a variable at a location which doesn't exist, you  will  get
          the default value.  If default values depend on the kind, the default pertaining to the
          blob executing the code is used.  This may change in the future.

       —  Changing a variable which doesn't exist does nothing (and does not result in an error).

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

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

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

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

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

              —  In the current step, the program to draw the blob has already been  invoked  (it
                 might  even  be  the  program which changed this variable); so in this step, the
                 blob will still look like one of the old kind.  However,  if  things  are  drawn
                 after the kind has been changed, icons from the new kind are taken.

              —  Defaults  of  the  new  kind that are declared with : reapply are applied.  This
                 happens at the same time that  kind  changed,  but  only  if  the  new  kind  is
                 different from the old one.

       version
              Is  assigned a hopefully distinctive value at the blob's creation.  See versions in
              section KIND DATA for details.

       qu     Tells "*" which part of the icon to draw.  It's possible to draw the whole icon, or
              only  one  of  its  quarters.  If a quarter is drawn, you may specify independently
              which of the quarters to take and at which position to draw it.  Use the  constants
              (see  below).  This variable is reset to "draw all" before the drawing procedure is
              executed.

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

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

       inhibit
              Set  this  variable  to a sum of the constants DIR_...; this will inhibit that this
              blob connects into the given directions.  This is not for the graphics but for  the
              calculation of the connected components and the explosions.

       behaviour
              This  is a bit field.  Refer to The Constants below for the meaningful of its bits.
              The    default    is    calculate_size+explodes_on_size    for    normal     blobs,
              explodes_on_explosion+explodes_on_chainreaction  for  grey  blobs,  floats  for the
              empty   blob   and   goalblob+explodes_on_explosion+explodes_on_chainreaction    or
              goalblob+explodes_on_chainreaction  (depending  on  whether  chaingrass is set) for
              grass blobs.

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

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

       turn   Is 1 resp. 2 if the blob is falling and  just  being  turned  by  the  user  and  0
              otherwise.   (1  in the first turning step, 2 in the second one.)  Be aware that if
              the user presses the turn key fast several  times,  some  of  these  steps  may  be
              omitted.   (Use  the  turn  event  if  you  want to be sure that a program block is
              executed once for every turn.)

       connect
              Contains internal data.  Will be removed.  Probably.

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

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

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

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

       loc_x, loc_y
              The absolute coordinates of the blob.  (0,0) = top left corner

       loc_xx, loc_yy
              The  absolute  coordinates  of  the blob in pixels.  This is not always the same as
              loc_x*32 and loc_y*32, particularly for the steered falling blobs.

       loc_p  The player of the blob (1 or 2)

       falling
              true, if the blob is falling or it is a preview of a falling blob.  (Falling in the
              sense of steered by the player.  Grey blobs are not falling in that sense.)

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

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

       players
              The number of players.

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

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

   The Constants:
       Constants for behaviour:

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

       calculate_size
              When  this  bit  is set, size will be regularly updated to the sum of weight in the
              connected component.

       explodes_on_size
              When this bit is set, a connected component explodes, when it has size>=numexplode.

       explodes_on_explosion, explodes_on_chainreaction
              When these bits are set, the blob explodes whenever an explosion that was triggered
              by explodes_on_size happens in its neighbourhood.  explodes_on_chainreaction refers
              to those triggering explosions that are  the  second  or  later  part  of  a  chain
              reaction.  explodes_on_explosion refers to the other ones.

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

       Constants for kind:

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

              Sometimes  it is necessary to perform arithmetic on kinds, for example when several
              have been declared using the  *  multiplier.   The  values  of  the  constants  are
              successive  in  the  order,  in which the kinds have been declared.  When a name is
              used several times, the first use defines the value.  Example:

                startpic = apple, orange
                pics = orange, pear, apple * 3, banana
                greypic = pineapple

              This initializes 2 kinds with the defaults for startpic, 6 kinds with the  defaults
              for  pics,  and  1  kind  with the defaults for greypic.  The value of the constant
              orange is 1 more than that of apple, pear is 2 more than orange, banana is  4  more
              than pear and pineapple is 1 more than banana.  We do not specify what these values
              actually are.

              This constant also exists for the empty  kind,  if  one  has  been  declared  using
              emptypic.   In  this case the value's relation to the other values is not specified
              at all.

       global, semiglobal
              Denote the kind of the global, respectively semiglobal, blob.

       nothing
              Is the same as the constant for the empty kind.  Is  provided,  because  sometimes,
              you don't have an empty kind, but you still need to test if a blob is empty.

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

       Constants for neighbours:

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

       neighbours_horizontal
              A blob connects left and right.

       neighbours_vertical
              A blob connects up and down.

       neighbours_diagonal
              A blob connects diagonally.

       neighbours_hex6
              When  used  in  the level-wide neighbours, this sets hex mode.  A blob connects up,
              down, left with a slight upwards shift, left with a slight downwards  shift,  right
              with a slight upwards shift, and right with a slight downwards shift.

       neighbours_hex4
              When  used  in the level-wide neighbours, this sets hex mode.  A blob connects left
              with a slight upwards shift, left with a  slight  downwards  shift,  right  with  a
              slight upwards shift, and right with a slight downwards shift.

       neighbours_knight
              A blob connects in knight moves (Two forward and then one sideways.  Forward is one
              of up, down, left or right.  Sideways is perpendicular to forward.   This  makes  a
              total of eight directions.).

       neighbours_eight
              Combines neighbours_rect with neighbours_diagonal.

       neighbours_3D
              A  more  obscure  mode  created  especially for 3d.ld.  When used in the level-wide
              neighbours, this sets hex mode.  A blob connects up, down, two (but not one) to the
              left,  and  two to the right.  In even columns it also connects right with a slight
              upwards shift.  In odd columns it also connects left with a slight downwards shift.

       neighbours_none
              A blob does not connect at all.

       Constants for qu:

       Q_ALL  Value for qu, which means "draw the complete picture".

       Q_TL, Q_TR, Q_BL, Q_BR
              Values for qu.  "TL" means draw top-left quarter, etc.  (See the "*" command in the
              Code section.)

       Q_SRC_DST
              SRC and DST may be TL, TR, BL, BR.  Take quarter SRC and draw it at position DST.

       Miscellanious constants:

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

VERSIONING

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

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

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

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

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

         cuyo --version=hard,geek

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

       There are several constraints to be observed:

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

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

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

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

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

BUSIENESS

       (No, not Business ;-)

       Busieness  is a concept to make it easier to implement simple animated sequences which are
       triggered by certain events.  Each code fragment has an internal state which tells  if  it
       is busy.

       —  Normal statements like assignments are never busy.

       —  A  chain  of  commands separated by "," is busy as long as not all of the commands have
          been executed.

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

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

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

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

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

THE GLOBAL BLOB

       Apart from the normal blobs which you can see on screen, there's one global blob (for  the
       whole  game, not one for each player), which, well, isn't really a blob, but behaves a bit
       like it.  It has its own set of variables, and it can have a program  which  is  run  once
       every  step.   To  define  such  a  global  program, use global=code.  However, the global
       variables do exist even if you don't  define  global  code.   See  section  VARIABLES  AND
       CONSTANTS  on how to access them.  Note that the global blob is always executed before any
       of the normal blobs.

       There are also semiglobal blobs.  There is one for each player.  These are programmed with
       semiglobal=code.

EVENT HANDLERS

       The following events exist:

       init   Is  called  only once, when the blob gets into life, just before the first time its
              main drawing routine is called.

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

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

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

       connect
              Is called when the connection of blobs is recalculated.

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

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

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

THE LIFE OF A BLOB

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

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

STARTDIST

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

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

       .      An empty blop.

       +, -, *
              A   blop   chosen   at  random  according  to  colourprob,  respectively  greyprob,
              respectively goalprob.  The value of nogreyprob has no influence.

       0..9, A..Z, a..z
              These characters denote a specific kind.  If the character matches the  distkey  of
              some  kinds,  the  first  of these is chosen.  More generally, these characters are
              ordered such that "9" comes before "A" and "Z" comes before "a".   In  this  order,
              the  maximal distkey, which does not come after the character, specifies the blob's
              kind.  The difference between the character and  the  distkey  then  specifies  the
              blob's version.

              Example  1:  In  the  special  case, where the character exactly matches a distkey,
              version is set to 0.

              Example 2: Suppose kind apple has distkey = "A", kind orange has distkey = "O"  and
              no further distkeys exist.  Then the character "C" denotes an apple with version=2,
              the character "N" denotes an apple with version=13, the character  "O"  denotes  an
              orange  with  version=0,  the  character  "S" denotes an orange with version=4, the
              character "a" denotes an orange with version=12, and the  character  "8"  does  not
              denote anything (and hence is illegal).

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

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

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

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

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

WHERE DO I PUT THE CUAL CODE?

       Cual procedures and variables can be defined in different sections of the .ld files:

       —  Outside  of  everything;  that  code  is  accessible from every level coming after that
          definition.

       —  In the section of a level.

       —  In the section of a kind.

       This basically does what you expect.  However, there's one thing you might want  to  know:
       Even  if  you  define  a  variable  inside a kind, every blob in that level will have that
       variable.  The only effect of defining the variable in the section of a kind is that  this
       kind is the only one which can access it.

AMPERSAND-CALL

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

       Example 1:
       <<
       myblob = {
         ...
         switch {
           myvar -> { 0A*; 1; A,B,C,D; *; 2A*};
                 -> { 0B*; 1; A,B,C,D; *; 2B*};
         };
       };
       >>

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

       myblob = {
         ...
         switch {
           myvar -> { 0A*; &anim; 2A*};
                 -> { 0B*; &anim; 2B*};
         };
       };
       >>

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

THE AI UTILITY FUNCTION

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

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

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

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

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

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

       —  aiu_grass, if the neighbour fulfills behaviour.goalblob.

       —  aiu_grey, if the neighbour fulfills behaviour.explodes_on_explosion.

SEE ALSO

       cuyo(6)

BUGS

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

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

                                            2014-10-25                                    CUAL(6)