Warning Beefy post

I've been looking at UristMcSparks' State Machine when developing my games NPCs, but have recently come to the problem of them simply "hanging".

After roughly 2 minutes all the npcs that were involved in any activity simply stop, as if they've crashed. I've been testing them and they all begin to stop working slowly one after the other, all at the condition check "CantShoot".

This is that Condition:

local CantShoot = StateMachine.NewCondition()
		CantShoot.Name = "CantShoot"
		CantShoot.Evaluate = function()
			local Check = math.random(1,10)
					if Check>=3 then 
					return true
			end
			return false
		end
	CantShoot.TransitionState = PursueState 

I'm not sure if it is an issue with this condition, or if there is something else happening. Also, it appears to be checking a condition that also just doesn't apply to the state:


table.insert(ShootState.Conditions,Damaged)
		table.insert(ShootState.Conditions,CantSee)
		table.insert(ShootState.Conditions,CantShoot)
		--table.insert(ShootState.Conditions,CanPunch)
		
		table.insert(PursueState.Conditions,Damaged)
		table.insert(PursueState.Conditions,CanShoot)

While in the pursue state, the CantShoot condition also appears in the debug. I've looked over the code, and there is no reason for that to occur. Is there something I'm missing? Here is UristMcSparks' State creator/switcher for reference.

local SMachine = {}

SMachine.new = function(Debug)
local StateMachine = {}	
	
	StateMachine.WaitTime = game:GetService('RunService').Stepped
	StateMachine.CurrentState = nil
	StateMachine.SwitchState = function(newState)
		if StateMachine.CurrentState then
			StateMachine.CurrentState.Stop()
		end
		StateMachine.CurrentState = newState
		Debug.Action.Text = newState.Name
		if newState then
			newState.Start()
		end
	end
	
	StateMachine.NewState = function()
		local state = {}
		state.Name = ""
		state.Conditions = {}
		state.isRunning = false
		state.Action = function() end
		state.Run = function()
			state.isRunning = true
			while state.isRunning do
				--check conditions
				--print(state.Name..": checking conditions")
				for _, condition in pairs(state.Conditions) do
				--	print("Checking " .. condition.Name)
					Debug.Condition.Text = condition.Name
					if condition.Evaluate() then
						--print(condition.Name .. " is true. Switching states")
						return StateMachine.SwitchState(condition.TransitionState)
					end
				end
				
				--if no conditions satisfied, perform action
				state.Action()
				wait(StateMachine.WaitTime)
			end
		end
		state.Init = function()
			
		end
		state.Start = function()
			--print("Starting " .. state.Name)
			state.Init()
			local thread = coroutine.create(state.Run)
			coroutine.resume(thread)
		end
		state.Stop = function()
			--print("Stopping " .. state.Name)
			state.isRunning = false
		end
		return state
	end
	
	StateMachine.NewCondition = function()
		local condition = {}
		condition.Name = ""
		condition.Evaluate = function() print("replace me") return false end
		condition.TransitionState = {}
		return condition
	end	
	
	return StateMachine
end
return SMachine

2 comments

0

Here is an example of the StateMachine in action.