nodebox / seed

Procedural Content Generator
https://seed.emrg.be/
MIT License
22 stars 8 forks source link

Conditional text generation #46

Open fdb opened 6 years ago

fdb commented 6 years ago

I have a use case where I want to generate text based on incoming data. Depending on different data parameters I want to be able to select a piece of text.

E.g. there's a parameter called "rain_chance". Depending on the values you get different pieces of text:

weather_report(rain_chance):
-(rain_chance < 0.1) No rain expected today.
-(rain_chance < 0.1) It won't rain today.
-(rain_chance < 0.5) It probably won't rain today.
-(rain_chance < 0.8) We're pretty sure it will rain.
-(rain_chance > 0.8) Bring an umbrella!
-(_) No idea what the weather is going to be.

The syntax is preliminary: we should be able to distinguish between a conditional statement and a line of text that begins with a bracket.

stebanos commented 6 years ago

Hm but this conflicts with the current randomizing aspect of the - signififier. It would no longer mean "choose one of these options", but instead act like switch/case.

fdb commented 6 years ago

I don't think it has to conflict. It just has a set of options that are also conditional. This means that if there are two options that satisfy the condition (like the rain_chance < 0.1 in the above example) the system can choose between the two; otherwise it is as if there was only one option to choose from.

stebanos commented 6 years ago

Ah I see. Well it's definitely something else that I had in mind for conditional logic, but yes this makes sense too!

dhruvramdev commented 6 years ago

Hi. If the syntax is somewhat finalized, then I can give it a shot .

AlexanderRossa commented 6 years ago

This Issue has been resolved in seedtext - the NPM module based on Seed. The repository for the project is here.

The syntax, for now, has been slightly altered so that the conditions are more distinct to anything else, simplifying the process of finding them and dealing with them. Using the example from above, the current adjusted syntax would be:

weather_report(rain_chance):
- ([rain_chance < 0.1]) No rain expected today.
- ([rain_chance < 0.1]) It won't rain today.
- ([rain_chance < 0.5]) It probably won't rain today.
- ([rain_chance < 0.8]) We're pretty sure it will rain.
- ([rain_chance > 0.8]) Bring an umbrella!
- ([_]) No idea what the weather is going to be.

The wildcard operator _ has been implemented as well, but its usage is identical to not preceding the choice with any condition and as such it might be a bit redundant, unless we want to enforce that each choice in a block with at least one choice preceded with a condition must be preceded with a condition.

It might also be worth noting that the conditions are evaluated as classic JavaScript and if rain_chancepassed in would be, for example, 0.05, any of the choices could be selected based on solely this condition. While this generally makes sense, in this example it could result in'Bring an umbrella!' which does not seem to be correct. To specify choices valid for ranges of values, classic logical expressions chaining can be used:

- ([(rain_chance < 0.5) && (rain_chance > 0.25)]) It probably won't rain today.

The conditions are evaluated in the parsePhraseBook method and the condition variables are passed in as aconditionalVariables parameter which is a JS object with key:value pairs where key is the variable name and value is the value. The documentation explains this in more detail.