Skip to content

Commit

Permalink
Significantly slash savefile sizes
Browse files Browse the repository at this point in the history
This change drops the average savefile from 2MB to 500KB.
We're smarter about what data we actually need to serialize -
MatrixTransform is only ever positioned by animations, and we don't
(yet) need to know about every space station market in the system at once.
  • Loading branch information
sturnclaw authored and Webster Sheets committed Dec 19, 2020
1 parent 3b76572 commit 25688d0
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 96 deletions.
45 changes: 20 additions & 25 deletions data/libs/SpaceStation.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ local function updateEquipmentStock (station)
assert(station and station:exists())
if equipmentStock[station] then return end
equipmentStock[station] = {}

local hydrogen = Equipment.cargo.hydrogen
for key, e in pairs(Equipment.cargo) do
if e.purchasable then
Expand All @@ -65,6 +66,7 @@ local function updateEquipmentStock (station)
equipmentStock[station][e] = 0 -- commodity that cant be bought
end
end

for _,slot in pairs{"laser", "hyperspace", "misc"} do
for key, e in pairs(Equipment[slot]) do
equipmentStock[station][e] = Engine.rand:Integer(0,100)
Expand Down Expand Up @@ -289,13 +291,6 @@ local function addRandomShipAdvert(station, num)
end
end

local function createShipMarket (station)
shipsOnSale[station] = {}

local shipAdsToSpawn = Engine.rand:Poisson(N_equilibrium(station))
addRandomShipAdvert(station, shipAdsToSpawn)
end

local function updateShipsOnSale (station)
if not shipsOnSale[station] then shipsOnSale[station] = {} end
local shipsOnSale = shipsOnSale[station]
Expand Down Expand Up @@ -612,11 +607,8 @@ function SpaceStation:LockAdvert (ref)
end

local function updateAdverts (station)
-- XXX this should really just be a single event
-- XXX don't create for stations we haven't visited
if not SpaceStation.adverts[station] then
SpaceStation.adverts[station] = {}
Event.Queue("onCreateBB", station)
logWarning("SpaceStation.lua: updateAdverts called for station that hasn't been visited")
else
Event.Queue("onUpdateBB", station)
end
Expand Down Expand Up @@ -662,18 +654,23 @@ end

local function updateSystem ()
local stations = Space.GetBodies(function (b) return b.superType == "STARPORT" end)
for i=1,#stations do
updateEquipmentStock(stations[i])
updateShipsOnSale(stations[i])
updateAdverts(stations[i])
for i, station in ipairs(stations) do
if SpaceStation.adverts[station] then
updateEquipmentStock(station)
updateShipsOnSale(station)
updateAdverts(station)
end
end
end

local function createSystem()
local stations = Space.GetBodies(function (b) return b.superType == "STARPORT" end)
for i=1,#stations do
createShipMarket(stations[i])
end
local function createStationMarket (station)
SpaceStation.adverts[station] = {}
shipsOnSale[station] = {}

updateEquipmentStock(station)
local shipAdsToSpawn = Engine.rand:Poisson(N_equilibrium(station))
addRandomShipAdvert(station, shipAdsToSpawn)
Event.Queue("onCreateBB", station)
end

