Online save backup using events

Hyouryuu-Na

Sapphire Sodium
Veteran
Joined
Jun 15, 2017
Messages
935
Reaction score
2,186
First Language
Not English
Primarily Uses
RMMV
Hello ^^ I've been working on this online save backup system for quite some time now. It turned out pretty good and it's highly customizable since it is fully evented.
Want a demonstration?
Save.gifYes, I know proceed is spelled wrong here btw. The Account.txt file is auto generated for verification purposes. Without this file, if anyone enters a name and password that isn't contained in your dev's dropbox, they'll get the 'account exists' message (in the 'Yes, I have an account' choice) but files won't get uploaded or downloaded. That's why it was important for me to create this file. The event checks if this account.txt file exists or not in the dropbox folder and then goes on to say if account truly exists or not.

load.gif

Before I get to the explanations, there's some things you should know:

What is this?
-->This is an evented system through which the players can backup their saves in the developer’s dropbox and retrieve them again when needed.

Why Dropbox?
-->Because I could actually wrap my head around their api. Google drive also has an api but I couldn't understand anything no matter how much I browsed the web for answers. And me being a non-programmer definitely doesn't help. But can you use google drive? Obviously. But honestly, I really hope someone would make a plugin for something like this. Eventing this was toughhh.

Who is this for?
-->People like me… who don’t understand codes and stuff and simply can’t use this plugin right here: https://forums.rpgmakerweb.com/inde...ger-simple-cloud-based-savegame-system.57750/ (If you can, please consider using this plugin. Because making this system work is tedious. Don't proceed if you don't want to go through a lot of trial and error. You have been warned.)

Why would you need to use this?
-->Well… because you can? XD Honestly, I don’t think it’s such a big requirement since it’s not cross platform (it’s only for desktop). But I spent quite some time on this (a lot actually… because I’m lifeless and I sort of enjoyed the process :p) so I’m making a tutorial regardless ✧*。٩(ˊᗜˋ*)و✧*。

But seriously- If a player forgets to backup their saves and they lose the files for whatever reason, they can get them back. This also works if the game is on different computers.

And it doesn’t have to be saves. You can get any other information from the player like a survey. Or maybe a report to see how far they got in the game. As it reads text contents, you can make the game save Player’s info like level, play time, achievements, whatever you want to know about in to a txt file so it gets uploaded to you. I don’t know about other people but I will certainly find it amusing to know how my players are doing ^^

It might work for browser deployment too but I’m not that smart to figure it out. Maybe someone else can utilize this and make a plugin that offers that function.
-----------------------***------------------------​
Well, now that you know if you should use this, let's get to the actual tutorial.

Requirements:
A Dropbox account

-Setting up your Dropbox account-

If your existing dropbox account has decent amount of space, you don’t need a new account since we’re just going to store written content (.txt, .rpgsave, .json etc.) and they're fairly small in size. Consider making a separate dropbox account if you think your remaining space isn’t enough.

Go to https://www.dropbox.com/ and make an account if you want a new one. Or skip to the next step if you already have one.
Go to https://www.dropbox.com/developers/apps and click create an app.
Select the following options:
tutorial1.png

Hit create app
Next, you’ll be taken to a new page with a bunch of settings.

Under the permissions tab,
Tick files.content.read and files.content.write. These are the only ones we’ll need.
Remember to click submit!
tutorial2.png

Under the settings tab,
Click generate access token. You’ll be given a looong random string. You’ll need that so copy it somewhere or it will disappear and you’ll need to generate a new one.
Set Access Token expiration to No expiration.
tutorial3.png

We’re done with the dropbox part.

-Eventing-

Uploading files:


Make a section where you ask the player for their name and password. You can use the Name Input scene for this or any of these plugins here:
Here, I’m using name_password as the folder name. You might not even need a password but a name along with a password makes the combination stronger. This way players can’t access another player’s folder. If my name is HyouryuuNa and my password is iloveprocrastinating~, then my folder name is HyouryuuNa_ iloveprocrastinating~. Unique enough? Yes. What you do here is up to you. You can ask whether the player has a profile. If they do, you ask if they want to load saves. If they don’t have a profile, you can ask whether they’d like to make one. Basically, you can event this part in any way you like.

I’m making the game upload the save file every time the player saves. For this you’ll need Caethyril’s Save Load Switch plugin
(Thank you so much for taking my request Caethyril!)
Get the plugin here: https://forums.rpgmakerweb.com/index.php?threads/caethyrils-plugins.106255/ [under general]
Set the plugin parameters. I’ve set the save switch to 1 and the save Id variable to 4.

