OOP State Machine Help

in the state machine i made, each state inherits this BaseState which holds the stateMachine object which makes the data on said state machine accessible between the different states. what i’m trying to do here is make the data and functions attached to the state machine accessible to the state object via self and not self.stateMachine.

local BaseState = {}
BaseState.__index = BaseState

BaseState.new = function(stateMachine)
	local self = setmetatable({}, BaseState)
	
	self.stateMachine = stateMachine
	
	return self
end

BaseState.update = function(self, deltaTime)
	
end

BaseState.enter = function(self, oldState)
	
end

BaseState.leave = function(self, newState)
	
end

--[[BaseState.setState = function(self, stateName)
	return self.stateMachine:setState(stateName)
end

BaseState.getState = function(self, state)
	return self.stateMachine:getState(state)
end]]

return BaseState

the whole thing is pretty shoddy as you can see. here at the bottom you can see that i made the getState functions from self.stateMachine more accessible by having an awkward shortcut function that basically just returns self.stateMachine.

below is an example of how self.stateMachine is used

local BaseState = require(ReplicatedStorage:WaitForChild"BaseState")

local Idle = setmetatable({}, BaseState)
Idle.__index = Idle

Idle.new = function(stateMachine)
	local self = setmetatable(BaseState.new(stateMachine), Idle)

	return self
end

Idle.update = function(self, deltaTime)
	if not self.stateMachine:getIsAlive() then return end
	
	self.stateMachine.humanoid:Move(Vector3.zero)
	
	local moveVector = self.stateMachine.moveVector
	
	if self.stateMachine.isGrounded then
		if self.stateMachine:getActionKeyDown"Jump" then
			self:setState"Jump"
		else
			if moveVector ~= Vector2.zero then
				self:setState"Walk"
			end
		end
	else
		self:setState"Fall"
	end
end

return Idle

it works fine but i’m hoping that there are better alternatives? perhaps cleaner at least? thanks in advance

if you need me to elaborate on a few things, i’d be more than happy to. kinda half asleep here lol

-edit 1
i should probably mention that the stateMachine object has values that get updated every frame. the states fail to work if the stateMachine object is static or doesn’t get updated.

Try this:

Idle.new = function(stateMachine)
	local self = BaseState.new(stateMachine)
	
	return setmetatable({}, {
		__index = function(_, k)
			return self[k] or self.stateMachine[k]
		end,
	})
end

huh, i thought this would work but i think the metatable is returning a static copy of the state machine or something like that because the states aren’t recognizing any changes on the state machine now.

i had to rethink my state machine and write the whole thing up again from scratch. ended up making a state machine more efficient than my last lol.