Jump to content

State Management in scripts

Recommended Posts

State management is a very common thing for a lot of different tasks. I've made a fairly basic state management script in lua that I'm using and was thinking it would be handy if LE maybe had some state management built into Script's.


Each state generally has an Enter, Exit, Update (maybe Draw for 2D) function. In the LE Script's these could be named functions that we add during init. Might be nice to be able to do:


self.entity:AddState("reload", self.Reload_Enter, self.Reload_Exit, self.Reload_Update, self.Reload_PostRender)





Just a thought.

Share this post

Link to post

Below is the state manager script itself. It can call onEnter, onExit, onUpdate functions that you add for each state. The onUpdate can be called at intervals vs every frame if you need (think AI thinking and maybe it has some heavier processing to it that you don't want to do every frame).


if StateManager ~= nil then return end

StateManager = {}

function StateManager:Create(container)
local obj = {}

obj.states = {}
obj.container = container
obj.activeState = nil
obj.nextState = nil
obj.lastState = nil
obj.lastUpdate = Time:GetCurrent()

for k,v in pairs(StateManager) do
obj[k] = v

return obj

-- methods param = { onEnter = self.function, onUpdate = self.function, onExit = self.function }
function StateManager:AddState(name, methods, updateInterval)
self.states[name] = {}
self.states[name].methods = methods
self.states[name].updateInterval = updateInterval or 0

function StateManager:GetCurrentState()
return self.activeState

function StateManager:ChangeState(name)
-- this happens the FIRST time we change to the first state
if self.activeState == nil then
self.activeState = name
self.nextState = nil
self.nextState = name
self.lastUpdate = self.states[self.nextState].updateInterval * -2 -- make it so Update is called once right away

local name = self.container.entity:GetKeyValue("name")
System:Print("Changing state to "..name.." for "..name)

function StateManager:ChangeToLastState()

function StateManager:Update()
if self.activeState == nil then return end

-- check for switching states
if self.nextState ~= nil then
-- exit function of current state
if self.states[self.activeState].methods.onExit ~= nil then

-- set new state
self.lastState = self.activeState -- save off the last state
self.activeState = self.nextState
self.nextState = nil

-- enter function of new state
if self.states[self.activeState].methods.onEnter ~= nil then

-- update function of current state called every interval
if self.states[self.activeState].methods.onUpdate ~= nil then
if Time:GetCurrent() >= self.states[self.activeState].updateInterval + self.lastUpdate then
self.lastUpdate = Time:GetCurrent()



I'll have to work up an example I guess. Looking at the MonsterAI.lua it seems like it might be a good one to do with a state machine. It basically removes a bunch of if/else statements you'd normally have and directs things to the onEnter/onExit/onUpdate methods of each state and you just change between states based on what's happening.

Share this post

Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...