Ren'Py Obfuscate code when creating distribution

maniwa

Newbie
Game Developer
Dec 3, 2022
29
63
Hi,

So, I have been thinking about this for a while. There are multiple tools available online with which we can see the source code of any renpy game. Even if it's compressed into a .rpa file. I know there's no easy way to create a solution where the code will be invisible, but I was thinking if it's viable to create a script which upon execution mixes the code to a level where it won't be easily understood.
Like, changing function names, variables and class names to random characters. I know something like this is possible for pure python code, but I was wondering if there's something similar for renpy files.
 

clowns234

Engaged Member
Game Developer
May 2, 2021
3,090
4,845
Hi,

So, I have been thinking about this for a while. There are multiple tools available online with which we can see the source code of any renpy game. Even if it's compressed into a .rpa file. I know there's no easy way to create a solution where the code will be invisible, but I was thinking if it's viable to create a script which upon execution mixes the code to a level where it won't be easily understood.
Like, changing function names, variables and class names to random characters. I know something like this is possible for pure python code, but I was wondering if there's something similar for renpy files.
If there is a way to scramble the code, then there must be a way to unscramble the code to play it. If the game is worth cracking, someone will figure out your unscrambler, and most likely pass it on to others. That's where those multiple tools came from.
 

hiya02

Member
Oct 14, 2019
171
98
Yeah, why would it bother if other devs can see your Vn "code"? Or is it to hide some questionable content from shitreon & Co?
 

Alcahest

Engaged Member
Donor
Game Developer
Jul 28, 2017
3,486
4,331
If there is a way to scramble the code, then there must be a way to unscramble the code to play it. If the game is worth cracking, someone will figure out your unscrambler, and most likely pass it on to others. That's where those multiple tools came from.
That's not true. We're talking about obfuscating code here, not scrambling text in a book. You could rename all labels to just letters, like a, aa, aaa, aaaa, aaaaa or whatever. The code will work just fine but it will be very hard to read, and there is no way to unscramble that.
 

clowns234

Engaged Member
Game Developer
May 2, 2021
3,090
4,845
That's not true. We're talking about obfuscating code here, not scrambling text in a book. You could rename all labels to just letters, like a, aa, aaa, aaaa, aaaaa or whatever. The code will work just fine but it will be very hard to read, and there is no way to unscramble that.
I tend to do that already. For an experienced programmer, I feel my code would be easy to follow. For a novice, not so much.
label S0000:
call dataFill
scene black with dissolve
scene image A[1] with pixellate
$ dLine(1,2)
BTW, I don't do it to obfuscate. I do it because it fits how I program.
$ x09 = 0
if "t0500R" in tags:
$ x09 +=4
if "t2700L" in tags:
$ x09 +=2
if "t1000R" in tags:
$ x09 +=1
$ X09 = "y" + str(x09)
if X09 not in tags:
$ tags.append(X09)
call expression X09
 
Last edited:

Alcahest

Engaged Member
Donor
Game Developer
Jul 28, 2017
3,486
4,331
I tend to do that already. For an experienced programmer, I feel my code would be easy to follow. For a novice, not so much.
label S0000:
call dataFill
scene black with dissolve
scene image A[1] with pixellate
$ dLine(1,2)
Yeah, renpy code is usually pretty simple and structured, so obfuscating that code can only do so much unless you actually encrypt the code, but then you would need to include the way to decrypt it in the program, so not much point to it.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,979
16,236
I know there's no easy way to create a solution where the code will be invisible,
No, the answer is: There's just no way, not a single one, to create a solution where the code will be invisible.

Whatever you'll think about, there will always be a way to reverse it.


