Hello,
I was looking for a Finite State Machine implementation for my game, but found only limited implementations working as plugins.
As FSM are a commonly used tool to define objects behavious in video games, I was wondering why not implement it as a built-in feature for godot.
Thus, I open this issue to discuss multiple thing:
Here is my idea of a possible implementation:
add_transition(NodePath from, NodePath to, FuncRef[] conditions, FuncRef[] inverted_conditions, int priority=0)
conditions
return true and all functions called in inverted_conditions
return false. The current state node is then set to to
. Transitions with higher priorities are treated first.on_state_enter
is trigerred when the node becomes the current stateon_state_exit
is trigerred when the node is no more the current stateon_state_update
is triggered once per update
FSM call, once we have found the new state.This implementation could be completed with a specific editor view, with something like that:
What do you think ?
Unity supports state machine (although only for animations).
I think generic state machine would be very useful tool in Godot:
and probably more.
I don't like node-based implementations, also godot offer many ways to do it (code, node, signal), and 3 could let make complex designs to tweak with visual scripts for mechanics designers.
For generic FSM could be better to have a framework, like Escoria.
Strange that nobody yet mentioned the FSM plugin by @kubecz3k ... https://godotengine.org/asset-library/asset/5 (though it is slightly WIP it seems...)
Well, I do not see why the three solution should be considered separately. I mean, scripts are basically an extend to a base node class. Creating a script attached to a node is like creating a class inheriting from its parent class node. When some features are used by a lot of people (FSM are), I think the considered features could be implemented as a real node.
Signals are, IMO, an unadequate design pattern (they correspond to the _Observer_ design pattern) for implementing FSMs. That is why I suggest an other implementation for them.
I do not get why you do not like Node-based implementations. I mean, even the GUI system is based on nodes, so why not provide the developper with node-based AI features ?
@bojidar-bg I saw the plugin and tested it, but it lacks some flexibility (no functions are called when states changes, but the global idea is what i propose). It is also still a plugin implemented in gdscript, the question was also "should it be implemented as a builtin-features ?" (I believe so) :)
As far as I know, something like this is already planned for 3.1 under the name transition graph.
@groud what do you mean that no function is called when the state changes? You can connect a signal "stateChanged" to be notified about state changes. I'm using this plugin a lot in my projects, version on the asset store is very slightly outdated (cosmetic stuff).I think I will get some windows machine and try to test it on it since 'tool editor' part is not working on windows as far as I know. If I succeed I think I will record some tutorial on how to use it since it seems there might be need for that.
@tagcup it seems that you are right. I hope this will be usable as a generic state machine too.
@kubecz3k well if you need to connect all children to the fsm node to detect if they are the current state, this is a little bit heavy no ? But I may miss something in how to use your plugin... ^^"
@groud Yeah you totally missed the point how to use the plugin (I guess it's my fault in the end). Will create some video tutorial and put it on the net. You can use signal to be notified about state change, but you can also just use fsm.getStateID()
method. Check fsm.gd script to see how api looks like: https://github.com/kubecz3k/FiniteStateMachine/blob/master/addons/net.kivano.fsm/content/fsm.gd
Also I have managed today to test the plugin on Windows 10 and it seems it's working fine in the end...
@kubecz3k ok, I had a look to the code, I understand it a little bit better I believe. The enter(), update() and exit() functions, called for the children node do what I was looking for.
Anyway, does it features hierachical FSM ? I cannot see how they could be implemented in your code.
Aside from that, as your plugin does not provide a structure to store the transitions, I believe creating a visualization tool will be difficult.
@groud no it does not provide stucture do store transforms. I didn't had an y good idea for this part at the time, there is just an option to hardcode transforms inside states (so you can implement computeNextState() from https://github.com/kubecz3k/FiniteStateMachine/blob/master/addons/net.kivano.fsm/content/StateTemplate.gd ) alternatively you can not use this option and just steer manually with fsm.setStateID(). I also think visual tool for FSM would be the best. Do you have any structure for storing transforms in mind? Some kind of function references 2 states map? That part sounds like something I could benefit from, if you have any ideas for this it would be great if you could open an issue on plugin github page (don't want to spam to much this discussion with discussion related to my plugin)
Also yes there is no support for hierarhical fsm since I'm not using those in my current games - I think the most close what you can have in this plugin is to have multiple FSMs and manually steer them from up to down (more important fsms know about atomic ones but not other way), but haven't tried this.
Also as I said the plugin is little outdated right now, I think I will update it tomorrow, changes are cosmetic in terms of LOC but handy sometimes (like passing custom arguments to update/init or having dictionary with states names so you dont need to use strings at all (more error prone)).
Ok I see :)
Well, for now it was thinking in using a FuncRef to store transitions, instead of using hardcoded ones. I will try to code something in the next few days and see what i can came up with.
@groud I have booked couple hours tomorrow to create video and clean/upload changes. I think I might give a shot for this transition structure as well since it's something that this plugin (and my projects :P) could benefit for sure.
I know it has been couple of days and there still is no tutorials/new functions... but I think you will forgive me :)
(still wip but almost done)
@kubecz3k what do you think about a structure to be used with Visual Script? I think that with custom nodes may be possible to do something.
This is one of the few things where I think VS may be useful :smile:
@kubecz3k
Holly crap!
@eon-s well I have prototyped fsm on visual script when I was giving initial feedback on visual script :) In short I don't have any strong opinion on it, I kind of like it even without any additional nodes/structures. But for now I think VS is not as readable for FSM purpose as much as that kind of simple graph that was designed only for FSM, to tell truth when I started implementing this on Monday I was using initially GraphNodes from VisualShaders but it was a little unreadable and I was not happy with this solution. But for sure I will experiment with VS a lot more in 3.0
ps. if you would have build with VS you could double click on state/transition and implement it in VS (at least I think it should work this way)
Nice, awesome job ! 馃槃
I have been thinking a few days about how to implement those FSMs, and came up with a more or less similar design. The only difference I can find is that I though it was more easy to understand if you to put a transition as a child of the source node (instead of a direct child of the FSM node).
I am currently working on a built-in (C++) implementation of such module, let me know if you update your code on github, I am very interested by how you implemented the visualization part ! :)
@groud in this implementation transition can have multiple source states (but only one target one). I'm finishing it right now, will test today if there will be no problems, maybe I will be able to record vid today.
also curious why you want c++ implementation? I mean, runtime is really minimal, maybe couple dozens of gdscript loc running every update, linearly without any bigger loop or any other heavy stuff, and people will implement more heavy stuff (like actual game logic) in gdscript anyway so...
Well it is not a matter of complexity or whatever... It is just because I believe this should be included into the godot engine itself (because it is a feature used by a lot of people), and not as a plugin. Thus it would need to be coded in C++. :)
@groud
True. Also, next step would be Behavior Trees :) and then we will be on par with Unity and Unreal if AI/Logic systems are concerned :)
@n-pigeon actually I believe all good fsm implementations for unity are a plugins :P
I believe if we will have fsm functionality it should be extension for our visual scripting system (basically couple new VS nodes). There is no need to introduce two competing systems into core.
I also think @reduz was already thinking about that kind extension, but we need to get people to start use VS in the first place and get real life feedback.
@kubecz3k
I agree with you. FSM and BT logically belongs to VS. Probably new Controls will be needed for them but it would be the best if they would act as one system. It would be also easier to maintain :)
In any case as I promised I made a quick vid on how to use the plugin: https://youtu.be/n4lJXjLAHoI
I had a look to how visual scripting works and is implemented, but I hardly understand how we could combine them with either Behaviour Trees or State Machines. In terms either or visualization or implementation I find that it would be a little bit hacky to combine them. Also, this may overload the visual script editor.
The solutions I can imagine are the following:
WDYT ?
@groud I'm doing an overview of the old issues from this time period. Do you have maybe an new ideas on the topic? Do you still think this one should be build into the core?
Probably, I think animation state machines are on the roadmap anyway. Maybe there's another issue about that and this one can probably be closed though.
Yeah I feel like animation state machines will not have such much common with those
Hey guys!
I have to make any advanced C++ project for my lecturer and I thought that I could make godot module. I considered FSM.
Closing in favor of #25021, as we have built-in state machines for animation since Godot 3.1.
Most helpful comment
I know it has been couple of days and there still is no tutorials/new functions... but I think you will forgive me :)
(still wip but almost done)