[TUTORIAL] Converting a variable to base64 and back

BreakerZero

Veteran
Veteran
Joined
Jul 8, 2018
Messages
1,140
Reaction score
504
First Language
English (USA)
Primarily Uses
RMMV
After reading a recent discussion on "save scumming" I decided that I'd like to improve my casino implementation by making the number of casino tokens illegible. Since MV and MZ use base64 to provide a basic form of game data protection I decided that perhaps the easiest way to avoid this kind of exploit is to also make the number of casino tokens a base64 value, decode it to make deductions or additions and then immediately convert it back to base64. Most likely I am going to do it at the immediate point where the calculation occurs in order to maximize the amount of data protection, and I may also consider stacking the base64 effect for additional protection.

Anyway, here's the means to do this: btoa encodes to base64, and atob reverses the encoding. So for example, if you have 21 casino tokens saved to variable 77 and you want to encode the value to make it less susceptible to scumming then you would set the variable to use the following script evaluation:

JavaScript:
btoa($gameVariables.value(77))

And the resulting value would be MjE=. To get back to 21 tokens you would then use atob() like this:

JavaScript:
atob($gameVariables.value(77))

Note that this is not a perfect solution of course: if you have any text or other variable data that cannot be easily handled in an 8-bit value (read: anything in the Unicode range) then the game will throw an error and stop working. This isn't the game's fault of course, just a limitation of the Javascript function. MDN has a complete explanation over here. Also, it's meant to make it more difficult to modify the variable even if you don't go through the hassle of encrypting the data, the latter of which would be somewhat more involved than this basic mechanism.

Now here's where it gets interesting: what if you want to stack the base64 effect for extra protection of sensitive game data? Consider the following example, this time using a script evaluation:

JavaScript:
for (var i = 0; i <= 4; i++) {
  data = btoa($gameVariables.value(77));
  $gameVariables.setValue(77, data);
}

Starting from 0 (which in programming is actually 1) this counts to 4 (or rather 5) and stacks the encoding that many times. Now instead of the original, four-character value you have an insane, 32-character value of Vm10YWEyUXhTbk5SYkVwUlZrUkJPUT09. And to get back to 21 you use the same number of encoding steps that you used to stack the encoding as follows:

JavaScript:
for (var i = 0; i <= 4; i++) {
  data = atob($gameVariables.value(77));
  $gameVariables.setValue(77, data);
  $gameVariables.setValue(77, parseInt($gameVariables.value(77)));
}

Note the addition of parseInt: this is a Javascript function which takes the returned value (which is a string of text) and parses out the numeric portion into an integer format (so that it's usable as a number). C++, C# and ObjectiveC programmers may consider it the Javascript version of int.Parse, however there is no int object in Javascript and so the parse function is called separately from an object designation. This is important because otherwise mathematical operations will either fail or append to the end of the number depending on the operation, so if you don't do this then something like 99999 + 18 will result in a value of 99999018 or similar instead of the expected result of 100017, which can send your calculations to infinity and beyond.
 
Last edited:

Dev_With_Coffee

Veteran
Veteran
Joined
Jul 20, 2020
Messages
1,013
Reaction score
498
First Language
PT-BR
Primarily Uses
RM2k3
Hello again!

This method doesn't actually encrypt the value, I can suggest that you use the game's own encryption key to create a "2.0" tutorial based on this one:
Code:
{Your Project}/js/libs/lz-string.js
 

BreakerZero

Veteran
Veteran
Joined
Jul 8, 2018
Messages
1,140
Reaction score
504
First Language
English (USA)
Primarily Uses
RMMV
Hello again!

This method doesn't actually encrypt the value, I can suggest that you use the game's own encryption key to create a "2.0" tutorial based on this one:
Code:
{Your Project}/js/libs/lz-string.js
This was intended to create a basic variable conversion, not a full-blown encryption. That would be a bit more involved than what I was going for. But the idea is the same, as you probably don't want these variables to be easily modified.

With that being said, I'll consider updating the tutorial once I have a chance to do some digging into that matter.
 

Latest Threads

Latest Posts

Latest Profile Posts

I am supposed to be preparing to teach my students this afternoon and tomorrow morning about Refugees, Asylees, and Fraud/Misrepresentation and all I can think about is how to improve my Turn Order display. :stickytongue:
Try changing POV battle, near and far away like suikoden...
watercave2.jpg

diablofar.jpg

In the end I choose near over shoulder resembles RE4. Tight close window better. The correlation between battleback, monster style and battler should also be observed and merged.
Upgraded my avatar to be cuter.
When you look for several things for ages and then suddenly find it all at once.

Status.png
Status2.png
equip.png
I'm going to see if I can set up a triple booting setup. Windows for standard use & gaming, debian for linux development and manjaro for linux gaming, wine & proton use.

Forum statistics

Threads
129,703
Messages
1,204,424
Members
170,769
Latest member
ghostyen
Top