hobby-ish gamedev. This website contains my raw notes and documents my progress.

← Best practices - Data preferences Static properties →

Coop FSM

Introduction

The last couple of days I learned a lot of theoretical things about FSM. As I was not really able to understand the FSM script which was part of the multiplayer tutorial, I had to bury deep into it. Lets continue and see, where my gaps are?

Disclaimer: This post is primarly about notes related to the tutorial specific implementation of the FSM script(s). Further resources about this topic are in the link down below, in my other nodes and of course in the godot documentation.

Notes

There are multiple ways of implementing state machines. Firebelley Games has created his own kind of state machine, a “callable state machine.”

StateX (runs code) -> transitions -> StateY (runs code)

Callable = reference to a function (functions are states here as they run code)

Three states:

Dictionary entries then get assigned to states

	...
	"normal": normal_state_callable
	...

Start state gets called in the ready() function.

Custom update() function (not a builtin function) we call every frame, that checks that the current state exists and if it does, it calls the normal state from the dictionary.

Remember that we have three dictionary keys for each state. “normal”, “leave” and “enter”. Imagine we have “running” as a state. If you want to bind specific movement to the player running, you want a beginning animation and an ending animation. Here, the different keys of the state can be of use. “Enter” would handle the start-up animation, normal the actual movement animation every frame and “leave” the wind-down animation. This is very animation specific, but of course, this can also be adapted to the running code itself.

An example on how the dictionary would look like for two states:

# adding the states
state_machine.add_states(idle, enter_idle, leave_idle)
state_machine.add_states(run, enter_run, leave_run)
# dictionary
{
    "idle": {
        "normal": idle,        # Callable -> idle()
        "leave": leave_idle,   # Callable -> leave_idle()
        "enter": enter_idle    # Callable -> enter_idle()
    },
    "run": {
        "normal": run,         # Callable -> run()
        "leave": leave_run,    # Callable -> leave_run()
        "enter": enter_run     # Callable -> enter_run()
    }
}

Definitions

call_deferred() = Delays a function call until the end of the current frame.

is_multiplayer_authority() doesn’t mean “run this code only if you are the host” but “run this code only if you own this node where this script is attached to”

Credits and Resources

More infos on state machines: https://www.gdquest.com/tutorial/godot/design-patterns/finite-state-machine/

Credit: Firebelley Games (Coop Tutorial, check it out!)

← Best practices - Data preferences Static properties →