Dynamically load a lua module from a string path

Hi. I’m trying to dynamically load a lua module based on an id:

[Simplified example]

local id = 1
local modules = {
	"game.first",
	"game.second",
	"game.third",
}
local my_module = require(modules[id])

And I’m getting an error “module ‘game.first’ not found”.

But when I do

local my_module = require("game.first") 

Everything seems to work fine. I’m thinking it’s because the module itself has to be referenced somewhere to be included?
It seems like a defold thing to include only things that are mentioned/needed. Is that what’s happening? Is there a workaround ?

Hello! I know only this workaround if you really want to do this:

To be able to do that, you should explicitly require all of these “dynamically loaded” lua files somewhere

You can make a lua file like dynamic_modules.lua with content

require("game.first")
require("game.second")
require("game.third")

and require this file. Then all of you files will be included in the build and you will able to call ocal my_module = require(modules[id])

6 Likes

Or alternatively:

local id = 1
local modules = {
	require("game.first"),
	require("game.second"),
	require("game.third"),
}
local my_module = modules[id]
5 Likes

If you really need to load code dynamically you can also use dofile(). This loads and interprets a chunk of lua in place. This would be the easiest drop-in replacement.

You can do
local my_module = dofile(“game/first.lua”)

However, since your app bundle will not contain your .lua files as is normally, you’d have to copy them manually.

Another possible route would be to bundle dynamic lua files as custom resources and then go resource.load(“game/first.lua”). Then interpret the result using loadstring().

The latter is probably safer, and would likely work on every platform, through no guarantees. Both would probably require some tinkering to get working reliably.

Neither of these approaches I would really recommend, though I use dofile() during development for hot reloading things that are tricky to hot reload using Defold’s regular mechanism.

Using dofile() could unlock potentially unlock powerful modding features for a community, now that I think about it.

1 Like