roll x returns in the interval [0, x), and in this case a roll of 0 will always trigger. It is not equivalent to a floating point roll due to quantization, e.g. at 120 fps an integer roll triggers at p = 1/10000, but a floating point roll triggers at p = 1/120000. Instead it should be done in a framerate independent cycle, maybe every 0.1 sec, with an adjusted roll calibrated on the quantized behaviour of vanilla at a standard fps, maybe roll float (10000 * 60fps * 0.1s).
This is very confusing, but your idea seems correct.
Let's see vanilla behaviour at 60 fps.
With the default fVoiceIdleOdds (10), 10 * (1/60.f) = 0.16 requires a roll of 0 to succeed. (1/10000 chance per 1/60 seconds, i.e. 0.006 voices per second).
Due to the quantization issues, increasing fVoiceIdleOdds by say, a factor of 2, won't actually have an effect (you'd have to increase it by a factor of at least 6). Likewise, reducing fVoiceIdleOdds will not have an effect either.
Are there any known mods that change fVoiceIdleOdds?
Goal 1: make the chance FPS independent.
Goal 2: make changes to fVoiceIdleOdds work properly, with no gaps in between.
Goal 3: for the default value of the GMST, have the same frequency of voices as vanilla would have in a fixed 60 fps setting.
So, assuming we run the check at a fixed timestep INTERVAL of 0.1s.
Code: Select all
x = fVoiceIdleOdds * 0.6
if (roll float (10000) < x)
trigger idle voice
Should yield a chance of 6 / 10000 every 0.1s, i.e. 0.006 voices per second.
And since there's no quantization left here, we don't actually need to use a fixed timestep either.
Code: Select all
x = fVoiceIdleOdds * 0.6 * (frametime / 0.1)
if (roll float (10000) < x)
trigger idle voice
This seems about right to me in addressing all the 3 goals. Did I make any mistakes?
Edit: of course I did... corrected silly mistake.