[TUTORIAL] Converting a variable to base64 and back

BreakerZero

Veteran
Veteran
Joined
Jul 8, 2018
Messages
1,058
Reaction score
450
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
967
Reaction score
470
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,058
Reaction score
450
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 Profile Posts

No way, these madlads actually did it, they made Sans in real life
Awright ya marshmallows! :kaopride: Here's a peek of what Alice's 8-bit Gothic gonna be like! EXPECT IT! (...in 2025?) :kaoswt:

alice_gothictiles.png
SF_People3_4 added!
index.php

Finds notes for an old side project... Oh, that's right, the two tracks that sounded really cool and gave inspiration for the big bad in that game... Spends day working on cutscene from old notes, looks okay, now lets slot in the first track... um... I did have those tracks??? It was a year or so ago but I did buy them didn't I?

Forum statistics

Threads
118,602
Messages
1,117,227
Members
155,673
Latest member
colbymh92
Top