Post-0.10.0 feature wishlist
Re: Post-0.10.0 feature wishlist
You can always track your own time using timer function. It's a high resolution timer so there aren't repercussions to using it.
Re: Post-0.10.0 feature wishlist
Thats all true, but i dont want to track "my own time for something". I want to fine tune the love.run() loop.raidho36 wrote:You can always track your own time using timer function. It's a high resolution timer so there aren't repercussions to using it.
One in most cases sufficiant way is vsync=true but this is somehow out of my control.
Please imagine the following situation: I create a chess like game. Most of the time the window needs no update. Therefore 20fps are more than enouth and my weak gpu will bcome less stressed. To maintain a constant loop time i need to know as exact as possible the time went by since the last love.update(). Knowing this time would allow me to sleep() until the next love.update() call. To figure this time out the getDelta() function is not helpfull because the returned deltatime is outdated (late by one loop).
- zorg
- Party member
- Posts: 3480
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: Post-0.10.0 feature wishlist
I'm pretty sure you do want to time how much time your code spends in the current love.run loop cycle.Fuzzlix wrote:Thats all true, but i dont want to track "my own time for something". I want to fine tune the love.run() loop.raidho36 wrote:You can always track your own time using timer function. It's a high resolution timer so there aren't repercussions to using it.
You can't really do what you want to any other way. Fine-tuning love.run with dynamic sleep times, i mean.
Well, that depends on the current screen's refresh rate, if it works, that is. I wouldn't rely on it a 100%.Fuzzlix wrote:One in most cases sufficient way is vsync=true but this is somehow out of my control.
Despite how the default love.run works, update time usually does not equal draw(render) time. Besides, with 20 FPS, your input will be choppy as well, even for a turn-based game as chess, 1/3th of a second of potential input delay is noticeable, and to be honest, quite irritating.Fuzzlix wrote:Please imagine the following situation: I create a chess like game. Most of the time the window needs no update. Therefore 20fps are more than enouth and my weak gpu will bcome less stressed.
Also, until you benchmarked exactly how a simple chess game can melt down your GPU, i'd tend to say you're trying to over-optimize (prematurely) right now.
Maintaining a constant loop time means you not messing with love.run (and love.timer.sleep) though. Also, dynamically calculating how much time has elapsed and sleeping that amount will never sleep for exactly how much you want it to... OS schedulers won't be nice to your program, just because you'd ask nicely; there may and probably will be drifts in the timing.Fuzzlix wrote:To maintain a constant loop time i need to know as exact as possible the time went by since the last love.update(). Knowing this time would allow me to sleep() until the next love.update() call. To figure this time out the getDelta() function is not helpfull because the returned deltatime is outdated (late by one loop).
By the way, as you saw in love.run, love.timer.step gets called in there, and getDelta basically uses that to compute the elapsed times.
Note that i'm not saying you shouldn't experiment with love.run, only that what you're trying to do doesn't really make much sense to me, for your use-case. It will probably bring you more bugs than whatever you intended for it to solve.
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: Post-0.10.0 feature wishlist
I don't think it makes sense to have such a function. Your func1() describes exactly [wiki]love.timer.getDelta[/wiki]() and your func2() can easily be implemented like this:Fuzzlix wrote:It looks like, getDelta() returns the time between the last 2 step() calls? In this case the result of getDelta() would be outdated by one loop! Shure it is not a big issue but i cant get any information about the actual time spent since the last step() command and sometimes i need this information.
I suggest a new pair of functions which may be used in addition or as a replacement to the existing ones:
func1(): returning the time since the last step() command.
func2(): returning the time since the last step() command AND executing step().
Inside your love.run() you call......to get the time spent since the last love.update(dt) and reset the timer automatically.Code: Select all
love.update(func2())
In the next love.run() loop you can call func1() as often you wish to get the time spent since the last love.update() call without the 1-loop-delay the getDelta() function has.
Code: Select all
function func2()
love.timer.step()
return love.timer.getDelta()
end
Code: Select all
function func2()
local elapsed = love.timer.getDelta()
love.timer.step()
return elapsed
end
Without having looked at the sources, my understanding is that the implementations of [wiki]love.timer.step[/wiki]() and [wiki]love.timer.getDelta[/wiki]() are functionally equivalent to the following:
Code: Select all
local frozenDelta = 0
local lastTime = love.timer.getTime()
function step()
local oldTime = lastTime
lastTime = love.timer.getTime()
frozenDelta = lastTime - oldTime
end
function getDelta()
return frozenDelta
end
Re: Post-0.10.0 feature wishlist
Exactly! that is the state now. i can call getDelta() as often as i wish and i get the same result until i call step(). As you mentioned, this delta time is one frame late! THIS is the state now and i have no chance to get a information about the actual time spent since the last step() call. This limits my abilities to fine tune the love.run() loop.pgimeno wrote: Or viceversa, if that's what you mean:but then the returned time would be 1 frame behind.Code: Select all
function func2() local elapsed = love.timer.getDelta() love.timer.step() return elapsed end
Ok lets try it in pseudo code:pgimeno wrote: Without having looked at the sources, my understanding is that the implementations of [wiki]love.timer.step[/wiki]() and [wiki]love.timer.getDelta[/wiki]() are functionally equivalent to the following:How do you propose any new functions to work in terms of [wiki]love.timer.getTime[/wiki]()?Code: Select all
local frozenDelta = 0 local lastTime = love.timer.getTime() function step() local oldTime = lastTime lastTime = love.timer.getTime() frozenDelta = lastTime - oldTime end function getDelta() return frozenDelta end
Code: Select all
local lastTime = love.timer.getTime();
function newStep()
local t = lastTime;
lastTime = love.timer.getTime();
return lastTime - t;
end;
function newGetDelta()
return love.timer.getTime() - lastTime;
end;
Re: Post-0.10.0 feature wishlist
I think i found out, whats so difficult to understand on my proposal: When i look at the [wiki]love.run[/wiki] example code for 0.10.0 the calls for step() and getDelta() are placed close together without any code between.
I want to sleep some time until the next update() and draw() calls need to run. In front of love.update() i call step() like the example code and i want to run the next love.update() exactly (lets say) 20ms later. I need to find out how long the last love.update() and love.draw() calls took for calculating the time, i need to sleep. Lets say, it took 5ms, i want to sleep 15ms and the next love.update() call will be issued 20ms past the previous one.
I want to sleep some time until the next update() and draw() calls need to run. In front of love.update() i call step() like the example code and i want to run the next love.update() exactly (lets say) 20ms later. I need to find out how long the last love.update() and love.draw() calls took for calculating the time, i need to sleep. Lets say, it took 5ms, i want to sleep 15ms and the next love.update() call will be issued 20ms past the previous one.
- bartbes
- Sex machine
- Posts: 4946
- Joined: Fri Aug 29, 2008 10:35 am
- Location: The Netherlands
- Contact:
Re: Post-0.10.0 feature wishlist
This is the way it's supposed to work, you then use the delta time to simulate the period between the start of the previous frame and this one. It works well, without any big surprises, and you get a consistent end result, one where all entities are at the "same position in time", the start of this frame.Fuzzlix wrote: As you mentioned, this delta time is one frame late!
That said, if you are intent on doing this, you can do so now. Instead of calling love.timer.step() (or in addition to), store the current time in a variable, then wherever you want to figure out how much time has passed since that point, get the current time and subtract that start time from it.
- slime
- Solid Snayke
- Posts: 3183
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: Post-0.10.0 feature wishlist
This example has one frame of delay compared to the default [wiki]love.run[/wiki]. In that example, the past delta is retrieved and then step is called which updates the internal delta, but it's not retrieved until the next frame.Fuzzlix wrote:Exactly! that is the state now.pgimeno wrote: Or viceversa, if that's what you mean:but then the returned time would be 1 frame behind.Code: Select all
function func2() local elapsed = love.timer.getDelta() love.timer.step() return elapsed end
With the default love.run, the delta time is calculated and then retrieved at the start of every frame. Since you need the delta time right after the start of the frame in order to use love.update, its latency cannot be reduced from that.
Keep in mind this is the time that an entire frame takes (which is generally what you want if you want your numbers in terms of real time). If you just want to compute the time that an update step takes, you can do that manually. You can also pretty easily have a fixed update rate and a variable display frame rate. This is a popular webpage which goes into detail about it: http://gafferongames.com/game-physics/f ... -timestep/
Re: Post-0.10.0 feature wishlist
True! and using vsync i am fixed to the screen refresh rate.zorg wrote:Well, that depends on the current screen's refresh rate, if it works, that is. I wouldn't rely on it a 100%.Fuzzlix wrote:One in most cases sufficient way is vsync=true but this is somehow out of my control.
All truezorg wrote:Despite how the default love.run works, update time usually does not equal draw(render) time. Besides, with 20 FPS, your input will be choppy as well, even for a turn-based game as chess, 1/3th of a second of potential input delay is noticeable, and to be honest, quite irritating.Fuzzlix wrote:Please imagine the following situation: I create a chess like game. Most of the time the window needs no update. Therefore 20fps are more than enouth and my weak gpu will bcome less stressed.
Also, until you benchmarked exactly how a simple chess game can melt down your GPU, i'd tend to say you're trying to over-optimize (prematurely) right now.

Ok lets talk about pros and cons:zorg wrote:Note that i'm not saying you shouldn't experiment with love.run, only that what you're trying to do doesn't really make much sense to me, for your use-case. It will probably bring you more bugs than whatever you intended for it to solve.
At least one pro: love.update() allways will get the correct delta time no matter what i do in my own love.run().
the standard love.run becomes simpler:
Code: Select all
...
-- Update dt, as we'll be passing it to update
if love.timer then
dt = love.timer.step() -- no need for love.timer.getDelta() anymore
end
-- Call update and draw
if love.update then love.update(dt) end -- will pass 0 if love.timer is disabled
if love.graphics and love.graphics.isActive() then
love.graphics.clear(love.graphics.getBackgroundColor())
love.graphics.origin()
if love.draw then love.draw() end
love.graphics.present()
end
if love.timer then love.timer.sleep(0.001) end
Code: Select all
local fps = 20 -- or whatever you want as fps.
local sleepTime = 1 / fps;
...
-- Update dt, as we'll be passing it to update
if love.timer then
love.timer.sleep(max(sleepTime - (love.timer.getDelta()), 0.001));
dt = love.timer.step() -- no need for love.timer.getDelta() anymore
end
-- Call update and draw
if love.update then love.update(dt) end -- will pass 0 if love.timer is disabled
if love.graphics and love.graphics.isActive() then
love.graphics.clear(love.graphics.getBackgroundColor())
love.graphics.origin()
if love.draw then love.draw() end
love.graphics.present()
end
--if love.timer then love.timer.sleep(0.001) end
But it is not more or less than an answer on the stated question: "What feature do you want to see in the next release."
It is up to you, guys, to judge.

