User Tools

Site Tools


Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /homepages/41/d601926503/htdocs/clickandbuilds/dokuWiki/Dicenomiwiki/inc/parser/handler.php on line 1552

Advanced Operations

ELDARScript provides some advance string capabilities, which include the ability to make random text generation possible, as well as formatting commands.

String Formatting

When displaying text as the results of a roll, the UI support special “rich text” formatting commands. This include the ability to change the color of the text, size, font, and even embed images, icons, and play sounds. All of this is based on “escape” code, which all being with a backwards slash. Some of them are then single letters, others are “paired” - sequences that being and end with the same punctuation character (with longer information between the pairs). Formatting is cumulative - making something bold and then red results in making it bold and red, or increasing the font size and decreasing it results in the original font size. Note that some combinations don’t appear - for example certain fonts don’t have bold and italic variations. Also note that the editor in The Dicenomicon + 1 support easy access to these escape codes while editing a string.

Escape Code Purpose Example Result
\n Inserts return “First Line\nSecond Line” First Line
Second Line
\p Resets formatting “Regular, \eBold, \RBold Red, \pPlain” Regular, Bold, Bold Red, Plain
\e Emphasized (bold) “Regular, \eBold” Regular, Bold
\i Italic “Regular, \iItalic” Regular, Italic
\_ Underline “Regular, \_Underline” Regular, Underline
\r, \g, \b, \c, \m, \y, \k, \w Set the color to red, green, blue, cyan, magenta, yellow, black, or white “\rRed, \gGreen, \bBlue, \cCyan, \mMagenta, \yYellow, \kBlack, \wWhite” Red, Green, Blue, Cyan, Magenta, Yellow, Black, White
\+, \- Increase/Decrease font size “Medium, \+Larger, \-Medium, \-Smaller” Medium, Larger, Medium, Smaller
\=size= Changefont size “Medium, \=18=Larger, \=10=Smaller” Medium, Larger, Smaller
\!name! Change the font name (assuming a font of the given font family name exists - these include AmericanTypewriter, AppleGothic, ArialMT, Courier, Georgia, Helvetica, MarkerFelt-Thin, TimesNewRomanPSMT, TrebuchetMS, Verdana, Zapfino) “Regular, \!Georgia!Georgia, \!Zapfino!Zapfino” Regular, Georgia, Zapfino
\#hex# Change to HTML style color “Default, \#800000#Brown, \#888#Gray” Default, Brown, Gray
\$name$ Plays the name of a given sound the first time it is “printed” as a result. This is not applicable for things like the name of a favorite roll (where the string isn’t a result) “Missed!$Whoosh$” Missed  (The sound 'Whoosh' would be played’)
\uXXXX A special 5 character escape code, used to specify unicode characters (where XXXX is for hex characters). “Black Pawn: \u265f Black Star: \u2605” Black Pawn: Black Star: ★
\`inline data` Displays an inline PNG image, where the data is base64 encoded between the back ticks \`iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbybl AAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO 9TXL0Y4OHwAAAABJRU5ErkJggg==`
\&path& Displays a filled shape whose path is specified by SVG path elements \& M 10 25 L 10 75 L 60 75 L 10 25&
\:badge: Displays a specified badge image \:plus:
\~lorc~ Displays an inline LORC element, specified in the following format: name[:fg-color[+bg-color]][@size] (where the square brackets indicate optional values)
\*x,y,w,h* Used only when specifying the face of a custom die, Causes the text to be placed in a grid that is w x h large at x, y “\*0,0,3,3*A\*1,1,3,3*B”
\@global,style=,max=,min=,color=@ embeds an global variable “adjuster”, where global is the value to control; style is either adjust, circle, or check; max is the maximum value (default = current value); min is the minimum value (default = 0) \@HP,style=adjust,min=0,max=10@

Text Generation

Via the % operator with a string and a list, strings can be formatted to include other values - a process called string interpolation where each % inside the string corresponds to a list element:

Expression Value Notes
“First % second %” % (1, 2) “First 1 second 2” Each element is substituted in turn
“Second %2 first %1” % (1, 2) “Second 2 first 1“ By using a number after the percent, that specific element is used
“Start % skip %! next %” % (1, 2, 3) “Start 1 skip next 3” An exclamation point causes that value to not be displayed at all
“Percent first %” % (1, 2, 3) “Percent % first 1” Using a double percent we get a single percent (and no substitution)
“Plain %, Title %^ Capital %^^ Upper %^^^” % (“first word”, “second word”, “third word”) “Plain first word, Title Second word, Capital Third Word, Upper FOURTH WORD” By adding a ^ after the %, the first letter of the substituted value will be converted to upper case. Two ^^ will capitalize the first letter of each word. Three ^^^ will capitalize all the letters
“Title %~ Lower %~~” % (“FIRST WORD”, “SECOND WORD”, “THIRD WORD”, “FOURTH WORD”) “Title fIRST WORD Lower second word” Adding a single ~ converts the first letter to lower case, while two ~~ converts all the letters to lower case
“Value %#%” % (1, “pie”) “Value %#%” % (2, “pie”) “Value a pie” “Value 2 pies” A %# indicates that this value is a count of how many of the next item there are, and it attempts to form a reasonable singular or plural of the word of the next % (i.e., this works across two substitutions)
@X 5. “X is %@X” % ”“ “X is 5” Using a variable name with the leading @, we will display that variable’s value. Remember, this only happens with the % operator, so we have a dummy empty string on the right hand side
”%@X plus one is %(@X + 1)“ % (5) “5 plus one is 6” Besides displaying a variable, we can use a special operation to assign the value from the list to a local variable (@X←5). Note that if we wanted to suppress showing that value, we’d use the ! modifier. Then, by placing an expression inside parenthesis, we evaluate that (instead of getting the next value from the right hand side of the %).
”%(d8)“ % ”“ “3” Note that even dice can be used inside the expression (however, no dice are actually rolled here)
“I see%#(d4-1) %” % “sword” “I see no swords” “I see a sword” “I see 2 swords” We can combine the # format (to indicate count) with an expression to make random amounts
“I see a %(generate('Flavor:Color')) %” % “gem” “I see a Blue gem” Calls to random text generators can be made, like any other ELDARScript function in an expression…
“I see a %[Flavor:Color] %” % “gem” “I see a Red gem” … but this is common enough to have a shortcut by enclosing the generate() parameter inside []

If one of the right hand values is actually a frame instead of a simple string or number, we can create sophisticated text generation based on the fields of that frame. Again, this only happens when we use the % operator to create a string with formatting characters or if we use the built in function string(). In all of these examples, we will create a table and then display it, altering the table to show various options (and show various possible outputs)

