mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-12-13 02:01:51 +00:00
Add example for storing data in the savegame
This commit is contained in:
parent
20dca5bcc1
commit
bf7e1887a8
@ -38,6 +38,7 @@ To get into shapez.io modding, I highly recommend checking out all of the exampl
|
||||
| [modify_theme.js](modify_theme.js) | Modifies the default game themes | Modifying the builtin themes |
|
||||
| [custom_theme.js](custom_theme.js) | Adds a new UI and map theme | Adding a new game theme |
|
||||
| [mod_settings.js](mod_settings.js) | Shows a dialog counting how often the mod has been launched | Reading and storing mod settings |
|
||||
| [storing_data_in_savegame.js](storing_data_in_savegame.js) | Shows how to store custom (structured) data in the savegame | Storing custom data in savegame |
|
||||
| [modify_existing_building.js](modify_existing_building.js) | Makes the rotator building always unlocked and adds a new statistic to the building panel | Modifying a builtin building, replacing builtin methods |
|
||||
| [modify_ui.js](modify_ui.js) | Shows how to add custom IU elements to builtin game states (the Main Menu in this case) | Extending builtin UI states, Adding CSS |
|
||||
| [pasting.js](pasting.js) | Shows a dialog when pasting text in the game | Listening to paste events |
|
||||
|
||||
78
mod_examples/storing_data_in_savegame.js
Normal file
78
mod_examples/storing_data_in_savegame.js
Normal file
@ -0,0 +1,78 @@
|
||||
// @ts-nocheck
|
||||
const METADATA = {
|
||||
website: "https://tobspr.io",
|
||||
author: "tobspr",
|
||||
name: "Mod Example: Storing Data in Savegame",
|
||||
version: "1",
|
||||
id: "storing-savegame-data",
|
||||
description: "Shows how to add custom data to a savegame",
|
||||
minimumGameVersion: ">=1.5.0",
|
||||
};
|
||||
|
||||
class Mod extends shapez.Mod {
|
||||
init() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Option 1: For simple data
|
||||
this.signals.gameSerialized.add((root, data) => {
|
||||
data.modExtraData["storing-savegame-data"] = Math.random();
|
||||
});
|
||||
|
||||
this.signals.gameDeserialized.add((root, data) => {
|
||||
alert("The value stored in the savegame was: " + data.modExtraData["storing-savegame-data"]);
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Option 2: If you need a structured way of storing data
|
||||
|
||||
class SomeSerializableObject extends shapez.BasicSerializableObject {
|
||||
static getId() {
|
||||
return "SomeSerializableObject";
|
||||
}
|
||||
|
||||
static getSchema() {
|
||||
return {
|
||||
someInt: shapez.types.int,
|
||||
someString: shapez.types.string,
|
||||
someVector: shapez.types.vector,
|
||||
|
||||
// this value is allowed to be null
|
||||
nullableInt: shapez.types.nullable(shapez.types.int),
|
||||
|
||||
// There is a lot more .. be sure to checkout src/js/savegame/serialization.js
|
||||
// You can have maps, classes, arrays etc..
|
||||
// And if you need something specific you can always ask in the modding discord.
|
||||
};
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.someInt = 42;
|
||||
this.someString = "Hello World";
|
||||
this.someVector = new shapez.Vector(1, 2);
|
||||
|
||||
this.nullableInt = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Store our object in the global game root
|
||||
this.signals.gameInitialized.add(root => {
|
||||
root.myObject = new SomeSerializableObject();
|
||||
});
|
||||
|
||||
// Save it within the savegame
|
||||
this.signals.gameSerialized.add((root, data) => {
|
||||
data.modExtraData["storing-savegame-data-2"] = root.myObject.serialize();
|
||||
});
|
||||
|
||||
// Restore it when the savegame is loaded
|
||||
this.signals.gameDeserialized.add((root, data) => {
|
||||
const errorText = root.myObject.deserialize(data.modExtraData["storing-savegame-data-2"]);
|
||||
if (errorText) {
|
||||
alert("Mod failed to deserialize from savegame: " + errorText);
|
||||
}
|
||||
alert("The other value stored in the savegame (option 2) was " + root.myObject.someInt);
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
}
|
||||
@ -27,4 +27,7 @@ export const MOD_SIGNALS = {
|
||||
gameStarted: /** @type {TypedSignal<[GameRoot]>} */ (new Signal()),
|
||||
|
||||
stateEntered: /** @type {TypedSignal<[GameState]>} */ (new Signal()),
|
||||
|
||||
gameSerialized: /** @type {TypedSignal<[GameRoot, import("../savegame/savegame_typedefs").SerializedGame]>} */ (new Signal()),
|
||||
gameDeserialized: /** @type {TypedSignal<[GameRoot, import("../savegame/savegame_typedefs").SerializedGame]>} */ (new Signal()),
|
||||
};
|
||||
|
||||
@ -162,6 +162,7 @@ export class Savegame extends ReadWriteProxy {
|
||||
SavegameInterface_V1009.migrate1008to1009(data);
|
||||
data.version = 1009;
|
||||
}
|
||||
|
||||
if (data.version === 1009) {
|
||||
SavegameInterface_V1010.migrate1009to1010(data);
|
||||
data.version = 1010;
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { ExplainedResult } from "../core/explained_result";
|
||||
import { createLogger } from "../core/logging";
|
||||
import { gComponentRegistry } from "../core/global_registries";
|
||||
import { createLogger } from "../core/logging";
|
||||
import { MOD_SIGNALS } from "../mods/mod_signals";
|
||||
import { SerializerInternal } from "./serializer_internal";
|
||||
import { HUDPinnedShapes } from "../game/hud/parts/pinned_shapes";
|
||||
import { HUDWaypoints } from "../game/hud/parts/waypoints";
|
||||
|
||||
/**
|
||||
* @typedef {import("../game/component").Component} Component
|
||||
@ -42,8 +41,12 @@ export class SavegameSerializer {
|
||||
beltPaths: root.systemMgr.systems.belt.serializePaths(),
|
||||
pinnedShapes: root.hud.parts.pinnedShapes ? root.hud.parts.pinnedShapes.serialize() : null,
|
||||
waypoints: root.hud.parts.waypoints ? root.hud.parts.waypoints.serialize() : null,
|
||||
|
||||
modExtraData: {},
|
||||
};
|
||||
|
||||
MOD_SIGNALS.gameSerialized.dispatch(root, data);
|
||||
|
||||
if (G_IS_DEV) {
|
||||
if (sanityChecks) {
|
||||
// Sanity check
|
||||
@ -151,6 +154,9 @@ export class SavegameSerializer {
|
||||
return ExplainedResult.bad(errorReason);
|
||||
}
|
||||
|
||||
// Mods
|
||||
MOD_SIGNALS.gameDeserialized.dispatch(root, savegame);
|
||||
|
||||
return ExplainedResult.good();
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +25,8 @@
|
||||
* pinnedShapes: any,
|
||||
* waypoints: any,
|
||||
* entities: Array<Entity>,
|
||||
* beltPaths: Array<any>
|
||||
* beltPaths: Array<any>,
|
||||
* modExtraData: Object
|
||||
* }} SerializedGame
|
||||
*
|
||||
* @typedef {{
|
||||
|
||||
@ -20,5 +20,9 @@ export class SavegameInterface_V1010 extends SavegameInterface_V1009 {
|
||||
logger.log("Migrating 1009 to 1010");
|
||||
|
||||
data.mods = [];
|
||||
|
||||
if (data.dump) {
|
||||
data.dump.modExtraData = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user