Draft: WIP RNG overhaul
Changes how RNGs work, more or less. Can't be merged right now because some things don't work right (notably: netgames).
There's a general base class, srb2::math::rng
, which implements the standard C++ UniformRandomBitGenerator named requirement set plus methods that more or less correspond to the M_Random
/P_Random
interface. This is done because exactly how those methods are implemented has to be the same, or demos can desync.
C++ code can create rng
instances whenever or wherever it would like, making it easier to add non-synchronized generators that are used for one specific purpose without making m_random.cpp
more complicated, such as apparently was done with the HUD interpolation.
There are two implementations of that class:
-
srb2::math::sfc32_rng
: based on the SFC32 RNG. Additionally, it implements some algorithms differently and fixes theRandomByte
bug. -
srb2::math::legacy_rng
: A completely backwards-compatible implementation of the current Ring Racers RNG.
It also exposes srb2::math::default_rng
, which is a type alias for srb2::math::default_rng
. If a new RNG is added in the future, it can be set as default_rng
and the old ones can be retained for backwards compatibility. Non-synchronized generators are always default_rng
.
Old demos will be played back with legacy_rng
in use. New demos explicitly save the RNG type they are using.
New rng
s of both types default to being seeded by std::random_device
, which I believe is usually based on whatever the "good quality OS source" (e.g. /dev/urandom
) would be on a particular platform.
Some new P_Random
functions have been added, and some old ones have been removed. This will be documented later.
Merge request reports
Activity
While #68 is a pretty minor bug, it was pointed out that it being fixed would cause old demos to desync, so there would have to be a flag set somewhere to provide compatibility.
I also think the way that
M_Random
is currently handled is a little dubious, asrand()
is generally a poor-quality random number generator and if you're going to go to the trouble of running its output through another generator it might be better just to replace with a better one.As Ring Racers is partially C++, it seemed like writing RNG classes would be the way to do both of those and could provide for easier backwards compatibility in case of future RNG changes.
At that rate, why not also use the new generator that for
P_Random
as well, as you'd have to add something to handle fixing 68 anyway.I noticed the commit message complaining about having to hack the HUD interpolation generator in later; with this change, as long as your code is C++, you'd never need to do that.
The UniformRandomBitGenerator compatibility is there because C++ provides some useful standard library features (shuffles, probability distributions) that can use UniformRandomBitGenerators, though as I note those features wouldn't be useful in code that has to be netsynced.
Edited by tertu marybigI did not make this clear in the MR itself but one of the goals is that once an
rng
implementation is released, it should remain functionally identical. That is, if you seed twolegacy_rng
s (for example) the same way, and call the same set of functions on them, they will produce the same results in any version of Ring Racers.added Feature label