So I’m learning about Expressions, and I’m having trouble coming up with use cases for it. The only thing I can think of is using it to create a dev console. In a lot of cases, it seems like it would just be easier to not use the Expression class at all.
For example:
#do this
var result = 20 + 10*2 - 5/2.0
#instead of
var expression = Expression.new()
expression.parse("20 + 10*2 - 5/2.0")
var result = expression.execute()
I mean obviously with something as simple as that, using the Expression class is overkill and unnecessary but you know what I mean.
I know that with Expression classes I can use a base instance’s methods, constants and member variables but still…
Other than a dev console, I can’t think of any situations where it’s ideal to use this class.
You are aware that you can type an expression in any numerical property field in the inspector and it will get evaluated. It recognizes all global built in functions. As a fun example try typing print("HELLO") in the x position field of your sprite. The class is needed internally for that. Since it’s already in the engine, why not expose it to scripting.
Another case - imagine you’re making a game that you intend to be moddable and tweakable. Something like Sid Meier’s Civilization. And there you describe the ruleset in external XML files which - for some things - also include formulas.
I would like to say I am using Expressions for what ratrogue already stated. There are a lot of logical conditions that needed to be stored, but not evaluated, until it was called for. Huge pain to do it without Expressions.
I want to preface that I don’t have any hands-on experience with behavior trees but conceptually, I know what they are, so please excuse any basic questions I might have.
@ratrogue@TheGrotto What’s being stored in the text files other than the logical conditions and the node id?
Also, I’m assuming you pre-constructed your behavior tree in a scene to something similar to this
Do each of them have the same script attached to them where the only thing that’s different between them are the values assigned to their (exported) member variables?
My implementation of a behaviour tree does not use nodes at all. Instead you provide it with a target script and you can use a text file to construct the tree, with the leaves calling methods from that target script.
And with the support for expressions you could, for example, simply double the speed of a character like this: walk_to_next_pos {2.0 * speed}.
Of course, there’s a class I just call N, which is the baseclass of the nodes of the behaviour tree. They’re not Godot nodes though.
I don’t know if there is a big advantage, but personally I feel it’s much less bloat when the behaviour trees get a bit bigger, and you see all the parameters of each action (leaf node) in one sight, instead having to use the Inspector for each single action. In the end it’s just a matter of taste.
I would never use a tree that looks like that. I would just handle everything directly through code. You could just have a variable which stores the data you need. If it needs to be added dynamically I would probably just dump it all in an Array and manage it that way.
In my case it is a very large JSON/Autoload which stores “objectives” for each stage. It takes the Expression and evaluates it at certain points in the gameplay. This way I don’t need to have doors, or NPCs, or buttons handle any of the logic itself. In my case the “objectives” vary wildly.
Plus I can use JavaScript syntax with it, which I find to be the easiest to use vs a dict/list.
I’m not looking at the code right now, here’s my pseudocode to get you an idea:
func evaluate_objectives(id:int):
if all_objectives.id.condition: all_objectives.id.status = "Completed"