HamsterSpeak Specification

From OHRRPGCE-Wiki
Jump to: navigation, search
Revise.png
This article does not meet the standard of quality we would like to have. Feel free to revise it and make it better by using the edit link at the top of the page. This tag should be removed when an editor feels it is of high quality.

The reason this article has been marked is: This page is out of date, is too incomplete and too informal to be a good reference, and at some point will be replaced with a new specification and a proper "HamsterSpeak for programmers" article


HamsterSpeak is the scripting language used by the OHRRPGCE. For historical reasons scripting is referred to as plotscripting. HamsterSpeak is compiled by HSpeak compiler which parses scripts and converts them into a binary format that can be executed by an interpreter such as the one built into Game. This article explains most of the syntax and reserved words for HamsterSpeak, though it is a bit out of date.

This document may appear ovewhelming to non-programmers, so instead, you will want to read the Plotscripting Tutorial, which is written for beginners, and the Dictionary of PlotScripting Commands, which also documents language features like flow control constructs and strings. On the other hand this document isn't written for programmers either.

Syntax[edit]

HamsterSpeak function and variable names are case insensitive and whitespace insensitive. The following are all valid ways of writing the same command:

Suspend Player
suspendplayer
sUsPeNdPlAyEr
Susp Endpla Yer

Remember this when you are naming your scripts and variables.

Statements are separated by commas or newlines. Blank lines are ignored, and double commas are treated as single commas. You can use commas and newlines interchangeably. For example, the following blocks of code are the same:

Suspend Player
Suspend NPCs
Suspend Obstruction
Suspend Player, Suspend NPCs, Suspend Obstruction

You can use the # symbol to put comments in your script. Anything from the # to the end of the line is ignored.

walk hero, begin
  me      # who does the walking? Me!
  north   # this is the direction we want to walk
  3       # this is how many tiles we want to go
end

Argument lists[edit]

Most HamsterSpeak functions take arguments. The arguments for a function follow it between parenthesis. The following are examples of HamsterSpeak functions:

walk hero (me,north,3)
wait for hero (me)
show text box (37)

Also, as an alternative to using parentheses, you can write begin and end. It's common to use begin and end for constructs like script and parantheses for function calls.

The following blocks of code do exactly the same thing

walk hero (me, north, 3)
walk hero, begin
  me
  north
  3
end

If you pass no arguments to a command or script then you can omit the parentheses altogether:

wait, fade screen out, wait, fade screen in

However an empty pair of parentheses in other contexts, such as after case, may not be optional.

