Live coding on Linux with LÖVE

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
purplehuman
Citizen
Posts: 72
Joined: Thu Mar 05, 2015 4:25 pm
Location: Ankara, Turkey
Contact:

Live coding on Linux with LÖVE

Post by purplehuman »

I don't know if everybody knows this, but I just recently figured it out, so I decided to share it if anyone else needs it.

To see the changes to your main.lua file live, add these lines to your love.update() function:

Code: Select all

if love.filesystem.load("main.lua") == nil then
     love.timer.sleep(1)
     love.filesystem.load("main.lua")()
end
Then run your game in the game directory with

Code: Select all

love .
(Note the dot at the end.)

Now when you make a change in the main.lua file and save, the running game will be updated. It doesn't reset the global variables, so it's great to code live. I use it for rapid prototyping.

What we do here in the code is to tell LÖVE if main.lua isn't available, wait a little and reload main.lua. It's a trick using a filesystem feature. When main.lua is saved, the old version of the file is removed for a moment before being replaced by the new version. I don't know if this works on Windows or Mac OS X though.

EDIT: I just realized that it's not about the filesystem, but about the text editor I use. I use vim for development, and vim seems to remove the old file when saving which causes LÖVE to throw an error. That's why I couldn't run only this line:

Code: Select all

love.filesystem.load("main.lua")()
But in gedit this line alone works fine.
Last edited by purplehuman on Thu Mar 05, 2015 7:41 pm, edited 4 times in total.
I am 2D.
I am purplehuman on github.
And I am purplegordebak on twitter
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Live coding on Linux with LÖVE

Post by zorg »

The following code is more straightforward, and doesn't use tricks that may be either unpredictable or not cross-platform; nor does it block for 1 second per update:

Code: Select all

local lastModified
function love.load()
  lastModified = os.time()
end
function love.update(dt)
  if love.filesystem.getLastModified('main.lua') > lastModified then
    love.filesystem.load('main.lua')()
    lastModified = os.time()
  end
end
This checks the last modified time of the main.lua file, and if it's newer than what we set in love.load, it reloads it, and stores the date the newest update happened.
You could also use a timer, 4 times per second or so, or combine that with this method as well, it may reduce cpu or hdd/ssd/usb usage. (depending on where the main.lua file is located)
Also, this does not check / protect against code errors or editor-induced file existence failure idiosyncrasies, so if the new main.lua has some error in it, it will stop execution; there are ways around these though.
I do something similar like this in my codebase, but that's contained per-gamestate (i.e. i'm never modifying main.lua), don't know what the possible repercussions may be if you do this though.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
purplehuman
Citizen
Posts: 72
Joined: Thu Mar 05, 2015 4:25 pm
Location: Ankara, Turkey
Contact:

Re: Live coding on Linux with LÖVE

Post by purplehuman »

Thanks zorg! Yours is a better solution than mine. I just realized that problem wasn't about the filesystem, but the text editor I use. Vim seems to remove the old file when saving. But I will use your solution, since it's more elegant.

EDIT: I just tried your solution. I'm afraid when using vim, it throws the same error. For a moment, the file isn't there, so LÖVE throws an error when you compare the last modified time. My solution might be vim specific maybe, but it works for me.
I am 2D.
I am purplehuman on github.
And I am purplegordebak on twitter
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Live coding on Linux with LÖVE

Post by zorg »

Code: Select all

local lastModified
function love.load()
	lastModified = os.time()
end
function reload(path)
	local result, chunk
	result, chunk = pcall(love.filesystem.load, path)
	if not result then print("chunk error: " .. chunk) return false end
	result, chunk = pcall(chunk,...)
	if not result then print("exec. error: " .. chunk) return false end
	return true
end
function love.update(dt)
	if love.filesystem.getLastModified('main.lua') > lastModified then
	if reload('main.lua') then
		lastModified = os.time()
	end
  end
end
This is one step closer; now if it fails to read or execute the chunk, it won't mess with the modification time it stores, so after fixing the source, it will be able to reload it.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
yetneverdone
Party member
Posts: 446
Joined: Sat Sep 24, 2016 11:20 am
Contact:

Re: Live coding on Linux with LÖVE

Post by yetneverdone »

zorg wrote:

Code: Select all

local lastModified
function love.load()
	lastModified = os.time()
end
function reload(path)
	local result, chunk
	result, chunk = pcall(love.filesystem.load, path)
	if not result then print("chunk error: " .. chunk) return false end
	result, chunk = pcall(chunk,...)
	if not result then print("exec. error: " .. chunk) return false end
	return true
end
function love.update(dt)
	if love.filesystem.getLastModified('main.lua') > lastModified then
	if reload('main.lua') then
		lastModified = os.time()
	end
  end
end
This is one step closer; now if it fails to read or execute the chunk, it won't mess with the modification time it stores, so after fixing the source, it will be able to reload it.
Throws an error:
'...' outside a vararg function near '...'
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Live coding on Linux with LÖVE

Post by zorg »

Just remove the '...' from pcall(chunk,...); to be honest, i have no idea what the purpose of that was...

Late edit: The purpose was probably to send in arguments to the chunk itself, so those could be accessed by doing local args = {...} or something at the top of the loaded file; i just forgot to give the reload function the same ... parameter in the definition.
Last edited by zorg on Sat Mar 10, 2018 4:44 pm, edited 2 times in total.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Darlex
Party member
Posts: 128
Joined: Sun Sep 24, 2017 10:02 am
Location: Chile
Contact:

Re: Live coding on Linux with LÖVE

Post by Darlex »

Doesn't work on Android :(
Just stays on black
Hi! I wish you have an amazing day!
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Live coding on Linux with LÖVE

Post by zorg »

Darlex wrote: Sat Mar 10, 2018 3:17 pm Doesn't work on Android :(
Just stays on black
Which one, and how are you trying to run it?
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Darlex
Party member
Posts: 128
Joined: Sun Sep 24, 2017 10:02 am
Location: Chile
Contact:

Re: Live coding on Linux with LÖVE

Post by Darlex »

I downloaded the LÖVE2D app on my phone and I just loaded the main.lua on it, But doesn't work

Pd: Sorry, my English is so bad :(
Hi! I wish you have an amazing day!
Darlex
Party member
Posts: 128
Joined: Sun Sep 24, 2017 10:02 am
Location: Chile
Contact:

Re: Live coding on Linux with LÖVE

Post by Darlex »

Code: Select all

local lastModified
function love.load()
	lastModified = os.time()
end
function reload(path)
	local result, chunk
	result, chunk = pcall(love.filesystem.load, path)
	if not result then print("chunk error: " .. chunk) return false end
	result, chunk = pcall(chunk)
	if not result then print("exec. error: " .. chunk) return false end
	return true
end
function love.update(dt)
	if love.filesystem.getLastModified('main.lua') > lastModified then
	if reload('main.lua') then
		lastModified = os.time()
	end
  end
end
This one..
Hi! I wish you have an amazing day!
Post Reply

Who is online

Users browsing this forum: No registered users and 69 guests