Difference between revisions of "Cabal Common Library Doc PhraseGen"

From Elite Wiki
(Started documentation)
 
m (Retagged!)
 
(24 intermediate revisions by one other user not shown)
Line 1: Line 1:
 
== Overview ==
 
== Overview ==
 +
[[Image:CCL PhraseGen Tool.gif|thumb|right|200px|Helper tool]]
 
This is the main class for the generator with its members and part of the [[Cabal_Common_Library]].
 
This is the main class for the generator with its members and part of the [[Cabal_Common_Library]].
  
PhraseGen is a generator for phrases, names, sentences or other messages and works similiar to other random mechanisms on the net. It uses 3 scripts:
+
Generating meaningful sentences from a pool of available words is hard to achieve, combining lots of available words often needs thinking, planning and pen and paper work before it gets halfway useable (or pretty complex tools).
  
* a data script holds a few objects only (words, sets, irregular nouns, irregualar verbs and superlatives).
+
CCL_PhraseGen is a tool to aid OXP developers in this process and also implements a way to use these presets in the game itself. It works similiar to other random mechanisms on the net with lots of additional features and uses the 'soft' references in JS.
* a build script which prefills some lists, processes OXP input and handles the rules.
 
* a helper script which does the communication between HTML and build script. This is not used in Oolite.
 
  
 +
* the data script (Cabal_Common_PhraseGenWords.js) holds a few objects only (words, Samples, irregular nouns, irregular verbs and superlatives).
 +
* the build script (Cabal_Common_PhraseGen.js) which prefills some lists, processes OXP input and handles the rules.
 +
* the helper script (PhraseGen.js) which does the communication between HTML and build script. This is not used in Oolite.
  
The words object is the heart of the whole thing. It contains arrays which are used in the sets. Multiple arrays can be concatenated easily and content can be reused - if I recall it right it's a similiar approach to CMcLs RandomShipNames.oxp. The concept is basically using the 'soft' references in JS.
+
The tool works in Firefox and other browsers using the same engine.
  
Every set contains 18 arrays with words (or phrases) and a array with sentence patterns.
 
  
The helper script + HTML will be available as separate download, but probably only works properly in Firefox/SeaMonkey. If someone wants to create a crossbrowser version, give me a call.
+
== How it works ==
 +
CCL_PhraseGen uses a collection (a [[#Samples|Sample]]) of words, sylables or phrases which are ordered in 18 available arrays ([[#Fields|Fields]]) and a special array which controls how these should be combined ([[#Patterns|Pattern]]). Fields and Patterns have their own set of rules (e.g. to control pluralization). Fields can hold lots of single words or even complete sentences and, basically, entries in Fields are selected randomly, but a optional seed is available.
  
 +
You can imagine a Sample as a wardrobe with drawers. The Pattern controls which drawer gets opened and the script picks one item out of it and attaches it to the final output before it walks further over the Pattern.
  
== How it works ==
+
The script simply replaces the numbers (1-9) in the Pattern with content from the Field arrays.
The script simply replaces the numbers (1-9) in the pattern with content from the arrays.
 
  
Switching between 1-9 and 10-18 is done via special char. Some other special chars are giving patterns some more oompf, e.g. for displaying player.name or setting flags for the word processing. And when a word is picked from the arrays additional rules are applied before it replaces the number in the pattern. The rules are designed to work with english words (some exceptions are handled).
+
Switching between Field 1-9 and 10-18 is done via special char. Some other special chars are giving Patterns some more oompf, e.g. for displaying player.name or setting flags for the word processing. And when a word is picked from the arrays additional [[#Rules|rules]] are applied before it replaces the number in the Pattern. The rules are designed to work with english words (some exceptions are handled).
  
 
Main goal is performance while handling a wide range of possibilities and it really looks promising.
 
Main goal is performance while handling a wide range of possibilities and it really looks promising.
  
The script also precreates some specials and populates the corresponding arrays to be combined via pattern when a OXP requests it.
+
The script also precreates some specials and populates the corresponding arrays to be combined via Pattern when a OXP requests it. Additionally Fields can be [[#Field combiner|related to each other]] and even a [[#Conditional|conditional markup]] is processed (recursion depth is limited). Samples can additionally use other more specialized Samples, e.g. to create names (again recursion depth is limited).
 +
 
 +
All Samples have the same form (although some may have more members):
 +
SampleName: {
 +
  fieldA: [],
 +
  fieldB: [],
 +
  fieldC: [],
 +
  ...
 +
  fieldR: [],
 +
  sentences: []
 +
}
 +
The Fields A-I (1-9) are treated as row1, J-R (10-18) as row2.
 +
 
 +
In cases where the Sample reaches the recursion depth limit (Field or Sample recursion), the script takes the entry as is without further expanding. It is adviced to use the [[#recGuard|recursion guard]] while writing and testing.
 +
 
 +
Best performance is reached by moving as much as possible into the Fields. The script checks Patterns char by char.
 +
 
 +
 
 +
== Samples ==
 +
There are a couple of Samples included.
 +
 
 +
=== CCL_Names ===
 +
A mixture between sylables and fixed names for humans, e.g Ron Ironwood.
 +
Uses [[#CCL_NamesOolite|CCL_NamesOolite]].
 +
Also used to prefill Pattern expansion @F and @N.
 +
 
 +
=== CCL_NamesOolite ===
 +
Similiar to Oolite own name generation, e.g. Wilkins.
 +
 
 +
=== CCL_NamesPirates ===
 +
Fixed names, e.g. Barnaby 'The Cantankerous' Morgan.
 +
 
 +
=== CCL_NamesOther ===
 +
Names based on race, e.g. Beggers Athifire.
 +
Uses [[#CCL_NamesOolite|CCL_NamesOolite]] for humans.
 +
 
 +
=== CCL_NamesShips ===
 +
Generates ship names, e.g. The Golden Tiger.
 +
Also used to prefill Pattern expansion @i.
 +
 
 +
=== CCL_NumPattern ===
 +
e.g. NX-305
 +
 
 +
=== CCL_NamesBrews ===
 +
e.g. Blasting Evening's Ferment.
 +
Also used to prefill Pattern expansion @Z.
 +
 
 +
=== CCL_NamesGods ===
 +
e.g. Six-headed Homerus
 +
 
 +
=== CCL_Blessing ===
 +
e.g. Let Kosior the Eternal kiss you!
 +
Uses [[#CCL_NamesGods|CCL_NamesGods]].
 +
 
 +
=== CCL_PirateInsult ===
 +
e.g. You poisonous mound of scum!
 +
 
 +
 
 +
== Examples of usage ==
 +
=== Simple ===
 +
var a = worldScripts.Cabal_Common_PhraseGen.makePhrase("CCL_Names");
 +
 
 +
=== Simple with specific Pattern ===
 +
var a = worldScripts.Cabal_Common_PhraseGen.makePhrase("CCL_Names","1 {12");
 +
 
 +
=== Own Samples ===
 +
var b = {
 +
  fieldA:["hello"],fieldB:["world"],fieldC:[],fieldD:[],fieldE:[],fieldF:[],fieldG:[],fieldH:[],fieldI:[],
 +
  fieldJ:[],fieldK:[],fieldL:[],fieldM:[],fieldN:[],fieldO:[],fieldP:[],fieldQ:[],fieldR:[],sentences:["1 2!"]
 +
};
 +
var a = worldScripts.Cabal_Common_PhraseGen.makePhrase(b);
 +
 
 +
=== Own Samples II ===
 +
The words object in <tt>CCL_PhraseGenWord.js</tt> (this.w) can be used to fill your Fields with values. The object itself is frozen to avoid accidental changes by other OXPs if references are used. OXPs can still use the words object in their own scripts.
 +
 
 +
A. If you have single references to the words object and don't need to alter it (recommended way).
 +
In this example fieldA is frozen, memory usage is low (only a reference is used).
 +
 
 +
var w = worldScripts.Cabal_Common_PhraseGenWords.w;
 +
var OXP_Sample_A = {
 +
  fieldA: w.p.wish2,
 +
  ...
 +
};
 +
 
 +
B. If you have multiple references or need to change values in the Sample.
 +
No reference is used, concat() creates a new object, memory usage is higher.
 +
 
 +
var w = worldScripts.Cabal_Common_PhraseGenWords.w;
 +
var OXP_Sample_A = {
 +
  fieldA: [].concat(w.p.wish2),
 +
  ...
 +
};
 +
 
  
Additionally fields can be related to each other and even a conditional markup is processed (recursion depth is limited).
+
== Properties ==
 +
=== recGuard ===
 +
Boolean. Recursion depth guard. If depth limit is reached it will spit out warnings. The Helper tool has a option to enable it.
  
  
 
== Methods ==
 
== Methods ==
 
=== makePhrase() ===
 
=== makePhrase() ===
{{CodeEx|codeex=var a = worldScripts.Cabal_Common_PhraseGen.makePhrase(setname [,pattern]);}}
+
{{CodeEx|codeex=var a = worldScripts.Cabal_Common_PhraseGen.makePhrase( samplename [,pattern [,store [,seed [,custom]]]] );}}
 
Is simple and straightforward. When called the method returns the created string.
 
Is simple and straightforward. When called the method returns the created string.
  
 
'''Parameters:'''
 
'''Parameters:'''
:;setname:String/Object.
+
:;samplename: String/Object.
:::String:PhraseGen looks up if the pool contains a set with this name.
+
:::String: PhraseGen looks up if the pool contains a Sample with this name.
:::Object:PhraseGen uses the passed object.
+
:::Object: PhraseGen uses the passed object.
 +
 
 +
:;pattern: String/Array. Optional. If not specified PhraseGen will use a randomly choosen pattern from the current Sample.
 +
:::String: Pattern.
 +
:::Array: PhraseGen will randomly choose a element, if seed is not used.
 +
 
 +
:;store: Boolean. Optional. It true PhraseGen will return a array instead.
 +
 
 +
:;seed: Number. Optional. If a positive integer it influences the selection of Patterns and Field entries and the conditional (D) dice roll.
  
:;pattern:String/Array. Optional. If not specified PhraseGen will use a randomly choosen pattern from the current set.
+
:;custom: Array. The first entry must be a number which is used as bitmask. This can be used to control the flow in Samples. The following entries are strings to be used in Patterns (@Y1...@Y#).
:::String:
 
:::Array:PhraseGen will randomly choose a element.
 
  
 
'''Returns:'''
 
'''Returns:'''
:;phrase:String. The generated string or false.
+
:;phrase: String. The generated string or false.
 +
:;phrase: Array.
 +
:::Element 0: String. The generates string or false.
 +
:::Element 1: Object. Holding various members for further processing in scripts.
  
  
=== addSet() ===
+
=== addSample() ===
{{CodeEx|codeex=var a = worldScripts.Cabal_Common_PhraseGen.addSet(setname, obj [,clone]);}}
+
{{CodeEx|codeex=var a = worldScripts.Cabal_Common_PhraseGen.addSet( samplename, obj [,clone] );}}
For adding data to the pool there are two possible ways.
+
For adding data to the Sample pool there are two possible ways.
  
 
'''Parameters:'''
 
'''Parameters:'''
:;setname:String. Unique identifier for the set. Probably the easist way is to use OXPName_SetID.
+
:;samplename:String. Unique identifier for the Sample. Probably the easist way is to use OXPName_SetID.
:;obj:Object. Holds the arrays with words and patterns.
+
:;obj:Object. Holds the arrays with words and Patterns.
 
:;clone:Boolean. Optional. If specified PhraseGen creates a deepcopy of the object. Otherwise it will store a object holding references.
 
:;clone:Boolean. Optional. If specified PhraseGen creates a deepcopy of the object. Otherwise it will store a object holding references.
  
 
'''Returns:'''
 
'''Returns:'''
:;success:Boolean. True if set was placed, otherwise false.
+
:;success:Boolean. True if Sample was placed, otherwise false.
 +
 
 +
 
 +
== Rules ==
 +
The following rules are processed by PhraseGen:
 +
 
 +
=== Patterns ===
 +
Patterns are simple strings to control the sentence building. They can contain plain text, control chars
 +
or [[#Conditional|conditional checks]] (with [[#Field combiner|Field combiners]] or words/phrases as actions). The script replaces numers (in range 1-9) with content from the Samples Field arrays.
 +
 
 +
First letter and next word after . ! or ? is capitalized
 +
+ -> Forces capitalization
 +
} -> Forces Fields 1-9
 +
{ -> Forces Fields 10-18
 +
> -> Applies plural rules
 +
< -> Applies singular rules (probably obsolete)
 +
| -> Random plural (50%)
 +
# -> Verb case 1. simple present
 +
_ -> Verb case 2. simple past
 +
^ -> Verb case 3. past participle
 +
* -> Verb case 4. perfect
 +
@B -> player.bounty
 +
@C -> player.name
 +
@D -> player.ship.displayName
 +
@F -> Random Firstname *
 +
@I -> player.ship.name
 +
@L -> player.legalStatus
 +
@N -> Random Surname *
 +
@P -> Current system.name
 +
@R -> player.rank
 +
@S -> Random system.name *
 +
@T -> player.ship.target.displayName
 +
@X -> Select random system
 +
@W -> Random full name *
 +
@Y1-@Yx -> Custom Sample settings
 +
@Z -> Random Brew name *
 +
@a -> Random Roman Numerals
 +
@b -> Random Letters A-Z
 +
@c -> Random Numbers 0-9
 +
@d -> Random date. clock.days-(1-7)
 +
@f -> Stored @F, if empty @F
 +
@h -> Inhabitant from @S *
 +
@i -> Random ShipName *
 +
@n -> Stored @N, if empty @N
 +
@s -> Stored @S, if empty @S
 +
@z -> Stored @Z, if empty @Z
 +
@0-@9 -> Reusable stored values (*)
 +
a followed by
 +
  ^[FHLMNRSX][A-Z] -> an
 +
  ^u[^aeiou\d\s][^aeiou\d\s] -> an
 +
  ^un[aeou] -> an
 +
  ^uni && ^unim|(?:ive|ble)$ -> an
 +
  ^(?:[aei]|o[^ne]|ho(?:ur|nest|no|mage|mbre|rs d')|he(?:ir|rb)) -> an
 +
a followed by superlative -> the
 +
[a-zA-Z_] -> Sample combiner. Recursion depth is limited. By prefixing the Sample name with !, seed will be ignored.
 +
 
 +
=== Fields ===
 +
Fields can contain plain text, [[#Field combiner|Field combiners]] or [[#Conditional|conditional checks]].
 +
 
 +
$ -> identifies verb (e.g. decide$)
 +
& -> identifies irregular noun or verb (e.g. &go$ or &bison)
 +
[#] -> Field combiner. Recursion depth is limited.
 +
 
 +
=== Noun Plural ===
 +
& -> irregular, uses lookup table
 +
otherwise:
 +
  [^es]s -> unchanged
 +
  fe -> replace with ves
 +
  e -> word + s
 +
  [^o]o,[^ei]x,es[s],[cs]h -> word + es
 +
  [^aeiou]y -> replace with ies
 +
  [^erf]f -> replace with ves
 +
  [ei]x -> replace with ices
 +
  else -> word + s;
 +
 
 +
=== Verb Tenses ===
 +
& -> irregular, uses lookup table
 +
  Can be combined with plural prefix
 +
    case 0 -> base form, e.g. go
 +
    case 1 -> simple present, e.g. goes
 +
    case 2 -> simple past, e.g. went
 +
    case 3 -> past participle, e.g. gone
 +
    case 4 -> singular: has gone
 +
    case 4 -> plural: have gone
 +
otherwise:
 +
  case 0 -> base form
 +
  case 1 -> apply plural noun rules
 +
  case 2 ->
 +
    e -> word + d
 +
    [^aeou]y -> replace with ied
 +
    [^adeliosy][aeioy][bcdfgjklmnpqrsvz] -> word + last char + ed
 +
    else -> word + ed
 +
  case 3 ->
 +
    e -> word + d
 +
    [^aeou]y -> replace with ied
 +
    [^adeliosy][aeioy][bcdfgjklmnpqrsvz] -> word + last char + ed
 +
    else -> word + ed
 +
  case 4 -> singular: has + case 3
 +
  case 4 -> plural: have + case 3
 +
 
 +
=== Field combiner ===
 +
Field combiner are used to place content of Fields of the same row in other Fields.
 +
The rows are Field 1-9 (A-I) and Field 10-18 (J-R). Recursion depth is limited.
 +
 
 +
[#] -> Field combiner
 +
 
 +
=== Conditional ===
 +
PhraseGen can also be instructed to check values against collected data and react accordingly.
 +
After <tt>.startUp</tt> and <tt>.playerEnteredNewGalaxy</tt> PhraseGen stores the nodes from [[Cabal_Common_Library_Doc_Functions#moreInfo|Cabal_Common_Library_Doc_Functions]] and the node of the current system (additionally updated on launching and exiting witchspace).
 +
 
 +
These nodes are used to compare the instructions in Fields and Patterns against the nodes values. E.g.
 +
(Sg>0,e!5=[7]|[6])
 +
 
 +
Nested conditionals like <tt>(Sg>0=[7]|(Se>5=[7]|[6]))</tt> are not supported, but stacked ones are possible,
 +
fieldA (Sg>0=[3]|[5])
 +
fieldC (Se>0=[7]|[6])
 +
 
 +
Multiple checks in the same Field are supported
 +
The (Sg>0=standard|anarchy) system is (Se>4=agricultural|industrial)
 +
 
 +
Syntax:
 +
Must be enclosed by round brackets.
 +
A: (Any, bitmask)
 +
  Number.
 +
  Checks if all Bits are set, e.g. (A3=[3]|[5])
 +
B: (Bitmask)
 +
  Number 0-24
 +
  operators:
 +
    + -> sets the bit, e.g. (B2+)
 +
    - -> clears the bit, e.g. (B2-)
 +
    = -> checks the bit and handles the following actions, e.g. (B2=[3]|[5])
 +
D: (Dice roll)
 +
    Number in range 1-100. Checked if greaterthan random number, e.g. (D50=yes|no). Ignored if seed is used.
 +
    or 3 Numbers to generate random number in range param1-param2 in steps of param3 e.g. (D25,150,25)
 +
G: (Galaxy)
 +
    Number. Uses galaxyNumber, e.g. (G2=[2]|[4])
 +
N: (None, bitmask)
 +
    Number.
 +
    Checks if all bits are unset, e.g. (N0x34=[1]|[2])
 +
S, P: (node handling with S = @S, P = @P)
 +
  multiple conditions are separated by , (logical AND)
 +
  type:
 +
    c -> productivity
 +
    d -> description token, e.g. civil war
 +
    e -> economy
 +
    g -> government
 +
    i -> inhabitant token, e.g. frog
 +
    p -> population
 +
    r -> radius
 +
    s -> sun
 +
    t -> techlevel
 +
  operators:
 +
    : -> equal
 +
    < -> lessthan
 +
    > -> greaterthan
 +
    ! -> not equal
 +
Y: (Any, Bitmask)
 +
  Number.
 +
  Checks if any Bit is set, e.g. (Y3=[3]|[5])
 +
actions:
 +
  = -> identifies the actions
 +
  | -> separator matched / not matched
 +
 
  
 +
== Undocumented yet ==
 +
* splitRules
  
 
----
 
----
[[Category:OXPDoc]]
+
[[Category:OXP API's]]

Latest revision as of 15:09, 20 September 2023

Overview

Helper tool

This is the main class for the generator with its members and part of the Cabal_Common_Library.

Generating meaningful sentences from a pool of available words is hard to achieve, combining lots of available words often needs thinking, planning and pen and paper work before it gets halfway useable (or pretty complex tools).

CCL_PhraseGen is a tool to aid OXP developers in this process and also implements a way to use these presets in the game itself. It works similiar to other random mechanisms on the net with lots of additional features and uses the 'soft' references in JS.

  • the data script (Cabal_Common_PhraseGenWords.js) holds a few objects only (words, Samples, irregular nouns, irregular verbs and superlatives).
  • the build script (Cabal_Common_PhraseGen.js) which prefills some lists, processes OXP input and handles the rules.
  • the helper script (PhraseGen.js) which does the communication between HTML and build script. This is not used in Oolite.

The tool works in Firefox and other browsers using the same engine.


How it works

CCL_PhraseGen uses a collection (a Sample) of words, sylables or phrases which are ordered in 18 available arrays (Fields) and a special array which controls how these should be combined (Pattern). Fields and Patterns have their own set of rules (e.g. to control pluralization). Fields can hold lots of single words or even complete sentences and, basically, entries in Fields are selected randomly, but a optional seed is available.

You can imagine a Sample as a wardrobe with drawers. The Pattern controls which drawer gets opened and the script picks one item out of it and attaches it to the final output before it walks further over the Pattern.

The script simply replaces the numbers (1-9) in the Pattern with content from the Field arrays.

Switching between Field 1-9 and 10-18 is done via special char. Some other special chars are giving Patterns some more oompf, e.g. for displaying player.name or setting flags for the word processing. And when a word is picked from the arrays additional rules are applied before it replaces the number in the Pattern. The rules are designed to work with english words (some exceptions are handled).

Main goal is performance while handling a wide range of possibilities and it really looks promising.

The script also precreates some specials and populates the corresponding arrays to be combined via Pattern when a OXP requests it. Additionally Fields can be related to each other and even a conditional markup is processed (recursion depth is limited). Samples can additionally use other more specialized Samples, e.g. to create names (again recursion depth is limited).

All Samples have the same form (although some may have more members):

SampleName: {
  fieldA: [],
  fieldB: [],
  fieldC: [],
  ...
  fieldR: [],
  sentences: []
}

The Fields A-I (1-9) are treated as row1, J-R (10-18) as row2.

In cases where the Sample reaches the recursion depth limit (Field or Sample recursion), the script takes the entry as is without further expanding. It is adviced to use the recursion guard while writing and testing.

Best performance is reached by moving as much as possible into the Fields. The script checks Patterns char by char.


Samples

There are a couple of Samples included.

CCL_Names

A mixture between sylables and fixed names for humans, e.g Ron Ironwood. Uses CCL_NamesOolite. Also used to prefill Pattern expansion @F and @N.

CCL_NamesOolite

Similiar to Oolite own name generation, e.g. Wilkins.

CCL_NamesPirates

Fixed names, e.g. Barnaby 'The Cantankerous' Morgan.

CCL_NamesOther

Names based on race, e.g. Beggers Athifire. Uses CCL_NamesOolite for humans.

CCL_NamesShips

Generates ship names, e.g. The Golden Tiger. Also used to prefill Pattern expansion @i.

CCL_NumPattern

e.g. NX-305

CCL_NamesBrews

e.g. Blasting Evening's Ferment. Also used to prefill Pattern expansion @Z.

CCL_NamesGods

e.g. Six-headed Homerus

CCL_Blessing

e.g. Let Kosior the Eternal kiss you! Uses CCL_NamesGods.

CCL_PirateInsult

e.g. You poisonous mound of scum!


Examples of usage

Simple

var a = worldScripts.Cabal_Common_PhraseGen.makePhrase("CCL_Names");

Simple with specific Pattern

var a = worldScripts.Cabal_Common_PhraseGen.makePhrase("CCL_Names","1 {12");

Own Samples

var b = {
  fieldA:["hello"],fieldB:["world"],fieldC:[],fieldD:[],fieldE:[],fieldF:[],fieldG:[],fieldH:[],fieldI:[],
  fieldJ:[],fieldK:[],fieldL:[],fieldM:[],fieldN:[],fieldO:[],fieldP:[],fieldQ:[],fieldR:[],sentences:["1 2!"]
};
var a = worldScripts.Cabal_Common_PhraseGen.makePhrase(b);

Own Samples II

The words object in CCL_PhraseGenWord.js (this.w) can be used to fill your Fields with values. The object itself is frozen to avoid accidental changes by other OXPs if references are used. OXPs can still use the words object in their own scripts.

A. If you have single references to the words object and don't need to alter it (recommended way). In this example fieldA is frozen, memory usage is low (only a reference is used).

var w = worldScripts.Cabal_Common_PhraseGenWords.w;
var OXP_Sample_A = {
  fieldA: w.p.wish2,
  ...
};

B. If you have multiple references or need to change values in the Sample. No reference is used, concat() creates a new object, memory usage is higher.

var w = worldScripts.Cabal_Common_PhraseGenWords.w;
var OXP_Sample_A = {
  fieldA: [].concat(w.p.wish2),
  ...
};


Properties

recGuard

Boolean. Recursion depth guard. If depth limit is reached it will spit out warnings. The Helper tool has a option to enable it.


Methods

makePhrase()

var a = worldScripts.Cabal_Common_PhraseGen.makePhrase( samplename [,pattern [,store [,seed [,custom]]]] );

Is simple and straightforward. When called the method returns the created string.

Parameters:

samplename
String/Object.
String: PhraseGen looks up if the pool contains a Sample with this name.
Object: PhraseGen uses the passed object.
pattern
String/Array. Optional. If not specified PhraseGen will use a randomly choosen pattern from the current Sample.
String: Pattern.
Array: PhraseGen will randomly choose a element, if seed is not used.
store
Boolean. Optional. It true PhraseGen will return a array instead.
seed
Number. Optional. If a positive integer it influences the selection of Patterns and Field entries and the conditional (D) dice roll.
custom
Array. The first entry must be a number which is used as bitmask. This can be used to control the flow in Samples. The following entries are strings to be used in Patterns (@Y1...@Y#).

Returns:

phrase
String. The generated string or false.
phrase
Array.
Element 0: String. The generates string or false.
Element 1: Object. Holding various members for further processing in scripts.


addSample()

var a = worldScripts.Cabal_Common_PhraseGen.addSet( samplename, obj [,clone] );

For adding data to the Sample pool there are two possible ways.

Parameters:

samplename
String. Unique identifier for the Sample. Probably the easist way is to use OXPName_SetID.
obj
Object. Holds the arrays with words and Patterns.
clone
Boolean. Optional. If specified PhraseGen creates a deepcopy of the object. Otherwise it will store a object holding references.

Returns:

success
Boolean. True if Sample was placed, otherwise false.


Rules

The following rules are processed by PhraseGen:

Patterns

Patterns are simple strings to control the sentence building. They can contain plain text, control chars or conditional checks (with Field combiners or words/phrases as actions). The script replaces numers (in range 1-9) with content from the Samples Field arrays.

First letter and next word after . ! or ? is capitalized
+ -> Forces capitalization
} -> Forces Fields 1-9
{ -> Forces Fields 10-18
> -> Applies plural rules
< -> Applies singular rules (probably obsolete)
| -> Random plural (50%)
# -> Verb case 1. simple present
_ -> Verb case 2. simple past
^ -> Verb case 3. past participle
* -> Verb case 4. perfect
@B -> player.bounty
@C -> player.name
@D -> player.ship.displayName
@F -> Random Firstname *
@I -> player.ship.name
@L -> player.legalStatus
@N -> Random Surname *
@P -> Current system.name
@R -> player.rank
@S -> Random system.name *
@T -> player.ship.target.displayName
@X -> Select random system
@W -> Random full name *
@Y1-@Yx -> Custom Sample settings
@Z -> Random Brew name *
@a -> Random Roman Numerals
@b -> Random Letters A-Z
@c -> Random Numbers 0-9
@d -> Random date. clock.days-(1-7)
@f -> Stored @F, if empty @F
@h -> Inhabitant from @S *
@i -> Random ShipName *
@n -> Stored @N, if empty @N
@s -> Stored @S, if empty @S
@z -> Stored @Z, if empty @Z
@0-@9 -> Reusable stored values (*)
a followed by
  ^[FHLMNRSX][A-Z] -> an
  ^u[^aeiou\d\s][^aeiou\d\s] -> an
  ^un[aeou] -> an
  ^uni && ^unim|(?:ive|ble)$ -> an
  ^(?:[aei]|o[^ne]|ho(?:ur|nest|no|mage|mbre|rs d')|he(?:ir|rb)) -> an
a followed by superlative -> the
[a-zA-Z_] -> Sample combiner. Recursion depth is limited. By prefixing the Sample name with !, seed will be ignored.

Fields

Fields can contain plain text, Field combiners or conditional checks.

$ -> identifies verb (e.g. decide$)
& -> identifies irregular noun or verb (e.g. &go$ or &bison)
[#] -> Field combiner. Recursion depth is limited.

Noun Plural

& -> irregular, uses lookup table
otherwise:
  [^es]s -> unchanged
  fe -> replace with ves
  e -> word + s
  [^o]o,[^ei]x,es[s],[cs]h -> word + es
  [^aeiou]y -> replace with ies
  [^erf]f -> replace with ves
  [ei]x -> replace with ices
  else -> word + s;

Verb Tenses

& -> irregular, uses lookup table
  Can be combined with plural prefix
    case 0 -> base form, e.g. go
    case 1 -> simple present, e.g. goes
    case 2 -> simple past, e.g. went
    case 3 -> past participle, e.g. gone
    case 4 -> singular: has gone
    case 4 -> plural: have gone
otherwise:
  case 0 -> base form
  case 1 -> apply plural noun rules
  case 2 ->
    e -> word + d
    [^aeou]y -> replace with ied
    [^adeliosy][aeioy][bcdfgjklmnpqrsvz] -> word + last char + ed
    else -> word + ed
  case 3 ->
    e -> word + d
    [^aeou]y -> replace with ied
    [^adeliosy][aeioy][bcdfgjklmnpqrsvz] -> word + last char + ed
    else -> word + ed
  case 4 -> singular: has + case 3
  case 4 -> plural: have + case 3

Field combiner

Field combiner are used to place content of Fields of the same row in other Fields. The rows are Field 1-9 (A-I) and Field 10-18 (J-R). Recursion depth is limited.

[#] -> Field combiner

Conditional

PhraseGen can also be instructed to check values against collected data and react accordingly. After .startUp and .playerEnteredNewGalaxy PhraseGen stores the nodes from Cabal_Common_Library_Doc_Functions and the node of the current system (additionally updated on launching and exiting witchspace).

These nodes are used to compare the instructions in Fields and Patterns against the nodes values. E.g.

(Sg>0,e!5=[7]|[6])

Nested conditionals like (Sg>0=[7]|(Se>5=[7]|[6])) are not supported, but stacked ones are possible,

fieldA (Sg>0=[3]|[5])
fieldC (Se>0=[7]|[6])

Multiple checks in the same Field are supported

The (Sg>0=standard|anarchy) system is (Se>4=agricultural|industrial)

Syntax:

Must be enclosed by round brackets.
A: (Any, bitmask)
  Number.
  Checks if all Bits are set, e.g. (A3=[3]|[5])
B: (Bitmask)
  Number 0-24
  operators:
    + -> sets the bit, e.g. (B2+)
    - -> clears the bit, e.g. (B2-)
    = -> checks the bit and handles the following actions, e.g. (B2=[3]|[5])
D: (Dice roll)
    Number in range 1-100. Checked if greaterthan random number, e.g. (D50=yes|no). Ignored if seed is used.
    or 3 Numbers to generate random number in range param1-param2 in steps of param3 e.g. (D25,150,25)
G: (Galaxy)
    Number. Uses galaxyNumber, e.g. (G2=[2]|[4])
N: (None, bitmask)
    Number.
    Checks if all bits are unset, e.g. (N0x34=[1]|[2])
S, P: (node handling with S = @S, P = @P)
  multiple conditions are separated by , (logical AND)
  type:
    c -> productivity
    d -> description token, e.g. civil war
    e -> economy
    g -> government
    i -> inhabitant token, e.g. frog
    p -> population
    r -> radius
    s -> sun
    t -> techlevel
  operators:
    : -> equal
    < -> lessthan
    > -> greaterthan
    ! -> not equal
Y: (Any, Bitmask)
  Number.
  Checks if any Bit is set, e.g. (Y3=[3]|[5])
actions:
  = -> identifies the actions
  | -> separator matched / not matched


Undocumented yet

  • splitRules