The Regnus Scripting Tutorial

Welcome to the tutorial for the Regnus scripting language! Regnus is a powerful recursive language for the generation of random text, and can be used for a wide number of applications. Before you start this tutorial, it is recommended that you try playing with some existing scripts to give yourself some idea of the capabilities of the language!

Part 1: Your First Regnus Script

So, to begin with, let's get started by creating your very first Regnus script!

First, open a text editor of your choice. For instance, the Windows Notepad will do at a pinch (although something like Edit Pad Lite is a good recommendation for any serious text-editing).

Create a new plain text file in your editor, and give it the file extension ".rsf" - this stands for "Regnus Script File", and is the standard file extension for Regnus scripts.

Into this file, paste the following:

START <First Label>Hello world!

Now, open this script with your Regnus parser and click to generate some text. You will see that the text presented to you by the parser is the sentence "Hello world!" - the entire line of text from the file, except for the part enclosed in triangular brackets and the first word of the line.

Now try this:

START <First Label>Hello brave new world!
START <Second Label>Goodbye cruel world!

You should now be given a selection of two options from the parser's contents menu: "First Label" and "Second Label". Go ahead and select one, and generate some text!

These line identifiers (the parts in triangular brackets) are called "labels", and they tell the parser that it can start parsing from that line, as well as letting it know what that option should be called!

Labels do not have to appear at the beginning of the line; they are just as welcome at the end, or at any point in between! So, for instance, the following will work just as well:

START Hello brave new world!<First Label>
START Goodbye cruel <Second Label>world!

...Though it probably goes without saying that it is considered bad practice to insert labels haphazardly in the middle of sentences like that!

Of course, a line with no label will not appear as an option in your parser's contents list. In the following script, the parser will never display the unlabelled line:

START <First Label>Hello brave new world!
START <Second Label>Goodbye cruel world!
START This line does not have a label, and so will never be displayed!

Those five-letter words at the beginning of each line of the file are called "qualifiers", and they are also important: every line in a Regnus script file must start with a qualifier, which lets the parser know what kind of information is contained in that line...

More on that shortly though!

Part 2: References, Groups & Entries

The most important capability of the Regnus scripting language is the ability to substitute parts of a text with other randomly selected text. This is done using what are called "references".

Create a new script file (or overwrite your old one!) and copy the following text into it:

START <Example Label>Hello ##SecondGroup; world!

GROUP SecondGroup
ENTRY cool
ENTRY groovy
ENTRY cruel
ENTRY brave new
ENTRY confusing
ENTRY Disney

If you open this new script with your parser, you will be given a single choice of label ("Example Label"), which will produce for you the words "Hello" and "world!", but with a random word or phrase inserted in between.

As you can see when you play with this script, the random part of the output is selected from the "entries" listed in the second block of text in the script.

These blocks of text are called "groups", and are very important to how Regnus operates. A group consists of a group name (identified with the "GROUP" qualifier), and any number of "entries", each of which is defined using the qualifier "ENTRY".

Before continuing, it would probably be best to try playing with this script a little until you are comfortable with how it works. Try adding some more entries in the second group and see what results you can make!

Note: while it's common practice to write qualifiers in capitals, Regnus is not at all case-sensitive; it is just done to make the code look tidier!

When you want to include an entry from a particular group, you use what is called a "reference"; this is what we call the little snippet of text in the script that starts with a hash character ("#") and ends with a semicolon (";").

In between these two characters lie two important parts:

The RTC in this case is the second hash character, but there are many other options available which we will look at later.

For now, all you need to know is that the bit of text in between the RTC and the semicolon that marks the end of the reference is called an "expression", and that when this expression is the name of a group in the script, the resulting text will be a randomly selected entry taken from that group.

Anyway, to take this concept further, create the following script:

START <Example Label>Today is ##Weekday;, so I will ##Action;!

GROUP Action
ENTRY go out and play
ENTRY stay indoors
ENTRY play with my friends
ENTRY play by myself
ENTRY go to sleep

GROUP WeekDay
ENTRY Monday
ENTRY Tuesday
ENTRY Wednesday
ENTRY Thursday
ENTRY Friday
ENTRY Saturday
ENTRY Sunday

As you can see from this script, entries can contain as many references as you want. But on top of this, entries can also contain further references...

START <Example Label>Today is ##Weekday;, so I will ##Action;!

GROUP Action
ENTRY go out and ##Action2;
ENTRY ##Action2; with my friends

GROUP WeekDay
ENTRY Monday
ENTRY Tuesday
ENTRY Wednesday
ENTRY Thursday
ENTRY Friday
ENTRY Saturday
ENTRY Sunday

GROUP Action2
ENTRY dance
ENTRY play
ENTRY sing
ENTRY fight

...And of course, each further entry can be filled with further references, creating as complex a chain of random selections as you want!

Another useful thing to know about entries within groups is that you can add a label to any entry if you would like to add the option to start parsing from that location! For example:

START <Random Selection!>##StartPoints;

GROUP StartPoints
ENTRY <Example One>Today is sunny, so I will ##Action;!
ENTRY <Example Two>I would like to ##Action; today!

GROUP Action
ENTRY go out and play
ENTRY stay indoors
ENTRY play with my friends
ENTRY play by myself
ENTRY go to sleep

If you run this script in your parser, you will see that you can choose to start parsing from any of the labelled entries. In fact, so long as a script has at least one labelled entry, there is no reason to include a "START" qualifier at all! The following script will work just as well:

GROUP StartPoints
ENTRY <Example One>Today is sunny, so I will ##Action;!
ENTRY <Example Two>I would like to ##Action; today!

GROUP Action
ENTRY go out and play
ENTRY stay indoors
ENTRY play with my friends
ENTRY play by myself
ENTRY go to sleep

So, go ahead and play around with your script and see what you can do with what you already know – and then come back for the next chapter once you're comfortable with those concepts!

Note: When naming groups, you can use any letter or number character, and also the hyphen ("-"), full-stop ("."), underscore ("_"), exclamation-mark ("!") and question-mark ("?") characters.

Part 3: Ratios & Weights

Now you've got the hang of the basic idea of references, let's take a look at how to better control the probability of certain entries being selected by a reference...

Ratios

When you set up a list of entries under a particular group in Regnus using the methods you have learned so far, you will no doubt have noticed that each entry is given an equal probability of being selected. This is, of course, correct for many applications.

However, there are also many times when you may want a particular entry to be more or less likely to be selected than others in the same group. A crude way to achieve this, which you may already have thought of, is to simply repeat entries to increase their probability, like so:

START <Weighting Example>##Probabilities;

GROUP Probabilities
ENTRY 25%
ENTRY 75%
ENTRY 75%
ENTRY 75%

Here, there is a 75% chance of generating the text "75%", and only a 25% chance of "25%". This works, of course, but is not a very good way of defining probability, especially if you have a lot of entries, as it can quickly become confusing to look at, makes your scripts unnecessarily large, and is increasingly difficult to edit if you need to change particular probabilities.

A far more sensible way to alter the probability (or "weight") of a particular entry being selected is to use the "RATIO" qualifier. This qualifier is used in exactly the same way as an "ENTRY" qualifier, but also allows you to define a probability for the text contained. The syntax for using the "RATIO" qualifier is as follows:

START <Weighting Example>##Probabilities;

GROUP Probabilities
RATIO 25:One quarter!
RATIO 75:Three quarters!

Here, we have used two ratio qualifiers to define percentage probabilities for the two entries. Actually, using percentages as in the above example is unnecessary; this example would work just as well written as:

START <Weighting Example>##Probabilities;

GROUP Probabilities
RATIO 1:One quarter!
RATIO 3:Three quarters!

This is because the maximum probability is always calculated as the combined total of all probabilities defined, in this case, 4. Thus, the first entry has a probability of being selected of one in four, just as in the previous example, the probability was twenty-five in one-hundred.

You can also mix and match "RATIO" qualifiers with "ENTRY" qualifiers. Standard entries are always given a probability of 1. So, the following example will have the exact same results as the previous one:

START <Weighting Example>##Probabilities;

GROUP Probabilities
ENTRY One quarter!
RATIO 3:Three quarters!

Ratios can also be fractional values, which is useful if you want a single entry in a group to be less commonly selected than the other entries in that group. For example:

START <Weighting Example>##Probabilities;

GROUP Probabilities
ENTRY Four fifths!
RATIO 0.25:One fifth!

The standard entry has a weight of 1, or four times the weight of the fractionally-weighted entry, so here, the under-weighted entry has a selection probability of one fifth.

Note: Fractional ratios are accurate to a precision of one thousandth (0.001) in the current standard. Values lower than this will not function correctly.

Having a quick play with using ratios should soon give you a firm idea of how they work, but although simple, they can be very useful, especially when writing scripts which need to use specific probabilities (for example in research projects or encounter charts and such for roleplaying games), so it's well worth being aware of how to use them!

Counted Weights

Another way to weight entries is to use the "COUNT" qualifier. This allows you to assign a weight to an entry equal to the number of entries in another group. For example:

START <Weighting Example>##Probabilities;

GROUP Probabilities
ENTRY One quarter!
COUNT AnotherGroup:Three quarters!

GROUP AnotherGroup
ENTRY Something
ENTRY Something else
ENTRY Yet another thing

In this example, the second entry in the "Three quarters!" entry is assigned a weight of three as there are three entries in the referenced group "AnotherGroup".

This is primarily useful when the intention is to combine the contents of two groups for one purpose, while keeping them separate for other purposes, but wanting to ensure that each individual entry is treated with the same weight. For example, consider the following situation:

START <Weighting Example>##Animal;

GROUP Animal
ENTRY ##Cat;
ENTRY ##Dog;

GROUP Cat
ENTRY Lion
ENTRY Tiger
ENTRY Puma
ENTRY Cheetah
ENTRY Felis Silvestris Lybica

GROUP Dog
ENTRY Wolf
ENTRY Rottweiler

In this example, a Reference to the group "Animal" will return an entry from the group "Cat" fifty percent of the time, and an entry from the group "Dog" fifty percent of the time; but as there are five entries in the "Cat" group and only two in the "Dog" group, this means that such a Reference would only return the result "Puma" ten percent of the time, whereas "Rottweiler" would be returned twenty-five percent of the time.

Clearly, this is not the intention, and it can of course be fixed using a "RATIO" qualifier in the following way:

START <Weighting Example>##Animal;

GROUP Animal
RATIO 5:##Cat;
RATIO 2:##Dog;

GROUP Cat
ENTRY Lion
ENTRY Tiger
ENTRY Puma
ENTRY Cheetah
ENTRY Felis Silvestris Lybica

GROUP Dog
ENTRY Wolf
ENTRY Rottweiler

Now, there is an equal one-in-seven chance of any particular animal being returned. However, the problem with using "RATIO" qualifiers here is that the ratios would need to be updated each time a new entry is added to either group. The "COUNT" qualifier makes this much easier:

START <Weighting Example>##Animal;

GROUP Animal
COUNT Cat:##Cat;
COUNT Dog:##Dog;

GROUP Cat
ENTRY Lion
ENTRY Tiger
ENTRY Puma
ENTRY Cheetah
ENTRY Felis Silvestris Lybica

GROUP Dog
ENTRY Wolf
ENTRY Rottweiler

The "COUNT" qualifier takes into account all calculated weights for a named group, including any "COUNT" or "RATIO" qualifiers within that group, so the following would also provide an equal chance of any particular animal being returned:

START <Weighting Example>##Animal;

GROUP Animal
COUNT Cat:##Cat;
COUNT Dog:##Dog;

GROUP Cat
COUNT BigCat:##BigCat;
COUNT SmallCat:##SmallCat;
ENTRY Leopard
ENTRY Puma

GROUP BigCat
ENTRY Lion
ENTRY Tiger
ENTRY Cheetah

GROUP SmallCat
ENTRY Felis Silvestris Lybica

GROUP Dog
ENTRY Wolf
ENTRY Rottweiler
RATIO 1:Great Dane

Note: A "COUNT" qualifier should not be used to count the group in which it appears, as this will create an infinite logic loop and cause your Regnus parser to hang! The same is also true of "COUNT" qualifiers which attempt to count groups which themselves attempt to count the original group, for the same reasons, so be careful!

Finally, it is worth noting that both ratios and counted entries are also able to include labels, just as with "START" and "ENTRY" qualifiers:

START <Random Selection!>##StartPoints;

GROUP StartPoints
ENTRY <Example One>Today is sunny, so I will ##Action;!
RATIO 2:<Example Two>I would like to ##Action; today!
COUNT Action:<Example Three>I don't like to ##Action;!

GROUP Action
ENTRY go out and play
ENTRY stay indoors
ENTRY play with my friends
ENTRY play by myself
ENTRY go to sleep

Part 4: Exclusive References

As briefly mentioned earlier, when you declare a reference using a hash, the character directly after the hash tells Regnus how to deal with the reference. This character is called a "Reference Type Character", or RTC. In all the examples so far, a second hash character has been used as the RTC, which has no special effect on the reference. However, there are other RTCs you can use...

One common requirement of a Regnus script is to return several results from the same group, but ensure that the same result is not returned twice. For example:

START <Example>My ##Animal; is not a ##Animal;!

GROUP Animal
ENTRY cat
ENTRY dog
ENTRY fish
ENTRY bird

In this example, it would obviously not be desirable for the script to return the sentence "My cat is not a cat!"

However, as you will see if you run this script, as both references are entirely random, there is a good chance that you will see the same animal selected for both. What is needed, of course, is a way to ensure that the results of both entries are exclusive from each other.

This is actually very easy using the exclusion RTC, represented by the ampersand ("&") character:

START <Example>My #&Animal; is not a #&Animal;!

GROUP Animal
ENTRY cat
ENTRY dog
ENTRY fish
ENTRY bird

If you run this script now, you will find that none of the animal types will be returned twice. This is because no exclusive reference will return the same result as another exclusive reference in the same script.

Of course, this would not work if only one of the references were exclusive...

START <Example>My ##Animal; is not a #&Animal;!

GROUP Animal
ENTRY cat
ENTRY dog
ENTRY fish
ENTRY bird

