RobloxStateMachine - A Simple State Machine implementation

It really depends on however you wish to approach this, I also have multiple NPCs in my game each using their own state machine. I pretty much have a main file to manage the NPCs and fire events to it whenever it is necessary.

Instead of bindable events you can use the Signal library to keep events 100% in code Signal | RbxUtil (sleitnick.github.io)

thanks for the rbx util tip

can u give an example of how we use Transition:Extend() please

I understand the basics of inheritance, as it essentially creates a subclass, but I have trouble figuring out how to benefit from it when it comes to npc behaviours

I’ve tried to use this for a player state machine.

However when I try to create a state machine in a local script I keep getting errors when trying to load states. It keeps telling me that it’s iterate over nil values.

Perfection. That’s it, it’s PERFECT

When I try to force a state change using the :ChangeState method, nothing happens. No errors, no change of state.
My code in idle:

local idle = RobloxStateMachine.State.new("idle")
idle.Transitions = {
	require(ServerStorage.fsm_npcs.wandernpc.Transitions.goToWander)
}

function idle:OnEnter(data)
	print("Состояние ", idle.Name)
	idle:ChangeState("wander")
end

and wander:

local wander = RobloxStateMachine.State.new("wander")

function wander:OnEnter(data)
	print("Состояние ", wander.Name)
end

output:
image_2025-01-27_23-05-48

I’m new to programming, so honestly, I don’t understand why such a check is needed, but later I realized:

function State:ChangeState(newState: string): ()
	if not self._changeState then -- print(self._changeState) -> nil
		return
	end

	self._changeState(newState)
end

After some time of thinking and searching, I want to say thank you for teaching me the __call method, but most importantly, I found this in RobloxStateMachine:

		stateClone._changeState = function(newState: string)
            self:ChangeState(newState)
        end

Similarly, all other methods that are “reassigned” in this way do not work. I’ll try something else, but honestly, I hope the author notices and fixes it before I do. He will definitely be more reliable.

I realized that the FSM instance itself can call these functions, and it also stores the states that have _changeState with a function (see the first screenshot), which was defined during copying. However, the instance in the state modules (see the second screenshot) does not have keys like _changeState or others.

first screenshot:
onescreen

and second:
image_2025-01-28_01-24-40

I have no idea how to fix it, so that’s it for now.

Hey! Just wondering, does this module run on clientside too?
Also, the images in the documentation are missing.

Love how someone made an accessible state machine though!

It seems I lied a little.
I fixed this by simply thinking a little about how the FSM constructor works. I don’t know for what reason, but the author decided to make copies of classes of various states and transitions:

-- RobloxStateMachine 
local stateClone: State.State = Copy(state) -- line 199
...
local transitionClone: Transition = Copy(transition) -- line 221

Just erasing copy() will fix the problem

I’m also having the same problem with :ChangeState() not changing to the target state.

This will only temporarily fix the issue and it won’t work properly if you’re trying to use multiple NPCs that has the same state machine. (which is probably why those are copied)

Nice audio quality on the tutorial video. :neutral_face:

Very underrated module. This helped me get a nice complex behavior. Soon will add Melee and Ranged based attacks. With this module am able to create behavior such as below. Im able to spawn with animations and behavior 500 Mobs with no issues. Still testing it out.

I also updated the plugin if anyone was interested to have priorities when Transitions were evaluated. See changes here if anyone is interested in Optional Priorities for their Transitions.