godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Add a generalized StateMachine node #9517

Open emmetoneillpdx opened 6 months ago

emmetoneillpdx commented 6 months ago

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 state enums, or by delegating behavior to state Nodes, 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 of States and Transitions, and by attaching scripts to the StateMachine Node, as well as the individual States, 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 current AnimationTree Node as a more generalized, fundamental and flexible tool.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

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 a AnimationNodeStateMachine).

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, like CanvasItems, 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 while StateMachines 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.

AThousandShips commented 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