but I was thinking if it's viable to create a script which upon execution mixes the code to a level where it won't be easily understood.
  • Is it possible ? Yes

    Globally speaking, everything is possible.
    You can even XOR all your scripts, using a complex string as key, and adding a salt value that the loaded will automatically get online, in order for it to no be stored locally. Then you'll join the result into a single file that will be nothing more than a big raw binary data. And final touch, you'll compress it using an homemade algorithm.
    Then you'll add to Ren'Py bootstrap process the code to reverse all this. A code that will works exclusively in RAM, making Ren'Py generate the AST in real time, without creating it's RPYC save.

    Yet it will be totally possible, and relatively easy, to access the source of your game and have it wrote on files. At first sigh, all it would take to revert what is a heavy level of obfuscation should be a dozen of lines to make unrpyc be called from a different point of the bootstrap.
    As long as the AST exist, and it need to exist for Ren'Py to works, there will be a way to revert it into a file that will contain the source code. You can change Ren'Py core to make it more difficult to build those files, but it would just mean that your code will looks a bit more raw, that's all.
  • Do it worth it ? No

    Because as I said, there will always be an easy way to reverse all this. You'll pass months to find a way to protect your code, and someone, me by example, will revert all your works in few hours.
    Last time I did it was when the game Forbidden Fruit was released for the first time. It was relying on a change made in the RPYC files signature, and the sole distribution of the pyc file where the change happened in Ren'Py core. I don't know how much time they past on it, but it took me two hours to not only revert it, but also restore Ren'Py to its original behavior. And those two hours include the creation of a tool that would automatically do it for any games that would follow the same method, but with different values.
  • Is it viable ? Maybe
    It totally depend of your own codding skills. Are you sure that you'll write the decoding part correctly, and that your game will not be broke to some extend, because a bit of your code was wrongly decoded ?
    Because the real issue lands, and will always lands, here. The more advanced will be your obfuscation method, the higher will be the risks that you'll just achieve to shoot your own foot. And this for no benefit because the more you'll annoy the person who try to revert it, the further he will go on its reversion.
    I talked about Forbidden Fruit... Wouldn't this obfuscation have interfered with my variable viewer, preventing someone to use it with the game, I wouldn't have cared and wouldn't have tried to revert their obfuscation.


Like, changing function names, variables and class names to random characters.
Have you took a look at the source of the games released here ?

Functions, variables and class names that looks like a random suits of characters is already a reality. And it's not even in an attempt to obfuscate the code, it's just the result of poor codding skills.


If the game is worth cracking, someone will figure out your unscrambler, and most likely pass it on to others.
And when it come to Ren'Py games, the simple fact that there's this obfuscation attempt will make it worth being cracked due to a simple thought:

There's nothing that worth to be hidden. It's not in a Ren'Py game that you'll use magic algorithm, and if you have the knowledge to design magic algorithms you'll not use Ren'Py for your game.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,979
16,236
[sorry for the double post]

I tend to do that already. For an experienced programmer, I feel my code would be easy to follow. For a novice, not so much.
And as experienced in reverse engineering, when it starts to be too boring you just write a quick script that will change all this with less annoying names.

The name of the variables, functions, whatever, never matters. It help to understand the code, but it's just this, a help. As you said, anyone with enough knowledge would be able to understand the code even with "stupid" names.
 

Alcahest

Engaged Member
Donor
Game Developer
Jul 28, 2017
3,486
4,331
The name of the variables, functions, whatever, never matters. It help to understand the code, but it's just this, a help. As you said, anyone with enough knowledge would be able to understand the code even with "stupid" names.
For renpy games on this site, yes, but it's harder when the code looks like this :D 3.png
 

Nagozo

Member
Sep 30, 2017
125
246
Have you took a look at the source of the games released here ?

Functions, variables and class names that looks like a random suits of characters is already a reality. And it's not even in an attempt to obfuscate the code, it's just the result of poor codding skills.
I think this is enough of an answer in itself. Going through hoops to encode and decode your program makes little sense for games like these, and obfuscation through obscurity is often enough to repel would-be cheaters. Unless someone is very dedicated, sitting through hundreds of lines of spaghetti code just to figure out how to the endings in some likely mediocre VN work just isn't worth the effort.
If you truly want to hide your source for some reason, you're better of choosing another engine (which uses a compiled language) and just distributing executables. I guess someone could still decompile them but that would add another hefty layer of difficulty.
 
  • Like
Reactions: clowns234

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,979
16,236
[...] and obfuscation through obscurity is often enough to repel would-be cheaters.
Except that it's Ren'Py.

Wanabe cheaters will use the rollback to trial&error their way through the choices, and the console to give themselves the highest value possible in everything that is numerical.
95% of those who will look at the source code have at least average knowledge. What mean that they'll perhaps be annoyed by the obscurity, but will not care. They have an anti-aircraft projector ready to light up everything.


Unless someone is very dedicated, sitting through hundreds of lines of spaghetti code just to figure out how to the endings in some likely mediocre VN work just isn't worth the effort.
Once again, since wanabe cheaters rarely looks at the source code, what left is people who would just grep for the current dialog line, or use some of the available tools, including, but not limited to, the , an embedded trace-like feature that double with some real time edition functionalities.


If you truly want to hide your source for some reason, you're better of choosing another engine (which uses a compiled language) and just distributing executables.
But the question stay: for what reasons ?