Now let’s create the save common event. Every time the player saves, the game will upload the save file to the dropbox account. We use the save switch defined in the plugin parameter (it's 1 in my case) and set the trigger to parallel.
I’ve used this script (Unfortunately I couldn’t find the original source(s) of this snippet. But anyways, thank you strangers. Because seriously, putting this together was really tough for someone with no coding experience like me. I had to browse through numerous threads because one answer didn’t have the whole thing. Oh and you guys will probably need to squish it so it fits the 12 line script space -_-):
JavaScript:
var xhr = new XMLHttpRequest();
xhr.open("GET", "save/file" + $gameVariables.value(4) + ".rpgsave", false); //Reads the save file's contents. Variable 4= Save ID. //You should change the path to www/save/... for after deployment.
xhr.send(null);
var fileContent = xhr.responseText;
var path = "/" + $gameVariables.value(1) + "_" + $gameVariables.value(2) + "/file" + $gameVariables.value(4) + ".rpgsave";
//Variable 1= name and variable 2= password. Here, the folder name is name_password. You can make it name+password, name*password, name&password or simply namepassword lmao
var accessToken = "<Your Access Token here, without the angle brackets>";
var uploadUrl = "https://content.dropboxapi.com/2/files/upload"; //Do not change this
var result;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
        result = xhr.responseText;
        //console.log(result);
    }
};
xhr.open("POST", uploadUrl, true);
xhr.setRequestHeader("Authorization", "Bearer " + accessToken);
xhr.setRequestHeader("Content-type", "application/octet-stream");
xhr.setRequestHeader('Dropbox-API-Arg', JSON.stringify({
    path: path,
    mode: 'overwrite',
    autorename: true,
    mute: false
}));
xhr.send(fileContent);
1593279376592.png
Remember to turn the switch off or it will keep on running and you don’t want that.

Writing multiple files:

And I’ve made a ‘Save multiple’ common event too. This is useful when the player decides to upload all saves that has been made beforehand… when they didn’t have a profile. This doesn’t need a switch. Simply call it when the player chooses ‘backup saves’ or something like that.
JavaScript:
for (checker = 1; checker <= 5; checker++) { //Replace 5 with your maximum save file number
    var xhr = new XMLHttpRequest();
    const fs = require("fs");
    if (fs.existsSync("save/file" + checker + ".rpgsave")) {
        xhr.open("GET", "save/file" + checker + ".rpgsave", false); //You should change the path to www/save/... for after deployment.
        xhr.send(null);
        var fileContent = xhr.responseText;
        var path = "/" + $gameVariables.value(1) + "_" + $gameVariables.value(2) + "/file" + checker + ".rpgsave"; //Var 1=name, var 2=password
        var accessToken = "<Your Access Token here, without the angle brackets>";
        var uploadUrl = "https://content.dropboxapi.com/2/files/upload"; //Do not change this
        var result;
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                result = xhr.responseText;
                //console.log(result);
            }
        };
        xhr.open("POST", uploadUrl, true);
        xhr.setRequestHeader("Authorization", "Bearer " + accessToken);
        xhr.setRequestHeader("Content-type", "application/octet-stream");
        xhr.setRequestHeader('Dropbox-API-Arg', JSON.stringify({
            path: path,
            mode: 'overwrite',
            autorename: true,
            mute: false
        }));
        xhr.send(fileContent);
    } else {}
}

Reading files:

I swear, this part had me banging my head against the pillow. I don’t want to get hurt ( ≧Д≦). I managed to make it work… but with the help of two variables. I wanted to do this without any game variables at all but for loop was not working and I had to step outside the little script call space.

JavaScript:
var path2 = "save/" + $gameVariables.value(11); //var 11= the ID of the save file. Saves in the 'save' folder. Change it to www/save/ for after deployment
var path = "/" + $gameVariables.value(1) + "_" + $gameVariables.value(2) + "/" + $gameVariables.value(11); //var 1= name, var 2 = password
var token = "<Your Access Token here, without the angle brackets>";
var url = "https://content.dropboxapi.com/2/files/download"; //as usual, don't change the url please
var result;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status != 409) {
        result = xhr.responseText;
        var fs = require('fs');
        fs.writeFile(path2, result, function(err) {
            if (err) throw err;
            console.log(result);
        });
    } else if (xhr.status == 409) {
        $gameVariables.setValue(12, $gameVariables.value(12) + 1) //when save files are missing, simply ignore them and continue forward
    }
};
xhr.open("GET", url, true);
xhr.setRequestHeader("Authorization", "Bearer " + token);
xhr.setRequestHeader('Dropbox-API-Arg', JSON.stringify({
    path: path
}))
console.log(JSON.stringify({
    path: path
}));
//console.log(path2 + " " + result);
xhr.send();
1593280019093.png

I guess we’re done with all the basic stuff. The rest is up to your creativity. You can use the save and load script in combination to create any type of 'menu' you want.
Don't hesitate to ask me if you have any questions ^^ Though I don't have much coding knowledge, I'll try to help. Have fun eventing ^^
 
Last edited:

Kes

Veteran
Veteran
Joined
Aug 3, 2012
Messages
22,297
Reaction score
11,712
First Language
English
Primarily Uses
RMVXA
A very neat idea, and you've obviously put a lot of work into this, so well done.

There is one potential problem. At one time if someone's dropbox got a lot of traffic, dopbox would decide that really it was a business account, and therefore you either had to upgrade to a paid box, or they would shut it down. I don't know if that is still the case, and it would only be a potential problem if your game was popular and you had a lot of players saving to dropbox. But it might be worth checking that out.
 

Hyouryuu-Na

