Skip to content

Commit

Permalink
Fix desync #164, unify RND for logic into one, add asserts
Browse files Browse the repository at this point in the history
Volcanos were using xm_random_generator which was also used by
electro weapon rendering in the render thread, causing generator
to go out of sync thus triggering different volcano shapes for each client
 after it, fix the issue by properly separating logic and non logic generators
 and unify them into one single generator for logic randomness.
 Asserts have been added to ensure logic only calls logic RND and
 non logic thread calls non logic RNDs
IonAgorria committed May 31, 2024
1 parent fe20342 commit 74754c5
Showing 23 changed files with 263 additions and 283 deletions.
15 changes: 4 additions & 11 deletions Source/Game/Universe.cpp
Original file line number Diff line number Diff line change
@@ -75,7 +75,6 @@

const int REGION_DATA_FILE_VERSION = 8383;

RandomGenerator logicRND;
int terRealCollisionCount = 0;
int terMapUpdatedCount = 0;

@@ -893,13 +892,9 @@ bool terUniverse::universalLoad(MissionDescription& missionToLoad, SavePrm& data
ia >> WRAP_NAME(savePrmBinary, "SavePrmBinary");

//Restore random generators
XRndSet(savePrmBinary.X_RND);
logicRND.set(savePrmBinary.logic_RND);
xm_random_generator.set(savePrmBinary.xm_RND);
} else {
XRndSet(1);
logicRND.set(1);
xm_random_generator.set(1);
logicRND.set(123456);
}

//---------------------
@@ -1127,14 +1122,12 @@ bool terUniverse::universalSave(MissionDescription& mission, bool userSave) cons
SavePrmBinary savePrmBinary;

//Save RND generator states
savePrmBinary.X_RND = XRndGet();
savePrmBinary.logic_RND = logicRND.get();
savePrmBinary.xm_RND = xm_random_generator.get();