local function destroySystem ()
Expand Down Expand Up @@ -717,14 +714,12 @@ Event.Register("onGameStart", function ()
loaded_data = nil
end

createSystem()
updateSystem()
Timer:CallEvery(3600, updateSystem)
end)
Event.Register("onEnterSystem", function (ship)

Event.Register("onShipDocked", function (ship, station)
if ship ~= Game.player then return end
createSystem()
updateSystem()
createStationMarket(station)
end)

Event.Register("onLeaveSystem", function (ship)
Expand Down
2 changes: 0 additions & 2 deletions src/posix/FileSystemPosix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ namespace FileSystem {
CFRelease(resourcesURL);
return path;
#else
printf("Init!\n");

if (!getenv("PIONEER_LOCAL_DATA_ONLY")) {
/* PIONEER_DATA_DIR should point to ${prefix}/share/pioneer/data.
* If this directory does not exist, try to use the "data" folder
Expand Down
14 changes: 11 additions & 3 deletions src/scenegraph/MatrixTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,24 @@

#ifndef _MATRIXTRANSFORM_H
#define _MATRIXTRANSFORM_H
/*
* Applies a matrix transform to child nodes
*/

#include "Group.h"
#include "matrix4x4.h"

namespace Graphics {
class Renderer;
}

namespace SceneGraph {

/*
* Applies a matrix transform to child nodes
*
* Note: transforms are not automatically serialized when saving to disk;
* they are derived from the original model and animations.
* If you have programmatically positioned a MatrixTransform, it is your
* responsibility to ensure the new position is properly serialized.
*/
class MatrixTransform : public Group {
public:
MatrixTransform(Graphics::Renderer *r, const matrix4x4f &m);
Expand Down
55 changes: 0 additions & 55 deletions src/scenegraph/Model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,32 +526,10 @@ namespace SceneGraph {
}
}

class SaveVisitorJson : public NodeVisitor {
public:
SaveVisitorJson(Json &jsonObj) :
m_jsonArray(jsonObj) {}

void ApplyMatrixTransform(MatrixTransform &node)
{
const matrix4x4f &m = node.GetTransform();
Json matrixTransformObj({}); // Create JSON object to contain matrix transform data.
matrixTransformObj["m"] = m;
m_jsonArray.push_back(matrixTransformObj); // Append matrix transform object to array.
}

private:
Json &m_jsonArray;
};

void Model::SaveToJson(Json &jsonObj) const
{
Json modelObj({}); // Create JSON object to contain model data.

Json visitorArray = Json::array(); // Create JSON array to contain visitor data.
SaveVisitorJson sv(visitorArray);
m_root->Accept(sv);
modelObj["visitor"] = visitorArray; // Add visitor array to model object.

Json animationArray = Json::array(); // Create JSON array to contain animation data.
for (auto i : m_animations)
animationArray.push_back(i->GetProgress());
Expand All @@ -562,44 +540,11 @@ namespace SceneGraph {
jsonObj["model"] = modelObj; // Add model object to supplied object.
}

class LoadVisitorJson : public NodeVisitor {
public:
LoadVisitorJson(const Json &jsonObj) :
m_jsonArray(jsonObj),
m_arrayIndex(0),
hadError(false) {}

void ApplyMatrixTransform(MatrixTransform &node)
{
// do nothing if the model has corruption issues
if (m_arrayIndex >= m_jsonArray.size()) {
hadError = true;
return;
}

node.SetTransform(m_jsonArray[m_arrayIndex++]["m"]);
}

bool success() const { return !hadError; }

private:
const Json &m_jsonArray;
unsigned int m_arrayIndex;
bool hadError;
};

void Model::LoadFromJson(const Json &jsonObj)
{
try {
Json modelObj = jsonObj["model"];

Json visitorArray = modelObj["visitor"].get<Json::array_t>();
LoadVisitorJson lv(visitorArray);
m_root->Accept(lv);
if (!lv.success()) {
Log::Info("Error(s) occurred while loading saved data for model '{}'. The model file may have changed on disk.\n", m_name);
}

Json animationArray = modelObj["animations"].get<Json::array_t>();
if (m_animations.size() == animationArray.size()) {
unsigned int arrayIndex = 0;
Expand Down
17 changes: 6 additions & 11 deletions src/scenegraph/ModelSkin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,14 @@ namespace SceneGraph {
Json colorsArray = modelSkinObj["colors"].get<Json::array_t>();
if (colorsArray.size() != 3) throw SavedGameCorruptException();
for (unsigned int i = 0; i < 3; i++) {
Json arrayElem = colorsArray[i];
m_colors[i] = arrayElem["color"];
if (colorsArray[i].is_array())
m_colors[i] = colorsArray[i];
}

Json decalsArray = modelSkinObj["decals"].get<Json::array_t>();
if (decalsArray.size() != MAX_DECAL_MATERIALS) throw SavedGameCorruptException();
for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) {
Json arrayElem = decalsArray[i];
m_decals[i] = arrayElem["decal"].get<std::string>();
if (decalsArray.size() > i && decalsArray[i].is_string())
m_decals[i] = decalsArray[i].get<std::string>();
}

m_label = modelSkinObj["label"].get<std::string>();
Expand All @@ -138,18 +137,14 @@ namespace SceneGraph {

Json colorsArray = Json::array(); // Create JSON array to contain colors data.
for (unsigned int i = 0; i < 3; i++) {
Json arrayElem({});
arrayElem["color"] = m_colors[i];
colorsArray.push_back(arrayElem);
colorsArray.push_back(m_colors[i]);
}

modelSkinObj["colors"] = colorsArray; // Add colors array to model skin object.

Json decalsArray = Json::array(); // Create JSON array to contain decals data.
for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) {
Json arrayElem({});
arrayElem["decal"] = m_decals[i];
decalsArray.push_back(arrayElem);
decalsArray.push_back(m_decals[i]);
}

modelSkinObj["decals"] = decalsArray; // Add decals array to model skin object.
Expand Down

0 comments on commit 25688d0

Please sign in to comment.