Log In  


Do anyone know how constant is the duration of a frame in PICO-8?

I am considering making samething that will use rhythm and decided to use the frames as a time basis. First thing I implemented was a simple metronome.

Code below:

This function rounds a number n to the nearest integer that is multiple of m:

function round_mult(n, m)
 -- n is the number to be 
 --  rounded.
 -- m is the integer 
 --  significance.
 -- returns the nearest 
 --  multiple of m.

 if (n % m) == 0 then

 	return n

 else

  v_up = flr(n) + 1
  v_up = n + (m - n % m)

  v_dn = flr(n)
  v_dn = n - (n % m)

  if (v_up - n) <= (n - v_dn) then
  	return v_up
  else
  	return v_dn
  end

 end

end

On the metronome itself, I want to put a bpm and use the nearest bpm that can fit inside a frame time.

function _init()
	bpm = 50 -- this is not necessarily the actual bpm ingame.
	btime = 60/bpm -- time per beat in seconds
	subdivs = 4 -- subdivisions of a beat

	fps = stat(7) -- framerate
	ftime = 1/fps -- time per frame

	bframes = round_mult(
	 btime / ftime, 
	 subdivs) -- the actual bpm to be used, but in frames instead of seconds

	curframe = 1 -- frame count starts at 1
end

function _update()
	if curframe == bframes then
		sfx(1) -- this is the end of a beat
		curframe = 1
	elseif (curframe 
	 % (bframes / subdivs)) 
	 == 0 then
	 sfx(0) -- this is a subdivision of a beat
	 curframe = curframe + 1
	else
	 curframe = curframe + 1
	end
end

function _draw()
	cls()
	print(tostr(curframe))
end

The thing is, I recorded the beeps and I noticed (using audacity) that the times of the beats are not always the same. It differs a little bit. Can frames take slightly longer or shorter times to occur inside PICO-8?



maybe look into _update60() and be sure to use the console and not the web browser.


1

Take care to use the local keyword for local variables. Otherwise you're declaring globals, even inside of functions.

PICO-8 calls _update() 30x per second, or _update60() 60x per second, depending on which is present.

Any timing you do that uses the update clock cannot be any more precise than to the level of 1/30th or 1/60th of a second.

PICO-8's music clock seems to run at 120Hz. You can see this by setting an SFX to run at SPD=120, which actually means its notes are all 120 clock ticks long, so each note in the SFX will be one second long.

Similarly to the update clock, you can't play a note at a time any more precise than 1/120th of a second. The precise time it plays likely depends on how much time has elapsed during the current frame. I haven't tested this, though, so I don't know if calling sfx() triggers the sound change immediately, buffers it for the next 1/120th, or buffers it for the next update.

If it doesn't buffer the triggered sound, then for consistent timing, it's probably best to trigger new sounds at the start of the update, because the remainder of most games' updates usually take variable amounts of time. That isn't always viable for triggered sounds, but for unconditional stuff like a beat, it'd work.


^Much better long answer of what I was gettin' at. ^

As always, Felice. ;p


Long answers is the only kind I gives. ;)


But surely you have a respect for minimalism, no? o:


Respect, yes. :)

Ability, no. :(


It depends on what your use-case is, but instead of counting frames, I've found stat(26) i.e. "ticks played on current pattern" to be a useful source of timing which isn't affected by potential frameskips (but you do have to be playing music...it made even more sense in my use-case because I specifically wanted to maintain synchronization/timing with the music on a tween animation).

I suppose you could also use the undocumented time() or t() to similar effect, without having to have music playing.



[Please log in to post a comment]