I'm working on a game using Lua and LÖVE.
I prefer a closure based approach to OOP and each level is a new instance of a function containing all the locals and functions needed to run the game.
I'd like to break this single function into multiple files. My current solution is similar to what I did here: concatenating multiple files into a single one - but I really don't think this is ideal yet.
For instance, I would have a load.lua file with the self.load function from the snippet below.
Code snippet of giant function for reference below:
levelSetup = function()
local time = 60
local timer = time
local timerIsRunning = true
local danger = 10
local handSize = 2
local itemsLeft = handSize
local curHand = 0
local lastHand = 10
local multiplier = 1
local self = {}
------------------------------------------------------
-- Initialize Values based on level Creation
------------------------------------------------------
self.load = function()
if curLevel.time == 1 then
time = 60
elseif curLevel.time == 2 then
time = 40
multiplier = multiplier*1.5
else
time = 20
multiplier = multiplier*2
end
if curLevel.danger == 1 then
danger = 10 --low catastrophe chance
elseif curLevel.danger == 2 then
danger = 30 --medium chance
multiplier = multiplier*1.5
else
danger = 50--high chance!
multiplier = multiplier*2
end
if curLevel.handSize == 1 then
handSize = 2
elseif curLevel.handSize == 2 then
handSize = 3
multiplier = multiplier*1.5
else
handSize = 4
multiplier = multiplier*2
end
itemsLeft = handSize
timer = time
self.nextHand()
end
return self
end
A function must be defined in a single chunk. However, using the load
function you can assemble your chunk data using multiple sources. E.g.:
function closuredef( ... )
local modules, n = { ... }, select( "#", ... )
local index = -1
local function reader()
index = index + 1
if index == 0 then -- chunk prefix
return "local self = {};"
elseif index == n+1 then -- chunk suffix
return "\nreturn self"
else -- read specified Lua files and add them to the chunk data
local modname = modules[ index ]
if modname ~= nil then
local fname = assert( package.searchpath( modname, package.path ) )
local file = assert( io.open( fname, "r" ) )
local data = assert( file:read( "*a" ), "could not read '"..fname.."'" )
file:close()
return data
end
end
end
return assert( load( reader, "=closuredef" ) )
end
levelSetup = closuredef( "level.variables", "level.load" )
This sample implementation uses package.searchpath
(which is new in Lua 5.2) to make
specifying Lua files more convenient. If you still use Lua 5.1, you can use absolute file names or implement your own package.searchpath
function. See here, here, or here for samples.
I'm not sure this is the best solution for your problem though, e.g. you will have a hard time mapping line numbers in error messages to the real error locations ...