dice_syntax_gd icon indicating copy to clipboard operation
dice_syntax_gd copied to clipboard

probabilities as parsed string

Open eimfach opened this issue 1 year ago • 6 comments

Is it possible to account for possibilities in the dice syntax ? Like I want to have a one percent chance to roll 4d6 instead of 4d3, "4d3|1%4d6"

eimfach avatar Feb 06 '24 16:02 eimfach

I believe this is currently not possible as its neither part of the syntax nor an operation supported by Godot expressions. However if I allowed passing base instances when evaluating the expressions one could define any number of arbitrary functions though resulting syntax would look something like fun_name(4d3,0.9,4d6,0.1) which no longer looks very pretty. Does that satisfy you use case?

Relevant reading https://docs.godotengine.org/en/stable/tutorials/scripting/evaluating_expressions.html

oganm avatar Feb 06 '24 17:02 oganm

A bit more difficult thing to implement would be to allow nested dice but I am not sure if I can easily extend all functions to support it.. Something like

3d[(1d100s<1+1)*3]

Where [ is evaluated first to return a 3 or a 6.

or of course adding the |1% operator is an option on itself but I don't really like it for.. reasons i can't quite explain. Something about the introduction of the % or decimals to denote probability as part of the standard syntax about dice rolls

oganm avatar Feb 06 '24 17:02 oganm

https://github.com/oganm/dice_syntax_gd/tree/base_instance this branch accepts instances. You can use the editor script below to replicate the behaviour you want but I would recommend using a dedicated class as the base instance. Note that spacing is important when == is used as an operator since otherwise the parser will try to parse it as a component of the dice

@tool
extends EditorScript

func _run():

	print(dice_syntax.roll("ifelse(1d100 == 1, 4d6, 4d3)",RandomNumberGenerator.new(),RegEx.new(),self))

func ifelse(condition:bool,t,f):
	if(condition):
		return t
	else:
		return f

oganm avatar Feb 07 '24 01:02 oganm

Hi, thanks for the elaborations. What do you mean by Base Instances ?

eimfach avatar Feb 08 '24 13:02 eimfach

Maybe like this ? "4d3?1d100=1:4d6|1d100=5:2d6"

Like:

if 1%: 4d6 elif 5%: 2d6 else: 4d3

eimfach avatar Feb 08 '24 13:02 eimfach

A base instance is a Godot instance that you pass to an executing expression. It allows you to define functions of your own. If you see the example above, I have created an ifelse function in the current EditorScript, the used that function when rolling the dice while passing self to dice rolling function so that the expression can see the ifelse function I just created

This basically makes ifelse part of the syntax as long as you pass the instance whenever you use dice_syntax functions. Making it a custom class or a singleton might help if you are using dice_syntax in different classes/files

Adding an a built in operator like that to the syntax itself is quite a bit more work since it requires some fundemental changes to the assumptions I currently make about the nature of the syntax, introducing recursion that it currently isn't built for

oganm avatar Feb 08 '24 14:02 oganm

Just merged the base_instance branch to allow defining custom functions. Another improvement could be creating a default base instance with possibly commonly used functions but for now, i'm a bit unclear on what else would be commonly used so will set it aside for now. Of note, with the addition of counting for successes the current syntax can be as simple as "if(1d100s=100, 4d6, 3d6)"

oganm avatar May 28 '24 21:05 oganm

Thank you, that's a very nice addition.

eimfach avatar Jun 06 '24 12:06 eimfach