Difference between revisions of "String Parsing Optimization"
(→[if ][end if] Mistakes) |
|||
(50 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | <br> String Parsing is a | + | <br> String Parsing is a scripting language for designing content on the Flexible Survival MUCK. The language supports read functions, write functions, and allows users to create dynamic content based on a combination of those functions. The language was originally designed and coded by Damaged and later refactored by Fauna for improved performance. |
+ | |||
+ | String Parsing by nature reduces performance when inserted into plain text. This article exists as a reference for those seeking to squeeze the most performance out of their code without reducing readability. For information on how to write parsing, see the wiki article on [http://wiki.flexiblesurvival.com/w/String_Parsing String Parsing] and review the in-game manual. | ||
− | |||
<br> | <br> | ||
+ | == Performance: Why should I care? == | ||
+ | |||
+ | 1) Optimized code reduces the perceived latency of navigation in a MUCK. | ||
− | + | 2) Optimized code reduces the Flexible Survival server load. | |
− | + | 3) Optimized code reduces the memory cost of programs and database references (#dbrefs). | |
− | |||
− | |||
− | |||
=== How does this relate to String Parsing? === | === How does this relate to String Parsing? === | ||
− | String Parsing is | + | String Parsing is pervasive. It can be placed in transformation messages, sex scenes, rooms, NPCs, and more. As a result, it's important to ensure that this code is functional, readable, and swift to execute. |
+ | |||
+ | For the subsequent sections, please use the in-game @viewparse command to indent and colorize markup for better legibility. | ||
+ | |||
+ | == Conditionals == | ||
− | + | === [if ][end if] === | |
+ | ---- | ||
+ | A basic [if ] statement is prone to syntactic errors. | ||
− | For | + | For genitals, appearance, and time, always use the template [if [target] is <thing>]. The "is" function has been optimized for these checks. |
− | == [if ] | + | ::'''<span style="color:#FF0000">[if [player] = neuter] |
+ | ::'''<span style="color:#FF0000">[if [player] = neutral] | ||
+ | ::'''<span style="color:#FF0000">[if time = day] | ||
+ | ::'''<span style="color:#008000">[if [player] is neuter] | ||
+ | ::'''<span style="color:#008000">[if [player] is neutral] | ||
+ | ::'''<span style="color:#008000">[if time is day] | ||
− | + | Use "==" to evaluate integers. Benchmarks have shown that this executes faster than checking for a string with "=". | |
+ | ::'''<span style="color:#FF0000">[if stat cocks of [player] = 1] | ||
+ | ::'''<span style="color:#008000">[if stat cocks of [player] == 1] | ||
− | + | Avoid not statements when possible. For example, [if time is not night] is the same as [if time is day]. | |
− | + | ::'''<span style="color:#FF0000">[if time is not night] | |
+ | ::'''<span style="color:#FF0000">[if time is not day] | ||
+ | ::'''<span style="color:#008000">[if time is day] | ||
+ | ::'''<span style="color:#008000">[if time is night] | ||
+ | <br> | ||
+ | === [if ][else][end if] === | ||
+ | ---- | ||
+ | Try to avoid duplicated words when using the [if ][else] structure. | ||
− | |||
− | |||
− | |||
− | + | ::'''<span style="color:#FF0000">[if time is day]A woman in tight jeans and an unassuming blouse mans the counter. She's twirling a pen in her fingers, seemingly disinterested in her body of work.[else]A woman in tight jeans and an unassuming blouse would normally man the counter. However, she doesn't appear to be here right now.[end if] | |
− | |||
− | |||
− | |||
− | + | ::'''<span style="color:#008000">A woman in tight jeans and an unassuming blouse [if time is day]mans the counter. She's twirling a pen in her fingers, seemingly disinterested in her body of work[else]would normally man the counter. However, she doesn't appear to be here right now[end if]. | |
− | :: | ||
− | |||
− | |||
− | |||
− | |||
− | [else] | + | In the above example, repeated text has been removed from the [if ][else] structure and added as a prefix. This provides the exact same user-visible output with less characters. Processing requirements are identical, but the text fits in less space and is just as readable. |
+ | Note: Do not do this for letters that are part of a word. Splitting words in text results in less readable code and hampers assistive technology like screen readers. | ||
<br> | <br> | ||
+ | |||
+ | === [if ][else if ][else][end if] === | ||
+ | ---- | ||
+ | This structure checks statements in brackets one after another, left to right. If a statement evaluates as true, the code stops and prints the text within. The structure requires consideration for order of events. | ||
+ | |||
+ | |||
+ | ::'''<span style="color:#FF0000">[if [player] is pure male]You are male[else if [player] is pure female]You are female[else if [player] is herm]You are a herm[else]You are neuter[end if]. | ||
+ | |||
+ | ::'''<span style="color:#008000">[if [player] is herm]You are a herm[else if [player] is female]You are female[else if [player] is male]You are male[else]You are neuter[end if]. | ||
+ | |||
+ | |||
+ | The full logic of the first snippet is | ||
+ | |||
+ | :[if (stat cocks of [player] > 0) and (stat cunts of [player] == 0)][else if (stat cunts of [player] > 0) and (stat cocks of [player] == 0)][else if (stat cocks of [player] > 0) and (stat cunts of [player] > 0)][else][end if] | ||
+ | |||
+ | The second snippet simplifies this logic to the equivalent of | ||
+ | |||
+ | :[if (stat cocks of [player] > 0) and (stat cunts of [player] > 0)][else if stat cunts of [player] > 0][else if stat cocks of [player] > 0][else][end if] | ||
+ | |||
+ | === [case ] === | ||
---- | ---- | ||
− | < | + | Case-statements are useful where lengthy [if ][else if ][end if] statements would result in redundancy. |
+ | |||
+ | |||
+ | ::'''<span style="color:#FF0000">[case stat X of [player] ==][when (target) 1]A[end when][when (target) 2]B[end when][when (target) 3]C[end when][when (target) 4]D[end when][when 1]E[end when] | ||
+ | |||
+ | ::'''<span style="color:#008000">[case [stat X of [player]] ==][when (target) 1]A[end when][when (target) 2]B[end when][when (target) 3]C[end when][when (target) 4]D[end when][when 1]E[end when] | ||
+ | |||
+ | |||
+ | If something is valid parsing on its own, such as '[stat X of [player]]' and '[the mutation X of [player]]', use that, so the stat will only have to be read once instead of in every [when ]-statement. | ||
+ | |||
+ | |||
+ | ::'''<span style="color:#FF0000">[if stat placeholder of [player] == 1]A[else if stat placeholder of [player] == 2]B[else if stat placeholder of [player] == 3]C[else if stat placeholder of [player] == 4]D[else if stat placeholder of [player] == 5]E[else]F[end if] | ||
+ | |||
+ | ::'''<span style="color:#008000">[case [stat placeholder of [player]] ==][when (target) 1]A[end when][when (target) 2]B[end when][when (target) 3]C[end when][when (target) 4]D[end when][when (target) 5]E[end when][when 1]F[end when][end case] | ||
+ | |||
− | + | In the above example, a complex [if ]-chain is optimized to only read a stat once and evaluate its stored value. | |
− | |||
+ | == Randomization == | ||
− | + | The following functions display content at random. Input is separated by [or]. | |
− | + | === [one of][or][at random] === | |
---- | ---- | ||
− | < | + | The standard [one of][or][at random] statement is prone to redundancy. |
+ | |||
+ | |||
+ | ::'''<span style="color:#FF0000">Sometimes, you need to do something. [one of]Other times,[or]Sometimes,[at random] you don't. | ||
+ | |||
+ | ::'''<span style="color:#008000">Sometimes, you need to do something. [one of]Other times[or]Sometimes[at random], you don't. | ||
+ | |||
+ | |||
+ | In the above example, text redundancy is reduced by moving a comma after [at random]. | ||
+ | |||
+ | |||
+ | ==== [with odds: ] ==== | ||
+ | |||
+ | [with odds: ] allows you to simplify many longer [one of] statements. | ||
+ | |||
+ | Example 1: | ||
− | |||
− | ::'' | + | ::'''<span style="color:#FF0000">[one of]1[or]1[or]1[or]1[or]1[or]2[at random] |
− | ::'' | + | ::'''<span style="color:#008000">[one of]1[or]2[with odds: 5 1] |
− | + | Example 2: | |
− | + | ::'''<span style="color:#FF0000">[one of]1[or]1[or]1[or]2[or]2[or]3[at random] | |
− | + | ::'''<span style="color:#008000">[one of]1[or]2[or]3[with odds: 3 2 1] | |
− | + | === [random x to y] === | |
---- | ---- | ||
− | < | + | This function is specialized for ranges of values. Note that it only accepts integers (negative ones included) and that 'x' should be less than 'y'. |
+ | |||
+ | |||
+ | ::'''<span style="color:#FF0000">[one of]1[or]2[or]3[or]4[or]5[or]6[at random] | ||
− | + | ::'''<span style="color:#008000">[random 1 to 6] | |
<br> | <br> | ||
Line 86: | Line 148: | ||
<br> | <br> | ||
− | + | [[Category:Guides]][[Category:Code]] | |
− | |||
− | [[Category:Guides]] |
Latest revision as of 20:17, 26 August 2020
String Parsing is a scripting language for designing content on the Flexible Survival MUCK. The language supports read functions, write functions, and allows users to create dynamic content based on a combination of those functions. The language was originally designed and coded by Damaged and later refactored by Fauna for improved performance.
String Parsing by nature reduces performance when inserted into plain text. This article exists as a reference for those seeking to squeeze the most performance out of their code without reducing readability. For information on how to write parsing, see the wiki article on String Parsing and review the in-game manual.
Contents
Performance: Why should I care?
1) Optimized code reduces the perceived latency of navigation in a MUCK.
2) Optimized code reduces the Flexible Survival server load.
3) Optimized code reduces the memory cost of programs and database references (#dbrefs).
How does this relate to String Parsing?
String Parsing is pervasive. It can be placed in transformation messages, sex scenes, rooms, NPCs, and more. As a result, it's important to ensure that this code is functional, readable, and swift to execute.
For the subsequent sections, please use the in-game @viewparse command to indent and colorize markup for better legibility.
Conditionals
[if ][end if]
A basic [if ] statement is prone to syntactic errors.
For genitals, appearance, and time, always use the template [if [target] is <thing>]. The "is" function has been optimized for these checks.
- [if [player] = neuter]
- [if [player] = neutral]
- [if time = day]
- [if [player] is neuter]
- [if [player] is neutral]
- [if time is day]
Use "==" to evaluate integers. Benchmarks have shown that this executes faster than checking for a string with "=".
- [if stat cocks of [player] = 1]
- [if stat cocks of [player] == 1]
Avoid not statements when possible. For example, [if time is not night] is the same as [if time is day].
- [if time is not night]
- [if time is not day]
- [if time is day]
- [if time is night]
[if ][else][end if]
Try to avoid duplicated words when using the [if ][else] structure.
- [if time is day]A woman in tight jeans and an unassuming blouse mans the counter. She's twirling a pen in her fingers, seemingly disinterested in her body of work.[else]A woman in tight jeans and an unassuming blouse would normally man the counter. However, she doesn't appear to be here right now.[end if]
- A woman in tight jeans and an unassuming blouse [if time is day]mans the counter. She's twirling a pen in her fingers, seemingly disinterested in her body of work[else]would normally man the counter. However, she doesn't appear to be here right now[end if].
In the above example, repeated text has been removed from the [if ][else] structure and added as a prefix. This provides the exact same user-visible output with less characters. Processing requirements are identical, but the text fits in less space and is just as readable.
Note: Do not do this for letters that are part of a word. Splitting words in text results in less readable code and hampers assistive technology like screen readers.
[if ][else if ][else][end if]
This structure checks statements in brackets one after another, left to right. If a statement evaluates as true, the code stops and prints the text within. The structure requires consideration for order of events.
- [if [player] is pure male]You are male[else if [player] is pure female]You are female[else if [player] is herm]You are a herm[else]You are neuter[end if].
- [if [player] is herm]You are a herm[else if [player] is female]You are female[else if [player] is male]You are male[else]You are neuter[end if].
The full logic of the first snippet is
- [if (stat cocks of [player] > 0) and (stat cunts of [player] == 0)][else if (stat cunts of [player] > 0) and (stat cocks of [player] == 0)][else if (stat cocks of [player] > 0) and (stat cunts of [player] > 0)][else][end if]
The second snippet simplifies this logic to the equivalent of
- [if (stat cocks of [player] > 0) and (stat cunts of [player] > 0)][else if stat cunts of [player] > 0][else if stat cocks of [player] > 0][else][end if]
[case ]
Case-statements are useful where lengthy [if ][else if ][end if] statements would result in redundancy.
- [case stat X of [player] ==][when (target) 1]A[end when][when (target) 2]B[end when][when (target) 3]C[end when][when (target) 4]D[end when][when 1]E[end when]
- [case [stat X of [player]] ==][when (target) 1]A[end when][when (target) 2]B[end when][when (target) 3]C[end when][when (target) 4]D[end when][when 1]E[end when]
If something is valid parsing on its own, such as '[stat X of [player]]' and '[the mutation X of [player]]', use that, so the stat will only have to be read once instead of in every [when ]-statement.
- [if stat placeholder of [player] == 1]A[else if stat placeholder of [player] == 2]B[else if stat placeholder of [player] == 3]C[else if stat placeholder of [player] == 4]D[else if stat placeholder of [player] == 5]E[else]F[end if]
- [case [stat placeholder of [player]] ==][when (target) 1]A[end when][when (target) 2]B[end when][when (target) 3]C[end when][when (target) 4]D[end when][when (target) 5]E[end when][when 1]F[end when][end case]
In the above example, a complex [if ]-chain is optimized to only read a stat once and evaluate its stored value.
Randomization
The following functions display content at random. Input is separated by [or].
[one of][or][at random]
The standard [one of][or][at random] statement is prone to redundancy.
- Sometimes, you need to do something. [one of]Other times,[or]Sometimes,[at random] you don't.
- Sometimes, you need to do something. [one of]Other times[or]Sometimes[at random], you don't.
In the above example, text redundancy is reduced by moving a comma after [at random].
[with odds: ]
[with odds: ] allows you to simplify many longer [one of] statements.
Example 1:
- [one of]1[or]1[or]1[or]1[or]1[or]2[at random]
- [one of]1[or]2[with odds: 5 1]
Example 2:
- [one of]1[or]1[or]1[or]2[or]2[or]3[at random]
- [one of]1[or]2[or]3[with odds: 3 2 1]
[random x to y]
This function is specialized for ranges of values. Note that it only accepts integers (negative ones included) and that 'x' should be less than 'y'.
- [one of]1[or]2[or]3[or]4[or]5[or]6[at random]
- [random 1 to 6]