The Regnus Scripting Tutorial
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!