Expression Value Notes
@X {
“:table:”: “Hello”
“Hello” The magic is that the frame has an slot called “:table:” which will be used to generate the text. In this case, we just display that string
@X {
“:table:”: (“red”,”green“)
If the value of “:table:” is a list, one element will randomly be picked from it
@Y 5.
@X {
“:table:”:“Y is %@Y”
“Y is 5” By having escape values inside the “:table:” string, we can evaluate that as if it were actually “Y is %@Y” % “” (i.e., at run time we treat it as if we were formatting it vs an empty value)
@X {
“:table:”:“X is %@X”
“X is X is X is X is…” You can refer to itself, which is normally bad (though it will eventually limit you to how deeply it will nest itself)
@Y {
@X {
“:table:”:“X is %@Y”
“X is red”
“X is green”
You can refer to a second frame with a “:table:” key, and that gets randomly generated, so you can make multiple random text tables and refer to each other
@X {
“:table:”:“X is %:color”
| “color”:(“red”, “green”)
“X is red”
“X is green”
It is usually easier to use the : shortcut and refer to another slot in the current frame, which then has random text generation applied to it.
@X {
“:table:”:“The %:animal %:verb %:animal”
| “animal”:“%:adj %:noun”
| “adj”:(“quick”, “lazy”, “large”, “small”)
| “noun”:(“dog”, “cat”, “fox”, “bear”)
| “verb”:(“jumped over”, “saw”, “ignored”)
“The lazy dog jumped over the quick fox” We can use multiple tables, which use other tables, etc… In this case we have @X whose :table: slot refers to “%:animal” and “%:verb”. “animal” generates using “%:adj” and “%:noun”.
@X {
“:table:”:(“red”, “green”)
| “:tprefix:”:“<”
| “:tsuffix:”:“>”
By using the special :tprefix: and :tsuffix: slots, we can specify a string for a prefix/suffix of the resulting table generation
@X {
| 7…9:“Uncommon”
| 10:“Rare”
If a frame has numeric slots, it will automatically be treated as if there was a :table: slot which will pick one at random. Note that the value should range from 1 upwards
@X {
| 1…6:“Common”
| 7…9:“Uncommon”
| 10:“Rare”
“Common” (always) If for some reason, you want to limit the maximum index value, you can do so by specifying a numeric value for the :table: slot.
@X {
| 1…6:“Common”
| 7…9:“Uncommon”
| 10:“Rare”
“Common” (15 in 25)
“Uncommon” (9 in 25)
“Rare” (1 in 25)
If the index for a table with numeric slots needs to be something other than a linear random pick, we can use the :tableroll: slot to indicate an expression to evaluate. It is important to put the expression in quotes, or else it will get evaluated when the table is created, not when it is formatted
@X {
“:tableroll:”:“@Y ← 2d5”
| 1…6:“Common %:color”
| 7…9:“Uncommon”
| 10:“Rare”
| “color”:(“red %Y”, “green”)
string(@X), @Y
“Common red 5, 0” Variables that are set in the process of evaluating a table are available to other parts of that table (or things called from there) but not “outward”. So @Y has a value inside color, but not in the ultimate formatting call (this is also know as “scoping” - and in this case “dynamic scoping”)


Frames can “inherit” values from other frames - this is used a great deal internally, but rarely will you need to use it explicitly. There are two special slot names used for this:

Slot Used for
:proto: Providing an abstract frame that this is based on at creation time
:parent: Providing an “enclosing” frame that this is contained in during execution

When asking for a value of a frame, if the frame doesn’t contain one with that slot name, it will first look in the :proto: slot’s frame (if any) for that key. If there is nothing there, it will look in the :parent: slot (if any). To give an example of how this would work, consider a group of orcs. All orcs are basically the same, though they may have different HPs. So each orc would be represented by an frame that has a “CURHP” slot with the current health, but all would have a :proto: that refers to the same frame (providing all the basic information such as AC, attacks, etc..). This is classical “prototype inheritance” where instance is based on another (this is the model for JavaScript objects as well as NewtonScript).

:parent: based more on runtime nesting of object. An example of this would in a character sheet - a row in the “attacks” section of the sheet would have the character sheet data as a whole as its :parent:. Or for some sort of encounter, a room would have the current “zone” as its ::parent: and that zone would have the level as its :parent: and that would have the module as its :parent:.

As an example of where this is used internally, consider the following:

  1. @W{
  2. “:table:” : “Got %:item”
  3. | “item”:{
  4. 17:“%:material”
  5. | 810:“%:color %:material”
  6. }
  7. | “color”:{
  8. 16:“Red”
  9. | 79:“Blue”
  10. }
  11. | “material”:{
  12. 14:“Silk”
  13. | 610:“Cotton”
  14. }
  15. }.
  16. string(@W)

Most of the time it will spit out “Silk” or “Cotton”, but sometimes it will also apply a color to it. Note that references to the color and material table are actually made from within a table in lines 3 through 6. In order for that inner frame to find color and material, the runtime actually creates a new object whose :proto: is the frame on line 3 and whose :parent: is the whole frame on lines 1 through 15. This allows the text generation system to be able to generate the first table (which it finds through :proto: inheritance) and access color and material (via :parent: inheritance).

See “Libraries and Extensions” for more details about how to define generators.


ELDARScript and The Dicenomicon include support for working with items that are expressed in units (this has changed and been improved significantly in 2.0). One prime example of where this is useful is with keeping track of money - you can’t just have a single value, since there will be gold, silver, copper, etc… What’s more, you can convert from one form to the other (i.e., “making change”). To make matters even worse, in many campaigns, there is different currency in different locations. To deal with this, we have the ability to mark a frame as being a scalar unit. These units are defined inside XML configuration files , which define:

  • Unordered List ItemFamily of the unit (money, time, distance, etc…)
  • Name of unit and abbreviation (“Common gold/gp”, etc…)
  • Each unit has a conversion ratio to a standard unit (“20 silver to 1 gold”)

When a frame has a slot named “:unit:”, this is the name of family of the unit. Every unit that is a member of that family can have a corresponding slot. For example:

  1. @wealth <- {
  2. “:unit:” : “money”
  3. | “gold” : 3
  4. | “silver” : 10
  5. }

Much like the “:table:” key, having this “:unit:” key invokes special formatting to display this showing the abbreviated form of the units (in this example, it would format as “3 gp, 10 sp”). There are also functions to convert from one unit to another, and in general, make change (by converting rational values to integer where possible).

See “Libraries and Extensions” for more details about how to define units.

elderscript_advanced_operators.txt · Last modified: 2019/07/17 16:47 by dicenomiwiki