RBX docs Docs Idk

FSM

by:

Parihsz

A Finite State Machine (FSM) is a computation model that’s used to design systems with a finite number (limited amount) of states. At any given moment, the system can be in one of these states and can switch between states based on certain conditions or events, known as transitions. The benefit of using FSMs is to clearly separate state behaviors making systems easier to manage and understand.

Use case:

Consider a system where a npc has 3 states: Idle, Attacking, and Fleeing.

In this case:
States:
Transitions:

Example:

main

local StateMachine = require(script.Parent.StateMachine)
local NPCStates = StateMachine.CreateMachine()

local Idle = NPCStates:State({
	Name = "Idle",

	OnEnter = function(entity, fsm)
	end,

	OnExit = function(entity, fsm)
	end,
})

local Attacking = NPCStates:State({
	Name = "Attacking",

	OnEnter = function(entity, fsm)
	end,

	OnExit = function(entity, fsm)
	end,
})

NPCStates:Transition("Idle")

state machine

--!strict
type StateConfig = {
	Name: string,
	OnEnter: (any, StateMachine) -> (),
	OnExit: (any, StateMachine) -> (),
}

type StateMachine = {
	states: { [string]: StateConfig },
	currentState: string?,
	State: (StateMachine, StateConfig) -> (),
	Transition: (StateMachine, string, any) -> (),
}

local StateMachine = {}

function StateMachine.CreateMachine(): StateMachine
	local fsm: StateMachine = {
		states = {},
		currentState = nil,
		State = function(self, stateConfig: StateConfig)
			assert(self.states[stateConfig.Name] == nil, "State already exists: " .. stateConfig.Name)
			self.states[stateConfig.Name] = stateConfig
		end,
		Transition = function(self, stateName, entity)
			local state = self.states[stateName]
			assert(state ~= nil, "State " .. stateName .. " does not exist.")

			if self.currentState then
				self.states[self.currentState].OnExit(self, entity)
			end

			self.currentState = stateName
			state.OnEnter(self, entity)
		end,
	}
	return fsm
end

return StateMachine