I read this post by the Legend of Grimrock guys on dynamically loading Lua to speed up their code, build, test iteration cycle.
It got me thinking, if this is possible within a C++ environment that runs Lua, is it possible in a Lua-only environment like a Löve game?
Ideally it'd be great to be able to change some entity definitions in my game, and then have my code re-load that on the fly.
Has anyone tried this already?
Dynamically Reloading Lua Files
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
-
- Prole
- Posts: 31
- Joined: Thu Sep 13, 2012 2:10 am
- Robin
- The Omniscient
- Posts: 6506
- Joined: Fri Feb 20, 2009 4:29 pm
- Location: The Netherlands
- Contact:
Re: Dynamically Reloading Lua Files
Yeah, I think people have tried it, though I can't remember specific examples.
You can do it pretty easily if you design your data structures right. Then you can reload your game on the fly without crashing or resetting the game.
... someone with actual experience with this care to comment?
You can do it pretty easily if you design your data structures right. Then you can reload your game on the fly without crashing or resetting the game.
... someone with actual experience with this care to comment?

Help us help you: attach a .love.
- bartbes
- Sex machine
- Posts: 4946
- Joined: Fri Aug 29, 2008 10:35 am
- Location: The Netherlands
- Contact:
Re: Dynamically Reloading Lua Files
Yeah, there's been a couple of these things, like LICK.
Personally, I've used some bash scripts hooked up to inotify to restart love when a file is modified.
Personally, I've used some bash scripts hooked up to inotify to restart love when a file is modified.
- Robin
- The Omniscient
- Posts: 6506
- Joined: Fri Feb 20, 2009 4:29 pm
- Location: The Netherlands
- Contact:
Re: Dynamically Reloading Lua Files
That's simple and doesn't require any changes to the game itself, nice.bartbes wrote:Personally, I've used some bash scripts hooked up to inotify to restart love when a file is modified.
Those don't preserve state, though. If you can manage that, it'll be epic. Can we intercept signals? If so, your bash script could send a signal and the game would intercept that and store the state in the savedir.
Help us help you: attach a .love.
Re: Dynamically Reloading Lua Files
I am not doing this in love2d, but in my other lua project, I use sockets to send the data over the network and then execute. I have some code that runs on the command line looking for file changes.
It lets me preserve state, which is nice.
It lets me preserve state, which is nice.
Re: Dynamically Reloading Lua Files
Hey (sorry for the double posting), but I just went ahead and wrote a pure lua thing that watches the file system and loads in lua files that change. It preserves state, so you can just go along editing things.
just use it like this:
I don't think that it works on windows (I am unsure on how to do directory separators in a crossplatform way), and it dumps out errors to the console that opened it, rather than blue screening.
Hope that someone finds this useful, let me know if there are any changes that you want.
just use it like this:
Code: Select all
local fw = love.filesystem.load("fileWatch.lua")()
fw:start()
function love.update(dt)
fw:update()
end
Hope that someone finds this useful, let me know if there are any changes that you want.
- Attachments
-
- filewatch.zip
- (1.35 KiB) Downloaded 349 times
-
- Prole
- Posts: 31
- Joined: Thu Sep 13, 2012 2:10 am
Re: Dynamically Reloading Lua Files
jonbro that looks super-useful! Thanks for posting it!
I'm wondering how I could build this into a larger system.
Calling require() again on a file that's already been require'd won't do anything?
I guess if the files you are watching and reloading are functions and class data, you could find the matching existing instance(s), and replace their properties to point to the modified functions and class data. You'd have to preserve instance data though...
Something like this:
I'm not sure how to do this cleanly yet using MiddleClass. Hmm.
I'm wondering how I could build this into a larger system.
Calling require() again on a file that's already been require'd won't do anything?
I guess if the files you are watching and reloading are functions and class data, you could find the matching existing instance(s), and replace their properties to point to the modified functions and class data. You'd have to preserve instance data though...
Something like this:
Code: Select all
modifiedStuff -- our asynchronously loaded table
for _, entity in ipairs(entities) do
foreach key, val in pairs(modifiedStuff) do
entity[key] = val
end
end
Re: Dynamically Reloading Lua Files
I have some code to do this in Zoetrope. The approach it takes is different and more basic. When it initially loads, it takes a snapshot of _G (the table where all globals live) and packages.loaded (which tracks what's already been loaded). To reload, it resets _G and packages.loaded to their previous values and restarts things by requiring main.lua, then calling love.load().
The code that takes the snapshot is here, and here is how I do the reloading.
The code that takes the snapshot is here, and here is how I do the reloading.
Re: Dynamically Reloading Lua Files
I've taken on a pattern (I think kikito may have suggested it, but I could be wrong) where I do the primary list of library loading out of love.load, which makes sure to clear out package.loaded. Then I rig a quick reset button (like F9) to the love.load call. Here's some sample code:
Code: Select all
libraries = {
"class", "graphics", "color", "input", "util", "statemachine"
}
function loadLibraries()
for _, lib in ipairs( libraries ) do
package.loaded[lib] = nil
end
for _, lib in ipairs( libraries ) do
require(lib)
end
end
function love.load()
loadLibraries()
end
- bartbes
- Sex machine
- Posts: 4946
- Joined: Fri Aug 29, 2008 10:35 am
- Location: The Netherlands
- Contact:
Re: Dynamically Reloading Lua Files
Correct, but the easy workaround is something like this:benhumphreys wrote: Calling require() again on a file that's already been require'd won't do anything?
Code: Select all
function rerequire(module)
package.loaded[module] = nil
return require(module)
end
Who is online
Users browsing this forum: Ahrefs [Bot], Google [Bot] and 4 guests