Page 4 of 5
Re: Hot reload plugin that actually works?
Posted: Sun Jan 28, 2018 11:32 am
by hasen
No it's built into the simulator, that's what I'm talking about.
pgimeno wrote: ↑Sun Jan 28, 2018 10:20 am
I don't run software I can't compile myself. It may be free as in beer, but not free as in freedom.
It's free for you to go ahead and test it if you didn't want to put barricades in front of yourself. Nobody is compelling you to write a game with it either, you can just test your theory with it should you want to.
pgimeno wrote: ↑Sun Jan 28, 2018 10:20 am
It can't find the other file. Make sure it is placed somewhere where Corona can find it.
Of course both module.lua and main.lua are in the same folder..
Re: Hot reload plugin that actually works?
Posted: Sun Jan 28, 2018 11:34 am
by hasen
Tjakka5 wrote: ↑Sun Jan 28, 2018 10:07 am
What Corona does is defined at 'Live Reloading'. Which can be pretty easy to setup with either Love or your Editor.
'Hot Reloading' on the other hand only reloads files that where changed, and maintains the state of the program, something that is difficult to achieve which has been explained earlier.
Well how exactly? That's what this whole thread is about. Lick certainly doesn't do the job well at all. How can we do exactly what Corona does but in Love2d? I'd honestly 'love' to know.
Re: Hot reload plugin that actually works?
Posted: Sun Jan 28, 2018 11:36 am
by hasen
I think everyone is confusing 'hot reload' with 'hot update'. Hot reload DOES have to reload the program each time, hence the word 'reload' in the name and the word 'reload' in the title of my thread. 'Hot update' is where I have a guy jumping on screen, I adjust the jump height and he starts jumping higher suddenly with no reload at all.
Hot reload is what the Corona simulator does as standard. That's the functionality I was after in Love2d.
Re: Hot reload plugin that actually works?
Posted: Sun Jan 28, 2018 12:44 pm
by zorg
Okay, so let's use simple terms; you want to restart the game without exiting it and manually starting it up again.
That is easy.
Code: Select all
function love.load(arg)
-- Put all require statements and initial code here;
-- file-local declaractions can go above, into the file scope, as long as you don't assign anything to them.
end
function love.keypressed(k,s)
if s == 'escape' then
love.event.quit('restart') -- Works since 0.10.2, recreates the whole lua state from scratch.
end
end
While it does state in the wiki that the restart variant of love.event.quit shuts down the main lua state instance, there may be some other caveats;
- require's table where it stores already loaded libs is probably emptied, so this isn't an issue that needs to be handled separately
- if you use threads, those use their own lua states, maybe you need to clean up those yourself.
- Löve objects (i think) aren't tied to the lua state, they're on the C++ side, so they may survive this, so they may need to be cleaned up manually too.
Re: Hot reload plugin that actually works?
Posted: Sun Jan 28, 2018 1:19 pm
by hasen
So your code will restart the game if I press escape? It's not really an auto reload like with Corona...? It should reload on changes to the code on any lua files in the project...or to be the same as Corona, any files in the project folder at all but I'd be satisfied with the former.
Re: Hot reload plugin that actually works?
Posted: Sun Jan 28, 2018 1:39 pm
by zorg
My mistake, this thread is still very confusing to be honest
Here, a better code:
Code: Select all
local sourceFiles = {}
function love.load(arg)
-- Go over all "filesystem objects" löve can detect
local files = love.filesystem.enumerate(dir)
for k, file in ipairs(files) do
-- if it's a file, and it's in the source directory / .love file itself...
if love.filesystem.isFile(file) and love.filesystem.getRealDirectory(file) == love.filesystem.getSource() then
-- put the file and its last modified date (restricted to 1 return value with the parentheses) in the file-local table.
sourceFiles[file] = (love.filesystem.getLastModified(file))
end
end
-- Put all require statements and initial code here;
-- file-local declaractions can go above, into the file scope, as long as you don't assign anything to them.
end
function love.update(dt)
-- Go over all "filesystem objects" löve can detect
local files = love.filesystem.enumerate(dir)
for k, file in ipairs(files) do
-- if it's a file, and it's in the source directory / .love file itself...
if love.filesystem.isFile(file) and love.filesystem.getRealDirectory(file) == love.filesystem.getSource() then
-- if the file was catalouged, and it has been modified after, restart the whole program.
if sourceFiles[file] and (love.filesystem.getLastModified(file)) > sourceFiles[file] then
love.event.quit('restart')
end
end
end
end
Does things automatically, although this still has a few issues;
- it doesn't check for files you might add in later,
- it runs the check each frame, which is overkill; once every second would be sufficient. It can be made to do that, but certainly not with love.timer.sleep
- haven't tested it, so expect it to not work.
Re: Hot reload plugin that actually works?
Posted: Sun Jan 28, 2018 2:58 pm
by hasen
zorg wrote: ↑Sun Jan 28, 2018 1:39 pm
Does things automatically, although this still has a few issues;
- it doesn't check for files you might add in later,
- it runs the check each frame, which is overkill; once every second would be sufficient. It can be made to do that, but certainly not with love.timer.sleep
- haven't tested it, so expect it to not work.
It's checking every frame? Shouldn't it only check when saving a file? Not sure exactly how the one in Corona works...do you assume it's doing the same thing then?
Re: Hot reload plugin that actually works?
Posted: Sun Jan 28, 2018 3:09 pm
by nander
Hot reloading is basically impossible if you want to maintain state*.
The problem is, your data may have been put in a state that doesn't fit your new code as well.
If you only want to be able reload when the data-model doesn't change, then an Entity Component System can help you out. You would need to reload the Systems in that case, while keeping the Entities and Components loaded. I have had experimental code for this, but it broke once Systems needed to keep track of their own (derivative) state.
Re: Hot reload plugin that actually works?
Posted: Sun Jan 28, 2018 3:39 pm
by zorg
I don't give a squat about how corona does it, to be completely honest. You did explain it clearer in one of the later post of yours:
hasen wrote:I think everyone is confusing 'hot reload' with 'hot update'. Hot reload DOES have to reload the program each time, hence the word 'reload' in the name and the word 'reload' in the title of my thread. 'Hot update' is where I have a guy jumping on screen, I adjust the jump height and he starts jumping higher suddenly with no reload at all.
Hot reload is what the Corona simulator does as standard. That's the functionality I was after in Love2d.
Despite the fact that words can have tons of meanings and terminology like this isn't standardized across everything, i have decided to use "game restart" and "hotswapping" to refer to the two separate things (the latter not making the distinction between code and asset reloading)
The project needs to check in regular time intervals, otherwise, how would löve know that a file has changed? The code i posted is responsible for that. Your text editor or IDE or whatever won't notify another program that you modified a file.
That said, here's the modified code that only checks every 1/4th of a second and adds newly added files to the sourceFiles table.
Code: Select all
local sourceFiles
local fileCheckDelay
local timer
function love.load(arg)
fileCheckDelay = 0.25 -- 1/4
timer = 0.0
sourceFiles = {}
-- Go over all "filesystem objects" löve can detect
local files = love.filesystem.enumerate(dir)
for k, file in ipairs(files) do
-- if it's a file, and it's in the source directory / .love file itself...
if love.filesystem.isFile(file) and love.filesystem.getRealDirectory(file) == love.filesystem.getSource() then
-- put the file and its last modified date (restricted to 1 return value with the parentheses) in the file-local table.
sourceFiles[file] = (love.filesystem.getLastModified(file))
end
end
-- Put all require statements and initial code here;
-- file-local declaractions can go above, into the file scope, as long as you don't assign anything to them.
end
function love.update(dt)
timer = timer + dt
if timer > fileCheckDelay then
-- Go over all "filesystem objects" löve can detect
local files = love.filesystem.enumerate(dir)
for k, file in ipairs(files) do
-- if it's a file, and it's in the source directory / .love file itself...
if love.filesystem.isFile(file) and love.filesystem.getRealDirectory(file) == love.filesystem.getSource() then
-- if the file was catalouged, and it has been modified after, restart the whole program.
if sourceFiles[file] then
if (love.filesystem.getLastModified(file)) > sourceFiles[file] then
love.event.quit('restart')
end
else
-- add it to the list
sourceFiles[file] = (love.filesystem.getLastModified(file))
end
end
end
timer = timer - fileCheckDelay
end
end
Hot *restart* plugin that actually works? Feasible.
Posted: Sun Jan 28, 2018 5:00 pm
by pgimeno
hasen wrote: ↑Sun Jan 28, 2018 11:36 am
I think everyone is confusing 'hot reload' with 'hot update'. Hot reload DOES have to reload the program each time, hence the word 'reload' in the name and the word 'reload' in the title of my thread. 'Hot update' is where I have a guy jumping on screen, I adjust the jump height and he starts jumping higher suddenly with no reload at all.
Hot reload is what the Corona simulator does as standard. That's the functionality I was after in Love2d.
I call that "hot restart". "Reload" to me applies to individual files, as in, when you modify a file, it is reloaded into the running program. Everyone else has understood it that way. "Restart" implies your application starts again from the beginning.
Hot restart is of course simple to get right for many workflows, starting in 0.10.2 as zorg mentioned.
AFAIK the libraries you mentioned upthread, lick and lovedebug, are aimed at hot swapping (using zorg's terms) or hot update (using your terms). They are not aimed at hot restarting.
I'm wondering if it's possible to call love.event.quit("restart") from a thread. The docs don't mention this, but I don't see why not. So, you could have a dedicated thread monitoring your filesystem. Perhaps even interfacing to a file modification monitor library via FFI if available.
The only problem I see with this way of restarting is that while hot restarting, you should ensure that your program returns false in the love.quit() event if you define it. That's where it may interfere with some workflows and require manual intervention. Maybe Löve could incorporate love.event.quit("forcerestart") to ignore the result of love.quit(), but I'm not sure that's wise. It would be best if Löve was also changed to make love.quit() receive a force parameter that is true if it will ignore the return value and quit straight away.