Greetings, i'm wondering if there is a way to run love.draw() in a thread and love.update() in another thread.
So basicaly don't touch the draw function, just move the update() one on a thread.
So FPS would not be bound to update() and draw() but only draw().
I found this thread : viewtopic.php?f=4&t=78795
Peoples seems to says it could be hard/not a good idea, but i just would work like a multiplayer game.
The server(One thread here) is making most of the calcs and the client (the other thread)the draw.
Thanks.
[SOLVED] One thread for update() and one for draw()
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
[SOLVED] One thread for update() and one for draw()
Last edited by Lapin on Mon Jun 08, 2015 2:19 pm, edited 1 time in total.
- kikito
- Inner party member
- Posts: 3153
- Joined: Sat Oct 03, 2009 5:22 pm
- Location: Madrid, Spain
- Contact:
Re: One thread for update() and one for draw()
It is theoretically possible, but that approach has some significant hurdles to go over.
The biggest one is this: you can't share memory between threads. This means that you can't "modify a table in the update thread" and then "use it in the draw thread".
If you want to use the information produced by one thread in another thread, the first thread must "send it" and the other one must "read it". In order to do this you build a [wiki]Channel[/wiki]. And you pass along values - things like "the enemy with id 5 has moved 3 pixels to the right", for example. Values can't be tables - they must be strings, numbers or booleans.
This communication between threads isn't free - it takes time. I don't know how much. Depending on the amount of information you need to share, and how fast they are, it might be possible that your "dual-thread" system is slower than a single-thread one. There is also the fact that you will need two "structures" for your game - the "logic structure" for the update thread and the "visual structure" for the draw thread. So your memory consumption probably will also go up.
The biggest one is this: you can't share memory between threads. This means that you can't "modify a table in the update thread" and then "use it in the draw thread".
If you want to use the information produced by one thread in another thread, the first thread must "send it" and the other one must "read it". In order to do this you build a [wiki]Channel[/wiki]. And you pass along values - things like "the enemy with id 5 has moved 3 pixels to the right", for example. Values can't be tables - they must be strings, numbers or booleans.
This communication between threads isn't free - it takes time. I don't know how much. Depending on the amount of information you need to share, and how fast they are, it might be possible that your "dual-thread" system is slower than a single-thread one. There is also the fact that you will need two "structures" for your game - the "logic structure" for the update thread and the "visual structure" for the draw thread. So your memory consumption probably will also go up.
When I write def I mean function.
Re: One thread for update() and one for draw()
Oh ok, i get it.
So i guess it would be better to keep the update() function on the default thread, and create a new one for draw() and it would be here i send the draw calls.
Too bad no one tried to do that before erh.
Thanks anyway.
Edit : or maybe i should try to use OpenCL.
Edit 2 : Wait, would it be possible to compile all the draw calls (not really the draw calls but the function like love.graphics.print) into bytecode, then turn the bytecode into strings and send it to a thread ?
(Like luajit -b yourfile.lua) (Would it be slow)
Actually my game is a GUI based game, not a one with "npcs" or a map.
So i guess it would be better to keep the update() function on the default thread, and create a new one for draw() and it would be here i send the draw calls.
Too bad no one tried to do that before erh.
Thanks anyway.
Edit : or maybe i should try to use OpenCL.
Edit 2 : Wait, would it be possible to compile all the draw calls (not really the draw calls but the function like love.graphics.print) into bytecode, then turn the bytecode into strings and send it to a thread ?
(Like luajit -b yourfile.lua) (Would it be slow)
Actually my game is a GUI based game, not a one with "npcs" or a map.
Last edited by Lapin on Mon Jun 08, 2015 2:17 pm, edited 1 time in total.
- slime
- Solid Snayke
- Posts: 3160
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: One thread for update() and one for draw()
love.graphics cannot be used on any thread other than the main one (mostly due to the way OpenGL works.)Lapin wrote:So i guess it would be better to keep the update() function on the default thread, and create a new one for draw() and it would be here i send the draw calls.
Too bad no one tried to do that before erh.
Thanks anyway.
Re: One thread for update() and one for draw()
Darn.
Understood, thanks.
Understood, thanks.
- zorg
- Party member
- Posts: 3465
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: [SOLVED] One thread for update() and one for draw()
But you can always modify love.run to somewhat separate the update and draw routines;
An example:
1. don't enable vsync - makes the game loop in love.run loop more than what the primary (or the selected, don't know which) screen's refresh rate
2. use accumulators and conditionals (if-then-else) to only call love.update and possibly the event handling (and separately, love.draw) if enough time has passed
With some interpolation in your love.draw, it could work swell.
An example:
1. don't enable vsync - makes the game loop in love.run loop more than what the primary (or the selected, don't know which) screen's refresh rate
2. use accumulators and conditionals (if-then-else) to only call love.update and possibly the event handling (and separately, love.draw) if enough time has passed
With some interpolation in your love.draw, it could work swell.
Me and my stuff True 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.
- Positive07
- Party member
- Posts: 1014
- Joined: Sun Aug 12, 2012 4:34 pm
- Location: Argentina
Re: One thread for update() and one for draw()
They can be simple table, that is, without references to other tables or functionskikito wrote:Values can't be tables - they must be strings, numbers or booleans.
Be careful with the event handling part, you should always call love.event.pump or (at least in Windows) the OS will think that the app is not respondingzorg wrote: 2. use accumulators and conditionals (if-then-else) to only call love.update and possibly the event handling (and separately, love.draw) if enough time has passed
I wouldnt recommend separating in threads either, totally possible but would end up in less performance due to the draw thread updating too late and you would also have to deal with repeated (accumulated) information on the channels.
About zorg method, even though that is possible too, I would always call update and draw just when necessary... It is better to have an instant update than having, say 4 frames with the same things drawn to the screen, because the first would look less laggy than the second. So I wouldnt go with your approach either, sorry
First OpenCL? I dont know how would you go about that and I dont think it would be nice to create a game with that... OpenCL is useful for extremely repetitive task that can totally run in parallel with no shared information.Lapin wrote: Edit : or maybe i should try to use OpenCL.
Edit 2 : Wait, would it be possible to compile all the draw calls (not really the draw calls but the function like love.graphics.print) into bytecode, then turn the bytecode into strings and send it to a thread ?
(Like luajit -b yourfile.lua) (Would it be slow)
Actually my game is a GUI based game, not a one with "npcs" or a map.
Second, about your EDIT 2, compiling to bytecode doesnt make your memory shared and also doesnt allow you to use those functions in a thread, the graphics functions are bound to the window, because the window is the one that displays stuffs, if you dont have a window you cant display stuff, and the window is created by the main thread.
Also dont be confused bytecode is the same as Lua code (it will be run as Lua code by the interpreter, but the compiler can skip the compilation step)
Compiling to bytecode doesnt compile your C/C++ code just your Lua code to bytecode, also C++ code is already compiled (love.exe and its dlls)
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
- kikito
- Inner party member
- Posts: 3153
- Joined: Sat Oct 03, 2009 5:22 pm
- Location: Madrid, Spain
- Contact:
Re: One thread for update() and one for draw()
You are right, I missed that in the "value" wiki page. I stand corrected.Positive07 wrote: They can be simple table, that is, without references to other tables or functions
When I write def I mean function.
- zorg
- Party member
- Posts: 3465
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: One thread for update() and one for draw()
Actually, i wanted to include a paragraph about having the event handling in the "free-running" part, that is, not inside the conditional, that makes update work with a fixed rate; but then one must handle that fact in all the input handlers, like love.keypressed, with storing the input and the inter-tick dt-s, so the update callback can do meaningful work with them, and not miss those events, at least in my opinion.Positive07 wrote:Be careful with the event handling part, you should always call love.event.pump or (at least in Windows) the OS will think that the app is not respondingzorg wrote: 2. use accumulators and conditionals (if-then-else) to only call love.update and possibly the event handling (and separately, love.draw) if enough time has passed
No problem, though i'd argue that with updates set at 60 ticks/sec, and fps set at the screen's refresh rate, it would not look laggy at all.Positive07 wrote: About zorg method, even though that is possible too, I would always call update and draw just when necessary... It is better to have an instant update than having, say 4 frames with the same things drawn to the screen, because the first would look less laggy than the second. So I wouldnt go with your approach either, sorry
Me and my stuff True 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.
Re: [SOLVED] One thread for update() and one for draw()
A technique that I'm playing with is to have your game wrapped in a coroutine, so that you don't have to deal with writing your own love.run function.
Code: Select all
function StartGame()
while true do
local dt = coroutine.yield(true) -- maybe you can pipe back a drawing function to the update function
x = x + math.random(10)*dt
y = y + math.random(10)*dt
end
end
function DrawGame()
love.graphics.rectangle("fill", x, y, 16, 16)
end
function love.load()
RunGame = coroutine.wrap(StartGame)
x = 400
y = 300
end
function love.update(dt)
RunGame(dt)
end
function love.draw()
DrawGame()
end
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 5 guests