...Here, as only the second reference uses the ampersand RTC, it is still possible for it to return the same result as the previous reference, which is not exclusive.

Exclusive references of this kind do not need to be in the same entry to work, either; they will remain exclusive no matter how deeply nested they are in the script. For example:

START <Example>My #&Animal; is not a ##Predator;!

GROUP Animal
ENTRY cat
ENTRY dog
ENTRY fish
ENTRY bird

GROUP Predator
ENTRY #&Animal;-eating #&Animal;

Here, none of the references to the group "Animal" will return the same result, even though they are in different groups.

However, there are of course some situations in which the global nature of the exclusivity is undesired... For example:

START <Example>I have a #&Predator; but my friend has a #&Predator;.

GROUP Animal
ENTRY cat
ENTRY dog
ENTRY fish
ENTRY bird

GROUP Predator
ENTRY #&Animal;-eating #&Animal;

Here, you might want to allow both repetitions of the reference to "Predator" to return the same animal names (provided the whole phrase was not the same). So for example, this script as it is currently written, would never return the phrase "I have a dog-eating fish but my friend has a dog-eating cat!", because the word "dog" cannot be returned twice.

To solve this, we use a "locally exclusive" reference type (as opposed to the "globally exclusive" type as above). This is invoked using the asterisk character ("*") as an RTC, and will only force references to be exclusive from each other when they reside in the same entry.

Thus, the following script would work as desired:

START <Example>I have a #*Predator; but my friend has a #*Predator;.

GROUP Animal
ENTRY cat
ENTRY dog
ENTRY fish
ENTRY bird

GROUP Predator
ENTRY #*Animal;-eating #*Animal;

Note: Be careful when using exclusivity! If you include more exclusive references than there are possibilities of variation in the referenced content, you will cause your parser to fall into an infinite logic loop and hang!

There is also a third type of reference dealing with exclusivity. This is the "comparative exclusion" reference, but this will be covered later in the tutorial!

For now, once you are comfortable with the concept of exclusivity, please move ahead to the next chapter!

Part 5: Article Correction

A common situation you may encounter when randomising text is the difference between the articles "a" and "an". For example:

START <Example>I have a ##Fruit;!

GROUP Fruit
ENTRY banana
ENTRY plum
ENTRY apple

Here, the resulting text works fine if the reference returns "plum" or "banana", but if "apple" is selected, you might expect the text to read "I have a apple!", which would be linguistically incorrect.

However, in fact, Regnus will automatically correct any instance of the word "a" followed by a word starting with a vowel to the word "an", so the above script will work just fine.

Therefore, it is always correct to use the word "a" rather than "an" in a Regnus script, as it will be automatically corrected where necessary.

But what if this behaviour is undesired? Well, luckily, Regnus does have a function to achieve just this: the "DEBAR" qualifier.

This qualifier works by defining words which should not trigger an automatic correction. So, to give an example:

START <Example>I'm a member of a ##Group;!

GROUP Group
ENTRY chess club
ENTRY union
ENTRY academic institution

DEBAR union

Here, it would be undesirable to correct the article "a" to "an" if "union" were selected by the reference, even though it starts with a vowel. So, we use the "DEBAR" qualifier to exclude the word "union" from triggering this response from the parser.

If you would like to disable this functionality entirely, you can use the qualifier "DEBAR" by itself with no data, which simply tells the parser not to correct articles at all in this script!

Part 6: Automatic Grammar Characters

One very useful feature of Regnus is a range of special characters called "Automatic Grammar Characters", or "AGCs", which can be inserted into your text in order to affect the characters near them in some way. This chapter documents these characters and explain how to use them.

Pluralisation

A common requirement in a Regnus script is to be able to pluralise nouns without resorting to including both singular and plural versions of each word in separate groups. For example:

START <Example>My friend has just one ##Fruit;, but I have several ##Fruits;!

GROUP Fruit
ENTRY banana
ENTRY plum
ENTRY apple

GROUP Fruits
ENTRY bananas
ENTRY plums
ENTRY apples

As you can see, this would be an inefficient way to write a script! Luckily, there is an AG character to solve this problem. To us it, simply place a tilde character ("~") at the end of any word which you would like to be pluralised. For example:

START <Example>My friend just has one ##Fruit;, but I have several ##Fruit;~!

GROUP Fruit
ENTRY banana
ENTRY plum
ENTRY apple

You will find when you run this example that the result of the second reference is automatically pluralised.

The pluralisation function is fairly intelligent, and will correctly pluralise most words in the English language. However, there are of course certain exceptions which it will incorrectly pluralise, and there is a way to get around this: the "MULTI" qualifier. This simply allows you to define a noun, and its plural form. So, to use one example which the parser will have trouble with:

START <Example>I like ##Animal;~!

GROUP Animal
ENTRY cat
ENTRY sheep

MULTI sheep:sheep

If you run this script, you will see that the parser correctly pluralises "cat" to "cats", but if you remove the "MULTI" qualifier, it will try to correct "sheep" to "sheeps", which is of course incorrect.

The "MULTI" qualifier can also be used to correct noun phrases which would otherwise be difficult to automatically pluralise. For example, consider the following:

START <Example>I have several ##AnimalGroup;~!

GROUP AnimalGroup
ENTRY flock of birds
ENTRY gaggle of geese

MULTI flock of birds:flocks of birds
MULTI gaggle of geese:gaggles of geese

Here, it is the first word of each of the phrases returned by the "AnimalGroup" group, rather than the last, but as definitions set by "MULTI" qualifiers always take precendence over standard pluralisation, they can be used to ensure that these phrases are pluralised correctly.

Text Case

Another common requirement in Regnus scripts is to be able to capitalise letters of words. For example, you may want to start a sentence with a random word, but also use that entry in the middle of a sentence.

In these cases, you can use the circumflex accent character ("^") to convert the following letter to uppercase. So, for instance:

START <Example>My name is ^elvis!

This would return the text "My name is Elvis!", as the circumflex forces the following character to be uppercase. This might not seem immediately useful, but consider the following situation:

START <Example>^##Fruit;~ are nice!

GROUP Fruit
ENTRY banana
ENTRY plum
ENTRY apple

Here, we have used both a pluralisation and a capitalisation character alongside the reference to the "Fruit" group, in order to convert (for example) "banana" into "Bananas", which is correct as it appears at the beginning of the sentence.

The circumflex can also be followed by a dot character in order to have the opposite effect, and convert the following character to lowercase. Thus, the above example could also be written in reverse:

START <Example>I have some ^.##Fruit;~!

GROUP Fruit
ENTRY Banana
ENTRY Plum
ENTRY Apple

Here, the entries in the "Fruit" group already begin with a capital letter, but as we are referencing the group in mid-sentence, we use the capitalisation AGC to force lowercase.

A second circumflex character will force a whole word to appear in block capitals:

START <Example>I have some ^^bananas and apples!

This example would return the text "I have some BANANAS and apples!".

The effects of the capitalisation character can also be applied to whole sections of text using parantheses:

START <Example>Hello there! ##MyNameIsElvis;

