Ramus 2.5 scripting manual

Starting in version 2.2, Ramus includes a little scripting language. It was completely overhauled in version 2.4; here's what it looks like now:

	#do a = 1
	<p>a was set to {{a}}.
	#test a === 1
	#iftrue <p>Is too!
	#iffalse <p>Is not!

This is more properly called a Javascript template system, but that might lead to confusion with Ramus as a whole.

There are two kinds of constructs in the RamScript language:

Expressions must be in double curly braces and can appear anywhere in the text (but each must end on the same line where it begins). For example:

	<p>You've made {{moves}} moves so far.

As the name implies, these can be any Javascript expression; moves just so happens to be one of the variables defined in Ramus.

Commands must appear on a line of their own; they start with a hashtag and the command name (which can contain anything except whitespace). Each command decides how to parse the rest of the line, for example to substitute expressions. Each command returns a result, if only the empty string, that replaces it in the output.

Built-in commands

As of version 2.5, there are six built-in commands:

#do evaluates the rest of the line as Javascript code but doesn't display anything:

	#do gotLight = true;

Conversely, #literal displays the rest of the line as-is; this is useful for including RamScript code examples, like in the guide:

	#literal {{"Hello, " + "world!"}}

#include evaluates the rest of the line as a Javascript expression and uses the result as a fragment ID to include in the text. Included fragments are scored, marked as visited and parsed for scripts, but their title attribute (if any) is ignored. This can be as simple as:

	#include "ambient"

or for a more involved example:

	#include gotLight ? "nice-view" : "darkness"

which is one way to do conditional display in Ramus.

#test evaluates the rest of the line as a Javascript expression and sets an internal flag:

	#test lightLevel !== 0

Last but not least, #iftrue and #iffalse look at the flag set by #test and display the rest of the line (parsed for expressions), but only if the flag is true or false, respectively:

	#iftrue <p>You light the torch. {{inline("nice-view")}}
	#iffalse {{include("darkness")}}

That demonstrates another way to include other fragments in the current one.

Naturally, you can follow a test with any number of true/false lines, and even intermingle them with other commands. They'll just keep minding the latest test performed. If you forget to include one, the "false" branch is taken, if present.

Syntax quirks

There's one thing you should be aware of when using Javascript in Ramus. Because of how it's done internally, any <, > or & sign you type in will reach your script as &lt;, &gt; and &amp;, respectively. There's no easy way around it, either. Trouble is, that makes essential Javascript operators off-limits:

	<!-- This will break -->
	#test 1 <= a && a <= 10

One possible solution is adding a few functions to Ramus:

	function and(a, b) { return a && b; };
	function lt(a, b) { return a < b; };
	function lte(a, b) { return a <= b; };
	function gt(a, b) { return a > b; };
	function gte(a, b) { return a >= b; };

so that you can rewrite the code as follows:

	#test and(lt(1, a), lt(a, 10))

And so we inevitably end up back at Lisp (actually MUSHcode; long story).

Starting with Ramus 2.5 these functions are included by default.

Word of caution

RamScript is probably insecure! You shouldn't use it to pull data into Ramus from outside sources. If you need to e.g. embed an image or the like, do it in static HTML.

Since version 2.5, errors are logged to the browser console, but otherwise ignored. This is so the story keeps going instead of stopping the player cold.