How to ensure an action is performed 60 times a second?

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.
Post Reply
Substance12
Prole
Posts: 19
Joined: Fri Dec 11, 2015 7:01 pm

How to ensure an action is performed 60 times a second?

Post by Substance12 »

So, I'm working on a networked game and I need some data to be stored 60 times a second. Right now I'm only calling a function every love.update(), but I know that's not gonna work because framerate can vary a lot.

I've thought of doing it so a counter adds the delta time to a variable, and every time it's equal or higher than 0.01666666 it performs the function and takes 0.01666666 from the counter, leaving it usually a little higher than zero. However, I realized that maybe the delta time can be a lot higher than 0.01666666 sometimes, so I thought of checking how many times 0.01666666 can fit in whatever the number in the counter might be and performing the action the same number of times, as well as taking (0.01666666 * number of times) from the counter. Then when a second passes, the function will have been called 60 times. Is this correct?

Related to this, I was looking through the mari0 source code, and I found this odd snippet at the top of love.update(). Is this related to my problem? What does it do?

Code: Select all

	dt = math.min(0.01666667, dt)
	
	--speed
	if speed ~= speedtarget then
		if speed > speedtarget then
			speed = math.max(speedtarget, speed+(speedtarget-speed)*dt*5)
		elseif speed < speedtarget then
			speed = math.min(speedtarget, speed+(speedtarget-speed)*dt*5)
		end
		
		if math.abs(speed-speedtarget) < 0.02 then
			speed = speedtarget
		end
		
		if speed > 0 then
			for i, v in pairs(soundlist) do
				v:setPitch( speed )
			end
			music.pitch = speed
			love.audio.setVolume(volume)
		else
			love.audio.setVolume(0)
		end
	end
	
	dt = dt * speed
	gdt = dt
	
	if frameadvance == 1 then
		return
	elseif frameadvance == 2 then
		frameadvance = 1
	end

	if skipupdate then
		skipupdate = false
		return
	end
User avatar
zorg
Party member
Posts: 3468
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: How to ensure an action is performed 60 times a second?

Post by zorg »

From the looks of it, most of the code deals with syncing the audio playback rate to the framerate; not sure if that's a good idea or if that's something you want to implement for yourself.

There are a few ways on tackling things.

On windows at least, when you drag a window, it will suspend processing on the main thread; when you release the window, it'll give back an elapsed (delta) time between the start and end timestamps of the drag.

This means you can do one of three things:
- Limit the deltatime so that spikes like that will not cause the game to try and catch up however many seconds or even minutes of work all at once, which would cause jumps in both logic and rendering in your game. This way, it'll be like the game was paused when you started dragging it.
- Not limit it, which would make it catch up near-instantaneously... i'm sure this too could have its uses.
- Use a thread for logic... sadly, in löve, you cannot separate (all) of the graphics from the main thread, so you cannot sidestep this issue.



Onto your original issue; you could implement a simple timer inside your love.update, as you said yourself; add the current delta time to the accumulator, and either:
- use a branch (if): each update cycle would only do one "tick", even if the game would start to get slow and it would be unable to catch up
- use a loop (while): in the case of the accumulator containing more than one full period, this will process all backed up "ticks" and only then proceed to love.draw.

In both cases, you just put the data assignment inside that block, and it should work.
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.
Maurice
Prole
Posts: 23
Joined: Mon Jul 19, 2010 11:41 am

Re: How to ensure an action is performed 60 times a second?

Post by Maurice »

Just to elaborate on the code you copied from Mari0, it actually does 6 things:

- Limit the delta time to 1/60 of a second (zorg mentioned this)
- Modify the pitch of all sounds according to speed, which is modified by the bullet time cheat
- Modify the dt based on the speed (again, bullet time)
- Set a global dt variable because I can't code
- Debug code for frame advancing (there should be more somewhere)
- Skip the current update if so desired. This is mostly for after loading the level for example where I know that dt will be unusually high
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 10 guests