Add ensureDeterminism to saves
This commit is contained in:
parent
9c3b966c18
commit
a8604ef579
@ -539,6 +539,7 @@ void GameSave::readOPS(const std::vector<char> &data)
|
||||
CheckBsonFieldFloat(iter, "ambientAirTemp", &ambientAirTemp);
|
||||
CheckBsonFieldInt(iter, "edgeMode", &edgeMode);
|
||||
CheckBsonFieldInt(iter, "pmapbits", &pmapbits);
|
||||
CheckBsonFieldBool(iter, "ensureDeterminism", &ensureDeterminism);
|
||||
CheckBsonFieldLong(iter, "frameCount", reinterpret_cast<int64_t *>(&frameCount));
|
||||
CheckBsonFieldLong(iter, "rngState0", reinterpret_cast<int64_t *>(&rngState[0]));
|
||||
CheckBsonFieldLong(iter, "rngState1", reinterpret_cast<int64_t *>(&rngState[1]));
|
||||
@ -2546,6 +2547,7 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
|
||||
bson_append_binary(&b, "soapLinks", (char)BSON_BIN_USER, (const char *)&soapLinkData[0], soapLinkDataLen);
|
||||
if (ensureDeterminism)
|
||||
{
|
||||
bson_append_bool(&b, "ensureDeterminism", ensureDeterminism);
|
||||
bson_append_binary(&b, "blockAir", (char)BSON_BIN_USER, (const char *)&blockAirData[0], blockAirDataLen);
|
||||
bson_append_long(&b, "frameCount", int64_t(frameCount));
|
||||
bson_append_long(&b, "rngState0", int64_t(rngState[0]));
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "common/Plane.h"
|
||||
#include "common/String.h"
|
||||
#include "common/tpt-rand.h"
|
||||
#include "simulation/Sign.h"
|
||||
#include "simulation/Particle.h"
|
||||
#include "Misc.h"
|
||||
@ -95,8 +96,8 @@ public:
|
||||
bool hasPressure = false;
|
||||
bool hasAmbientHeat = false;
|
||||
bool hasBlockAirMaps = false; // only written by readOPS, never read
|
||||
bool ensureDeterminism = false; // only read by serializeOPS, never written
|
||||
std::array<uint64_t, 2> rngState;
|
||||
bool ensureDeterminism = false; // only taken seriously by serializeOPS; readOPS may set this even if the save does not have everything required for determinism
|
||||
RNG::State rngState;
|
||||
uint64_t frameCount = 0;
|
||||
|
||||
//Simulation data
|
||||
|
@ -5,8 +5,11 @@
|
||||
|
||||
class RNG
|
||||
{
|
||||
public:
|
||||
using State = std::array<uint64_t, 2>;
|
||||
|
||||
private:
|
||||
std::array<uint64_t, 2> s;
|
||||
State s;
|
||||
uint64_t next();
|
||||
public:
|
||||
unsigned int operator()();
|
||||
@ -18,12 +21,12 @@ public:
|
||||
RNG();
|
||||
void seed(unsigned int sd);
|
||||
|
||||
void state(std::array<uint64_t, 2> ns)
|
||||
void state(State ns)
|
||||
{
|
||||
s = ns;
|
||||
}
|
||||
|
||||
std::array<uint64_t, 2> state() const
|
||||
State state() const
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
@ -934,6 +934,31 @@ SaveInfo * GameModel::GetSave()
|
||||
return currentSave;
|
||||
}
|
||||
|
||||
void GameModel::SaveToSimParameters(const GameSave *saveData)
|
||||
{
|
||||
SetPaused(saveData->paused | GetPaused());
|
||||
sim->gravityMode = saveData->gravityMode;
|
||||
sim->customGravityX = saveData->customGravityX;
|
||||
sim->customGravityY = saveData->customGravityY;
|
||||
sim->air->airMode = saveData->airMode;
|
||||
sim->air->ambientAirTemp = saveData->ambientAirTemp;
|
||||
sim->edgeMode = saveData->edgeMode;
|
||||
sim->legacy_enable = saveData->legacyEnable;
|
||||
sim->water_equal_test = saveData->waterEEnabled;
|
||||
sim->aheat_enable = saveData->aheatEnable;
|
||||
if (saveData->gravityEnable && !sim->grav->IsEnabled())
|
||||
{
|
||||
sim->grav->start_grav_async();
|
||||
}
|
||||
else if (!saveData->gravityEnable && sim->grav->IsEnabled())
|
||||
{
|
||||
sim->grav->stop_grav_async();
|
||||
}
|
||||
sim->frameCount = saveData->frameCount;
|
||||
sim->rng.state(saveData->rngState);
|
||||
sim->ensureDeterminism = saveData->ensureDeterminism;
|
||||
}
|
||||
|
||||
void GameModel::SetSave(SaveInfo * newSave, bool invertIncludePressure)
|
||||
{
|
||||
if(currentSave != newSave)
|
||||
@ -947,23 +972,10 @@ void GameModel::SetSave(SaveInfo * newSave, bool invertIncludePressure)
|
||||
delete currentFile;
|
||||
currentFile = NULL;
|
||||
|
||||
if(currentSave && currentSave->GetGameSave())
|
||||
if (newSave && newSave->GetGameSave())
|
||||
{
|
||||
GameSave * saveData = currentSave->GetGameSave();
|
||||
SetPaused(saveData->paused | GetPaused());
|
||||
sim->gravityMode = saveData->gravityMode;
|
||||
sim->customGravityX = saveData->customGravityX;
|
||||
sim->customGravityY = saveData->customGravityY;
|
||||
sim->air->airMode = saveData->airMode;
|
||||
sim->air->ambientAirTemp = saveData->ambientAirTemp;
|
||||
sim->edgeMode = saveData->edgeMode;
|
||||
sim->legacy_enable = saveData->legacyEnable;
|
||||
sim->water_equal_test = saveData->waterEEnabled;
|
||||
sim->aheat_enable = saveData->aheatEnable;
|
||||
if(saveData->gravityEnable)
|
||||
sim->grav->start_grav_async();
|
||||
else
|
||||
sim->grav->stop_grav_async();
|
||||
GameSave *saveData = newSave->GetGameSave();
|
||||
SaveToSimParameters(saveData);
|
||||
sim->clear_sim();
|
||||
ren->ClearAccumulation();
|
||||
if (!sim->Load(saveData, !invertIncludePressure))
|
||||
@ -1011,27 +1023,10 @@ void GameModel::SetSaveFile(SaveFile * newSave, bool invertIncludePressure)
|
||||
delete currentSave;
|
||||
currentSave = NULL;
|
||||
|
||||
if(newSave && newSave->GetGameSave())
|
||||
if (newSave && newSave->GetGameSave())
|
||||
{
|
||||
GameSave * saveData = newSave->GetGameSave();
|
||||
SetPaused(saveData->paused | GetPaused());
|
||||
sim->gravityMode = saveData->gravityMode;
|
||||
sim->customGravityX = saveData->customGravityX;
|
||||
sim->customGravityY = saveData->customGravityY;
|
||||
sim->air->airMode = saveData->airMode;
|
||||
sim->air->ambientAirTemp = saveData->ambientAirTemp;
|
||||
sim->edgeMode = saveData->edgeMode;
|
||||
sim->legacy_enable = saveData->legacyEnable;
|
||||
sim->water_equal_test = saveData->waterEEnabled;
|
||||
sim->aheat_enable = saveData->aheatEnable;
|
||||
if(saveData->gravityEnable && !sim->grav->IsEnabled())
|
||||
{
|
||||
sim->grav->start_grav_async();
|
||||
}
|
||||
else if(!saveData->gravityEnable && sim->grav->IsEnabled())
|
||||
{
|
||||
sim->grav->stop_grav_async();
|
||||
}
|
||||
GameSave *saveData = newSave->GetGameSave();
|
||||
SaveToSimParameters(saveData);
|
||||
sim->clear_sim();
|
||||
ren->ClearAccumulation();
|
||||
if (!sim->Load(saveData, !invertIncludePressure))
|
||||
|
@ -114,6 +114,9 @@ private:
|
||||
void notifyToolTipChanged();
|
||||
void notifyQuickOptionsChanged();
|
||||
void notifyLastToolChanged();
|
||||
|
||||
void SaveToSimParameters(const GameSave *saveData);
|
||||
|
||||
public:
|
||||
GameModel();
|
||||
~GameModel();
|
||||
|
@ -214,6 +214,17 @@ static int simHash(lua_State *l)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int simEnsureDeterminism(lua_State *l)
|
||||
{
|
||||
if (lua_gettop(l))
|
||||
{
|
||||
luacon_sim->ensureDeterminism = lua_toboolean(l, 1);
|
||||
return 0;
|
||||
}
|
||||
lua_pushboolean(l, luacon_sim->ensureDeterminism);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m):
|
||||
TPTScriptInterface(c, m),
|
||||
luacon_mousex(0),
|
||||
@ -1003,6 +1014,7 @@ void LuaScriptInterface::initSimulationAPI()
|
||||
{"temperatureScale", simulation_temperatureScale},
|
||||
{"randomseed", simRandomseed},
|
||||
{"hash", simHash},
|
||||
{"ensureDeterminism", simEnsureDeterminism},
|
||||
{NULL, NULL}
|
||||
};
|
||||
luaL_register(l, "simulation", simulationAPIMethods);
|
||||
|
@ -64,8 +64,6 @@ int Simulation::Load(const GameSave * originalSave, bool includePressure, int fu
|
||||
}
|
||||
|
||||
RecalcFreeParticles(false);
|
||||
frameCount = save->frameCount;
|
||||
rng.state(save->rngState);
|
||||
|
||||
auto &possiblyCarriesType = Particle::PossiblyCarriesType();
|
||||
auto &properties = Particle::GetProperties();
|
||||
@ -490,15 +488,12 @@ GameSave * Simulation::Save(bool includePressure, int fullX, int fullY, int full
|
||||
}
|
||||
}
|
||||
}
|
||||
if (includePressure)
|
||||
if (includePressure || ensureDeterminism)
|
||||
{
|
||||
newSave->hasPressure = true;
|
||||
newSave->hasAmbientHeat = true;
|
||||
}
|
||||
if (true) // TODO: tie to an option maybe?
|
||||
{
|
||||
newSave->ensureDeterminism = true;
|
||||
}
|
||||
newSave->ensureDeterminism = ensureDeterminism;
|
||||
|
||||
newSave->stkm.rocketBoots1 = player.rocketBoots;
|
||||
newSave->stkm.rocketBoots2 = player2.rocketBoots;
|
||||
@ -1092,6 +1087,7 @@ int Simulation::parts_avg(int ci, int ni,int t)
|
||||
|
||||
void Simulation::clear_sim(void)
|
||||
{
|
||||
ensureDeterminism = false;
|
||||
frameCount = 0;
|
||||
debug_nextToUpdate = 0;
|
||||
debug_mostRecentlyUpdated = -1;
|
||||
|
@ -119,6 +119,7 @@ public:
|
||||
int sandcolour_frame;
|
||||
int deco_space;
|
||||
uint64_t frameCount;
|
||||
bool ensureDeterminism;
|
||||
|
||||
int Load(const GameSave * save, bool includePressure);
|
||||
int Load(const GameSave * save, bool includePressure, int x, int y);
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "Particle.h"
|
||||
#include "Sign.h"
|
||||
#include "Stickman.h"
|
||||
#include "common/tpt-rand.h"
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <json/json.h>
|
||||
@ -36,7 +37,7 @@ public:
|
||||
std::vector<sign> signs;
|
||||
|
||||
uint64_t FrameCount;
|
||||
std::array<uint64_t, 2> RngState;
|
||||
RNG::State RngState;
|
||||
|
||||
uint32_t Hash() const;
|
||||
|
||||
|
@ -68,7 +68,7 @@ struct SnapshotDelta
|
||||
HunkVector<uint32_t> stickmen;
|
||||
SingleDiff<std::vector<sign>> signs;
|
||||
SingleDiff<uint64_t> FrameCount;
|
||||
SingleDiff<std::array<uint64_t, 2>> RngState;
|
||||
SingleDiff<RNG::State> RngState;
|
||||
|
||||
SingleDiff<Json::Value> Authors;
|
||||
|
||||
|
Reference in New Issue
Block a user