Sapphire Sodium
Veteran
Joined
Jun 15, 2017
Messages
935
Reaction score
2,186
First Language
Not English
Primarily Uses
RMMV
Oh I didn't know this :( That certainly is a problem... Personally I don't have any fear of this happening to me since in no way I'm getting so many people play my game :") But other people might face this problem. Maybe I should update my post with this bit of info
 
Last edited:

Kes

Veteran
Veteran
Joined
Aug 3, 2012
Messages
22,297
Reaction score
11,712
First Language
English
Primarily Uses
RMVXA
Before you do that, check out that the info is up to date. It might be that things have changed over the years.
 

ShadowDragon

Veteran
Veteran
Joined
Oct 8, 2018
Messages
2,840
Reaction score
999
First Language
Dutch
Primarily Uses
RMMV
the other issue (not major), if you let players to have maxmum 2 save files or event 1,
they can create as many accounts as they wish as well for multiple save files that way.

what if the player lost his account or forgot to write it down? they have to start from
the very beginning, if not overwriting if the the other person have the exact same
name/account (name + password) it will be rare, but possible :p

the idea is nice though, but error's might come if the save file is not compitable with
a newer version ^^ nice job otherwise.

No idea that this was even possible :)
 

Hyouryuu-Na

Sapphire Sodium
Veteran
Joined
Jun 15, 2017
Messages
935
Reaction score
2,186
First Language
Not English
Primarily Uses
RMMV
@ShadowDragon That is true. I actually intended for this to happen and even I used 4 different accounts to test it. I don't think this would cause players to misuse the system as they can already do this by backing up saves manually within their computers. The whole idea is to just keep... less attentive players from losing their saves and to let devs keep an eye on their players XD (not gonna lie, my interest is the latter one)

It is probable that players might forget their name/password. But I've made it so that the game remembers... sort of like 'remember this password?' setting in browsers. All you need is a little bit of creativity to solve these issues. Hint: a txt file is what you need ^^

And yeah, I have no answers for the this one... There's nothing to do if save files aren't compatible with newer versions... I think they might be if the game doesn't change anywhere in the middle. Games with chapters might work... like, after chapter 1, chapter 2 was released as a completely different segment. Then the save files will work I think. But if any new content is added in chapter 1, it might break. That's a problem...

But if you decide to use this for something other than saves, then none of this might be a problem because you can just let the game upload anonymous files. For example, I don't need to know who is doing what, I don't even know these people by name... so why? I only need an overall report of the situation. I'll probably make the game update me on how many times a person has died, how and at what difficulty so that I can change the settings to be more appropriate. Or I can just laugh at how bad my players are at the game XD (or cry because that means I didn't balance the difficulty properly)
 
Last edited:

ShadowDragon

Veteran
Veteran
Joined
Oct 8, 2018
Messages
2,840
Reaction score
999
First Language
Dutch
Primarily Uses
RMMV
you can rather say? it's a basic built to get you started :p

but there are many things that needs to be fixed.
either way, the 12 line and without the big parts can be way shorter
if you create a simple plugin with a fuction like,
function api(var1, var2, api) {
code here
}

than you can basicly use api(var1, var2, apikey)

and your good to go (you have to test to see if its work), and you can adjust the code
in the plugin easier, but you still need to do a bunch of work to get a smooth non-cheat way
like, check the OS of the player if they have an savefile/account, if it exist, warn the player,
or want to delete the current savefile to create a new one? and or ID.

creative ways must be added for sure, but nice basis :)

maybe when you find a way or simple way to avoid issues.
 

Hyouryuu-Na

Sapphire Sodium
Veteran
Joined
Jun 15, 2017
Messages
935
Reaction score
2,186
First Language
Not English
Primarily Uses
RMMV
That'd be VERY convenient. But as I said, I know nothing about javascript and plugins. I started to work on this for my own use but later decided that I'd share it as it is. I'll see if I can make a small plugin out of this.
As for the remember setting, this is a relevant part of it:
1593369206663.png
I saved the name,password to a txt file after the player filled the info AND the account doesn't exist in the dev's dropbox (it's free to use)[for new account creation] and account exists[existing account] so that the game doesn't ask repeatedly every time for name and password.
 
Last edited:

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts


My only regret is the portal mirror effect is too subtle to show up in these GIFs. It probably just needs more sparkles. :LZSwink:
Microsoft: Hey, let's waste money advertising the Xbox Series X when nobody has any in stock, we don't seem to be making more, we aren't taking preorders and you can't get on a waiting list. BEST. IDEA. EVER.
So I'm practicing ITC with a spirit box, and decide to try to contact my deceased soulmate. It actually gave me multiple identifiers. Me, still a bit skeptical, asked aloud "Fine but does he still love me?" and the box spoke and printed the word "Forever" at the same time. Been a mess of tears since. :kaocry:
Been scratching away at my game and making progress, but just had a revelation. I'm working in full screen and adjusting all my pictures accordingly, but will they resize if someone's screen is smaller?? I hope this doesn't turn out to be a problem later.

Forum statistics

Threads
105,635
Messages
1,015,166
Members
137,306
Latest member
lzh1703
Top