Hello everyone,
I decided to start the migration with the simplest part of my state machine system instead of trying to transfer the entire architecture at once.
My goal is to reproduce the state machine architecture from a working "sample" project into a new "target" project. I am not trying to copy the gameplay itself, but rather the way the states, handlers, and actions are organized.
I am now focusing on the player states.
Relevant State Machine Files
StatePlayerBase.gd
extends StateBase
class_name StatePlayerBase
var player_handler:PlayerStateHandler
var player:GameCharacter
func _init(state_handler:BaseStateHandler) -> void:
super._init(state_handler)
player_handler = state_handler as PlayerStateHandler
player = player_handler.player
SignalsManager.on_input.connect(on_input)
func on_input(_inputs_dict:Dictionary):
pass
StatePlayerWalk.gd
extends StatePlayerBase
class_name StatePlayerWalk
var action_walk:ActionWalk
var in_sea:bool
func _init(state_handler:BaseStateHandler) -> void:
super._init(state_handler)
action_walk = ActionWalk.new(player)
SignalsManager.on_entered_sea.connect(on_entered_sea)
func on_input(inputs_dict:Dictionary):
if handler.current_state == self:
action_walk.execute(inputs_dict, delta)
func on_entered_sea(body:CharacterBody2D):
if body == player:
in_sea = true
func enter_state():
super.enter_state()
in_sea = false
func do_state_body():
super.do_state_body()
if in_sea:
return_state = player_handler.state_player_swim
StatePlayerSwim.gd
extends StatePlayerBase
class_name StatePlayerSwim
var action_swim:ActionSwim
var outside_sea:bool
func _init(state_handler:BaseStateHandler) -> void:
super._init(state_handler)
action_swim = ActionSwim.new(player)
SignalsManager.on_exited_sea.connect(on_exited_sea)
func on_input(inputs_dict:Dictionary):
if handler.current_state == self:
action_swim.execute(inputs_dict, delta)
func on_exited_sea(body:CharacterBody2D):
if body == player:
outside_sea = true
func enter_state():
super.enter_state()
outside_sea = false
func do_state_body():
super.do_state_body()
if outside_sea:
return_state = player_handler.state_player_walk
How the States Work
The player starts in a walking state.
When the player enters a sea area:
return_state = player_handler.state_player_swim
the state changes from Walk to Swim.
When the player exits the sea area:
return_state = player_handler.state_player_walk
the state changes back from Swim to Walk.
Input is received through a global signal system (SignalsManager) and each state executes its corresponding action (ActionWalk or ActionSwim) only when it is the current active state.
Missing Piece
I suspect the most important file for understanding the architecture is PlayerStateHandler.gd, because it creates the states, stores references to them, and defines the initial state. I can also post that file if needed.
My Questions
Looking at these state files, do you see any architectural issues that could cause problems when migrating them into another project?
Would you need to see PlayerStateHandler.gd to better understand how the state machine is assembled?
Any guidance would be appreciated.
Best Regards,
Alex