Cannon Macro Language ver0.20
This is a lazy reference for Cannon Macro Language (CML).

[Command reference]
[expand all] [expand index] [unexpand all]

Format
Comment, formula ...

Comments (// , /* ~ */)

// [Comment]
/* [Comment] */
' [Comment] '
Show comments.
Lines after "//" and statements between "/* ~ */" are ignored as a comments.
Statement between ' ~ '(Single quatation) is also ignored, but it is possible to refer from your program from the user defined command.

Sequence ( {...} )

{[Parameter] , [Parameter] , ... (A row of commands) }
Define sequences.
The sequence is a row of commands that defines a motion of an object. In cannon ML, a row of commands between "{" and "}" defines a sequence. The sequence can be set after & (Call sequence), @* (Create new fiber) and n*/f* (Create new object). And if you specify the sequence without any commands, the sequence is executed as "@0" command does.
The values after "{" can refer from your program, but it cannot include any formula, only constant values are available.
For example, "f{1 hoa0.1} f{2 hoa0.1}" you can refer the values of "1" and "2" when the f command calls the function CMLObject.fireObject() in your program.

Formula (operators)

+ , - , * , / , %, ( , )
Calculate in an argument.
== , != , >= , <= , < , >
Compare. The returning value is 1(true) or 0(false).
!
Bit calculation of "not". "0 to 1" and "not 0 to 0". This means !!2=1.
$sin, $cos, $tan, $asn, $acs, $atn, $sqr, $int and $abs
The sine, cosine, tangent, arcsine, arccosine, arctanenget, square root and floor calculation respectively.
$i?, $i??
(random) Return a random integer.The ranges are 0<=$i?(n)
You can calculate and compare the number in an argument. Interger, float and hexadecimal are available. Prefix of "0x" means hexadecimal. There are no "logical and" and "logical or". Use "*" and "+" instead of them.

Formula (variables)

$?, $??
(random) Return a random number.The ranges are 0<=n<1 and -1<=n<1 for $? and $?? respectively.
$r
(Rank) Return a game difficulty number. The renge depends on your program.
$i
(Iiterval) Return a number specifyed by i command.
$l, $l1, $l2, $l3, ... $l9
(Loop counter) Return a counter of loop command.
Return 0 at first and increament on each repeat.
You can also get the counter of 1 outer loop by "$l1" in nested loop. You can get the counter of 9 outer loops at maximum.
$1, $2, $3,... $9
(variable) Return a number assigned by assign command or an argument of call command.
In cannon macro language, you can use 9 variables ($1-$9) in a sequence.
These variables hold a number assigned by assign command. And these variables are initialized by the arguments of call command. For example, "#A{p$1,$2} &A 10,20" sets position at (10, 20). "&{p$1,$2}10,20" also sets position at (10, 20).
$x, $y
(position X/Y) Return the x and y values of the objects position.
$sx, $sy
(Sign of position X/Y) Return the sign of x and y values of the objects position. $sx=-1 when $x<0, and $sx=1 when $x>=0.
$v
(Velocity) Return the abslute value of the objects velocity.
$vx, $vy
(Velocity X/Y) Return x and y values of the objects velocity.
$ho
(Head angle of Object) Return the angle of the object.
$td
(Target Distance) Return the distance from the object to the target (usually player object).
$o, $o1, $o2,... $o9
(Count Object) Return the count of child objects with an object ID.
"$o1-$o9" returns the object count with specifyed ID, "$o" returns the total count of objects with ID.
For example, "n{}n1{}n1{}n2{}" creates 4 objects (and 3 objects are specifyed object ID) and "$o1" returns 2, "$o2" returns 1, and "$o" returns 3.
$p.x, $p.y, $p.sx, $p.sy, $p.v, $p.vx, $p.vy, $p.ho, $p.td, $p.o, $p.o1, ... $p.o9
(Parent) Refer the parents parameters.
To insert "p." after "$", you can refer the parents parameters.
$t.x, $t.y, $t.sx, $t.sy, $t.v, $t.vx, $t.vy, $t.ho, $t.td, $t.o, $t.o1, ... $t.o9
(Target) Refer the target objects parameters.
To insert "t." after "$", you can refer the target objects parameters. "$t.td" always returns 0.

Formula (assign) (l)

l$r=, l$1=, l$2=, l$3=,... l$9= [assignee number]
(Let) Assign the number to the variable.
The 'l' command assigns a value on a variables ($1, $2, ... $9 and $r).
You can refer variables by $1-$9 or $r.
l$1+=, l$1-=, l$1*=, l$1/= [number]
(Let) Assign the caluclation result.
You can also do assign with calculation.
For example, "l$1=0[p$1l$1+=10w5]" does start at 0, and move 10 pixels right for each 5 frames.
But, you CANNOT use these commands in an argument. So "l$1=0[pl$1+=10w5]" is NOT AVAILABLE.

Sequence controling commands
Wait, Looping, If, Call, Create new fiber ...

Wait (w)

w [Frames]
(Wait) Wait in specifyed frames.
[initial value]
  • w1
When you dont specifyed frames, wait same frame as specifyed previously. And when [Frames]=0, wait infinitly.
~
(wait interval) Wait frames specifyed by i command.
This command has no arguments. Wait frames specifyed by i command. When i0, this command is skipped.
w? [condition]
(Wait if) Wait while the [condition] returns 1.
Wait until the [condition] returns 0.

Looping excution ([...])

[ [Looping count] (sequence) ]
(loop) Execute sequence specifyed times.
The [Looping count] is caluculate only once when enter the loop.

If branch ([?...])

[? [condition] (sequence) : (sequence) ]
(if ... else ...) Execute conditional execution by [condition].
Execute before ":" when [condition]!=0, and execute after ":" when [condition]==0.
[s? [condition] (sequence) : [case] (sequence) : [case] (sequence) ... ]
(Select if ... grater than or equal to ...) Select the sequence by the [condition] value.
When the [condition] value is greater than or equal to the [case], the next (sequence) is executed. The [case] must be acsendant.
For example, "[s?$r seqA :0.3 seqB :0.6 seqC]" executes seqA, seqB or seqC when its $r<0.3, 0.3=<$r<0.6 or 0.6=<$r respectively.

Call sequence (&)

& ({(sequence)}|LABEL)
(call) Call sequence
Jump to another sequence, execute as ({(sequence)}|LABEL) is there. All fiber parameters are copyed to the called sequence. For example, "f4w10&{f}" and "#A{f} f4w10&A" is the same and fire 2 bullets with speed of 4, because the argument of f command is copyed.
^& ({(sequence)}|LABEL)
(fake call) Do nothing, but change the sequence refered by "&{.}" command.
Do nothing, Only change the sequence refered by "&{.}" command.

Create new fiber (@*)

@ [exclusive execution ID] ({(sequence)}|LABEL)
(execute) Execute the sequence on a new fiber.
Execute the sequence on a new fiber.'Fiber' is a kind of thread in some othor languages, the sequence is executed simultaniously. For example, "&{[5f4w3]}a0.1" accelarates after firing 5 bullets, "@{[5f4w3]}a0.1" accelarates with firing 5 bullets.

And you can omit "@0". If you write "{...}" or labels without f*, n*, & or @* command, "@0" is executed.

When [exclusive execution ID] >= 1 is specifyed, stop the other fiber with same ID and execute new fiber.

Writing with a format of "{sequence}", All fiber parameters are copyed to the called sequence. On the other hand writing with a label, all fiber parameters are initialized. For example, "f4w10@{f}" fires 2 bullets with speed of 4, "#A{f} f4w10@A" fires 2 bullets with speed of 4 and 1 respectively.
@o [object ID] (, [object ID] , ... ) ({(sequence)}|LABEL)
(execute Object) Execute a sequence with a new fiber on another objects created by n or f command with specifying [Object ID].
When you create a new object by the 'n', 'nc', 'f' or 'fc' command with [Object ID], the '@o' command executes the sequence on another objects that have specifyed [Object ID].
If you specify plural [Object ID] in the arguments, the sequence is executed on grand-child object. For example, "@o1,2{...}" is same as "@o1{@o2{...}}"
In the '@o' command, all fiber parameters are always initialized and you cannot specify the [exclusive execution ID].
@ko [end status] ({(sequence)}|LABEL)
(execute when Kill Object) Execute sequence when the object is destroyed with specifyed [end status].
Assign a sequence that execute when the object is destroyed. The sequence can be assigned each [end status]. The [end status] is specifyed by ko command or CMLObject.destroy() in your program.
The sequence is executed only 1 frame and waiting command (like "w*" and "~") stops the execution.
[see also]
^@ ({(sequence)}|LABEL)
(fake execute) Do nothing, but change the sequence refered by "@*{.}" command.
Do nothing, but change the sequence refered by "@*{.}" command.

Others

{.}
Refer the sequence called before.
This statement is available after &, @*, f* or n* and you can refer the sequence you called previously. The sequences called before are memoryed in a fiber for each command &, @*, f* or n*. For example, in "n{seqA} f{seqB} n{.} f{.}" the "n{.}" and "f{.}" refer seqA and seqB respectively. And in the case of "f{seqC} @{f{.}}", the sequence called before is copyed to the new fiber and the "f{.}" refers seqC.
kf
(Kill all Fibers) Kill all fibers.
Kill all fibers that are created from the sequence. Killed fibers include anothor objects fiber created by @o command. If you want to kill the fiber with [exclusive execution ID] >= 1, overwrite with a sequence does nothing, for example "@1{}". Only the way to kill the fiber with [exclusive execution ID] = 0 is kf command.

Sub commands
Commands used with anothor command. The arguments are refered from the other command and do nothing itself.

Specify the changing term or interval (i)

i [Frames]
(Interval) Specify the changing term/interval of the object parameters.

Specify the object creating point (q*)

q [x value] , [y value]
(creating point) Set the object creating point. Set 0 by omitting arguments.
qx [x value]
(creating point X) Set the x value of the object creating point. The y value does not change.
qy [y value]
(creating point Y) Set the y value of the object creating point. The x value does not change.
[see also] [default value]
  • q0,0
The values specifyed are based on the objects coordinate.

Specify the angle (h*)

Specify the setting of multiple creation of f* command (b*)

bm [count] , [center angle] , [range of speed] , [time interval of automatic fire]
(Barrage setting Multiple) Specify the setting of f* command by [center angle] and [range of speed].
bs [count] , [increament of angle] , [increament of speed] , [time interval of automatic fire]
(Barrage setting Sequencial) Specify the setting of f* command by [increament of angle] and [increament of speed].
br [count] , [range of angle] , [range of speed] , [time interval of automatic fire]
(Barrage setting Random) Set random multiple creation to f* command.
[see also] [default value]
  • bs1,0,0,0
After bm/bs/br command, you can create multiple objects by f* command.
Specifying [center angle]=-360 or 360 in bm command, the f* command creates all-round objects as the special case. Specifying [count]=0 and [time interval of automatic fire]>0 in bs/br command, the f* command creates objects infinitly.

Calling bm/bs/br commands in one sequence, you can specify multiply. For example, "bm3,30bm5,0,2 f" fires 3 bullet lines (constructed by 5 bullets) with center angle of 30[degree]. "br5,90,0,10bm4,10 f" fires 4way barrage in 5 times with a range of 90 degree randomly.
bv [Increament of speed]
(sequencial setting of Bullet Velocity) Specify the increament of speed for multiple creation.
[see also] [default value]
  • bv0
The bv command is a primitive command focused on the 3rd argument of bs command. By a conbination with loop command, you can write more complex barrage.
The f* command with no arguments fires bullets with a speed increaced by [increament of speed] from before.
The bv command CANNOT specify multiply as bm/bs/br command can.

Set target (t*)

td
(set Target to Default) Set target to the default (usually player object).
tp
(set Target to Parent) Set target to the parent object.
to [object ID]
(set Target to another Object) Set target to the object with specifyed [object ID].

Execute mirrord (m)

m [Mirroring axis]
(Mirror) Mirroring next command.
[see also] [default value]
  • not mirrored
Differ from some other sub commands, the m command mirror only the next command. The [mirroring axis] means 0=mirroring by axis holizontal with scrolling direction, 1=mirroring by axis vertical with scrolling direction,2=mirroring by x and y axis. The m command before &, @*, n* or f* command mirror all commands in the sequence.

Creating commands
Commands to create new object. There are 2 types, single creation and multiple creation.

Create single object (n*)

n [Object ID] ({(sequence)}|LABEL)
(New) Create single object.
The n command creates new object at the position specifyed by q command, with an initial speed of 0.
The [Object ID] is used to specify the object in @o, to and $co commands. If you want to use these commands, specify [Object ID] >= 1. This command calls CMLObject.newObject() in your program.
nc [Object ID] ({(sequence)}|LABEL)
(New Child) Create single object in parents coordinate.
The nc command creates new object at the position specifyed by q command, with an initial speed of 0. The object created by nc command is always set in parents coordinate.
The [Object ID] is used to specify the object in @o, to and $co commands. If you want to use these commands, specify [Object ID] >= 1. This command calls CMLObject.newObject() in your program.
^n ({(sequence)}|LABEL)
(fake New) Do nothing, but change the sequence refered by "n*{.}" command.
Do nothing, but change the sequence refered by "n*{.}" command.

Create multiple objects (f*)

f [Initial speed] , [Object ID] ({(sequence)}|LABEL)
(Fire) Create multiple objects with initial speed.
fc [Initial speed] , [Object ID] ({(sequence)}|LABEL)
(Fire Child) Create multiple objects in parents coordinate with initial speed .
This command is similar to n* command, but its different in sevral points as,
  • Specifys the initial speed of a new object,
  • Creates plural objects simultaniously according to the b* (Specify a setting of the multiple creation) commands,
  • Possible to omit {...} or LABEL,
  • Calls CMLObject.fireObject() in your program.
When you omit {...} or LABEL, execute as "{.}" (Refer the sequence executed before).
^f [Initial speed] ({(sequence)}|LABEL)
(fake Fire) Do nothing, but it behaves as one f command was done.
Do nothing, but it behaves as one f command was done as shown in below,
  • Changes the sequence refered by "f*{.}" command,
  • Increaments speed and angle according to the bv and hs commands.

Controling commands
Commands to operate the object. Set position, speed, accelaration, rotation,gravity motion, destruction and so on.

Set the position (p*)

p [x value] , [y value]
(Position) Set the object position. Set 0 by omitting arguments.
px [x value]
(Position X) Set the x value of the object position. The y value does not change.
py [y value]
(Position Y) Set the y value of the object position. The x value does not change.
pd [distance] , [horizontal distance]
(Position for head Direction) Set the object position by the distance and the angle specifyed by h* command from the origin.
When the object is a part of its parent, the values are on a coordinate of the parent. And in the other case, the values are on a coordinate of the screen (according to your program).
When you specifyed a parameter changing term by the i command before, the position will be interpolated while the specifyed time. Or specifying "i0", the position is changed with no time. If you set the velocity by v* command after this command, the interpolation considers the velocity as the goal value of it.

Set the velocity (v*)

v [x value] , [y value]
(Velocity) Set the object velocity. Set 0 by omitting arguments.
vx [x value]
(Velocity X) Set the x value of the object velocity. The y value does not change.
vy [y value]
(Velocity Y) Set the y value of the object velocity. The x value does not change.
vd [speed] , [horizontal speed]
(Velocity for head Direction) Set the object velocity by the speed and the angle specifyed by h* command.
Specifyed a velocity changing term by i command. When the changing term = 0, the velocity is changed with no time.
If the (i command)>0 and set (p command) before in a same frame, the values are considered as the end values of interpolation.
If the (i command)>0 and not set (p command) before in a same frame, the values are considered as the end values of accelaration.

Set the accelaration (a*)

a [x value] , [y value]
(Accelaration) Set the object accelaraion. Set 0 by omitting arguments.
ax [x value]
(Accelaration X) Set the x value of the object accelaraion. The y value does not change.
ay [y value]
(Accelaration Y) Set the y value of the object accelaraion. The x value does not change.
ad [accelaration] , [horizontal accelaration]
(Accelaration for head Direction) Set by the accelaraion and the angle specifyed by h* command.
You CANNOT specify the changing term of accelaration by i command. If you want to stop the accelaration,
  • Set the accelaration as (0,0) (write "a0,0" or just "a"),
  • Call cd(Change direction), cs*(Chenge speed) or gp(Set gravity),
  • Call p*(Set the position), v*(Set the velocity) after specifyed (i command)>0.

Change the direction (same as <changeDirection> in bulletML) (cd)

cd [Maximum rotation speed in 1 frame]
(Change Direction) Change the direction to the angle specifyed by h* command (same as <changeDirection> in bulletML).
The cd command changes the objects angle and the velocity direction together (the r command changes the objects angle only). The starting angle is the objects angle at that time.
After this command, the objects angle (even changing by r* command) synchronizes with the velocity direction (this behavior calls "bml motion mode"). If you want to stop this behavior, specify p*, v*, a* or gp command.

Specify the angle by h* command as <direction> and specify the changing term by i command as <term> in bulletML. The ha, ho, ht and hs commands mean type="absolute", type="relative", type="aim" and type="sequence" in <changeDirection> respectively.
The argument assigns maximum rotation in 1 frame and the argument of 0 means not to specify the maximum rotation.

Change the speed (same as <changeSpeed> in bulletML) (cs*)

csa [Speed]
(Change Speed Absolute) Change the speed to the specifyed value. (same as <changeSpeed type="Absolute"> in bulletML)
csr [Speed]
(Change Speed Relative) Change the speed by the specifyed difference. (same as <changeSpeed type="Relative"> in bulletML)
css [Speed]
(Change Speed Sequence) Change the speed by the specifyed value in 1 frame. (same as <changeSpeed type="Sequence"> in bulletML)
The cs* command changes the objects speed to the object angle(same as "hovd" sequence). After this command, the objects angle (even changing by r* command) synchronizes with the velocity direction (this behavior calls "bml motion mode"). If you want to stop this behavior, specify p*, v*, a* or gp command.

Specify the changing term by i command as <term> and specify the speed by the argument as <speed> in bulletML.

Set the gravity (gp)

gp [Gravity] , [Friction]
(Gravity at the Position) Set the gravity.
After this command, the object moves by the attracting force from the position specifyed by p* command (this behavior calls "gravity motion mode"). The motion is calculated by

[Accelaration] = [Distance to specifyed position] * [Gravity] / 100 - [Velocity] * [Friction] / 100

If you want to stop this behavior, specify "gp0,0", v*, a*, cd, cs* command or the p command after specifyed changing term by i command.
This command set the changing term to 0 (as specify "i0").

Set the rotation (r*)

r [First rotation speed] , [Final rotation speed]
(Rotate) Rotates the objects to the angle specifyed by h* command.
Specify the changing term by i command, and the angle by h* command. The rotation is calculated by bezier spline interpolation with the specifyed values.
The [First rotation speed] and [Final rotation speed] are the relative values the speed of constant rotation as 1.
For example, the "r0,0" rotates accelarating first, top speed in the middle, and then decelerating to 0.
The "r1,1" rotates with constant speed.
The "r2,0" rotates with constant accelaration.
The "r-1,0" rotates oppsite direction first, and accelarating then decelerating, finaly the speed goes to 0.
rc [Maximum rotation speed in 1 frame]
(Rotate Constant) Rotates the objects to the angle specifyed by h* command by constant speed.
Specify the changing term by i command, and the angle by h* command. You can specify the maximum rotation speed in 1 frame. The argument of 0 means no limitation in the rotation speed (and this is same as "r1,1").

Kill object (ko)

ko [End status]
(Kill Object) Remove the object from the stage.
Destroy the object and stop the fiber. The sequence after this command does not execute.
The [End status] is refered by @ko command and CMLObject.onDestroy() in your program.

Label
Label a sequence and call the sequence after.

Define the label

#NAME {(sequence)} (NAME = [A-Z_][A-Z0-9_]*)
Label the sequence.
Label the sequence and call the sequence after. You can use upper cases, under bar ("_") and numbers as a labels name.

When you define a label in another label, the outside label behaves as something like a name space.
For example in "#A{#C{seqA} &C} #B{#C{seqB} &C}", label C in label A refers {seqA} and label C in label B refers {seqB}.

Refer the label

NAME[.NAME]* [Argument] , [Argument] ... (NAME = [A-Z_][A-Z0-9_]*)
Refer the label
Specifying the label name in a sequence directly, the sequence of specifyed label is executed as it is there.
The label can be set after & (Call sequence), @* (Create new fiber) and n*/f* (Create new object). And if you specify the label without any command, the sequence of specifyed label is executed as "@0" command does.
You can specify the arguments when you refer the label and you can get the arguments by "$1,$2..." in the labeled sequence. But, because the numbers (0-9) can be used as the label name, a space is necessary between the label and number.

Using the access operator ".", you can specify the name-space and label. For example in "#A{&B.C &C} #B{#C{seqB} &C} #C{seqC}", the "&B.C" in sequence A refers {seqB}, the "&C" in sequence A refers {seqC} and the "&C" in sequence B refers {seqB}.

User defined commands
Commands to call the function in your program.

&[a-z]+
Call the function in your program from a cml sequence.
You can call the function that is specifyed by CMLSequence.registerUserCommand() from your cml sequence. You cannot use "_"(under bar) in the command name.