Hello
I'm trying to implement high-precision timing windows for a rhythm game (in Unity/C#, if you're curious), and I'd love to hear how you would all approach the problem.
Here's where I'm at right now:
I have 6 tiers of scores that each depend on how close you are to hitting the (right) button at the right time:
- Perfect: Within 1/60th of a second of the target time
- Great: 2/60th of a second
- Good: 4/60th of a second
- Okay: 6/60th of a second
- Bad: 8/60th of a second
- Miss: Anything worse than the above
In code, rather than expressing these values in seconds, I express everything in
samples. The song is played at a certain sample rate (number of samples per second). I know how many samples have been played at any given point during the game, as well as the number of samples played for each of the target times that the player has to tap a button.
The current song I'm testing is being played at a sample rate of 44100, which means the player only has 735 samples of leeway in order to hit the
Perfect time window (Sample Rate * ( 1 / 60 )).
The problem I'm up against is that the number of samples played per frame
isn't actually constant. As an example, assume the game is running at 60FPS, the target beat is on frame N, and the player hits the button on frame N + 1. The player hit the button within 1 frame, so they should receive a Perfect score. But the number of samples played by the audio engine within that time is often greater than the number of samples that
should be played within 1/60th of a second (735 samples).
It's not a big deal in the Perfect scenario; if the time window is 735 samples but the actual sample delta per frame is, say, 1000, I'll still treat that as a Perfect hit:
int perfectWindowInSamples = (int)( Math.Max( ( 1 / 60d ) * sampleRate, sampleDeltaFromLastFrame );
But what if the player hits the button on frame N + 2, or N + 4? How do I factor in multiple frames where the number of samples per frame could be more or less than
Sample Rate * ( 1 / FrameRate )?
I have a feeling I ought to store a history of sample deltas per frame (up to as many frames as I care about to assign a proper score) and then factor those numbers in when calculating the
actual timing windows for each score tier. But I was hoping I could get another opinion from the forum just to make sure I'm not crazy
Thanks in advance!