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 cybwhere 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:

ON ENTER {
    "Hello" SAY
}

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.