And it's not a proprietary Vs Open Source question, but a real one.

What is so important in your code that you feel the need to hide it ?
You are a bad coder ? Welcome, 75% of the scene is like you, you'll feel at home.
You found a new way to do something with Ren'Py ? Please, help improve the scene and share it.
You don't want people to cheat ? It's Ren'Py, anyone can restore the console and cheat like a pig. This without talking about all the players who wait for the walkthrough (mod or text) to be updated.
You don't want people to know the story in advance ? If someone look at the source, it's rarely for this reason.

In the same time, keeping your source available will make life more easy for modders. And this will do good to your game. Not only more people would play it, but you can also pick some of the ideas added by a mod. This will you'll still be the one who get all benefit from this now improved game.
It also help to identify the bugs and then help you to solve them. Once again something that will benefit to you.
And finally there's the translation. If the SDK can't handle your source, it will not be able to generate the translation files. And here too, the one who will benefit from this will be you.
 

Penfold Mole

Engaged Member
Respected User
May 22, 2017
3,118
7,618
I tend to do that already. For an experienced programmer, I feel my code would be easy to follow. For a novice, not so much.
label S0000:
call dataFill
scene black with dissolve
scene image A[1] with pixellate
$ dLine(1,2)
BTW, I don't do it to obfuscate. I do it because it fits how I program.
$ x09 = 0
if "t0500R" in tags:
$ x09 +=4
if "t2700L" in tags:
$ x09 +=2
if "t1000R" in tags:
$ x09 +=1
$ X09 = "y" + str(x09)
if X09 not in tags:
$ tags.append(X09)
call expression X09
Good luck debugging or changing your own code a year after writing such unreadable gibberish.
Experienced programmers write code that is easily readable to anyone and that includes themselves and anyone who might one day try to help them.
Some n00Bs either don't pay attention to readability or even tend to try to obfuscate it and later they will just rewrite it or let someone else to rewrite it from scratch when they realize that their code has become unreadable even to themselves and it becomes an unfixable mess. Or they finally realize how much time they are wasting on trying to read their own code some time after writing it.
 
Last edited:

clowns234

Engaged Member
Game Developer
May 2, 2021
3,090
4,845
Good luck debugging or changing your own code a year after writing such unreadable gibberish.
Experienced programmers write code that is easily readable to anyone and that includes themselves and anyone who might one day try to help them.
Some n00Bs either don't pay attention to readability or even tend to try to obfuscate it and later they will just rewrite it or let someone else to rewrite it from scratch when they realize that their code has become unreadable even to themselves and it becomes an unfixable mess. Or they finally realize how much time they are wasting on trying to read their own code some time after writing it.
I did automation for 40+ years (as an independent contractor for the last 25), and I can walk into any one of those factories and jump right into my code I wrote.
 

Diconica

Well-Known Member
Apr 25, 2020
1,135
1,189
Hi,

So, I have been thinking about this for a while. There are multiple tools available online with which we can see the source code of any renpy game. Even if it's compressed into a .rpa file. I know there's no easy way to create a solution where the code will be invisible, but I was thinking if it's viable to create a script which upon execution mixes the code to a level where it won't be easily understood.
Like, changing function names, variables and class names to random characters. I know something like this is possible for pure python code, but I was wondering if there's something similar for renpy files.
There is no full proof method. Anyone that tells you there is has poor understanding of security.
Microsoft went to pretty good lengths to try and make windows unable to be compiled.
Windows in compiled in C/C++. They compressed a part of the code. Then created a secondary bootstrapper to load that code into memory and then set to an execution pointer to it. Even passwording it didn't prevent it from being decompiled.
I can't remember if it was windows 95 or 98 they started that around. It only took 1 month.

The reason is simple people captured the memory and got the password and copied the live code. Then they just made a file containing all the code and ran a standard decompiler on it. But they couldn't distribute the code without risk. So they made a decompiler that they could distribute.

As long as the code and system for accessing it is run on another person's computer you have no way of preventing it from getting accessed.

What you can do at best is make it hard enough that most people won't waste time with it.
Even if you only leave rpyc files in the game directory. There are scripts like unrpyc that can restore most of them.
To make it harder you would need to use a script to rename all the variables, functions, and classes.
Unfortunately because python is python you can't get rid of the white spaces like you can in other languages.

If you want to beyond that wrap it in cython.

When you do all this you don't do it to your original code you do it to a copy of it in another directory. That way if you do want to a make changes down the road you can.