0
\$\begingroup\$

I'm currently developing a beat game (similar to osu and osu!mania), in which you basically have to press keys at the right time. I would like to calculate a score (x/100), based on the accuracy of the key-press. The beats are saved in a file like this:

timestamp (ms) | key
1200 c
1400 a
1400 c
1650 b
...

At the moment, if for example the player presses the [a] button, the game goes through every beat with the same key and finds the closest, then calculates beat.timestamp - press.timestamp and saves this value in an array. The average of these array values is the average reaction time of the player.

Is there a good way of calculating a score that includes edge-cases like what should happen if the player presses a key twice or don't press it at all?

\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

First of all, going through every beat with the same key is absolutely not efficient.

What you should do is to use an array (each member should contain a key and a timestamp which should be retrieved from your file) and look for the next value inside it, whenever the player presses the right button or the time exceeds go to the next one in the list.

And for not pressing a key you should have a Tolerance value (which can be used as the game's difficulty too) and if the key wasn't pressed at all, just store the tolerance inside your array.

Another thing to have in mind is that you should add beat.timestamp - press.timestamp only if its absolute value is less or equal to Tolerance

When the player presses a button (whether it's the correct button or not) you should use a RestTime and don't get any input from the user in that time (except for functions like stopping the game)

Finally, I would advise using just a float variable instead of a list for calculating, and after every beat add the data inside it and at the end, when you want to calculate the score use this single line:

FinalScore = (Tolerance - (Sum / KeysList.Count)) * 100

Hope it works for you!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I actually didn't think of the idea with the next value, thanks! (Also for the nice equation) \$\endgroup\$ Commented Mar 15, 2022 at 11:12
  • \$\begingroup\$ You're welcome. Just remember that I have written a basic solution; work your best to customize it for your game, or even come up with a new mechanism, that's what makes your game more unique! \$\endgroup\$
    – Arian_ki
    Commented Mar 15, 2022 at 12:11
1
\$\begingroup\$

Before talking about game design, one note… You say

the game goes through every beat with the same key and finds the closest

Assuming time goes forward (and I want to come back to that), you should not have to search among the beats that are before the last you found.


Is there a good way of calculating a score that includes edge-cases like what should happen if the player presses a key twice or don't press it at all?

Ern… nope. The question is how forgiving you want to make your game.

First of all, the common design is to take (the absolute value of) the difference between the press time and the target time and put it into brackets (if the difference is less than x time, you get y points, and so on - it could be only one bracket, but usually rhythm games have a few).

I mention absolute value because the player may rush notes, and that is Ok. Well, not in every game, but in general. In a rhythm game you should not be measuring reaction time, but mastery of the track.

Furthermore, usually rhythm games don't have an explicit penalty for skipping a note. It is simply score that the player does not get. And similarly double presses get ignored. However, you could add a penalty, which is a way to make a hard mode.


By the way, speaking of how you should not be measuring reaction time. There is also input and output latency. You should have a configurable offset to the time to account for that.


The game osu! does a great work with modifiers that can increase or decrease the difficulty and the score. You can do the same. One such modifier could be exactly what you are asking: Accepting a penalty for double presses or missed pressed in exchange for a score multiplier.

You, of course, would mark what modifiers were used in your leader board/high score table. Or track them on a separate leader board/high score table.

Oh, and please have the options of half and double time. These are features players expect to have.


Something I find many of these games lack is a good practice mode. I don't mean easy or forgiving mode. I mean a mode that makes delivered targeted practice easier to do.

Yet, it is not hard to conceptualize (some games do this): either mark check points in your track (or detect silences/gaps and use that as check points), then when the player misses a note, rewind time back to the last check point (I remind you I'm talking about a practice mode). Ok, time does not always go forward, but you still know from where to search.

If you also consider the periods between check points "sections" and allow skipping to them then players can go right to the part they are having trouble or even past it, for practice, of course. Furthermore, if you show percentage score per section, it helps the player identify area they are having trouble so they can revisit them in practice later.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .