Skip to content

Snapshot Save Single Action #7500

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

NeylMahfouf2608
Copy link
Collaborator

Save and/or load the whole game using the updateFromNetworkSyncData/getNetworkSyncData methods to write/read a complete JSON. Done in one action for each (at the moment, might change). Right now it writes both on a localFile and localStorage of the browser.

@NeylMahfouf2608 NeylMahfouf2608 requested a review from 4ian as a code owner March 24, 2025 16:28
…added some constants in separated files for clarity
if (channel) {
this._channel = channel;
} else {
this._channel = NaN;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote NaN as a value is mandatory. -1 isnt enough as it can be set in the editor.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand your logic.
Why is channel mandatory?
If you think it should not be mandatory, then make the private property mandatory:

private _channel: float | undefined;

Then you don't have to set NaN here

}

if (storageName) {
await gdjs.saveToIndexedDB(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here you can simplify this if/else by doing a:

await gdjs.saveToIndexedDB(
  INDEXED_DB_NAME,
  storageName || INDEXED_DB_KEY,
  INDEXED_DB_OBJECT_STORE,
  syncDataJson
);

if (channel) {
this._channel = channel;
} else {
this._channel = NaN;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand your logic.
Why is channel mandatory?
If you think it should not be mandatory, then make the private property mandatory:

private _channel: float | undefined;

Then you don't have to set NaN here

return {
globalVolume: this._globalVolume,
availableResources: this._availableResources,
cachedSpatialPosition: this._cachedSpatialPosition,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here you're passing availableResources & cachedSpatialPosition but you're not using them when updating the network sync data?

return;
}
return new Promise((resolve, reject) => {
const request = indexedDB.open(dbName, 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you've added a try catch in the load on the open() function but not here.

So either add it here,
or remove it and add the try catch around everything like I suggested before.
You don't need to check if indexedDB doesn't exist like you do above, just try using it and try doing the promise and everything... BUT with a try catch around everything.

In any case, be consistent between the load and the save function

if (extensionVariablesSyncData.length) {
if (
extensionVariablesSyncData.length &&
!syncOptions.forceSyncEverything
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic is wrong. you don't need to check on !syncOptions.forceSyncEverything you always sync this

zo: this.zOrder,
a: this.angle,
hid: this.hidden,
lay: this.layer,
if: this._instantForces.map((force) => force.getNetworkSyncData()),
pfx: this._permanentForceX,
pfy: this._permanentForceY,
n: this.name,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's add this name, only if forceSyncEverything, otherwise don't (just to save a bit of bandwidth...)
so: n: syncOptions && syncOptions.forceSyncEverything ? this.name : undefined

this._loadStorageName = storageName;
}
if (sceneVar) {
this._loadVariable = sceneVar;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are those values cleared the next time we use the function without the sceneVar and storageName?

If not, I think we should always set the value from what's coming from the props of the function.
This will allow setting undefined or whatever string/variable is passed

if (currentScene._loadVariable) {
try {
const allSyncData =
currentScene._loadVariable.toJSObject() as GameSaveState;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's not access a private variable from another object here (doing currentScene._loadVariable)

you're doing the same for _loadStorageName below.

I think that instead of having 2 props in runtimescene, you should have 1 object:
_loadRequestOptions = { storageName: ?string, storageVariable: ?Variable }

And you can get it with a method getLoadingRequestOptions() - something like that

@@ -66,6 +75,8 @@ declare type BasicObjectNetworkSyncData = {
pfx: number;
/** Permanent force on Y */
pfy: number;
/* name :*/
n: string;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's make it so it can be undefined: n?: string (so that we don't pass it if multiplayer)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants