 |
When We Were Very Young
A Cyborg Primer and Glossary
Confused by all the mumbo jumbo? Still wondering what the heck an "atom" is? Here are some key principles and keywords
for the novice iptscrae hacker (or the casually-interested BotBot user).
|
 |

Cyborg.ipt
|
Cyborg.ipt is a plain-text file
that contains your personal cyborg
script. It can't be edited directly from within the Palace client,
but can easily be altered by any capable text-editing program such
as wordpad, teachtext, BBEdit, Alpha, emacs, vi, vim... or made by the BotBot.
The script is a program,
written in Palace's own iptscrae language.
If you can handle basic HTML, you probably can handle simple
iptscrae, but we'll get to that later on. If you want to see some
sample iptscrae code, build a cyborg with the BotBot; or check out this example cyborg.
To be used, the cyborg.ipt file
must reside in the same directory/folder as your palace client
program ("Palace"). See the illustration at right to see a typical
Macintosh directory (Win95 looks about the same). The cyborg will
be loaded automatically by Palace at the time you first sign-on.
Most cyborg.ipt files are
arranged with four main sections, blocks of instructions for each
of the main event traps
; Sample Cyborg.ipt structure
ON SIGNON {
; Commands to run when you first sign on
}
ON ENTER {
; Commands to run when you enter a new room
}
ON INCHAT {
; Commands to run when people talk to you
}
ON OUTCHAT {
; Commands to run when you talk
}
|
As you'll see below, all these blocks are optional, and other
blocks (such as macro traps) are also available.
Any text following a semicolon,
; like this....
is considered a comment by the Palace, and ignored. This lets
us add notes and annotation to any script. Here at the House of
Bots we also mark such comments
; in
red for clarity
but actual scripts don't contain color.
|
Iptscrae
|
Iptscrae is pig-latin for "script." Some folks think it should be
"iptscray" but hey the romans never spelled anything like that in
the first place (Iptscræ?).
Iptscrae is a pretty simple language, as computer languages go
more
complicated than HTML, less complicated than Java (by a long
shot). To compare with some commonly-compared languages...
Language |
Similarities |
Key Differences |
Forth |
RPN.
Integer numbers only. |
No incremental compilation iptscrae is always interpreted.
Iptscrae recognizes strings and arrays as basic data types.
No overriding of built-in functions.
Iptscrae requires EXEC to run user-defined code blocks. |
Postscript |
RPN.
Special purpose not intended (originally) as a
general-purpose programming language. |
Same as Forth, plus: Postscript allows
floating-point math. Iptscrae doesn't have anything analagous to
Postscript dictionaries etc. |
Javascript aka "J-Script" |
Event-driven.
Special purpose dedicated to a single application
program (your browser). Interpreted, rather than compiled. |
Iptscrae has no cookie interface.
Javascript is object-oriented and uses
infix notation, rather than RPN.
Microcrosoft is not trying to steal control of Iptscrae
away from the rest of the world. |
Hypercard |
Event-driven.
Special purpose dedicated to a single application
program. Interpreted, rather than compiled. |
Iptscrae has no file access commands.
Less control of the user interface for iptscrae.
Infix rather than RPN.
|
BASIC |
Interpreted (yes, BASIC can be
compiled...). Supposedly common
across all platforms (yeah, yeah, tell it to Microsoft). |
Iptscrae's not a general-purpose language.
Iptscrae has no file operators.
BASIC is infix, not RPN.
No line numbers in Iptscrae, ever.
|
C and C++ |
Both created by humans
to run on late 20th-century computers. |
Similarities mostly end there.
Since the iptscrae interpreter was probably written
in C, it's pretty much guaranteed to always be slower
(as if you didn't know that). |
Legend has it that Iptscrae was originally designed for
programming TV set-top boxes. Go figure.
A common typo when writing
"ipstscrae" is "iptscare." It's up to you to decide if that's
deserved.
|
RPN:
Reverse
Polish
Notation
|
Iptscrae uses "Reverse Polish Notation," also known as postfix
notation. What this means is that actions (verbs) come
after the things they change (nouns usually numbers).
A classic example of this is
iptscrae addition. Instead of writing
2 + 3
in the usual ("infix") style, we write
2 3 +
In english, we can think of it as being "two and three, added"
instead of "two plus three."
Ugly? Counter-inituitive? Yeah,
probably. Iptscrae does things this way because technically, it's more
efficient for the computer to do it this way
(and thus Iptscrae joins some
famous company, such as the Postscript and Forth languages and some flashy high-end calculators). (If you're like
me,
you'd rather see it be easy for the user than for the computer...
but then, you and I didn't create this, heh)
Some human languages also
use the verb-last convention French (j t'aime "I you
love"), German (pretty strictly), and Japanese (absolutely
always without variance!). Even English uses verb-last in
some archaic and/or highly-formal circumstances (showing its
Norman French roots...), such as: "with this ring, I thee
wed."
What all postfix languages
share is the notion of a stack each
command either puts values onto the top of a stack of values,
or pulls values from the top of that stack. What
2 3 +
actually does is execute three separate actions, one for
each word:
- Put the value "2" on top of the stack.
- Put the value "3" on top of the stack.
- Take the top two values off the top of the stack,
add them
together,
and drop that back on the stack in their
place.
All programming languages actually have an internal stack, but only RPN
languages actually let you see and tweak the stack yourself.
Still confused? Try it yourself in Java...(use the "enter" key
to put spaces between the numbers....)
RPN and the stack permeate all
iptscrae commands. For example, instead of
if (condition) {
commands }
as you would find in languages like C, instead we have
{ commands } condition IF
in iptscrae.
One side
effect of RPN: you never need parentheses, because the order of
words determine their precedence. So instead of
Q * (3 + P)
to force the addition to happen first, we simply write
P 3 + Q *
(those {braces} on the IF statement above aren't parentheses,
they're an atom list, which is described later)
I know, it's weird.
Just repeat the mantra: "subject first, predicate last."
(Helpful, huh?)
And yes, there actually is a
"forward Polish notation," actually developed by a famous Polish
mathematician and taught to schoolchildren across eastern Europe
for many years, up until the turn of the century. It's also known
as "prefix" or "Leibniz" notation. The programming language "Lisp"
uses prefix format (and to a lesser extent, so does TCL).
|
Events,
Traps,
and
Handlers
|
Iptscrae is an event-driven language. Rather than writing a
program in iptscrae and running it, we make chunks of iptscrae
code which simply sit around until they're triggered by
significant "events." The scripts react to these events, rather than
taking independant action. Iptscrae "events" are typically things like
incoming speech balloons ("ON INCHAT"), room or macro changes ("On
ENTER," "ON LEAVE," and "ON MACRO3"), etc. Here's a short
list of the most commonly-scripted events, arranged in the order I
like to use them in the cyborg file (like this example):
Event |
What It Be |
SIGNON |
This event normally only occurs once during an entire
session just at the moment that you sign-on
by using the Palace "Connect..." menu. Note that the
SIGNON will not occur whenever you switch
palaces via jumpstations and so forth only through the
menu. Usually used to initialize scripts and set the
default macro. |
ENTER |
This event occurs once as you enter every room (even if
a SIGNON event has also occured). |
LEAVE |
This event only occurs once when you leave a room.
Note that it actually occurs the last moment before you
leave the room, not after.
|
INCHAT |
This event occurs between the time your computer
receives incoming text (even if you said it) and
the time that the text is displayed on-screen as a
balloon. The text is in the variable CHATSTR
and can be changed (even fully deleted) to your liking
which may chnage the ballon display
on your computer, but won't affect ballons on other
people's machines or in your session log. Note too that
INCHAT does not catch whispers, ESP,
global messages, room messages (white balloons),
or wizard pages. |
OUTCHAT |
This event occurs between the time you hit RETURN
when talking and the time the text is sent out to the
server. As with INCHAT events, the spoken text
is in the variable CHATSTR and you may change
or delete it at whim within the OUTCHAT
handler.
Most of the time, when
people say "I have a script..." they mean a script snippet
that goes into the OUTCHAT handler. Many (most?)
common script features are launched by entering an
OUTCHAT keyword like "zap," with the script also
usually dutifully setting CHATSTR to "" (empty, no
text) when launching such a word-driven command.
|
MACRO0 ... MACRO9 |
These events occur for macros 0 through 9. If you set
one of these macros in your cyborg file, the cyborg action
will replace the macro costume change.
There's no way to trap the "higher"
macros such as shift-control-macro-4. Just the basic set
of zero through nine.
|
A cyborg.ipt doesn't have to respond to every kind of event, and
most cyborg's don't. Untended events just "fall through" and
nothing special happens script-wise.
To "catch" an event, the cyborg
contains a trap, also known as a handler or as an
event block. It's a block of iptscrae commands bundled
together inside {braces} and with an event tag. As an example,
here's a super-simple ENTER trap:
Every time a user with this script enters a new room, their avatar
will say "Hello."
The basic pattern for any
handler is:
ON event_name { commands }
(yes, the part inside {braces} is an atom
list)
Some other more-esoteric events, such as SELECT, also
exist
they're reserved for use by room scripts, which are also written in
iptscrae (but which are outside what we talk about here at the old
House o Bots go to the House o Houses instead).
One occasionally-important room-script fact, however room
scripts may have their own OUTCHAT and other events. The
room script gets to run its event handler first.
|
Atom Lists
|
An atom list is any collection of iptscrae commands
and/or values enclosed in {braces} i.e., a list of "atomic" iptscrae
words. Once created, an atom list exists as one item on the
top of the stack -- even if it contains other atom lists. It can
be assigned to a variable name using the DEF command, it
can be SWAPped, etc.
A number of iptscrae commands expect that one or more of their
arguments (top-of-stack values) are atom lists:
Command |
What It Does |
atomList EXEC |
The contents of the atomList are executed
immediately, just as if they were part of the
current scope.
|
atomList delay
ALARMEXEC |
After delay ticks (a "tick" is 1/60th of a second),
the atomList will be executed independantly.
|
atomList name DEF |
Assigns the atomList to the variable name
just like using "=" to assign values to a variable name.
Name can thereafter be used in place of the
atomList for commands like EXEC.
|
atomList condition
IF |
If condition is non-zero, the atomList
will be EXEC'd.
|
yesAtomList noAtomList condition
IFELSE |
If condition is non-zero, the yesAtomList
will be EXEC'd. Otherwise, the noAtomList
will be EXEC'd.
|
doAtomList evalAtomList
WHILE |
The doAtomList will EXEC repeatedly. Each
time, the evalAtomList will also be EXEC'd
if evalAtomList leaves a zero
value on the top of the stack, doAtomList will
stop looping. Looping can also be stopped by pressing the
ESCAPE key (just in case....).
|
atomList array
FOREACH |
Each value in array will be placed on that stack
in turn, and the atomList will be EXEC'd
for each value.
|
ON
eventName atomList |
A rather non-standard construction, but this is how we
create event handlers.
|
|
Functions
|
Functions, also sometimes known as procedures (Pascal
language) or subroutines (BASIC or FORTRAN), are collections of
commands that are bundled together so that you can use them over
and over again. In iptscrae, functions are collected as an atom list and usually stored as a
GLOBAL (typically in the SIGNON event handler). They can then be run at any
time by declaring the function as GLOBAL, entering the
name of the function and following it with EXEC.
Note to C/Pascal programmers
and their ilk: iptscrae makes no distinction between "functions" or
"procedures." All arguments and returned values, if any, are passed on
the stack.
|
|