Hello, I want to share a piece of code to silently load a savegame in the web player.
Context:
-A game have pre-existing savegame that needs to be present. It’s important as a meta-element to the story.
-We cannot use easyrpgPlayer.api.uploadSavegame because it’ll open a file selector dialog and we want the loading to be silent.
-Beside, the savegame is on the webserver, not on the player device.
Solution reached tonight:
async function autoLoadSave(saveFileUrl) { // mywebsite.com/Save15.lsd
let slotNumber = saveFileUrl.substring(saveFileUrl.length-6, saveFileUrl.length-4);
console.log("need to autoload " + saveFileUrl + " in the slot " + slotNumber);
const dbName = "/easyrpg/910/Save"; //replace 910 by the number of your game
const dbVersion = 21;
// Check if the save already exists
const saveExists = await checkSaveExists(dbName, "FILE_DATA", slotNumber);
if (saveExists) {
console.log(`Save ${slotNumber} already exists in IndexedDB, skipping import`);
return;
}
// If save doesn't exist, proceed with loading
const response = await fetch(saveFileUrl);
const arrayBuffer = await response.arrayBuffer();
const saveData = new Uint8Array(arrayBuffer);
const buf = easyrpgPlayer._malloc(saveData.length);
easyrpgPlayer.HEAPU8.set(saveData, buf);
try {
console.log("Loading save via private api.");
easyrpgPlayer.api_private.uploadSavegameStep2(slotNumber, buf, saveData.length);
easyrpgPlayer.api.refreshScene();
} finally {
easyrpgPlayer._free(buf);
}
}
async function checkSaveExists(dbName, storeName, saveSlot) {
return new Promise((resolve, reject) => {
const request = indexedDB.open(dbName);
request.onerror = () => reject(request.error);
request.onsuccess = () => {
const db = request.result;
const transaction = db.transaction(storeName, 'readonly');
const store = transaction.objectStore(storeName);
// Construct the key path as it appears in the database
const keyPath = `/easyrpg/910/Save/Save${saveSlot.padStart(2, '0')}.lsd`; //replace 910 here too
const getRequest = store.get(keyPath);
getRequest.onsuccess = () => {
resolve(!!getRequest.result); // Convert to boolean
};
getRequest.onerror = () => reject(getRequest.error);
};
});
}
It needs to be called after easyrpgPlayer has been loaded, obviously.
See it in action here:
It’s not super clean (using setTimeout and a private api) but it works well enough.
Thanks again to all EasyRpg contributors, it’s really saving the hobby and makes people interested in playing/making RM200x games again.