Remove strange RNG sync hack

Previously it was using P_SetRandSeed, which sets both initial and current seed to the same thing, since it's meant for level load init. It first set all RNG seeds to the current seed, and then it set all of the seeds to their initial value. The comment about this just says its "stupid and hacky", and I have no idea how it even worked before.

Now we send over both init seed and current seed independently and set them both. Hopefully this will fix the desyncs.
This commit is contained in:
Sally Coolatta 2022-09-25 07:02:39 -04:00
parent 6ab24e6055
commit 3e4edc534d
3 changed files with 54 additions and 18 deletions

View file

@ -231,7 +231,7 @@ UINT32 P_GetInitSeedD(const char *rfile, INT32 rline, pr_class_t pr_class)
}
/** Sets the random seed.
* Used at the beginning of the game, and also for netgames.
* Used at the beginning of a game.
*
* \param pr_class RNG class to adjust.
* \param seed New random seed.
@ -251,8 +251,31 @@ void P_SetRandSeedD(const char *rfile, INT32 rline, pr_class_t pr_class, UINT32
rng.seed[pr_class] = rng.init[pr_class] = seed;
}
/** Sets both the initial seed and the current seed.
* Used for netgame sync.
*
* \param pr_class RNG class to adjust.
* \param init Sent initial seed.
* \param seed Sent current seed.
* \sa P_SetRandSeed
*/
#ifndef DEBUGRANDOM
void P_SetRandSeedNet(pr_class_t pr_class, UINT32 init, UINT32 seed)
{
#else
void P_SetRandSeedNetD(const char *rfile, INT32 rline, pr_class_t pr_class, UINT32 init, UINT32 seed)
{
CONS_Printf("P_SetRandSeedNet(%u) at: %sp %d\n", pr_class, rfile, rline);
#endif
if (!init) init = DEFAULT_SEED;
rng.init[pr_class] = init;
if (!seed) seed = DEFAULT_SEED;
rng.seed[pr_class] = seed;
}
/** Initializes random seeds for all classes.
* Used at the beginning of the game.
* Used at the beginning of a game.
*
* \param rindex New random index.
* \sa P_SetRandSeed

View file

@ -106,13 +106,16 @@ fixed_t P_RandomPeek(pr_class_t pr_class);
#define P_GetRandSeed(pr) P_GetRandSeedD(__FILE__, __LINE__, pr)
#define P_GetInitSeed(pr) P_GetInitSeedD(__FILE__, __LINE__, pr)
#define P_SetRandSeed(pr, s) P_SetRandSeedD(__FILE__, __LINE__, pr, s)
#define P_SetRandSeedNet(pr, i, s) P_SetRandSeedD(__FILE__, __LINE__, pr, i, s)
UINT32 P_GetRandSeedD(const char *rfile, INT32 rline, pr_class_t pr_class);
UINT32 P_GetInitSeedD(const char *rfile, INT32 rline, pr_class_t pr_class);
void P_SetRandSeedD(const char *rfile, INT32 rline, pr_class_t pr_class, UINT32 seed);
void P_SetRandSeedNetD(const char *rfile, INT32 rline, pr_class_t pr_class, UINT32 init, UINT32 seed);
#else
UINT32 P_GetRandSeed(pr_class_t pr_class);
UINT32 P_GetInitSeed(pr_class_t pr_class);
void P_SetRandSeed(pr_class_t pr_class, UINT32 seed);
void P_SetRandSeedNet(pr_class_t pr_class, UINT32 init, UINT32 seed);
#endif
void P_ClearRandom(UINT32 seed);

View file

@ -4452,6 +4452,17 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride)
playeringame[consoleplayer] = true;
}
static void P_NetArchiveRNG(void)
{
size_t i;
for (i = 0; i < PRNUMCLASS; i++)
{
WRITEUINT32(save_p, P_GetInitSeed(i));
WRITEUINT32(save_p, P_GetRandSeed(i));
}
}
static void P_NetArchiveMisc(boolean resending)
{
size_t i;
@ -4475,10 +4486,7 @@ static void P_NetArchiveMisc(boolean resending)
WRITEUINT32(save_p, pig);
}
for (i = 0; i < PRNUMCLASS; i++)
{
WRITEUINT32(save_p, P_GetRandSeed(i));
}
P_NetArchiveRNG();
WRITEUINT32(save_p, tokenlist);
@ -4602,6 +4610,19 @@ static void P_NetArchiveMisc(boolean resending)
}
}
static inline void P_NetUnArchiveRNG(void)
{
size_t i;
for (i = 0; i < PRNUMCLASS; i++)
{
UINT32 init = READUINT32(save_p);
UINT32 seed = READUINT32(save_p);
P_SetRandSeedNet(i, init, seed);
}
}
static inline boolean P_NetUnArchiveMisc(boolean reloading)
{
size_t i;
@ -4638,10 +4659,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
}
}
for (i = 0; i < PRNUMCLASS; i++)
{
P_SetRandSeed(i, READUINT32(save_p));
}
P_NetUnArchiveRNG();
tokenlist = READUINT32(save_p);
@ -4894,8 +4912,6 @@ boolean P_LoadGame(INT16 mapoverride)
boolean P_LoadNetGame(boolean reloading)
{
size_t i;
CV_LoadNetVars(&save_p);
if (!P_NetUnArchiveMisc(reloading))
@ -4918,12 +4934,6 @@ boolean P_LoadNetGame(boolean reloading)
LUA_UnArchive(&save_p);
// This is stupid and hacky, but maybe it'll work!
for (i = 0; i < PRNUMCLASS; i++)
{
P_SetRandSeed(i, P_GetInitSeed(i));
}
// The precipitation would normally be spawned in P_SetupLevel, which is called by
// P_NetUnArchiveMisc above. However, that would place it up before P_NetUnArchiveThinkers,
// so the thinkers would be deleted later. Therefore, P_SetupLevel will *not* spawn