Command | Type | Description |
<Value1> = <Value2>
<Value1> += <Value2>
<Value1> -= <Value2>
<Value1> *= <Value2>
<Value1> /= <Value2>
<Value1> &= <Value2>
<Value1> |= <Value2>
<Value1> ^= <Value2>
<Value1> >= <Value2>
<Value1> <= <Value2>
|
assign |
Assigns (or operates on) the two values. Value1 must be of
variable type. Most of these can be recognized by those proficient in C/C++.
All operators work on the level of the highest number of bits entered that
appear of the two arguments, with the exception of the two last shift
operators. Assign, add, subtract, multiply, divide, bitwise and, bitwise
or, and bitwise xor supply sign-extensions and zero extensions as needed for
values of different bit sizes, but left shift and right shift will take
only an integer as the number of bits to shift. |
flags <flag changes> |
assign |
Changes the flags of the current object. See the overview
for notation on assigning flags. This command is not to be confused with the
flags variable, which belongs to every object. The command is just a quick
way of setting or clearing flags of the current object. |
neg (<Value>) |
assign |
Negates Value, which must be of variable type. |
addvect <Coordpair1>, <Coordpair2> |
assign |
This is a nice way of assigning coordinate pairs without
the need to conjure up so much trigonometry each time a polar-rectangular
conversion of coordinates needs to be done. The vector quantity Coordpair1
is added by Coordpair2 and the result is left in Coordpair1. Either
rectangular or polar coordinates can be used for either coordinate pair
specified--the command is smart enough to know which conversions to perform
so that the type of the coordinate pair will always match Coordpair1
(rectangular or polar). Both values of Coordpair1, of course, must be
of variable type. In this command only, one does not need to apply the
plus and minus prefixes to signify that the coordinates are rectangular
vectors instead of absolute coordinates; it's obvious that they are. |
end |
control |
Ceases command flow. Once an object stops executing opcodes,
the only way to "wake it up" is by sending it a message. This is one way
to end an object's frame turn. |
goto <label> |
control |
The command flow jumps to the specified label. Jumping to
other parts of the program do not constitute an end-of-frame-turn. If
a loop is implemented with a goto, end-of-turns (such as wait commands) must
be inserted or else the loop will continue using the same frame turn. |
order (<object pointer>, <label>) |
control |
Sends the message label to the object specified by the
object pointer. Because each object has its own turn, the message will not
be recognized until the receiver executes its own turn. |
if (<conditional expression>)
<dothiscommand>
[else
<dothatcommand>]
or
if (<conditional expression>)
{ <multiple commands>
}
[else
{ <multiple commands>
}]
|
control |
Checks whether the condition is true. Executes the next
command if it is and skips it if it isn't. Not much to explain here. |
wait (int n) |
control |
To end a turn, use this command to wait n frame turns before
executing more opcodes. This command is vital for all sorts of timing.
Note that the current frame turn counts as one frame that might be waited
out, regardless of how long the frame turn actually takes to run to
completion. Thus "wait (1)" will wait at most one frame; however long
it takes to complete the opcode interpretation is absorbed within this
"waited" period. |
stop |
control |
To end the game sequence, use this command. This is a kind
of "global breakpoint" that passes all control back to NIB.EXE. Various
global variables must take on meaningful values so that the conditions of
the stoppage can be determined. For example, a stop command may occur upon
completion of the level, but if no correct end-of-level parameters are set,
a stoppage usually signals an erroneous procedure in object code. |
pause (int n) |
control |
This is not to be confused with wait. The pause command
pauses all action for the number of frame turns given. It is only
helpful to use the pause command when some sort of "slow-mo" animation
is needed for all objects. |
resume |
control |
If a message has been generated, the current object saves
information about its previous script location. The resume command goes back
to this location as if the message had not been sent. An object will only
be able to resume a previous script location if it is on the same frame
turn generated by the message. If an end-of-frame-turn is encountered,
the resume location is lost. |
switch (int n) { <statements> } |
control |
The switch statement uses a braced block to handle a range of
possible values for a variable. It works just like a switch statement in C/C++,
except the switch case labels are denoted with question marks instead of "case".
There is also no "break" clause; the goto command must be used to prevent case
fallthrough. For all practical purposes, program flow can jump in and out
of a switch control block with much liberty. The "block" is largely
superficial; it just feeds the command interpreter a series of labels to
jump to given certain conditions. |
place <Coordpair>, <Objname> [, <localvar1> =
<initval1>, <localvar2> = <initval2>...] |
control |
Creates an object at the specified location. The new object
will execute its first frame turn during the current frame. The optional
initial values that can be assigned to the new object can follow in any
number. These initial values will, in nearly all cases, override those
values defined as defaults in the script header of that object. One should
recall that the local variables have the scope of the new object, not
the current object. See the function variant of this command if one desires
to generate a pointer to the new object. |
call <label>
call <label>(param1)
call <label>(param1, param2) |
control |
Objects can employ "internal methods," or short subroutines
without changing scope. One needs only specify a label and optional parameters.
The optional parameters are passed to the subroutine in the form of n1 and n2,
two long global variables.
While subroutines give some rudimentary semblance of C/C++ functions to this
language, they are not all-powerful. The "wait" command is not allowed inside
of a subroutine, since the object's stack pointer is lost when control passes
to another object. The "end" command and all termination commands, however,
are permitted inside a subroutine. |
return |
control |
A return command ends a subroutine. One should not confuse this
command with resume, which takes effect only with messages. |
move <Coordpair> |
move |
Moves the current object to the specified location in
Coordpair. This command will act as a "space hog." In other words, it
causes movement regardless of what tile or object the current object moves
into. If the block flag is set on both the current object and the object
that is hit, a hit label will be generated in both objects. A frequent way
to generate messages without moving is "move |". |
moveoff (<object pointer>, <direction>) |
move |
Moves the current object away from the object specified by
the pointer, in the direction given. The direction must be a cartesian
direction (0, 64, 128, 192). The movement will evaluate the sprite
boundaries of both the objects and position the current object so that both
objects are "not touching" each other. No message will be generated between
each of the two objects by the move, but it is possible the current object
will interact with a third object, which can generate messages. |
moveobj <Coordpair>, <object pointer> |
move |
This is the "remote-control" variant of "move." Instead of
the current object moving, the object specified by the pointer will move.
This remote object is susceptible to messages from collisions from the
move. This is a commonly used command with objects that are composed of
multiple sprites. |
getongrid |
move |
To position the current object so that it fits completely
within the visible coordinate space, use this command. If an object gets
"lost" from the grid, this is kind of a quick teleport. Messages can be
generated from the repositioning. |
tilelock |
move |
Since Nibbler has square-based walls and obstacles, it is
often desirable to center an object at the nearest square. This command
centers the current object at the nearest square. Messages can be generated
from centering an object. After this command is invoked, the function
"centered" will always return true. |
testpoint <Coordpair> |
move |
This is a command that prepares an object for movement
without actually moving or generating messages. The coordinate pair marks
the new center of the current object after the move. After the command
has been executed, the global variables dxstraight, dystraight will contain
the diagonal vector offset to test in the general direction of the move, and
dxleft, dyleft, and dxright, dyright will contain, respectively, the flanking
"left" and "right" corners to test. This command takes the object's sprite
as an implicit argument to form a basis for the points to test. The result
is most useful with objects that behave as if they are "bouncing" off walls. |
predict (int objptr, int time, long mag, char dir) |
move |
For a simple puzzle game, differential vector correction
is not terribly important, but it can still be invoked with this command.
An object at the pointer is assumed to be stationary or moving at a constant
speed. The "time" value is the amount of time (in frames) that the current
object will use to close the distance between the two. The values "mag" and
"dir" represent the speed and direction of the object to intercept. The idea
is that the current object can move at constant velocity for the amount of time
given, and at the end of that interval, the object specified by the pointer
will be intercepted. Obviously, this command falls short of being able to
intercept a moving target that changes speed or direction. The destination
is obtained by moving at (+xpredict, +ypredict) for "time" frame turns, where
xpredict and ypredict are global variables set upon completion of this command.
|
fliphoriz (int asprite) flipvert (int asprite) |
display |
These commands take the arguments as if passed by reference.
The horiztonal or vertical flip flags, respectively, are XOR'ed, and the
result is left in "asprite." |
zmove (char height) |
display |
This command changes the drawing order (z-value) of the
current object. The value of z can range from 1 to 127. Higher values of
z are later in the drawing order (appear to be in front of other sprites.)
The secondary grid is always drawn at z == 20, so take this into
consideration when assigning z-values. |
msg ("Message text") msg1 ("Message text") |
display |
These two commands display messages that appear in the
comment box at the lower right corner of the screen. The "msg1" syntax
causes the comment to act as a hint (it displays only once and shows
a pointer from the comment box to the current object for a brief period).
The "msg" syntax will treat the message as standard dialogue (it displays
every time the command is executed, and no pointer will be displayed). |
subs (int matrixval, int loadoffset, int sprite, char pal)
subset (int matrixval, int arrayfirstelement, char pal) |
display |
The two substitution matrix load commands are tough to
use unless you are familiar with the science behind them (see the section
on advanced graphics for more details). The first command version is the
"single square" load command; the second version is the "multiple square"
load command.
The "single square" load requires a substitution matrix value (just plug
in the variable associated with a matrix definition), a load offset
in the matrix (MX_HEAD, MX_HEADBOD, MX_BODY, or MX_BODTAIL), an opaque
sprite to fill the position, and a palette change (if desired) number.
Although such substitutions require a lot of memory transfer per command,
I have never noticed any slowdowns that seemed directly related to such
commands.
The "multiple square" load assumes that an integer array of three sprites
will constitute the basis for the entire matrix, not just a single square.
Four substitutions take place when this command is executed. This type of
substitution is done whenever a matrix needs a complete makeover. For
example, when the snake is reversing direction, the subset command is used
to rapidly change the snake's appearance with very few programming tricks.
|
lsound (int num) |
sound |
Generate a "localized" sound that plays once. The sound
generated is called localized because it does not take into account the
inverse square law or the point of reference of the listener. Upon
execution of the command, the sound plays and cannot be stopped. Sound
identification numbers are defined in "nibsound.h". |
stopsound (int handle) |
sound |
Stop a global or ambient sound from playing. The handle is
returned with the sound and ambsound functions, and this
handle should be kept by an object that wishes to abort the playing of
a sound in mid-play. |
stopstype (int num) |
sound |
Stop a particular type of sound from playing. Instead of
stopping a single sound specified by a handle, this command searches for
any sounds that match the identification number provided, and halts them.
This is useful when several of a single type of sound will be played in
a rapid succession, but resonance and excessively high volume are not
desired. |
die dissolve explode
fall flash splash vanish |
terminate |
Use these commands to tell an object to pass on. Each
command will cause the object to end its frame turn, which is followed by
the removal of the object. NIB-OOL allows only for objects to remove
themselves; objects cannot "remote-remove" other objects. The difference
between the commands is the special effect that takes place upon removal.
The command "die" has no special effect. |
plummet (char ground) |
terminate |
This is the only "conditional terminator" command in
NIB-OOL. The object will terminate only if ground (which should be the
value of a floor tile) is a specific tile. A pit will cause the "fall"
special effect, water will cause the "splash" special effect, and acid
will cause the "dissolve" special effect. If none of these conditions
are true of the floor tile, no termination will occur. |