I think this is a place where a power function may be ideal. If the best score S
is achieved with N
manipulators, you can have N+1
manipulators yield a score of S * 0.9
(ie. 90% of the best score), then N+2
manipulators yield S * 0.81
(ie. 90% of 90% of the best score), and so on.
This is generalised by the following formula:
score(num_manip) = S * pow(0.9, num_manip - N);
The advantage of this method is that you don't need any clamping: progressively bad performance will tend towards a score of zero.
The general score formulas can be:
TimeScore = TimeScoreBase * pow(A, BestPlayTime - PlayTime);
ManipulatorScore = ManipulatorScoreBase * pow(B, BestManipulatorCount - UsedManipulators);
You then need to choose TimeScoreBase
and ManipulatorScoreBase
(these are probably global to the game), tune A
and B
by how much you want the score to decrease for each additional second spent or each additional manipulator used (again, global to the game) and choose BestPlayTime
and BestManipulatorCount
(these, however, should be specific to the level being played).
Note that if by chance the player managed to finish the level in less time than BestPlayTime
, it wouldn't be a serious problem, the score would simply be higher than TimeScoreBase
. You may accept this, thus rewarding outstanding players, or clamp the total play time to avoid cheating.
Then you need to choose how to combine the scores:
Score = TimeScore + ManipulatorScore;
Score = sqrt(TimeScore * ManipulatorScore);
Each formula will have a different asymptotic behaviour, but the general idea is that the worse the play, the lower the score. The first one will give points for using few manipulators even in case of a bad time. The second one will give a bad final score if any of the two scores is bad.