- zorg
- Party member
- Posts: 3480
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: Post-0.10.0 feature wishlist
In any case, here's my love.run, just to contrast:
Note that this isn't perfect either, but it does the job i want it to do. 
Code: Select all
love.run = function()
if love.math then
love.math.setRandomSeed(os.time())
end
if love.load then love.load(arg) end
-- We don't want the first frame's dt to include time taken by love.load.
if love.timer then love.timer.step() end
local dt = 0.0 -- delta time
local tr = 1/100 -- tick rate
local fr = 1/75 -- frame rate
local da = 0.0 -- draw accumulator
local ua = 0.0 -- update accumulator
-- Main loop time.
while true do
-- Process events.
if love.event then
love.event.pump()
for name, a,b,c,d,e,f in love.event.poll() do
if name == "quit" then
if not love.quit or not love.quit() then
return a
end
end
love.handlers[name](a,b,c,d,e,f)
end
end
-- Update dt, as we'll be passing it to update
if love.timer then
love.timer.step()
dt = love.timer.getDelta()
da = da + dt
ua = ua + dt
end
-- Call audio
if love.atomic then love.atomic(dt) end
-- Call update
if ua > tr then
if love.update then
love.update(tr) -- will pass 0 if love.timer is disabled
end
ua = ua % tr
end
-- Call draw
if da > fr then
if love.graphics and love.graphics.isActive() then
love.graphics.clear(love.graphics.getBackgroundColor())
love.graphics.origin()
if love.draw then love.draw() end -- no interpolation
love.graphics.present()
end
da = da % fr
end
-- Optimal sleep time, anything higher does not go below 0.40 % cpu
-- utilization; 0.001 results in 0.72 %, so this is an improvement. (on my computer anyway, results may vary)
if love.timer then love.timer.sleep(0.002) end
end
end

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.

Who is online
Users browsing this forum: Ahrefs [Bot] and 5 guests