#How can one master the ways of the State Machine?

1 messages · Page 1 of 1 (latest)

timber plume
#

I been trying for months to solve issues with my code (specifically with animations and audio playing correctly), and I finally realized how to do it. However, the problem is, it involves state machines -- a thing I have not a single iota of understanding. I mean, I been coding for months now, I can do raycasting and stuff (not Wolfenstein raycasting, but, like, press E to interact type stuff). But, what I wonder, is how do I set up even a simple one? I prefer code based, but node-based works, too. If the docs has a guide on state machines, please let me know lol. Even a partial demonstration would help. I'm not very good at math (or even anything slightly mindbending). So, if you have to explain it, explain it to me like I'm from the medieval era or smthn.

pseudo nebula
timber plume
#

I have gone through every tutorial, still no working result.
Am I cooked, chat?

#

Unless, I switch to Godot 3 -_-

pseudo nebula
#

The concept of a state machine is the same, regardless of Godot version. It is a well known thing in programming
That said, it is probably better if you explain or show what you tried, and what is not working as you expected

timber plume
#

I tried doing a node-based state machine. But, I kept running into issues with nonexistent functions and such. But, then I found an enum-based one. But, problem with that one is, is that it's kinda janky, as i copy and pasted the states all over the place to get it to work. (And, I doubt making it at 4 AM helped, either.)
I can send pictures of code Inna bit, I need to go to my PC.

Sorry if I come off as rude, I just am a bit frustrated with this coding issue.

#

idk how to copy and paste code into the code format thing so it doesn't surpass discord's word limit thing mb

pseudo nebula
#

Making code that late (or early) surely does not help. I can barely be awake that early, let alone code properly 😅
I'm not sure about the Discord limits, but you can always put the code on a external place and link here (like using GitHub or pastebin, etc)
That said, I think you should look into the tutorials and try recreating then, instead of trying to adapt into your already existing code. There's more than one way to do state machines, using nodes or classes or enums are all valid. It seems your struggle is more with how to organize the code, than to just understand state machines

#

I also made a very simple example, using only code for states (no enums or nodes). Consider this structure, where the player only have one main script:

#

You can have a base script which all states derive from:

extends Node

class_name BaseState

var player

func _set_player(_player):
    player = _player

func _on_enter():
    pass

func _on_physics_process(_delta : float):
    pass

func _on_exit():
    pass
#

Then, each state (another gd script) overrides the functions it needs. This is the Iddle State (iddle_state.gd):

extends BaseState

class_name IddleState

func _on_enter():
    print("Now on IDDLE STATE")
    # here, for example, you can change the animation
    # for example, if the player has a AnimationPlayer that holds the animations
    # and the walk animation 
    player.animation_player.play("IDDLE")
    pass

func _on_physics_process(_delta : float):
    pass

func _on_exit():
    print("Exiting the IDDLE STATE")
    pass
#

And this is the walk state (walk_state.gd):

extends BaseState

class_name WalkState

func _on_enter():
    print("Now on WALK STATE")
    # here, for example, you can change the animation
    player.animation_player.play("WALK")
    pass


func _on_physics_process(_delta : float):
    # do whatever
    pass


func _on_exit():
    print("Exiting the WALK STATE")
    pass
#

And the player, where it has a Dictionary with all states already created at the start, then setting a current state when ready, with a function to change states when needed. The state change is triggered by the velocity being zero or not (so, when the player tries to move), but it could be done by any other thing, and some parts of the code can even be put inside the states themselves:

#
extends CharacterBody2D

class_name Player

const SPEED : float = 2000

@onready var animation_player: AnimationPlayer = $AnimationPlayer

var current_state_name := ""
var current_state : BaseState

var available_states := {
    "IDDLE" = IddleState.new(),
    "WALK" = WalkState.new()
}

func _ready() -> void:
    for state_name in available_states: # loops all states in the available_states dictionary
        # note that state_name is the string name of the state
        available_states[state_name]._set_player(self) # tells each state what it will be controlling: the player

    change_state("IDDLE")


func _physics_process(_delta: float) -> void:
    var dir = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
    
    if (dir.is_zero_approx()): # no input, so no movement
        change_state("IDDLE")
    else:
        change_state("WALK")

    current_state._on_physics_process(_delta)
    
    velocity = dir * _delta * SPEED

    move_and_slide()


func change_state(_next_state_name : String):
    if (current_state_name == _next_state_name):
        return # does not change to state if it is already the current

    if (current_state): # if the current_state is not null
        current_state._on_exit() # calls exit on the current 

    current_state = available_states[_next_state_name] # changes to another state
    current_state._on_enter() # calls on_enter on the new state
#

You can also paste code into discord and format it using backticks` see

junior spruceBOT
#
Embedding code in discord messages
Inline Code

When you surround some words with single backticks like `this`, it will be formatted as code.

Code Blocks

You can also include code blocks by surrounding the code with three backticks. If you add "swift" then you will also get basic syntax highlighting:
```swift
print("hello world")
```
Discord will then show it as a code block like this:

print("hello world")
Upload

If your code snippet is rather long, you can upload it to a text paste site. One option that supports syntax highlighting for GDScript is https://bpa.st/