Open emmetoneillpdx opened 6 months ago
See also:
I'd say this is something that's too general to be in core, any standard system for this would be too simple to cover everything, it's better as a plugin or add-on, and it can be implemented in scripting with GraphEdit
and similar systems
Describe the project you are working on
My development partner and I have a couple of different games brewing including an arcade-style game with a variety of character interactions, a multiplayer puzzle game, a top-down action game, etc.
Describe the problem or limitation you are having in your project
Just about every game I can think of, including the ones I'm working on, relies heavily on finite state machine logic for everything from managing game states, character movement, animation, object interactions, puzzles, "ai" behavior, event scripting, and so on. The essence of a fighting game character, for example, is a complex state machine. As is the logic which controls the turns during a turn-based tactical RPG. State machines are everywhere.
Of course, all of this is possible in current versions of Godot using simple
match
statements and stateenums
, or by delegating behavior to stateNodes
, as described here and here.However, _for such a common pattern in game design there is more than a little bit of boilerplate code needed to manage state Nodes, especially considering the existence of the
AnimationTree
Node--which is already an almost perfectly good finite state machine controller with a pretty nice visual editor!_On top of that, having many states appear as a simple list of Nodes in the SceneTree isn't a great way to visualize which state is currently active or how the states relate to each other.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
As such, my proposal is to create a generalized
StateMachine
Node type, which represents a finite state machine (that may or may not be associated with animation) and could be used for a wide variety of different applications across just about any kind of game.A
StateMachine
Node would manage a finite number ofStates
andTransitions
, and by attaching scripts to theStateMachine
Node, as well as the individualStates
, we would create a very simple and standard way of making a Node that acts as a finite state machine with much less boilerplate code.The
StateMachine
Node could potentially be used to deprecate, and eventually replace, the currentAnimationTree
Node as a more generalized, fundamental and flexible tool.Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
StateMachine
Node to a scene would create a basic, logical Node that represents any finite state machine and appears to change behavior as it internally switches between activeStates
.StateMachine
Node and clicking aStateMachine
tab at the bottom of the editor would open a GUI for managing its various internalState
objects, attaching scripts, associating animations, signals, state groups, transitions, etc.StateMachine
node should be just as easy to use as theAnimationTree
) aStateMachine
node should be able to be associated with anAnimationPlayer
. This would allow you to use aStateMachine
much in the same way that we currently use theAnimationTree
, by creating new states from existing animations as well as using the current state of the node to control complex animation playback and blending.State
object would load up a template script with typical state-related functions likefunc enter
,func exit
, etc. From there, arbitrary data and functions could be added to eachState
as needed depending on the use case in question.States
would maintain their own built-in signals likesignal entered
andsignal finished
, which could be used by theStateMachine
to transition to another state based on the configuration of the state graph, among other things. (States might emitsignal finished
when their associated animation is over OR in the case of non-animated/looping/logical states at any arbitrary point in time.)State
emitssignal finished
it will follow one of its transitions (if it has any) in order to enter another State. A State with multiple out-bound transitions would select one transition to follow based on its configuration. (For example, to select one at random, to follow each branch as a sequence, to follow a branch conditionally, etc. Allowing for the creation of behavior trees.)StateMachine
node would also maintain their own list ofState Groups
which, likeScene Groups
andGlobal Groups
, could be activated and deactivated on eachState
object as needed. (For example, a character's StateMachine might have aState Group
called "JumpCancelable" which could be used to easily determine which states can be jumped out of.)AnimationNodeStateMachine
of theAnimationTree
,StateMachine
nodes could contain nested state machines.If this enhancement will not be used often, can it be worked around with a few lines of script?
At a basic level, this can be worked around using the "traditional" match-based or node-based methods of building state machines in Godot.
However, some of the aspects of this proposal are currently not possible at all (for example,
State Groups
, or creating "empty" States without existing animations inside aAnimationNodeStateMachine
).I also think creating a StateMachine node that's more loosely coupled with the animation systems creates a pipeline benefit, as it would allow teams with a dedicated designer (who may not be a programmer or animator) to quickly and easily define or tweak various StateMachines and State graphs, even before any code has been implemented or animations have been created. And by using the existing AnimationTree GUI, much of this work could be done visually, right in the Godot editor.
Is there a reason why this should be core and not an add-on in the asset library?
I think that
StateMachines
are just as fundamental to practically every game as other core node types, likeCanvasItems
,Node3Ds
, etc., and I'm confident that a wide variety of games would be able to find multiple ways to use this node.On top of that, in the context of controlling animation, Godot's
AnimationTree
is already a solid and functional finite state machine with a good editor. But whileStateMachines
are certainly an important part of game animation, their use goes far beyond animation alone, whether that's controlling the state of individual objects in a game world, managing the state of a puzzle or dungeon, or even managing the broad game states of an entire game.Based on all of that, I feel that a generalized
StateMachine
node would represent a more fundamental and flexible tool than the current AnimationTree, while building on top of the things that make the current AnimationTree nice to work with.