GROUP MyNameIsElvis
ENTRY I am ^.(Elvis Presley)!
ENTRY I am ^^(elvis presley)!
ENTRY I am ^(elvis presley)!

The first entry in the "MyNameIsElvis" group would return the text "I am elvis presley!", as all of the characters within the parantheses are forced to be lowercase. In the second entry, the returned text would be "I am ELVIS PRESLEY!", as all the characters are forced to be uppercase. The final example uses a single capitalisation character, and has the often-useful effect of applying namecase to span of text, meaning that the first letter of each word is capitalised. This entry would therefore return the text "I am Elvis Presley!", even though the contained text is originally lowercase.

New Lines

One issue you may well have already encountered is that, as Regnus relies on all text from an entry remaining on the same line as its qualifier, you cannot include line breaks in your scripts.

Luckily, the vertical line character ("|") achieves just that!

START <Example>This is line 1...|And this is line 2!|...And hey, this is line 3!

Conditional Spaces

Consider the following script:

START <Example>The cat sat ##Comfort; on the mat.

GROUP Comfort
ENTRY comfortably
ENTRY uncomfortably
ENTRY

Here, an empty "ENTRY" qualifier is used with the intention that in one third of cases, no adverb is used. However, as you will see, this will produce an erroneous two consecutive spaces in the output.

To solve this, the conditional space character can be used:

START <Example>The cat sat ##Comfort;_on the mat.

GROUP Comfort
ENTRY comfortably
ENTRY uncomfortably
ENTRY

By using the underscore character ("_"), a space is only inserted in this position if no preceding space character exists, which will cause the second space to appear only if an adverb is inserted.

Escape Characters

As you may have noticed, Regnus relies on a lot of special characters to signify various things, which has the side-effect of precluding these characters being used in the text of your script. For instance, if you want to include a hash character in your text, the parser will return an error message because it expects a reference, and if you include any of the AG characters, they will be treated as such rather than displayed in the text output.

So, to get around this, you can use Regnus' escape character, the asterisk ("*"), to overstep parsing of characters which you want to use exactly as they are. For example:

GROUP Example
ENTRY <Example 1>This will cause an error: #
ENTRY <Example 2>...But this won't: *#
ENTRY <Example 3>And if you want to include an asterisk, just use two!: **

Note: you can also use the asterisk to escape the letter "a" if there is a single example in your script which you want to debar from article correction, regardless of what word follows it.

Part 7: Literal Expressions

You should now be comfortable with the concept of using different RTCs, so we'll move on to the other fundamental part of references in Regnus: expressions.

As you are already aware, references start with a hash character and end with a semicolon. In between are two other things: an RTC, to determine any special rules applied to the result of the reference; and one or more "expressions", which actually choose what data is handled by the reference.

We say "one or more" because some reference types (depending on which RTC you use) require more than one expression. However, you don't need to worry about this yet; for now, we will only be working with single-expression reference types.

Anyway, the type of expression with which you are already familiar is the "group expression". Any expression which is a valid group name (so does not contain any invalid characters or start with a numeric character) is always treated as a group expression.

This means that when the expression is "resolved" by the parser (turned into actual text), the result is selected at random from the group with the name specified.

However, there are in fact several more types of expression available. Two of these, the "slot expression" and the "dice notation expression", we will deal with later. For now, we will concern ourselves with the other important type of expression: the "literal expression".

An expression is assumed by the parser to be a literal expression when it is contained within paranthesis characters ("(" and ")"), and the difference between how a literal expression and a group expression are treated is that whereas the group expression returns data from a specified group, the literal expression simply returns the data within the parantheses!

For example, try running the following script:

START <Example>My friend has a ##(spider);, but I have a ##Animal;.

GROUP Animal
ENTRY cat
ENTRY dog
ENTRY fish
ENTRY bird

You will see that the expression "Animal" returns one of the entries from the "Animal" group, whereas the expression "(spider)" simply returns the word "spider".

Why would you want to do this? Well, there are several important reasons... Supposing that "spider" was also one of the entries in the "Animal" group:

START <Example>My friend has a ##(spider);, but I have a ##Animal;.

GROUP Animal
ENTRY cat
ENTRY dog
ENTRY fish
ENTRY bird
ENTRY spider

As you can see, this script would sometimes return the (presumably undesired) phrase "I have a spider but my friend has a spider."

Now, assuming that you don't want to randomise the friend's pet, but you do want to make it exclusive from the narrator's own pet, you could do this in the following way:

START <Example>My friend has a #&(spider);, but I have a #&Animal;.

GROUP Animal
ENTRY cat
ENTRY dog
ENTRY fish
ENTRY bird
ENTRY spider

Here, the result of the expression "Animal" is kept exclusive from the result of the expression "(spider)" by the globally exclusive RTC.

Of course, in this particular case, it would do as well to simply remove the entry "spider" from the "Animal" group since it is never used, but there are many occasions where you may want to share a group with several different references, but in one instance, exclude a particular result. For example:

START <Example 1>My friend has a #&(spider);, but I have a #&Animal;.
START <Example 2>My friend would really like a pet ##Animal;.

GROUP Animal
ENTRY cat
ENTRY dog
ENTRY fish
ENTRY bird
ENTRY spider

Here, the reference in the entry labelled "Example 2" can return the result "spider", but the reference in the entry labelled "Example 1" cannot.

There is a further power to literals, however...

All text in a literal expression is itself parsed. So, the following would be completely valid:

START <Example>I have a #*Animal; and a #*Animal;, and my friend has a ##(#*Animal; and a #*Animal;);.

GROUP Animal
ENTRY cat
ENTRY dog
ENTRY fish
ENTRY bird
ENTRY spider

The advantage of this somewhat convoluted reference may not be immediately obvious, but have a look at the results when you run it in your parser...

You will see that the exclusive references within the literal expression are exclusive from each other, but not from the exclusive references outside of the literal expression.

Thus, both the narrator and their friend can possess the same species of pet, but the two pets owned by each party will never be the same.

Take a moment to get to grips with the way this works, and then consider this final example of literal expressions:

START <Example>I have a #&(#*Animal;-eating #*Animal;);, but my friend has a #&(#*Animal;-eating #*Animal;);.

GROUP Animal
ENTRY cat
ENTRY dog
ENTRY fish
ENTRY bird
ENTRY spider

In this example, the results of each literal expression are kept exclusive to each other, and the results within each literal expression are kept exclusive to each other. So, there can be no cannibal animal (for example "cat-eating cat"), but there can be both a "cat-eating dog" and a "dog-eating cat" in the overall output.

Hopefully, you'll find this all fairly straight-forward, but if not, play with your script and continue with the next chapter once you are comfortable with using literal expressions!

Part 8: Inline Entry Selection

Literal expressions serve an additional, powerful purpose, in that they allow entry selection inline within a reference. For example:

START <Example>I once fought and killed a ##(dragon\mastodon\wyvern);!

