gene.sis
CHYOA Guru
I'm currently working on a "Formula Parser" for Conditional Branch Stories.
It is an addition to the current possibilities to change Conditional Branch Variables.
Now I want to introduce you the currently planned syntax and would like to get some feedback about it and suggestions about missing functions.
There is a summary of functions at the end of this post (tldr).
(Please note, that everything described below isn't available yet and can be different when this feature will be finally published.)
The syntax for the formulas is inspired by the syntax of spreadsheet formulas, so if you have experience with spreadsheets you may be already familiar with it.
Why using formulas?
- Use of more complex mathematical operations. (e.g. add 20% of the current value)
- Use of conditional calculations. (e.g. if {charisma} is below 50, add 10 points, else add 5 points)
- Use of calculations with other Score Variables. (e.g. if {charisma}+{negotiating skill} is below 15 )
- Use of randomize functions.
Note: The most examples used below are using numbers to illustrate the functions while keeping it simple. Usually, most of the numbers would be functions or variables. (there are some more complex examples under 12.)
General usage:
Create a Score Change of the desired type, choose "formula" as operator and type your formula into the value field.
The Variable named in the left is the receiver of the calculated value of the formula.
If the previous value of the variable should be modified by the formula, you have to include the variable into the formula.
1. Result
Boolean variables: If the result of the formula is equal 0, the variable will be set to "false". Else the variable will be set to "true".
Numerical and Progress variables: The result will be converted into an integer (round down).
Within a formula, all calculations will be done with floating point numbers.
2. Syntax Errors
The syntax of the formula will be checked while saving the chapter. If the syntax isn't valid, the formula won't be saved.
3. Calculation Errors
Some errors may occur while evaluating a formula with actual values from variables (e.g. division by zero) or with nonexistent variables.
These uncaught "errors" will be evaluated as 0 to be able to calculate the rest of the formula.
There are functions to cover those situations and provide a default value.
4. Numbers
You can use any integer or floating point number.
You can use a decimal separator of your choice (decimal point or decimal comma).
You can omit leading zeros.
You mustn't use thousand separators.
5. Variables
You can use Score Variables within your formula.
6. Comments
You can use comments to remind yourself or an editor what the formula is about.
Write "//" followed by your comment at the end of your formula.
7. Mathematical calculations
You can use mathematical calculations with following operators (normal precedence)
8. functions
Functions usually looks like this:
Each function can have a definite or an indefinite number of parameters (depends on the function).
The semicolons are used as separators for the parameters.
A parameter can be a number, a variable, a function or a condition (depends on the function).
9. general functions
IF( condition ; value ; value )
This function checks if the "condition" is true. If so, the result will be the first "value" (parameter 2), else the second "value" (parameter 3).
ROUND( value [; number of decimal places] )
ROUNDUP( value [; number of decimal places] )
ROUNDDOWN( value [; number of decimal places] )
This functions can be used to round a value to a number of decimal places.
The parameter "number of decimal places" is optional. If omitted, the value will be rounded to no decimal places.
If the parameter is negative, the value will be rounded to a number of places before the decimal point.
POW( base ; exponent )
This function can be used to calculate the power of a number.
MOD( dividend ; divisor )
This function can be used to perform modulo operation on numbers.
IFNOTSET( variable ; alternative value )
This function can be used to provide a default value if a variable doesn't exists in the readers score. This function removes the error flag from the variable value.
IFERROR( value ; alternative value )
This function can be used to provide a default value if a value has an error flag. This removes an error flag from the value.
DICE( [number of sides] )
This function can be used to do a dice roll. The result will be a random integer between 1 and "number of sides".
The parameter "number of sides" is optional. If omitted, "number of sides" is supposed to be 6
RANDOM()
This function can be used to create a random floating point number between 0 and 1.
MIN( value ; value [; value [; ...]] )
MAX( value ; value [; value [; ...]] )
These functions can be used to determinate the minimum/maximum of two or more values.
You can use the as many additional values to compare.
SAVEnumber( value )
RETURNnumber()
These functions are used to save a value as a formula-internal interim result and return it at another position. This is necessary, if you work with random numbers or dice rolls. It can also be useful to shorten complex formulas.
"number" is the number to identify a particular interim result.
10. conditions
Conditions consist of two values connected by a comparison operator or a single value.
They can only be used within the IF-function and the logical functions (see 11.).
Available operators:
You can also use a single value as condition.
If the value is 0, the result will be "false", else the result will be "true".
11. logical functions
You can use logical functions wherever you can use a condition.
AND( condition ; condition [; condition [; ...]] )
OR( condition ; condition [; condition [; ...]] )
You can use these functions to evaluate multiple conditions
NOT( condition )
You can use this function to reverse the result of a condition.
12. concrete examples
Someone steals 20 backs from your purse. To ensure, that your purse won't contain a "negative amount of money, the thief will take only the rest, if you don't have that much.
Haggling. If haggling is successful, the price will be reduced by 3% per point of haggling skill. If haggling fails badly, the price will be 20% higher than normal.
Perform an attack and calculate the damage you do to your enemy. In most cases you would want to split this formula into smaller pieces, because you probably also want to tell the reader, if you hit, if the enemy parried and if the enemies armor absorbed the damage.
Calculate the attractiveness of a woman to the protagonist. (In this example we assume a 37 year old redhead with medium bust size. Haircolor and bust size are determinated by numbers in this example)
The attributes are weighted (hair color 3, bust size 2, age 3). if one of the attributes is important, the weighting gets doubled.
Summary of functions:
- use of numbers (allows decimal point and decimal comma and omitting of leading zeros)
- use of Score variables: {variable}
- mathematical operators: +, -, *, /, (, ), unary -, unary +
- comments //
- error handling IFNOTSET for missing variables and IFERROR for general errors like division by zero
- IF function
- rounding functions ROUND, ROUNDUP, ROUNDDOWN
- modulo function MOD
- power of function POW
- randomize functions DICE and RANDOM
- functions MIN and MAX
- comparison operators ==, =, !=, <, <=, >, >=
- logical functions AND, OR and NOT
I appreciate any feedback and suggestions (e.g. missing functions).
Feel free to ask questions.
It is an addition to the current possibilities to change Conditional Branch Variables.
Now I want to introduce you the currently planned syntax and would like to get some feedback about it and suggestions about missing functions.
There is a summary of functions at the end of this post (tldr).
(Please note, that everything described below isn't available yet and can be different when this feature will be finally published.)
The syntax for the formulas is inspired by the syntax of spreadsheet formulas, so if you have experience with spreadsheets you may be already familiar with it.
Why using formulas?
- Use of more complex mathematical operations. (e.g. add 20% of the current value)
- Use of conditional calculations. (e.g. if {charisma} is below 50, add 10 points, else add 5 points)
- Use of calculations with other Score Variables. (e.g. if {charisma}+{negotiating skill} is below 15 )
- Use of randomize functions.
Note: The most examples used below are using numbers to illustrate the functions while keeping it simple. Usually, most of the numbers would be functions or variables. (there are some more complex examples under 12.)
General usage:
Create a Score Change of the desired type, choose "formula" as operator and type your formula into the value field.
The Variable named in the left is the receiver of the calculated value of the formula.
If the previous value of the variable should be modified by the formula, you have to include the variable into the formula.
1. Result
Boolean variables: If the result of the formula is equal 0, the variable will be set to "false". Else the variable will be set to "true".
Numerical and Progress variables: The result will be converted into an integer (round down).
Within a formula, all calculations will be done with floating point numbers.
2. Syntax Errors
The syntax of the formula will be checked while saving the chapter. If the syntax isn't valid, the formula won't be saved.
3. Calculation Errors
Some errors may occur while evaluating a formula with actual values from variables (e.g. division by zero) or with nonexistent variables.
These uncaught "errors" will be evaluated as 0 to be able to calculate the rest of the formula.
There are functions to cover those situations and provide a default value.
4. Numbers
You can use any integer or floating point number.
You can use a decimal separator of your choice (decimal point or decimal comma).
You can omit leading zeros.
You mustn't use thousand separators.
Code:
2.03
.75
500,63
5. Variables
You can use Score Variables within your formula.
Code:
{Variable A} + 26
6. Comments
You can use comments to remind yourself or an editor what the formula is about.
Write "//" followed by your comment at the end of your formula.
Code:
{Variable A} + 26 // this is a comment
7. Mathematical calculations
You can use mathematical calculations with following operators (normal precedence)
Code:
+
-
*
/
unary +
unary -
parentheses ( )
Code:
-22.4*3-2/(6-2)*(-2) // results in -66.2
8. functions
Functions usually looks like this:
Code:
FUNCTIONNAME( parameter1 ; parameter2 ; parameter3 ; ... )
The semicolons are used as separators for the parameters.
A parameter can be a number, a variable, a function or a condition (depends on the function).
9. general functions
IF( condition ; value ; value )
This function checks if the "condition" is true. If so, the result will be the first "value" (parameter 2), else the second "value" (parameter 3).
Code:
IF( 25 > 17 ; 5 ; 10 ) // results in 5
IF( 17 > 25 ; 5 ; 10 ) // results in 10
ROUND( value [; number of decimal places] )
ROUNDUP( value [; number of decimal places] )
ROUNDDOWN( value [; number of decimal places] )
This functions can be used to round a value to a number of decimal places.
Code:
ROUND( 21.345 ; 2 ) // results in 21.35
ROUNDUP( 21.345 ; 1 ) // results in 21.4
ROUNDDOWN( 21.345 ; 2 ) // results in 21.34
Code:
ROUND( 21.345 ) // results in 21
Code:
ROUND( 21.345 ; -1 ) // results in 20
POW( base ; exponent )
This function can be used to calculate the power of a number.
Code:
POW( 3 ; 3 ) // results in 27
MOD( dividend ; divisor )
This function can be used to perform modulo operation on numbers.
Code:
MOD( 15 ; 4 ) // results in 3
Code:
MOD( 15 ; 0 ) // results in 0 and sets an error flag
IFNOTSET( variable ; alternative value )
This function can be used to provide a default value if a variable doesn't exists in the readers score. This function removes the error flag from the variable value.
Code:
IFNOTSET( {existant variable} ; 25 ) // results in the value of the variable
IFNOTSET( {non-existant variable} ; 25 ) // results in 25
IFERROR( value ; alternative value )
This function can be used to provide a default value if a value has an error flag. This removes an error flag from the value.
Code:
IFERROR( 25/0 ; 1 ) // results in 1
IFERROR( 25/1 ; 1 ) // results in 25
DICE( [number of sides] )
This function can be used to do a dice roll. The result will be a random integer between 1 and "number of sides".
Code:
DICE( 15 ) // results in a random integer between 1 and 15
Code:
DICE() // results in a random integer between 1 and 6
RANDOM()
This function can be used to create a random floating point number between 0 and 1.
Code:
RANDOM() // results in a random floating point number between 0 and 1
MIN( value ; value [; value [; ...]] )
MAX( value ; value [; value [; ...]] )
These functions can be used to determinate the minimum/maximum of two or more values.
Code:
MIN( 25 ; 10 ) // results in 10
MAX( 25 ; 10 ) // results in 25
Code:
MIN( 25 ; 10 ; 13 ; 17 ; 34 ; 64 ; 23 ) // results in 10
MAX( 25 ; 10 ; 13 ; 17 ; 34 ; 64 ; 23 ) // results in 64
SAVEnumber( value )
RETURNnumber()
These functions are used to save a value as a formula-internal interim result and return it at another position. This is necessary, if you work with random numbers or dice rolls. It can also be useful to shorten complex formulas.
"number" is the number to identify a particular interim result.
Code:
IF( SAVE1( DICE() ) <= 3 ; RETURN1()-1 ; RETURN1()+1 ) // result can have a value of 0, 1, 2, 5, 6 or 7
10. conditions
Code:
value operator value
They can only be used within the IF-function and the logical functions (see 11.).
Available operators:
Code:
== or = equal
!= not equal
< lower than
<= lower than or equal to
> greater than
>= greater than or equal to
Code:
value
If the value is 0, the result will be "false", else the result will be "true".
11. logical functions
You can use logical functions wherever you can use a condition.
AND( condition ; condition [; condition [; ...]] )
OR( condition ; condition [; condition [; ...]] )
You can use these functions to evaluate multiple conditions
NOT( condition )
You can use this function to reverse the result of a condition.
Code:
IF( AND( 15 > 10 ; 23 <= 50 ) ; 1 ; 0 ) // results in 1
IF( OR( 15 < 10 ; 23 <= 50 ) ; 1 ; 0 ) // results in 1
IF( NOT( 5 = 5 ) ; 1 ; 0 ) // results in 0
12. concrete examples
Someone steals 20 backs from your purse. To ensure, that your purse won't contain a "negative amount of money, the thief will take only the rest, if you don't have that much.
Code:
IF( {Money} < 20 ; 0 ; {Money} - 20 )
Haggling. If haggling is successful, the price will be reduced by 3% per point of haggling skill. If haggling fails badly, the price will be 20% higher than normal.
Code:
IF( ( {haggling} + ROUNDDOWN( {charisma} / 5 ) - {difficulty} + SAVE1(DICE( 20 ) ) ) > 20 ; {price} - {price}*{haggling}*0.03 ; IF( RETURN1() == 1 ; {price} * 1,2 ; {price} ) )
Perform an attack and calculate the damage you do to your enemy. In most cases you would want to split this formula into smaller pieces, because you probably also want to tell the reader, if you hit, if the enemy parried and if the enemies armor absorbed the damage.
Code:
IF( AND( DICE( 20 ) > {weapon_skill} ; DICE( 20 ) < {enemy_defense} ) ; IF( SAVE1( DICE( {weapon_damage_dice_sides} ) + {weapon_damage_modifier} + ROUNDDOWN({strengh} / 10) ) > {enemies_armor} ; RETURN1() - {enemies_armor} ; 0 ) ; 0 )
Calculate the attractiveness of a woman to the protagonist. (In this example we assume a 37 year old redhead with medium bust size. Haircolor and bust size are determinated by numbers in this example)
The attributes are weighted (hair color 3, bust size 2, age 3). if one of the attributes is important, the weighting gets doubled.
Code:
IF( {favorite haircolor} = 1 ; 3 * IF( {haircolor important} ; 2 ; 1 ) ; 0 ) + IF( {favorite bust size} = 3 ; 2 * IF( {bust size important} ; 2 ; 1 ) ; 0 ) + IF( AND( {favorite age minimum} <= 37 ; {favorite age maximum} >= 37) ; 3 * IF( {age important} ; 2 ; 1 ) ; 0 )
Summary of functions:
- use of numbers (allows decimal point and decimal comma and omitting of leading zeros)
- use of Score variables: {variable}
- mathematical operators: +, -, *, /, (, ), unary -, unary +
- comments //
- error handling IFNOTSET for missing variables and IFERROR for general errors like division by zero
- IF function
- rounding functions ROUND, ROUNDUP, ROUNDDOWN
- modulo function MOD
- power of function POW
- randomize functions DICE and RANDOM
- functions MIN and MAX
- comparison operators ==, =, !=, <, <=, >, >=
- logical functions AND, OR and NOT
I appreciate any feedback and suggestions (e.g. missing functions).
Feel free to ask questions.
Last edited: