Hello All,
I am quite new to Defold but have worked my way through enough tutorials to be comfortable starting small projects. One of these is the implementation of a Finite State Machine (pattern link) to control a game object’s behaviour. I was able to achieve a simple version in a single script by separating out the a states behaviour between the various functions (init, update, on_message, etc.). The next step is to find a way to consolidate a state’s behaviour into one block, which I attempted to do with Lua Modules and ran into trouble.
This is a example of a state written in a lua module (apologies for the use of pseudo code):
local M = {
state_name = "state_up"
}
local message = "module test message"
function M.message()
print(message + state_name)
end
function M.state_init(self)
end
function M.state_update(self, dt)
local p = go.get_position()
go.set_position(p + vmath.vector3(0, 1, 0) * 100 * dt)
end
function M.state_on_message(self, message_id, message, sender)
end
function M.state_on_input(self, action_id, action)
if action_id == hash("space") and action.released then
-- Switch go's current_states to state_idle
elseif action_id == hash("down") and action.released then
-- Switch go's current_states to state_down
end
end
return M
And this is a example of the script that would be attached to a game object:
local state_idle = require("main.state_idle")
local state_up = require("main.state_up")
local state_down = require("main.state_down")
function init(self)
self.current_state = state_idle
msg.post(".", "acquire_input_focus")
end
function update(self, dt)
self.current_state:state_update(self, dt)
end
function on_message(self, message_id, message, sender)
self.current_state:state_on_message(self, message_id, message, sender)
end
function on_input(self, action_id, action)
print(action_id)
self.current_state:state_on_input(self, action_id, action)
end
However straight away there is a issue passing “dt” as a argument for “self.current_state:state_update(self, dt)”. Where it was expecting dt to be a number valve, what was passed was “userdata”. I have not been able to fix this issue and, looking ahead, can see potential issues with this the whole lua module approach. So my questions are:
- Is there a way of passing the value of the userdata as a argument? Or do I need to use a getter to retrieve the valve?
- Have I misinterpreted Lua Modules and this approach to a FSM will not work?
I am happy to be told to ‘go back to basics’ with this one. However I was not to able to find much information specifically talking how to use lua modules for a state machine and would be really interested if I was anywhere close.