for (auto& pi : playersToSave) {
for (auto& pls : playersToSave) {
SavePlayerData& savePlayer = data.players.emplace_back();
if (pi) {
pi->universalSave(savePlayer, userSave);
if (pls) {
pls->universalSave(savePlayer, userSave);
if (!check_command_line("not_triggerchains_binary")) {
std::swap(savePlayer.currentTriggerChains, savePrmBinary.TriggerChains.emplace_back());
}
20 changes: 11 additions & 9 deletions Source/Render/client/Silicon.cpp
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@
#include "Scripts/Silicon.cppi"
#include "VertexFormat.h"

RandomGenerator silicon_rnd;

Vect3f ElasticSphere::unit_sphere[psi_size][theta_size];
Vect3f ElasticSphere::points_map[psi_size][theta_size];
@@ -53,10 +54,10 @@ void ElasticSphere::SetPosition(const MatXf& Matrix)
initial_position = Matrix.trans();

Vect3f dir;
dir.x = frnd(1);
dir.y = frnd(1);
dir.z = frnd(1);
GlobalMatrix.rot().set(dir, frnd(XM_PI));
dir.x = silicon_rnd.frnd(1);
dir.y = silicon_rnd.frnd(1);
dir.z = silicon_rnd.frnd(1);
GlobalMatrix.rot().set(dir, silicon_rnd.frnd(XM_PI));
}

void ElasticSphere::PreDraw(cCamera *DrawNode)
@@ -90,11 +91,12 @@ void ElasticSphere::GetColor(sColor4f *ambient,sColor4f *diffuse_,sColor4f *spec
void ElasticSphere::setRadius(float radius_, float relative_random_displacement)
{
radius = radius_;
for(int psi = 0; psi < psi_size; psi++)
for(int theta = 0; theta < theta_size; theta++){
height_map[psi][theta] = radius*(1 + frnd(relative_random_displacement));
velocity_map[psi][theta] = 0;
}
for(int psi = 0; psi < psi_size; psi++) {
for (int theta = 0; theta < theta_size; theta++) {
height_map[psi][theta] = radius * (1 + silicon_rnd.frnd(relative_random_displacement));
velocity_map[psi][theta] = 0;
}
}
velocity.set(0, 0, 0);
}

2 changes: 1 addition & 1 deletion Source/Render/client/Silicon.h
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ class ElasticSphere : public cIUnkObj
theta_size = 1 << theta_size_len,
psi_mask = psi_size - 1,
theta_mask = theta_size - 1
};
};

ElasticSphere();
~ElasticSphere();
18 changes: 8 additions & 10 deletions Source/Render/src/lighting.cpp
Original file line number Diff line number Diff line change
@@ -147,7 +147,7 @@ void cLighting::Animate(float dt)
time-=param.generate_time;
PreGenerate g;
g.pos_begin=pos_begin;
g.pos_end=pos_end[xm_random_generator()%pos_end.size()];
g.pos_end=pos_end[rnd() % pos_end.size()];
pre_generate.push_back(g);
}

@@ -174,10 +174,10 @@ void cLighting::Init(Vect3f pos_begin_, std::vector<Vect3f>& pos_end_, float sca
xassert(!pos_end.empty());
}

void cLighting::Generate(Vect3f pos_begin,Vect3f pos_end,cCamera *pCamera)
void cLighting::Generate(Vect3f pos_begin_,Vect3f pos_end_,cCamera *pCamera)
{
OneLight* p=new OneLight;
p->Generate(pos_begin,pos_end,pCamera,this);
p->Generate(pos_begin_,pos_end_,pCamera,this);
lights.push_back(p);
}

@@ -237,14 +237,12 @@ void cLighting::OneLight::Generate(Vect3f pos_begin_,Vect3f pos_end_,cCamera *pC
BuildStrip(pCamera,parent);
}

void cLighting::OneLight::GenerateInterpolate(std::vector<float>& pos,int size,float min_amp, float max_amp)
{

RandomGenerator& r=xm_random_generator;
std::vector<float> p(size);\
int i;
void cLighting::OneLight::GenerateInterpolate(std::vector<float>& pos,int size, float min_amp, float max_amp) {
std::vector<float> p(size);
int i;

for (i=0;i<size;i++) {
float a = r.frnd(max_amp);
float a = rnd.frnd(max_amp);
if (a < 0) {
p[i] = min(-min_amp, a);
} else {
5 changes: 3 additions & 2 deletions Source/Render/src/lighting.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

static RandomGenerator rnd;

struct LightingParameters
{
float generate_time;
@@ -25,8 +27,7 @@ class cLighting:public cIUnkClass
virtual void Draw(cCamera *UCamera);
virtual void Animate(float dt);

const MatXf& GetPosition(void) const
{
const MatXf& GetPosition() const {
return global_pos;
}
protected:
12 changes: 6 additions & 6 deletions Source/Terra/LAND.cpp
Original file line number Diff line number Diff line change
@@ -162,7 +162,7 @@ void vrtMap::deltaZone(sToolzerPMO& var) //(int x,int y,int rad,int smth,int dh,
case 1:
v = (int)(dd*1000000.0);
for(j = 0;j < max;j++)
if((int)XRnd(1000000) < v) voxSet((x + xx[j]) & clip_mask_x,(y + yy[j]) & clip_mask_y,h);
if((int)terLogicRND(1000000) < v) voxSet((x + xx[j]) & clip_mask_x,(y + yy[j]) & clip_mask_y,h);
break;
case 2:
v = (int)(dd*max);
@@ -359,15 +359,15 @@ void vrtMap::squareDeltaZone(sSquareToolzerPMO& var)//(int x,int y,int rad,int s
if(!h) h = dh > 0 ? 1 : -1;
v = (int)(dd*1000000.0);
//for(j = 0;j < max;j++) {
// if((int)XRnd(1000000) < v) voxSet((x + xx[j]) & clip_mask_x,(y + yy[j]) & clip_mask_y,h);
// if((int)terLogicRND(1000000) < v) voxSet((x + xx[j]) & clip_mask_x,(y + yy[j]) & clip_mask_y,h);
//}
for(j=-i; j<=i; j++){
if((int)XRnd(1000000) < v) voxSet((x + j) & clip_mask_x,(y + -i) & clip_mask_y, h);
if((int)XRnd(1000000) < v) voxSet((x + j) & clip_mask_x,(y + +i) & clip_mask_y, h);
if((int)terLogicRND(1000000) < v) voxSet((x + j) & clip_mask_x,(y + -i) & clip_mask_y, h);
if((int)terLogicRND(1000000) < v) voxSet((x + j) & clip_mask_x,(y + +i) & clip_mask_y, h);
}
for(j=-i+1; j<i; j++){
if((int)XRnd(1000000) < v) voxSet((x + +i) & clip_mask_x,(y + j) & clip_mask_y, h);
if((int)XRnd(1000000) < v) voxSet((x + -i) & clip_mask_x,(y + j) & clip_mask_y, h);
if((int)terLogicRND(1000000) < v) voxSet((x + +i) & clip_mask_x,(y + j) & clip_mask_y, h);
if((int)terLogicRND(1000000) < v) voxSet((x + -i) & clip_mask_x,(y + j) & clip_mask_y, h);
}

}
4 changes: 1 addition & 3 deletions Source/Terra/VMAP.cpp
Original file line number Diff line number Diff line change
@@ -510,8 +510,6 @@ void vrtMap::prepare(const char* name)
//Для Периметра
void vrtMap::selectUsedWorld(int nWorld)
{
XRndSet(1);

UndoDispatcher_KillAllUndo(); //Очистка всего буфера Undo-Redo

// reload
@@ -1147,7 +1145,7 @@ void vrtMap::generateChAreasInformation(XBuffer& out)

unsigned int vrtMap::getChAreasInformationCRC()
{
XBuffer buf(256, 1);
XBuffer buf(256, true);
generateChAreasInformation(buf);
return crc32((unsigned char*)buf.address(), buf.tell(), startCRC32);
}
Loading

0 comments on commit 74754c5

Please sign in to comment.