Argument lists are processed after processing operators. This is significant when operators require commas around their name, such as mod (modulus, written as %' in most programming languages). The following function invocation:

put hero(0, 100 + x, mod, 20, 200 + y, mod, 20)

is equivalent to:

put hero(0, (100 + modulus(x, 20)), (200 + modulus(y, 20)))

Obviously the first way is very unreadable and you should put parentheses around the expressions!

References[edit]

Script references[edit]

A few commands such as set timer need a reference to a script. Put an @ sign at the beginning of a script name to get the script's ID number. This reference can be stored in a variable or passed as an argument.

You can call a script using its ID number using the run script by ID command.

Global references[edit]

You can get the ID number of a global variable by putting @ in front of its name.

Declarations[edit]

script and plotscript[edit]

Most of the code in HamsterSpeak is in plotscript statements. plotscripts can be triggered directly by various events in your game. scripts can be run by other scripts and plotscripts. The only difference between a script and a plotscript is that scripts are never shown in Custom.

Here is a sample script

plotscript, My Script, begin
  # code goes here
end

Arguments are extra pieces of information that can be given to a script. Here is a sample script with arguments:

# This script has three arguments, the last two default to zero,
# while the first is mandatory.

plotscript, My Fancy Script, firstarg=0, secondarg=zero, begin
  # This script can use the arguments by name
  # just as if they were local variables
end

You can call scripts by using their names, just like you call built-in functions.

plotscript, my script, begin
  my other script
end

plotscript, my other script, begin
  # this script is called by the other one
end

subscript[edit]

Subscripts are scripts embedded inside another script (or plotscript or subscript). See subscript.

defineconstant[edit]

plotscr.hsd also has some constants to make life easier. Thanks to constants, there is no need to know what numbers plotscripting uses to internally represent things. The following are some of the constants defined in plotscr.hsd

zero, one, two, three, four, five, six, seven, eight, nine, ten, false, true, off, on, north, east, south, west, up, down, left, right, upkey, downkey, leftkey, rightkey, usekey, cancelkey, menukey, anykey, me, none...

Another use for constants is the ability to refer to heroes, maps, songs, items, and all sorts of other things in your RPG by name instead of by number. CUSTOM.EXE can export an include file from its Script Management menu that is full of constants that represent the names in your RPG. This file will have the same name as your RPG file, with the extension HSI (HamsterSpeak Include), and it will be automatically included into your script the exact same way that the plotscr.hsd file is automatically included.

In older versions, it was required that you manually include the hsi file yourself, so don't be surprised if you see old script examples with the line:

include, mygamename.hsi

You can add your own constants to your script with a defineconstant statement

Define Constant (1000,thousand)

plotscript, My Script, begin
  # now I can use the word thousand instead of 1000 in my script
  get money (thousand)
end

Operators[edit]

Almost all of the math and logic operators can be written either infix or as functions. You can use whichever you prefer (the first version of HSpeak did not support infix operators). The exception to this is the and or and xor commands. You must use the infix style.

The correspondence between infix operators and functions is actually defined in plotscr.hsd (see #defineoperator) instead of built into HSpeak.

The following table groups together operators with the same precedence, and all operators are left-associative; for example * and / are in the same block, so a*b/c is (a*b)/c while a/b*c is (a/b)*c. However * is higher than +, so a+b*c is a+(b*c) as expected. Note that in other programming languages, exponentiation, :=, +=, and -= are usually right- instead of left-associative. In HamsterSpeak you have to write a := (b := 3) to assign the same value to two variables.

Precedence blocks Operator Alternative Syntax
n ^ n exponent(n,n)
n * n multiply(n,n)
n / n divide(n,n)
n, mod, n modulus(n,n)
n + n add(n,n)
n -- n subtract(n,n)
n == n equal(n,n)
n <> n notequal(n,n)
n < n or n << n lessthan(n,n)
n > n or n >> n greaterthan(n,n)
n <= n lessthanorequalto(n,n)
n >= n greaterthanorequalto(n,n)
n, and, n and(n,n)
n, or, n or(n,n)
n, xor, n xor(n,n)
a && b logand(a,b)
a || b logor(a,b)
a ^^ b logxor(a,b)
v := n set variable(v,n)
v += n increment(v,n)
v -= n decrement(v,n)
dest $+ src concatenate strings(dest, src)
dest $= src copy string(dest, src)

Note that there are no unary operators at all, such as negation or logical and bitwise complement! ("-10" is a constant, not negation applied to "10".) However, there is the not() function for logical complement/negation.

The @ prefix to get a global or script reference is not an operator.


Math[edit]

Math operators take the value on their left, and the value on their right, perform math on them, and return the result.

plotscript, Math Sample, begin
  variable (n)
  n := 100    # we start with 100
  n := n + 5  # now n is 105
  n := n * 2  # now n is 210
  n := n -- 6 # now n is 204
  n := n / 4  # now n is 51
  show value (n)
end

The complete list of math operators is documented in the Plotscripting Dictionary.

Notice that the symbol for subtract is --. This is necessary to avoid confusion with script names and constants that have hyphens in them. If you wanted to subtract a negative number, you should write n -- -6.

An important note is that all Hamsterspeak variables are 32 bit signed integers. For example, in Hamsterspeak, 26 / 4 will return 6, not 6.5. With creative workarounds a clever scripter can circumvent any problems this causes. (For example, multiplying everything by 10...)

Comparison and Logic[edit]

Comparison and logic operators take the value on their left, and the value on their right, compare them, and return 1 (true) or 0 (false) based on the comparison. They are most often used in if statements.

plotscript, Comparison Sample, begin

  if (5==7)
  then,begin
    # five is never equal to seven, so this can't be true
  end

  if (5<7)
  then,begin
    # five is always less than seven, so this is always true
  end

  if (5>7)
  then,begin
    # five is never greater than seven, so this can't be true
  end

  if (5<=random(1,10))
  then,begin
    # there is a 50% chance that 5 will be less than or equal to
    # the random number between 1 and 10, so sometimes this will be
    # true and other times it will be false
  end

  if (1==1 && 2<>2)
  then,begin
    # one is always equal to one, but two is never not-equal to itself
    # so this can never be true
  end

end

The complete list of comparison operators is documented in the Plotscripting Dictionary.

Variables[edit]

A variable is a named number-holder in your script that you can give any value to. Variables can be global, which means they are available to every single script, and are saved in your RPG, or they can be local, which means they only work in the script they where created in, and once that script ends, they go away.

Global variables are defined with the globalvariable statement. Like scripts, global variables need unique ID numbers. You have 4096 global variables to work with, numbered from 0 to 4095.

Global Variable (1,var)

plotscript, one script, begin
  # I can set a global variable in one script...
  var:=100
end

plotscript, one script, begin
  # ...and use it in another
  show value (var)
end

Local variables are declared with the variable statement. A local variable always starts out as zero when the script starts. You can use the variable throughout the script, and when the script finishes, zap! the variable is gone. If you run the script a second time, it will be created all over again. Local variables do not need an ID number

plotscript, test script, begin
  variable (var)
  # this variable is only available to this script
  var:=100
end

Note that globalvariable always goes outside of your scripts. Variable always goes inside a script. Local variables are created as soon as the script starts, regardless of where in the script you define them (it makes absolutely no difference).

Flow control[edit]

All flow control constructs are documented in the Plotscripting Dictionary.

Strings[edit]

Strings have ID numbers, and all string-related commands take at least one string ID. There are 32 strings available. They are numbered from 0 to 31.

Strings literals are assigned with the syntax:

$ID = "text"

Or appended with the syntax:

$ID + "more text"

For a list of all functions that work with strings, see: String Functions

There may be some confusion about displaying strings. The show string command can only display a single string at a time, but the show string at command and the center string at commands can be used to display all strings simultaneously anywhere on the screen.

Obsolete Features[edit]

definescript[edit]

Old scripts used to require an ID number, assigned with the definescript statement. You do not need to use definescript anymore, but in case you see them in someone else's scripts, it can be helpful to know what they look like:

Define Script (1,My Script,none)
Define Script (2,My Other Script,none)

script, My Script, begin
  # do nothing
end

script, My Other Script, begin
  # do nothing
end

The first argument of definescript is the id number of the script. This is the number that the OHRRPGCE identifies the script by. No two scripts could have the same id number, and having an id number made a script triggerable in your game just like a plotscript

You may also see autonumbered scripts, which are also obsolete. Here is a sample script that is autonumbered.

Define Script (autonumber,My Numberless Script,none)
# this script will be hidden in CUSTOM.EXE,
# but can be called by other scripts

script, My Numberless Script, begin
  # blah blah blah
end


Internals[edit]

This section documents stuff that noone needs to know, except for possibly engine developers.


definetrigger[edit]

Revise.png
This article or section is not complete. If you wish, you may finish it, and remove this tag when you are done.

definetrigger isn't really used. It might be used or removed in the future, but has no current useful purpose.


defineoperator[edit]

The defineoperator command substitutes an infix operator for a function or script that is defined elsewhere. Hamsterspeak uses this to support math and logic operators such as 1+2. If you don't know what "infix" means, or what "operators" are, don't worry. You will never use defineoperator for anything. I only mention it here for the sake of documentation. If you want to turn some of your scripts into operators, you can use plotscr.hsd as an example.

The important part is knowing how to use the infix operators that have already been defined for you. The most common use of these operators is for doing math, and checking equality.

definefunction[edit]

For a script to make use of any plotscripting functions, It needs definefunction statements. Definefunction statements refer to special functions that are hard-coded into the interpreter. The normal convention is to call built-in functions commands.

If you had to manually type your definefunction statements, your code would look like this, only there would be waaaaay more of them. (but don't worry, you don't need to type these yourself):

define function, begin
 0,noop,0
 1,wait,1,1
 2,waitforall,0
 3,waitforhero,1,0
 4,waitfornpc,1,0
 5,suspendnpcs,0
 6,suspendplayer,0
 7,resumenpcs,0
 8,resumeplayer,0
 9,waitforkey,1,99
 10,walkhero,3,0,2,1
 11,showtextbox,1,1
 12,checktag,1,0
 13,settag,2,0,0
 # this isn't all! there are hundreds of plotscripting functions!
end

plotscript, My Script, begin
  # I can only use functions here if they have been declared
end

obviously nobody wants to type all that junk at the top of their script just to make it run, but fortunately there are definefunction statements for all of the plotscripting functions in a single file called plotscr.hsd. This file is automatically included by the compiler. You don't have to worry about it.

plotscript, My Script, begin
  # I can use any plotscripting function here I want,
  # because they have all been declared in the include file.
end

In older versions it was necessary to include the plotscr.hsd command manually, so don't be surprised if you see the following line at the top of a lot of old example scripts:

include, plotscr.hsd