GMS 2 Hiding or encrypting Included Files from players

Champol

Member
Hi everyone,

With my team we are about to publish the first chapter of our game, but we need to make sure players cannot access the "Included Files", as they contain the dialogs and other game data that is meant to be secret.

We could obviously transform those files into scripts somehow, but that would be very annoying to work with, as we use both INI files and text files (and lots of them, as the game has a strong narrative component).

So encryption sound like the only option remaining, but I don't know very well how to use it in the best way for our case. So I would be greatful if you can help us! =)

EDIT: But first, another question that could solve the problem for once: Where the bleep does Undertale (and similar games) store their in-game text? Don't they use Included Files? Which is their solution?

Ok, lets continue: our dialog files have the following format:
Code:
[dialog_id]
#L = Character1
#R = Character2
- L: "Generic dialog line."
- R: "Generic response to the previous line."
- L: "Generic dialog ending."
#END

[another_dialog_id]
#L = Character1
- L: "Generic monologue."
#END

... etc.
We have around 20 files like this, each with 3-15 different dialogues. I was wondering if it would be a good idea to encrypt each file as a whole, and make it so the game has to decrypt it each time a dialog occurrs in the game. In that case, many question arise:
1) Which encryption method would you suggest, and why?
2) Can GM decrypt the whole file at once? does it store it somewhere?
3) Or do I have to decrypt each line at a time, as I read them from the encrypted file?
4) How resource intensive would this method be?

We also have some ini files which contain the in-game text in different languages (one file per language), and the game constantly reads from these files (but doesn't write on them). Hopefully, not only the content should be encrypted, but also the sections and keys.
5) Which encryption method would you suggest in this situation?
6) Would you encrypt the file as a whole, or each text (section, key, value) in its own?

Finally, we have the save files, where we store flags and the game state when the player saves the game. This is also an ini file but it changes each time the game is played and saved, which happens less often, so we could use a slower method. Here, sections and keys should also be encrypted.
7) Which encryption method would you suggest in this situation, and why?

I know it's a complex topic, but partial answers are welcomed, too.
Thank you very much!

PD: I have only some partial knowledge about checksums, Json and all of that, but I can learn fast if I know what I need to learn.
 
Last edited:

CloseRange

Member
I was wondering if it would be a good idea to encrypt each file as a whole
For dialog? It's more of a pointless idea I'd say. Encryption is usually meant for sensitive information such as passwords.
Why hide dialog that the user can see? Nothing is stopping them from writing it down as they see it in game.
For images they can just take a screen capture of the character on screen and save it.
It would be illegal for them to do it but then again so is pirating movies....
I suppose you might not want them altering the text to change the game? But if it's single player then why bother, let them do what they want if they break it it's on them.

BUT that's not the question at hand so let's get to it:
0) not one of your questions but i'd actual recommend switching to ds_maps so you can use ds_map_secure_save and ds_map_secure_load.
that's how we usually do it but you seem like you wanna learn so continue as if you have to make it yourself.
1) I recommend RSA. When I did my first encryption test I used this video as reference
RSA is one of the 3 most common algorithms and so you shouldn't have problems (just note anyone can crack any encryption with enough time)
2) if you're writing this by hand then YOU can encrypt/decrypt it. You could encrypt a whole file, then decrypt it when you wanna use it. This file will not be stored anywhere otherwise the user could just go find where it's saved and then have the data none-the-less. This won't work with ini file handling as game maker needs a readable ini file in memory to read from.
3) For an ini file you could just take your string, perform the encription on each character, and save that string as the variable. If anyone trys to open it they will see a normal ini file but instead of seeing text1 = "hello world" they will see text1 = "fsdnajfnakdsfnkdsj" aka a bunch of gibberish.
if you want you can do it to the keys as well so it looks like fsadfa = "fkadsfmg" again more gibberish. but they will still see the same ini formatting of brackets around a section and = between key and data. Though that will still work fine because they won't be able to see what is happening.
But anyway now as you openthe ini file, if you wanna find the data in the key 'text1' (note that in the file the keys are gibberish as well) then you'd encrypt the word 'text1' then say
Code:
var text = ini_read_string(encrypt("section"), encrypt("text1"), "");
var realText = decrypt(text);
4) this will not take up any more memory. And for how slow it will be, well it depends. Encryption / decryption is O(n) meaning if you have a file with 100 bytes (aka 100 characters) then it will take 100 cycles. That's not that bad considering how fall your files are. An image file will take longer if it's bigger and it will be super bad if you decide to run this every frame (by mistake of course). If you are doing this any time you save/load it's 10000% fine if you run it every time you show a new message it's eh but you I promise nobody will see a difference with or without it.
5) this is the same as question 1 so i'll skip it
6) section key value is simplist (well ds_map is easiest but shhh)
7) this is the same as 5 and 1 so I'll skip it

If you wish to use checksum's that's fine but just note that the player can still read the data 100% fine and look at it and all that. What a cehcksum would do is make it so if they do change the file, then when they open the game you can say a fancy message saying "woah there hacker boi. Hold up"

Final thoughts. If you truly care about security in game maker use ds_map they arn't hard to learn especially because they use the exact same format as ini files: section, key, value. Then just use ds_map_secure_save and load.
However if you just wanna learn because you're curious then look into RSA

If I was confusing or you have further questions feel free to ask
 

Champol

Member
Sorry, with "encryption" I meant "encoding". I don't need fancy methods to hide the info, only to make it no human-readable, hopefully in a way that is not so easy to decode but more importantly in a way that doesn't causes lag when reading or writing from/on those files.

The ds_map scripts seem interesting, at least for saving and loading the game, thanks for the idea.
But I don't know if it's useful for our language files. Those are INI files which contain a lot of pairs the game reads very often, and do contain spoilers of the game (players are not supposed to see all the info, even if they play several times, so that's why it would be important to hide this info at least from the common user). But the files are around 200 lines long, and it would be stupid to decode it completely to get just one line of text. In this case, maybe the trick is encoding both the key and value but maitaining the INI format, as you suggested.

Finally, for the dialog files, I think I will go with a line-per-line encoding method. GM provides a base64 encoding script. What are the pros and cons of that method? I am also checking out the video about RSA, in case that shines some light. Thanks!
 

Champol

Member
Different question but maybe the answer is more useful: Where the bleep does Undertale (and similar games) store their in-game text?
Don't they use Included Files? Which is their solution?
 

CloseRange

Member
They probobly do it via code. It's how I do it at least and looking through undertail's files all I see is one options.ini and a bunch of sound files.
I mean it's not hard to do it in code just have one object that stores all the texts and spits them out when the dialog needs them.

Also if you read the whole text file 1 time at the start of the game and write it when you close it won't take much time no matter what encryption you use.
It would just slightly increase load times.
If you wanted you could write a small program in any language you want that just reads the ini file and converts it to code that you can just copy paste into gml. I've done similar things with other projects.
 

zbox

Member
GMC Elder
To be honest for a simple solution I'd recommend just zipping them, renaming the .zip to something else and then extracting it at runtime. It will extract it into %appdata% which most users do not know about, and if someone is nosey enough to look there they also may be nosey enough to break the client side encryption you're doing in the first place.

This will also make it easier for you. Very simple to add and change files in a zip, vs making a tool to encrypt stuff each time.
 
Top