CharCode Programming Language

Reference Manual

Contents:
Program format
Commands
Messages
Directions
Variables
Variable Scope
Expressions
Functions

Program Format

Besides direct commands, CharCode programs contain other statements that serve varying purposes. Each type of statement has an associated symbol:
 $  @  #  /  ?  :  '  !  `
Their meanings:
@objectname
When this is on the first line of an object, it identifies the object by name. If an object is not given a name, there is no way to direct messages to it except when using ALL and OTHERS.
#command
Identifies a programming language command.
/direction
Causes the object to move one space in the given direction. If it is blocked, it will wait until it is free.
?direction
Tells an object to try to move in a given direction. If its movement is blocked, the command will be ignored.
:label
Identifies the part of the program that handles a specified message. Whenever the program receives the message, it will execute statements following the label.
'comment
Comments have no effect, but serve to remind you (the programmer) what you were doing when you wrote the program. They also serve as "pre-zapped" labels which can be #restored.
text
When program execution comes to a line of text, the text will be displayed on the screen. If only a one-line message is given, it will be flashed on the bottom of the screen as a message. For multiple lines, a "scroll" will be opened up on screen and the text will appear. The contents of any window can be printed using Alt-P.
$text
This makes text white and centers it. It can be used for titles, dialogue, or just about anything! Note: this command does not work in a one-line message. It simply shows the $.
!msg;text
A hypertext-like button. When this statement is included among text descriptions, it appears to the player as a button... Then, as the user views the text, he may position the cursor on the button and press enter, causing the supplied message to be sent.
`expression`
Backticks evaluate a math expression and replace variables with their value.

Messages/Labels

An object can send and receive (exchange) messages with itself, other objects, and the game itself.

Messages caused by the game itself:

TOUCH(dir)
When player touches Program
SHOT
Program is hit by bullet
BOMBED
Bomb explodes near program
THUD(dir, x, y)
Program WALKs into wall
ENERGIZE
Player touches an ENERGIZER

Functions

All messages can be treated a functions with the #call command. When a function is called no other object can send that object a message except the callee. When a #end or #return command is issued in the function the callee picks up executing the next line.

Directions:

N, NORTH
S, SOUTH
E, EAST
W, WEST
Compass directions
I, IDLE
No direction, stationary.
SEEK
The direction toward the player, or the direction away from the player, if you are energized.
FLOW
The direction in which the object is currently walking.
RNDNS
Either North or South, at random.
RNDNE
Either North or East, at random.
CW <direction>
Clockwise from the given direction, i.e. CW NORTH = EAST
CCW <direction>
Counter-clockwise from the given direction. CW NORTH = WEST
RNDP <direction>
A random direction perpendicular to the given direction. For example, RNDP NORTH = either EAST or WEST
OPP <direction>
Opposite the given direction. i.e., OPP NORTH = SOUTH

Here are some example commands to demonstrate the use of directions:

#GO CW RNDNS 'Go either east or west.
#GO OPP SEEK 'Go away from the player.
#WALK CW FLOW 'Turn clockwise from the direction we're walking in.

Variable manipulation:

Objects can manipulate simple numeric variables. A variable assumes one of two possible states: SET and CLEAR. Objects can alter variables, then take action accordingly.
Variables are replaced within expressions and take the form of ${varname}

Flags are not associated with individual objects or boards. A flag set by one object can be accessed by all other objects on all boards.

Three commands are useful here:

#SET <variable> [<value>]
#CLEAR <variable>
Set and clear variables.
#IF [NOT] <flag> [THEN] <msg>
Tests the condition of a flag. If the flag is SET, the message is sent. Otherwise, the instruction is ignored.

If NOT is included, the message is sent if the flag is NOT SET. Otherwise, the instruction is ignored.

ALLIGNED
This flag is SET whenever the object is aligned with the player either horizontally or vertically.
CONTACT
This flag is SET whenever the object is adjacent to (touching) the player.
BLOCKED <direction>
This flag is SET when the object is not free to move in the given direction, and CLEAR when the object is free to move in the direction.
ENERGIZED
This flag is SET whenever the player has touched an energizer and can not be harmed by creatures and bullets.
ANY <color> <item>
This flag is SET if there are objects of the given type on the screen.
#IF [NOT] `expression` [THEN] <msg>
Tests the expression and if it evaluates to true or non-zero the message is sent.
If NOT is included, the message is sent if the expression is false. Otherwise, the instruction is ignored.

