There’s a very small thread on finite state machines already, but it’s a little old, and my topic is less broad I think. I was hoping to get more information on what britzl mentioned in that thread (https://github.com/kyleconroy/lua-state-machine) if anyone can chime in.
I’m trying to make a game sort of like Super Smash Bros. Melee, which I think utilizes a very complicated finite state machine to achieve its behavior. I’m in the process of trying to figure out all of the different states and how to transition between them, but I’m getting bogged down with not knowing how to integrate the specific FSM mentioned in Defold.
I’m not an experienced programmer so I hope you can bear with me.
I have tons of questions along the lines of:
- How do I deal with getting controller input to the FSM?
- How do I deal with governing the state transitions?
- How can I keep track of the time between states for frame-perfect state execution?
I’m pretty lost. If anyone can provide even broad clues it might help.
Here is what my state machine is looking like so far (the spacing doesn’t seem to want to copy right in here, sorry):
local state_machine = machine.create(
{
initial = "standing",
events =
{
{ name = "stop", from = "crouching", to = "standing" },
{ name = "stop", from = "walking", to = "standing" },
{ name = "stop", from = "dashing", to = "standing" },
{ name = "stop", from = "running", to = "standing" },
{ name = "stop", from = "landing", to = "standing" },
{ name = "stop", from = "ground_attacking", to = "standing" },
{ name = "stop", from = "shielding", to = "standing" },
{ name = "stop", from = "rolling", to = "standing" },
{ name = "stop", from = "spot_dodging", to = "standing" },
{ name = "stop", from = "getting_up", to = "standing" },
{ name = "stop", from = "teching", to = "standing" },
{ name = "crouch", from = "standing", to = "crouching" },
{ name = "crouch", from = "running", to = "crouching" },
{ name = "walk", from = "standing", to = "walking" },
{ name = "dash", from = "standing", to = "dashing" },
{ name = "dash", from = "walking", to = "dashing" },
{ name = "run", from = "dashing", to = "running" },
{ name = "jump", from = "standing", to = "jump_squatting" },
{ name = "jump", from = "walking", to = "jump_squatting" },
{ name = "jump", from = "dashing", to = "jump_squatting" },
{ name = "jump", from = "running", to = "jump_squatting" },
{ name = "jump", from = "shielding", to = "jump_squatting" },
{ name = "get_hurt", from = "*", to = "hurt" },
{ name = "fall", from = "standing", to = "falling" },
{ name = "fall", from = "walking", to = "falling" },
{ name = "fall", from = "dashing", to = "falling" },
{ name = "fall", from = "running", to = "falling" },
{ name = "fall", from = "jump_squatting", to = "falling" },
{ name = "fall", from = "shielding", to = "falling" },
{ name = "fast_fall", from = "falling", to = "fast_falling" },
{ name = "tumble", from = "hurt", to = "tumbling" },
{ name = "helplessly_fall", from = "air_dodging", to = "helplessly_falling" },
{ name = "land", from = "falling", to = "landing" },
{ name = "land", from = "fast_falling", to = "landing" },
{ name = "land", from = "helplessly_falling", to = "landing" },
{ name = "land", from = "air_attacking", to = "landing" },
{ name = "ground_attack", from = "crouching", to = "ground_attacking" },
{ name = "ground_attack", from = "walking", to = "ground_attacking" },
{ name = "ground_attack", from = "dashing", to = "ground_attacking" },
{ name = "ground_attack", from = "running", to = "ground_attacking" },
{ name = "ground_attack", from = "lying_down", to = "ground_attacking" },
{ name = "air_attack", from = "falling", to = "air_attacking" },
{ name = "air_attack", from = "fast_falling", to = "air_attacking" },
{ name = "air_attack", from = "tumbling", to = "air_attacking" },
{ name = "shield", from = "crouching", to = "shielding" },
{ name = "shield", from = "walking", to = "shielding" },
{ name = "shield", from = "dashing", to = "shielding" },
{ name = "shield", from = "running", to = "shielding" },
{ name = "get_stunned", from = "crouching", to = "stunned" },
{ name = "get_stunned", from = "walking", to = "stunned" },
{ name = "get_stunned", from = "dashing", to = "stunned" },
{ name = "get_stunned", from = "running", to = "stunned" },
{ name = "get_stunned", from = "shielding", to = "stunned" },
{ name = "roll", from = "shielding", to = "rolling" },
{ name = "spot_dodge", from = "shielding", to = "spot_dodging" },
{ name = "air_dodge", from = "falling", to = "air_dodging" },
{ name = "air_dodge", from = "fast_falling", to = "air_dodging" },
{ name = "lie_down", from = "hurt", to = "lying_down" },
{ name = "lie_down", from = "tumbling", to = "lying_down" },
{ name = "get_up", from = "lying_down", to = "getting_up" },
{ name = "tech", from = "hurt", to = "teching" },
{ name = "tech", from = "tumbling", to = "teching" },
{ name = "grab_ledge", from = "falling", to = "on_ledge" },
{ name = "grab_ledge", from = "fast_falling", to = "on_ledge" },
{ name = "grab_ledge", from = "tumbling", to = "on_ledge" },
{ name = "grab_ledge", from = "helplessly_falling", to = "on_ledge" },
{ name = "ledge_roll", from = "on_ledge", to = "ledge_rolling" },
{ name = "ledge_jump", from = "on_ledge", to = "ledge_jumping" },
{ name = "ledge_get_up", from = "on_ledge", to = "ledge_getting_up" },
{ name = "ledge_attack", from = "on_ledge", to = "ledge_attacking" },
},
callbacks =
{
onstop = function(self, event, from, to)
end,
oncrouch = function(self, event, from, to)
end,
onwalk = function(self, event, from, to)
end,
ondash = function(self, event, from, to)
end,
onrun = function(self, event, from, to)
end,
onjump = function(self, event, from, to)
end,
onget_hurt = function(self, event, from, to)
end,
onfall = function(self, event, from, to)
end,
onfast_fall = function(self, event, from, to)
end,
ontumble = function(self, event, from, to)
end,
onhelplessly_fall = function(self, event, from, to)
end,
onland = function(self, event, from, to)
end,
onground_attack = function(self, event, from, to)
end,
onair_attack = function(self, event, from, to)
end,
onshield = function(self, event, from, to)
end,
onget_stunned = function(self, event, from, to)
end,
onroll = function(self, event, from, to)
end,
onspot_dodge = function(self, event, from, to)
end,
onair_dodge = function(self, event, from, to)
end,
onlie_down = function(self, event, from, to)
end,
onget_up = function(self, event, from, to)
end,
ontech = function(self, event, from, to)
end,
ongrab_ledge = function(self, event, from, to)
end,
onledge_roll = function(self, event, from, to)
end,
onledge_jump = function(self, event, from, to)
end,
onledge_get_up = function(self, event, from, to)
end,
onledge_attack = function(self, event, from, to)
end,
}
})