If you run this script, you will find that the literal expression returns only one of the three creatures separated by backslash ("\") characters. As you can see, for simple entry selection, this is much simpler, as it removes the necessity for additional groups.

(Of course, should you wish to use backslash characters in an inline expression, they can be escaped as usual using the overstep (asterisk) character!)

As each option is fully parsed, there is no limit to how complex a nested selection can be! For example:

START <Example>I once fought and killed a ##(mastodon\troll\##(dragon\##(red wyvern\black wyvern);\wyrm););!

Entry weighting is not supported for this type of entry selection, so each option in a particular literal expression has an equal chance of selection. Thus in the above example, the results "mastodon" and "troll" each have a one-in-three chance of selection, as does the further reference containing various different forms of dragon; and within this reference, the options "dragon" and "wyrm" each have a one-in-three chance of selection, as does the further reference containing the two colours of wyvern, each of which has a fifty/fifty chance of selection.

Of course, for more complex scripts, inline entry selection like this can become very convoluted, so it is usually best used for simple one-off text replacements where the addition of a full group would be excessive, but as you can see, the possibility for nesting is very useful when appropriate!

Part 9: Dice Notation Expressions

You might find that it is sometimes useful to generate a number at random. For example:

START <Example>While playing Monopoly, I rolled a double-##(1\2\3\4\5\6); on my first turn!

As you can see, this is a very limited way to select a random value, and particularly arduous when dealing with a greater range of possibilities, or more complex parameters (for example the results of multiple multi-sided dice rolls when using Regnus to operate random encounter charts in RPGs!)

In order to generate random numerical values more easily, Regnus supports a type of expression which can be used in references much like the group expressions and literal expressions already covered, to generate random numbers and perform basic mathematical operations.

These expressions are enclosed in curly brace characters ("{" and "}"), and form a type of micro-syntax within Regnus, based on the dice notation commonly found in game rulebooks. For example:

START <Example>While playing Monopoly, I rolled a double-##{D6}; on my first turn!

The letter "D" signifies a dice-roll, and the number directly following it signifies the number of sides of each die rolled. So, "D6" would signify the result of a single six-sided die (thus a value from 1 to 6), and "D10" would signify a single ten-sided die (generating a value from 1 to 10).

If the result of multiple dice is desired, the number of dice can be given before the letter "D":

START <Example>While playing Monopoly, I rolled ##{2D6}; on my first turn!

In this example, the number generated will be the combined result of two six-sided dice (thus a number from 2 to 12). Equally, "3D6" would generate a number from 3 to 18, and so forth.

Dice notation expressions also allow for simple mathematical operators, so where multiple different dice are required, or a fixed value should be added to a dice-roll, these can be added together. For example:

START <Example 1>I rolled a six-sided die and a ten-sided die, and scored ##{D6+D10};!

START <Example 2>I rolled a six-sided die and added three, and scored ##{D6+3};!

Other operators currently supported are subtraction, multiplication, division and exponentiation. For example:

START <Subtraction>Two 6-sided dice, subtracting one from the result: ##{2D6−1};

START <Multiplication>A 10-sided die, multiplying the result by ten: ##{D10×10};

START <Division>Two 12-sided dice, dividing the result by two: ##{2D12÷2};

START <Exponentiation>A 6-sided die, squaring the result: ##{D6^2};

Note: Regnus dice notation expressions accept a variety of different operator characters! Subtraction can be performed using either the minus sign character ("−") or the hyphen character ("-"); multiplication using the multiplication symbol ("×"), the asterisk symbol ("*") or the letter "X" ("x" or "X"); division using the obelus symbol ("÷"), forward slash ("/") or backslash ("\") characters; addition using the plus sign ("+"); and exponentiation using the circumflex character ("^"). As a general rule for multiplication, it is generally recommended to avoid using the asterisk character, in order to avoid confusion with its use elsewhere in Regnus as an escape character.

Note: When using division in a dice notation expression, the result is always rounded down to the nearest integer.

It is also possible to use parantheses ("(" and ")") to bracket parts of mathematical expressions if more complex results are required:

START <Example 1>One six-sided die, subtracting one from the result, and then multiplying by two: ##{2×(D6−1)};

START <Example 2>Two six-sided dice, adding one to each result, and then multiplying the two results: ##{(D6+1)×(D6+1)};

Note: Unlike in the current convention for standard mathematical notation and most other programming languages, expressions are resolved strictly from left to right, with no operator priority; thus, the expression "2+1×3" is interpreted as "(2+1)×3" rather than as "2+(1×3)", as might usually be expected - so do use brackets to specify order of precedence where necessary!

Part 10: Storing Results

There are some cases in which you may want your script to use the same reference result twice, in order for your generated text to make sense.

For example, consider the following script:

START <Storage Example>Earlier, I met ##RandomName;. ##RandomName; is an old friend of mine.

GROUP RandomName
ENTRY Albert Possini
ENTRY Forrest Corruthers
ENTRY Jack Sprat

Here, it is important that the name chosen by the first reference is the same one chosen by the second.

For these situations, Regnus allows you to store the result of a reference in one of a hundred available "storage slots", to be recalled whenever necessary later in the script.

The RTC which handles this is the right-hand triangular bracket, or "greater-than" character (">"), which causes the result of the given expression to be stored in a slot number of your choice.

How do you you select the slot number? Well, you may remember it being mentioned earlier in the tutorial that some reference types require more than one expression, and this is one of them!

When an RTC requires more than one expression, each expression in the reference is separated by a colon character (":"). So, for example:

#>Expression1:Expression2;

In the case of the storage reference type, the result of the first expression decides the slot number in which to store the text, and the result of the second expression defines the text to be stored.

More specifically, the slot number used will be the numeric value of the text returned by the first expression... So, to give an example:

START <Storage Example>This will store the text "#>(10):Example;" in slot number 10.

GROUP Example
ENTRY Hello!

In this case, the text "Hello!", generated by the reference's second expression, will be stored in slot number 10, defined by the first expression "(10)".

And of course, the following will have the exact same result:

START <Storage Example>This will store the text "#>Example2:Example1;" in slot number 10.

GROUP Example1
ENTRY Hello!

GROUP Example2
ENTRY 10

In this case, the first expression, instead of being a literal expression returning the value "10", is a group expression which returns the value "10" from the group "Example2".

Note: As already mentioned, there are exactly one hundred slot numbers, but these range in value from zero to ninety-nine. Therefore, passing a value of minus one or one hundred will cause an error!

Note: Any expression resolving to a non-numeric character is simply understood to have a value of zero.

So anyway, how do we go about actually retrieving the text once we have stored it? Well, this is handled rather tidily by the third and final type of expression: the slot expression.

This type of expression is invoked by enclosing the expression in square brackets ("[" and "]"), and is treated in almost exactly the same way as a literal expression by the parser, except that it resolves to the contents of the slot number specified by the value of the final result. So, for example:

START <Storage Example>First, we store the text "#>(8):Example;" in slot number 8... Then, we retrieve it again and display it, like this: "##[8];"

GROUP Example
ENTRY Hello!

Here, the first reference stores the text "Hello!" in slot number 8, and then uses a reference with a standard "#" RTC with the expression "[8]", which returns the contents of slot 8.

And of course, as slot expressions are parsed in the same way as literal expressions, the following would have the exact same result:

START <Storage Example>First, we store the text "#>(8):(Hello!);" in slot number 8... Then, we retrieve it again and display it, like this: "##[##Example;];"

GROUP Example
ENTRY 8

In that example, the text stored in slot number 8 is defined by a literal expression rather than taken from another group, and the retrieval is made by a slot expression containing another standard reference, whose result is taken from the group "Example", and will therefore always return the value "8" (as this is the only entry, in this case).

Remember that the slot expression is fully parsed before being evaluated as a slot number, so you could even use multiple references within the slot expression to assemble the slot number:

START <Storage Example>First, we store the text "#>(18):(Hello!);" in slot number 18... Then, we retrieve it again and display it, like this: "##[##(1);##Example;];"

GROUP Example
ENTRY 8

And here's another somewhat convoluted example usage:

START <Storage Example>First, we store the text "#>(8):(Hello!);" in slot number #>(3):(8);... Then, we retrieve it again and display it, like this: "##[##[3];];"

In that example, we actually stored the value "8" into slot number 3 (in the second reference), and then retrieved the contents of slot number 8 by enclosing a reference to the contents of slot number 3 (which contains the value "8", remember) in the slot expression of the third reference!

As you can see, combining the different types of expression available to you can give you a lot of potentially useful possibilities!

So, back to our original example, in order to ensure that the same name is given twice, you would use the following method:

START <Storage Example>Earlier, I met #>(0):RandomName;. ##[0]; is an old friend of mine.

GROUP RandomName
ENTRY Albert Possini
ENTRY Forrest Corruthers
ENTRY Jack Sprat

And of course, as there are a hundred available slots, all of which are globally available to entries throughout the script, it is possible to store a number of pieces of information at once...

For example, examine the following script:

START <Storing Example>Earlier, I met ##RandomPerson;. ##[0]; was an old friend of mine.

GROUP RandomPerson
ENTRY #>(0):FirstName; #>(1):Surname;'s father, ##FirstName; ##[1];
ENTRY #>(0):FirstName; ##Surname;

GROUP FirstName
ENTRY Albert
ENTRY Forrest
ENTRY Jack

GROUP Surname
ENTRY Possini
ENTRY Corruthers
ENTRY Sprat

It may look rather complex, but try running it with your parser - you'll soon see how it works by watching the sentences generated.

It's actually very simple: the first reference to "RandomPerson" causes either of the selectable entries to save the result of their reference to "FirstName" into slot 0, meaning that it can be retrieved by the opening entry (the one labelled "Storing Example").

In the first entry under the group "RandomPerson", the result of the reference to "Surname" is also stored, but to slot 1 - this is used to simply make sure that both father and son in the story share the same surname.

The second reference to "FirstName" (the one generating the first name of the father) is not stored, as it is only used once. Thus, the father's surname is made the same as the son's by retrieving the son's stored surname from slot 1, and the son's first name is stored in slot 0, so when the parser returns to the original entry, the same name appears twice.

Well, go ahead and play with the script, anyway, and once that all makes sense, move on to the next chapter of the tutorial, which looks at some more ways of using storage slots!

Part 11: Naming Numerics

Of course, in large scripts, it can quickly get confusing if you're using lots of slot numbers and need to remember which is used for what!

However, there is a way to get around this, which is to name your slots something descriptive so that you can remember quickly what they're being used for.

Now, usually, if you were to pass a non-numeric character to a slot expression, it would resolve the contents of slot 0, since non-numerics are always assumed to have a value of zero. So, for instance, the following script would work fine:

START <Storage Example>If we store the text "#>(NonNumeric):(Hello!);" like this, it will be stored in slot 0. It can then be retrieved the same way: "##[NonNumeric];"

However, there is a way to associate non-numeric expressions with specific numbers, so that these expressions will return those numbers instead when used in expressions which are read as numerics, for instance in slot expressions...

This is achieved using a new qualifier: "REFER". It is used as follows:

REFER 10:SlotName

START <Storage Example>If we store the text "#>(SlotName):(Hello!);" like this, it will be stored in the slot we defined. It can then be retrieved by number: "##[10];"

As you can see, in a "REFER" qualifier, you define first a number, and then a name for that number, separated by a colon (":") character. The "REFER" qualifier can be placed anywhere in the script, and does not necessarily have to come earlier in the script than a reference using it.

The "REFER" qualifier is not limited to slot numbers, remember; there are also other reference types which require numeric values, and this method will work just as well for those!

For example, another useful feature of the "REFER" qualifier is that you can use named numeric values in "RATIO" qualifiers to define entry weighting:

REFER 2:ExampleName

START <Example>##ExampleGroup;

GROUP ExampleGroup
ENTRY #>(ExampleName):(This text is stored in slot number 2!);
RATIO ExampleName:This entry has twice as much chance of being selected!

And there is also no reason at all that you can't give several different names to the same number, should you wish!

REFER 2:ExampleName1
REFER 2:ExampleName2

START <Example>##ExampleGroup;

GROUP ExampleGroup
ENTRY #>(ExampleName1):(This text is stored in slot number 2!);
RATIO ExampleName2:This entry has twice as much chance of being selected!

Part 12: Aliases

Aliases are perhaps the most complex, but also one of the most powerful features of the Regnus language.

Put simply, an alias is a type of double-expression reference which allows you to return not the result of expression itself, but a pre-defined alternative to that result, allowing you to provide alternative selections of text based on previously generated content.

That may sound a little complicated, but hopefully, you'll quickly understand once you've played with a few examples!

There are two elements to an alias: firstly, there is the alias reference type, which is invoked using the at character ("@"), and secondly, there is the "ALIAS" qualifier, which is used to define the replacement text. So, to illustrate, imagine the following situation:

START <Example>My pet ##Animal; is eating a ##Food;!

GROUP Animal
ENTRY cat
ENTRY bird

GROUP Food
ENTRY mouse
ENTRY worm

Here, either type of animal can be eating either type of prey, which might not be desirable. It may be that you wish to randomise the pet involved, but choose the result of the second reference based on which animal is selected for the first.

This is exactly what aliases are for, and here's how you would use them to solve this problem:

START <Alias Example>My pet #>(0):Animal; is eating a #@[0]:(1);!

GROUP Animal
ENTRY cat
ENTRY bird

ALIAS cat:mouse
ALIAS bird:worm

Here, the first reference stores the result of the expression "Animal" to slot number 0. The second reference uses the alias RTC to return an alias for the selected animal. So, how does this work?

The alias reference expects two expressions. The first is the text for which you wish to return an alias, in this case the contents of slot number 0 (to which we saved the result of our first reference).

The second expression is the number of the alias of that text you wish to return, which we will cover shortly...

Each "ALIAS" qualifier defines firstly some text to replace, and secondly the alias text with which to replace it. In this case, the two aliases define that "cat" should be replaced with "mouse" and "bird" should be replaced with "worm".

This means that if the content of slot 0 is "cat", the second reference in the example will return "mouse", and if the content is "bird", it will return "worm".

So, what about that second expression in the alias reference? Well, this is in case you wish to use several aliases for the same text. In this case, you can simply add more "ALIAS" qualifiers, and specify the number (the first to appear in the script being "1", the second being "2" and so on) of the alias you wish to return.

So, to give a practical example:

START <Alias Example>My pet #>(0):Animal; ate a #@[0]:(1); and then #@[0]:(2);!

GROUP Animal
ENTRY cat
ENTRY bird

ALIAS cat:mouse
ALIAS bird:worm

ALIAS cat:miaowed
ALIAS bird:chirped

Here, the third reference asks for the second alias of the animal selected, which contains the noise associated with that animal. Hopefully, that's fairly straight forward!

Anyway, there is another important aspect to aliases: the alias text is itself parsed, and so can include further references! So, to enlarge on our example script:

START <Alias Example>My pet #>(0):Animal; ate a #@[0]:(1); and then #@[0]:(2);!

GROUP Animal
ENTRY cat
ENTRY bird

ALIAS cat:##CatFood;
ALIAS bird:##BirdFood;
ALIAS cat:##CatAction;
ALIAS bird:##BirdAction;

GROUP CatAction
ENTRY miaowed
ENTRY purred

GROUP CatFood
ENTRY mouse
ENTRY gerbil

GROUP BirdAction
ENTRY chirped
ENTRY flew away

GROUP BirdFood
ENTRY worm
ENTRY pile of seed

Also, remember that you can use the "REFER" qualifer to name numeric values, for instance:

REFER 1:Action
REFER 2:Food

START <Alias Example>My pet #>(0):Animal; ate a #@[0]:(Food); and then #@[0]:(Action);!

GROUP Animal
ENTRY cat
ENTRY bird

ALIAS cat:##CatAction;
ALIAS bird:##BirdAction;
ALIAS cat:##CatFood;
ALIAS bird:##BirdFood;

GROUP CatAction
ENTRY miaowed
ENTRY purred

GROUP CatFood
ENTRY mouse
ENTRY gerbil

GROUP BirdAction
ENTRY chirped
ENTRY flew away

GROUP BirdFood
ENTRY worm
ENTRY pile of seed

Hopefully, once you've played with that script a little, you'll be fully comfortable with using aliases, and ready to move on to the next chapter!

Part 13: Hidden Text

There are times when you may want to carry out the action of a reference without displaying the resulting text to the user. This is possible in Regnus using the "hidden text" feature, which allows you to simply enclose any portion of text in bracket characters ("{" and "}"), which causes it not to be displayed. So:

START <Example>{This text is not displayed!}This text is displayed!

In what circumstances might this be useful? Well, the main reason is for storing a set of data in storage slots at the beginning of a script to be retrieved later in order to keep a script tidy. For example:

START <Example>{#>(0):Animal;}Tommy had a pet ##[0]; called Jerry.

GROUP Animal
ENTRY frog
ENTRY dog
ENTRY beaver

Of course, in that particular example, there is little reason to use hidden text, but in a much larger script with a lot of different stored variables, it can help enormously in keeping the script tidy and readable if all the slots are named helpfully and the random data is all generated before the main part of the content.

However, where pre-generating data using hidden text brackets really comes into its own is when using aliases. For instance, consider the following script:

START <Example>{#>(0):RandomName;}I had a friend. #@[0]:(1); name was ##[0];.

GROUP RandomName
ENTRY Tom
ENTRY Hilda

ALIAS Tom:His
ALIAS Hilda:Her

Here, we want to use the correct gender pronoun based on the name selected, but we want to use the result before we know the name. Therefore to get around this, we generate the name first, but hide the result with brackets, then use the alias to return the correct pronoun.

A more complex, but probably more elegant version of the same concept would be to generate the sex of the character first, and then choose a name based on the result, as well as other relevant information:

START <Example>{#>(0):Sex;}I had a friend called #@[0]:(Name);. #@[0]:(Pronoun); had a #@[0]:(Spouse); called #@[0]:(SpouseName);.

GROUP Sex
ENTRY male
ENTRY female

GROUP MaleName
ENTRY Tom
ENTRY Jerry

GROUP FemaleName
ENTRY Hilda
ENTRY Bertha

REFER 1:Name
ALIAS male:##MaleName;
ALIAS female:##FemaleName;

REFER 2:Pronoun
ALIAS male:He
ALIAS female:She

REFER 3:Spouse
ALIAS male:wife
ALIAS female:husband

REFER 4:SpouseName
ALIAS male:##FemaleName;
ALIAS female:##MaleName;

This script is not especially complex, but once you understand how it works, you should be able to expand on these princibles to create very powerful text generation procedures!

Part 14: More Reference Types

There are a variety of different types of reference in Regnus which allow you to handle expressions in various different ways. The most important of these have already been looked at earlier in this tutorial, but this chapter will list and briefly explain the remaining RTCs and how to use them.

The Group Reference

This is a single-expression reference type invoked using the plus character ("+"), and returns text selected at random from an entry within a group with the name returned by its expression, essentially allowing you to treat any expression type as if it were a group expression. So, for example:

START <Example>I have a #+(Tools); and a #+SelectType;.

GROUP SelectType
ENTRY Tools
ENTRY Animals

GROUP Tools
ENTRY hammer
ENTRY nail
ENTRY saw

GROUP Animals
ENTRY cat
ENTRY badger
ENTRY dog

It is important to understand that the reference "##Example;" would be exactly functionally the same as "#+(Example);", but not the same as "#+Example;", which would first get an entry from the group "Example" because of the group expression, and then retrieve an entry from a group with a name matching the returned text from that group, due to the group reference RTC.

The Label Reference

This reference type is invoked using the underscore character ("_"), and returns text from an entry whose label matches the text returned by its expression.

START <Example 1>#_ExampleGroup; #_(Example 2);
START <Example 2>Hello!

GROUP ExampleGroup
ENTRY Example 2

The label "Example 1" from the above example should return the text "Hello! Hello!", as the first reference reads from the label name returned by the group "ExampleGroup" (which will always return "Example 2"), and the second reference returns text from the label with the name returned by the literal expression "(Example 2)", thus both return text from the same entry.

The Script Reference

This reference type allows you to generate text from a different Regnus script file. It expects two expressions, and is invoked with the dollar character ("$").

The first expression should return the name of the external script which you want to pars, and the second expression should return the name of the label within that script from which you want to return text.

Note: the first expression will need to contain path data if the external script is located in a different directory to the current script! However, paths will be adjusted by the Regnus parser to match the convention of the platform, so you should feel welcome to use slashes or backslashes as you prefer (though bear in mind that backslashes in a literal expression will need to be escaped, so forward slashes are probably much more sensible!)

START <Example>#$(NameOfScript):(NameOfLabel);

Note: It is important to note that when you generate text from an external script using the "$" RTC, all data from your script's slot-numbers will be shared with the new script. This gives the advantage of being able to share data between scripts, but also means that you have to be very careful not to accidentally overwrite data which you want to keep for later in the execution!

The Comparative Exclusion Reference

Don't let the name fool you; this type of reference is actually very simple, but very powerful! It is called using the forward slash character ("/").

Essentially, it allows you to define two expressions, and ensure that the second is exclusive from the first. So, for instance:

START <Example>#/(apple):Fruit;

GROUP Fruit
ENTRY apple
ENTRY banana

If you try running this script, you will find that the parser will never produce the result "apple". This is because the group-reference to "Fruit" is made exclusive from the literal expression "apple", so it can never be allowed to produce this result.

This is also very useful when combined with slot expressions, as it allows you to store an arbitrary result, and make a future reference exclusive from it, without affecting your usual local or global exclusions.

Part 15: Comments, Titles, & Blurb

By now, you should know everything you need in order to write your own Regnus scripts! This chapter simply covers some simple extra qualifiers which you may find come in handy...

Firstly, when you write a script, you may want to include some extra information about it, and perhaps give your own name, contact details or copyright information, for instance, to be displayed by the parser to those using your script. For these purposes, you can use the "TITLE" and "BLURB" qualifiers. So, for example:

TITLE Example Script
BLURB This is an example script written in 2009 by Ryan J. Bury - please direct any questions or comments to the Regnus forums!

Note: the text from the "BLURB" qualifier is also fully parsed, so you can include references if you want!

The second item covered by this chapter is the "BLANK" qualifier, which specifies that the current line should be ignored by the parser. This allows you to leave comments for people reading your script. For instance:

GROUP CommentExample
ENTRY <Example>This line is parsed...
BLANK This line is ignored.
RATIO 2:This line is parsed!

Regnus Language Reference

Qualifiers

ALIAS
Syntax
ALIAS OriginalText:AliasText
Description

Defines alternative text to be displayed when using the "@" RTC. AliasText is parsed.

Tutorial Chapter
Part 12: Aliases
BLANK
Syntax
BLANK Comment
Description

Defines text to be ignored entirely by the parser, to be used as comments within a script.

Tutorial Chapter
Part 15: Comments & Quotes
BLURB
Syntax
BLURB Information
Description

Defines information about the script to be displayed to the user by the parser. Information is parsed.

Tutorial Chapter
Part 15: Comments, Titles, & Blurb
COUNT
Syntax
COUNT Group:TextContent
Description

Defines text to be randomly selected by a reference to its containing Group, and specifies the chance of this text being selected as equal to the total weight (number of entries) of another named Group. TextContent is parsed. Group is the name of the Group to be counted.

Tutorial Chapter
Part 03: Ratios & Weights
DEBAR
Syntax
DEBAR Word
DEBAR
Description

Defines that its content word should not trigger the indefinite article correction system. Use with no content matches any word, effectively disabling IAC.

Tutorial Chapter
Part 05: Article Correction
ENTRY
Syntax
ENTRY TextContent
Description

Defines text to be randomly selected by a reference to its containing Group. TextContent is parsed.

Tutorial Chapter
Part 02: References, Titles & Entries
GROUP
Syntax
GROUP GroupName
Description

Defines a title under which entries are grouped. GroupName may only include letters, numbers, and the hyphen, underscore, question-mark and exclamation-mark characters.

Tutorial Chapter
Part 02: References, Groups & Entries
MULTI
Syntax
MULTI Singular:Plural
Description

Defines the plural form of a word, to be used by the "~" AGC. Plural is not parsed.

Tutorial Chapter
Part 06: Automatic Grammar Characters
RATIO
Syntax
RATIO Chance:TextContent
Description

Defines text to be randomly selected by a reference to its containing Group, and specifies the chance of this text being selected. TextContent is parsed. Chance is a numeric value.

Tutorial Chapter
Part 03: Ratios & Weights
REFER
Syntax
REFER Numeric:Name
Description

Defines a name by which a particular numeric value can be referred to.

Tutorial Chapter
Part 11: Naming Numerics
START
Syntax
START TextContent
Description

Defines a script entry which is not part of a group, ostensibly as a labelled starting point for parsing.

Tutorial Chapter
Part 01: Your First Regnus Script
TITLE
Syntax
TITLE ScriptTitle
Description

Provides the title of the script.

Tutorial Chapter
Part 15: Comments, Titles, & Blurb

Reference Types

Standard
RTC
#
Syntax
##Expression1;
Description

Resolves Expression1 and returns the result.

Tutorial Chapter
Part 02: References, Titles & Entries
Title
RTC
+
Syntax
#+Expression1;
Description

Returns an entry selected from a Group with the name returned by Expression1.

Tutorial Chapter
Part 14: More Reference Types
Locally Exclusive
RTC
*
Syntax
#*Expression1;
Description

Resolves Expression1 until result does not match any other result of a Locally Exclusive Reference in the same entry or expression, and returns the result.

Tutorial Chapter
Part 04: Exclusive References
Globally Exclusive
RTC
&
Syntax
#&Expression1;
Description

Resolves Expression1 until result does not match any other result of a Globally Exclusive Reference, and returns the result.

Tutorial Chapter
Part 04: Exclusive References
Comparison
RTC
/
Syntax
#/Expression1:Expression2;
Description

Resolves Expression2 until the result does not match Expression1, and returns the result.

Tutorial Chapter
Part 14: More Reference Types
Storage
RTC
>
Syntax
#>Expression1:Expression2;
Description

Resolves and returns the result of Expression2, and also stores it in a slot identified by numeric Expression1.

Tutorial Chapter
Part 10: Storing Results
Alias
RTC
@
Syntax
#@Expression1:Expression2;
Description

Resolves Expression1 and returns the AliasText taken from the Nth "ALIAS" qualifier whose OriginalText matches the result, where N is a numeric value resolved from Expression2.

Tutorial Chapter
Part 12: Aliases
Label
RTC
_
Syntax
#_Expression1;
Description

Returns text taken from the entry whose label matches the result of Expression1.

Tutorial Chapter
Part 14: More Reference Types
Script
RTC
$
Syntax
#$Expression1:Expression2;
Description

Returns text generated from the label matching the result of Expression2, in the external script whose path matches Expression1.

Tutorial Chapter
Part 14: More Reference Types

Automatic Grammar Characters

Pluralisation
AGC
~
Description

Pluralises the preceding word or phrase.

Tutorial Chapter
Part 06: Automatic Grammar Characters
Capitalisation
AGC
^
Description

Capitalises the following letter, word or phrase.

Syntax
ENTRY Hello there, I am ^elvis ^presley!
BLANK Returns: Hello there, I am Elvis Presley!

ENTRY Hello there, I am ^(elvis presley)!
BLANK Returns: Hello there, I am Elvis Presley!

ENTRY Hello there, I am ^^(elvis presley)!
BLANK Returns: Hello there, I am ELVIS PRESLEY!

ENTRY Hello there, I am ^.(Elvis Presley)!
BLANK Returns: Hello there, I am elvis presley!

ENTRY Hello there, I am ^.Elvis Presley!
BLANK Returns: Hello there, I am elvis Presley!

ENTRY Hello there, I am ^^elvis presley!
BLANK Returns: Hello there, I am ELVIS presley!
Tutorial Chapter
Part 06: Automatic Grammar Characters
New Line
AGC
|
Description

Breaks to a new line in the output.

Tutorial Chapter
Part 06: Automatic Grammar Characters
Conditional Space
AGC
_
Description

Inserts a space character, assuming it is not directly preceded by another space character.

Tutorial Chapter
Part 06: Automatic Grammar Characters
Overstep
AGC
*
Description

Escapes the following character.

Tutorial Chapter
Part 06: Automatic Grammar Characters