Variable Scope:

Global
${varname} Global variables can be accessed by any object and persist between boards.
Object
${this.varname} Object variables can only be accessed by the object and persist as long as object exists.
Label
${label.varname} Label variables are temporary in nature and persist until a #end or #return command. They are used for arguments when sending or calling a label.

Expressions:

Expressions are math statements such as `1+1` which evaluates to 2 or `2==2` which evaluates to true.

Programming commands:

All CharCode commands are preceeded by the pound sign (#). The following commands are supported:

Descriptions of commands:

#SEND <message>
Similar to basic's "GOTO" command. #SEND followed by the name of a label within the program will cause program execution to continue at that label.
Example:
:ABCDEF
...program loop goes here...
#SEND ABCDEF
#SEND <objectname>:<message>
Causes the execution of a different program to continue at a specified label within that program. By using this command, several creatures can be coordinated. For example, the player touches Creature A. Creature A tells Creature B to attack the player.
Example:
:TOUCH
#SEND CreatureB:AttackPlayer
Note: If the program receiving the message is in the locked state, the command will be ignored. See the #LOCK command for more information.

Note: If there are two or more programs with the given name, the message will be sent to all of them.

#SEND ALL:<message>
Sends a given message to ALL of the objects on the board.
#SEND OTHERS:<message>
Sends a given message to all objects on the board except the object itself. In all #SEND commands, the SEND may be omitted, but messages with the same name as a command can't be sent in this way.
#END
Causes program operation to halt. The object will just sit idly by until stimulated by a message.
#RESTART
Causes the program to go back to the top and start over.
#GO <direction>
Causes an object to move in a specified direction. The object will push boulders forward if they are in the way. If the object can not move in the given direction, it will stand by until either it can move, or it is stimulated by a message. In other words, it is equivalent to /.

Valid directions

#TRY <direction> [<msg>]
Causes the object to move in the given direction if it is not blocked. Otherwise, the given message will be sent.
#WALK <direction>
Sets the object moving in the given direction. The object will continue moving and executing commands. To cause a program to cease walking, issue the "Walk idle" command:
#WALK I
When an object WALKs into a wall, it automatically receives a THUD message. Unfortunately, it will keep going back to the same label over and over until #ZAP THUD is used.
#IDLE
Directs the creature to do absolutely nothing until it is updated next. Same as the /I command.
#ENDGAME
This command takes away all of the player's health, terminating the game. If the player has a high score, it will be recorded. Interestingly, if you immediately follow #endgame with #give health (n), the game will not be terminated, and the player's health will be set to n. Program execution continues past #endgame. In fact, only 3 commands halt program execution. #END, #DIE, and #BECOME.
#DIE
The object will instantly vanish when this command is issued. Program execution halts, and the object is erased from the screen. The game will continue on without it. It is equivalent to #become empty.
#SHOOT <direction>
Attempts to fire a bullet in the given direction.
#SHOOT SEEK 'fires a bullet toward the player
#THROWSTAR <direction>
Causes the object to throw a star in the given direction. The star will try to collide with the player. It is not recommended that you use stars in excess, as they are virtually impossible to avoid.

Throwstar WOULD be equivalent to #put <direction> star, but #put will destroy any fakes or water in its way.

#ZAP <message>
Disables the first occurance of a label by turning it into a comment. For example, #ZAP TOUCH would turn the label :TOUCH into the comment 'TOUCH. Allows a program to have several routines with the same labels, so that the desired label is called at the appropriate time. Remember that the #SEND command always calls the first occurence of a label. For example:
:TOUCH 'will be called first time creature is touched
"You touched me for the first time"
#ZAP TOUCH
#END
:TOUCH 'will be called all subsequent times
"You touched me again."
#END
#ZAP <objectname>:<message>
Zaps another object's label.
#RESTORE message
Changes a ZAPped label back into a normal label. Then, on subsequent calls to the label, the original one will be called instead of a secondary one.
#RESTORE <objectname>:<message>
Restores another object's label.

Note: <objectname> can be replaced with ALL or OTHERS to #zap or #restore labels of all objects or all other objects, respectively.

#LOCK
Puts a program into the "locked" state, so it will not be affected by any incoming messages. Often, conflicts occur when two messages are sent to a program in a short amount of time. The second message interrupts the program before it can finish handling the first one. However, if a program LOCKs itself when dealing with messages, it can not be disturbed.
#UNLOCK
Removes a program from the "locked" state, so it is free to receive incoming messages. Any messages that happened to arrive while it was LOCKed are lost.

:TOUCH
#LOCK
'code to handle "touch" message goes here...
#UNLOCK
#END
#GIVE <item> <quantity>
Gives a certain quantity of an item to the player. Good for giving bonus points, selling ammo, awarding extra health, etc.
Items: AMMO, TORCHES, GEMS, HEALTH, SCORE
#GIVE AMMO 10 ' gives the player 10 extra shots
#TAKE <item> <qty> [<message>]
Attempts to take a certain quantity of an item from the player. If the player does not have the given amount, none will be taken, and if a message is given, it will be sent.
#TAKE GEMS 2 TooPoor
"Thank you for the gems!"
#END
:TooPoor
"You don't have enough gems!"
#END

#PLAY <music>
Plays a musical score in the background as the game continues.
Music format
Parameters
T
32nd note follows
S
Sixteenth
I
Eighth
Q
Quarter
H
Half
W
Whole
3
Triplets: cut previous duration into thirds. For example, "Q3ABC" would play the notes A, B, and C, with all three taking up the time of a quarter note.
.
Adds time-and-a-half. For example, "H." would turn a half-note into a half-note tied to a quarter note.
+
Up octave
-
Down octave
Notes & rests
X
Rest
A-G
Piano notes, can be followed by:
#
Sharp
!
Flat
Rythmic sound effects
0
Tick
1
Tweet
2
Cowbell
3
(no effect, denotes triplet)
4
Hi snare
5
High woodblock
6
Low snare
7
Low tom
8
Low woodblock
9
Bass drum
Other notations
[]
Open and close brackets let you separate music code into parts. They are much like comments.
#CHANGE <kind> <kind>
Changes every specified item on the board into another item. <kind> is the name of an item, creature, or terrain as listed in the editor, but with all punctuation and spaces removed. LINE, BULLET, EMPTY and STAR are also valid values for <kind>.
#CHANGE LION GEM
'Turns all lions on the board into gems.
#CHANGE KEY SLIDEREW
'Changes all keys into east-west sliders.
#CHANGE RED KEY CLOCKWISE
'Changes all red keys into clockwise conveyors.
Names of Objects
#PUT <direction> <kind>
This causes a specified item to be placed adjacent to the object issuing the command.
#PUT N BLUE KEY
'Places a blue key north of us.
#PUT SEEK TIGER
'Puts a tiger in the direction of the player.
Names of Objects
#TRYPUT <direction> <kind> [<msg>]
This causes a specified item to be placed adjacent to the object issuing the command. If item cannot be placed msg will be sent.
#BECOME <kind>
Causes the object to suddenly change form into a specified item or creature. The object's program then ceases to exist.

Names of Objects

#CHAR <number>
Causes the object to change form, so that it is represented on the screen as a different character. <Number> can range from 0 to 1023, and should be the ASCII code of the new character.

#CYCLE <number>
Sets the speed at which an object is updated. This can range from 1 (fastest) to 255 (ridiculusly slow). When no CYCLE speed is specified, it defaults to 3.
#BIND <objectname>
When a Program executes this instruction, its code will be replaced by the code of another object, and it will start executing instructions from the beginning.

This is a useful and space-saving technique. Rather than creating ten objects with the same program (which would be stored in memory ten times), create one object with the program, and nine others that contain only a BIND statement.

#RETURN <number>
#RETURN is an alias of #END. It can be used to return control back to the program that called a function with an optional value.
#PATH <set> <"directions">
#PATH <run>
#PATH is useful for creating a movement path for an object. If a message interrupts it the last movement is saved and will continue on the next #PATH RUN.
#path set "eennwwss"
:loop
#path run
#send loop
#DRAW <overlay> <x> <y> <chr> <bgcolor> <fgcolor>
#DRAW <set> <x> <y> <chr> <bgcolor> <fgcolor>
#DRAW <clear> <x> <y>
#DRAW is useful for animations. It can write to the active object or overlay layer. It is only for display purposes, objects cannot interact with what is drawn.
#CREATE <x> <y> <kind> [<msg>]
#CREATE creates an item at any position on the board. If object cannot be placed at specified position msg will be sent. Names of Objects
#MOVETO <x> <y> [<msg>]
#MOVETO teleports object to any position on the board. If object cannot be placed at specified position msg will be sent.
#MIRROR <objectname>
#MIRROR causes movement to be matched. If object moves all mirroed objects will move. If one mirrored object cannot be moved none of them will be moved.
#STATS <add> <name> <varname>
#STATS <remove> <name>
#STATS allows custom items to be displayed within the status menu.
#ACTION <add> <name> <msg>
#ACTION <remove> <name>
#ACTION allows custom actions to be created. When user does new action the msg will be sent to the SYSTEM object.
#REGISTER <name> "<classes>"
#REGISTER allows custom object types to be created for use with other CharCode commands.

The following registers a new type called "shell"

#register shell "gravity=true|movex=true|movey=true|cpumove=true"
#char 31
#walk flow
#cycle 0
#set this.cntr 0
:loop
#set this.cntr `${this.cntr}+1`
#if `${this.cntr} <= 10` then #char 31
#if `${this.cntr} > 10` then #char 118
#if `${this.cntr} > 20` then #set this.cntr 0
#loop
:hurtplayer
Ouch!
#take health 10
#SOUND effect play hurt
#die
:reverse
#walk opp flow
#SOUND effect play bump
#end
:thud(dir, x, y)
#zap thud
#if `${this.x} <= 0 OR ${this.x} >= ${board_width}-1` then #die
#query pos `${label.x}` `${label.y}` ".enemy=shot|breakable=destroy|
...   @prizebox=touch(`SOUTH`)|SHELL=#die|player=shot" label.idx
#if `${label.idx} == 4` then #call hurtplayer
#if `${label.idx} == 3` then #die
#if `${label.idx} != 0` then #call reverse
#restore thud
#loop
#end

The following removes the action "SHOOT" and adds a new action called "Shell". It also creates a variable called "shells" set to 15 and adds it to the Status Menu.

#action remove shoot ' remove shoot action
#stats remove ammo ' remove ammo from status menu
#action add Shell onactionkick ' add new action called shell
#set shells 15 ' create a counter for new item
#stats add Shells shells ' add it to status menu

The following is added to the global "SYSTEM" object and processes the new action

:onactionkick(dir)
#if `${shells} <= 0` then #end
#set shells `${shells}-1}`
#if `${label.dir} == NORTH OR ${label.dir} == SOUTH` then #end
#tryput `${label.dir}` #ffffff shell
#SOUND effect play kick
#end
That's a complete example of a new type, status menu item, and action.
#FGCOLOR <csscolor>
#FGCOLOR causes objects foreground color to be changed. It supports all CSS colors.
#BGCOLOR <csscolor>
#BGCOLOR causes objects background color to be changed. It supports all CSS colors.
#QUERY <dir> <direction> "<query>" [<return>] <varname>
#QUERY <coords> <x> <y > "<query>" [<return>] <varname>
#QUERY is an extremely versatile and useful command. It allows a position on the board to be queried with a set a rules and returns the index of rule that it matches. It will return -1 if not rule is matched.
#query dir W ".enemy=shot|breakable=destroy|@prizebox=touch(`SOUTH`)|
...   SHELL=#die|player=shot" return label.idx

The above queries west of object.
If that position has an object of class "enemy" it will send the shot message to it.
If the position is a "breakable" it will be destroyed.
If its name is "prizebox" touch will be sent to it.
If its type is "SHELL" it will be killed.
If its type "player" shot will be sent to it.

Finally it returns the index of the match in a label variable call idx.
#SOUND <load> "<url>"
#SOUND <play> <msg when done>
#SOUND <stop>
#SOUND <volume> <0.0-1.0>
#SOUND <pause>
#SOUND <effect> <play> <sfx>
#SOUND <effect> <stop> <sfx>
#SOUND allows MP3s to be loaded and played through a HTTP URL.
:loop
#SOUND load "/mysound.mp3"
#SOUND play loop

A list of built in sound effects are: tick, explode, hurt, shoot, jump, item, spring, dooropen, hookshot, sword, shield, kill, forest, energizer, deflect, torch, push, and bump.
#CALL <objectname>:<message> [[<return>] <varname>]
#CALL <message> [[<return>] <varname>]
#CALL is similar to #SEND except that when the called program encounters an #END or #RETURN the next line continues processing.