Cheat Mod Ren'Py Rogue-Like Cheat Injector [v1.5.2] [SLDR]

sleepingkirby

Active Member
Aug 8, 2017
721
1,098
If someone know how to do Graphic Interface Applications and want to help me,
we could do app that generates cheats.

I mean the app where you put screen name, script to edit and edited script.
Would be even simpler than editing renpy files with python code.
It's not exactly my forte, but it's something I can do. I'm just not sure the motivation for having a GUI. These mods almost have to be done per game and making a GUI for something that's a one off is kind of expensive an waste of resource. When I mod these myself, I usually write a bash script that prompts for user input (using linux here).

Actually, you know what? Let me finish this coding challenge (doing this for a job application) first and then I'll download your mod and take a look at it. It may make sense if you're looking to auto generate an injector with custom code and do it for windows users who don't know how to use command prompt or powershell [ick]. Give me a day or two and I'll get back to you.
 

sleepingkirby

Active Member
Aug 8, 2017
721
1,098
Okay, I've scanned through the cheat injector (good job for not being a coder btw). I'm still not sure what the motivation for a GUI is. It seems you've done a good job in isolating the initializer from the functional logic. Short of a script to find and extract it into the proper place, I'm not sure there's anything a GUI can add to this that really isn't already there.

Like, if I were to improve this, there's only a few things I would do.

1) the initializer (__injector__.rpy) reads/executes another file. That file contains a list of files to explicitly find and execute in the proper order. This can also be done by making reading an directory where the files themselves are named in numeric order to maintain execution order. Like:
01_inventoryscreen.rps
02_charcter.rps
By making this middle man, the initializer (aka __injector__.rpy) can stay the same. All the logic for doing the actual changes that will change per game/version can just be dropped on top without a problem.

2) Provide the logic to download new version of the decompiler if needed.

3) More descriptive names for variables. Just like S0='\n' would be nl='\n' (nl is short for 'newline'). Not a big deal now, but as code grows, good variable names can prevent a lot of headaches.


Also, always provide comment in code where the original came from/credit the original creator. i.e. credit SLDR in code comments. Even if the new work is so different that it's nearly unrecognizable from the original. Without the original work, you (the general you, not the specifically you) would have never even thought to make said thing. Us programmers don't mind people reusing our ideas/code. We, however, demonize those that do and pretend it's their idea. These things take time, effort and heart. To pretend someone magically did it on their own without help, that's the real form of piracy most of us actually care about.


With that said, I'm not opposed to jamming out a GUI if you want it. I can extract the bones of it from my traditional chinese dictionary. It's just I don't know what to build if I don't know the motivation/goal.
 

ZLZK

Member
Modder
Jul 2, 2017
293
771
Okay, I've scanned through the cheat injector (good job for not being a coder btw). I'm still not sure what the motivation for a GUI is. It seems you've done a good job in isolating the initializer from the functional logic. Short of a script to find and extract it into the proper place, I'm not sure there's anything a GUI can add to this that really isn't already there.

Like, if I were to improve this, there's only a few things I would do.

1) the initializer (__injector__.rpy) reads/executes another file. That file contains a list of files to explicitly find and execute in the proper order. This can also be done by making reading an directory where the files themselves are named in numeric order to maintain execution order. Like:
01_inventoryscreen.rps
02_charcter.rps
By making this middle man, the initializer (aka __injector__.rpy) can stay the same. All the logic for doing the actual changes that will change per game/version can just be dropped on top without a problem.

2) Provide the logic to download new version of the decompiler if needed.

3) More descriptive names for variables. Just like S0='\n' would be nl='\n' (nl is short for 'newline'). Not a big deal now, but as code grows, good variable names can prevent a lot of headaches.


Also, always provide comment in code where the original came from/credit the original creator. i.e. credit SLDR in code comments. Even if the new work is so different that it's nearly unrecognizable from the original. Without the original work, you (the general you, not the specifically you) would have never even thought to make said thing. Us programmers don't mind people reusing our ideas/code. We, however, demonize those that do and pretend it's their idea. These things take time, effort and heart. To pretend someone magically did it on their own without help, that's the real form of piracy most of us actually care about.


With that said, I'm not opposed to jamming out a GUI if you want it. I can extract the bones of it from my traditional chinese dictionary. It's just I don't know what to build if I don't know the motivation/goal.
It's work in progress, I'll probably work on it till I'll finish it.
The code of injector is mine, I did regex myself.
I searched in ren'py code and find a way to get file scripts from the game itself, myself.
And I made code that can use it, myself.
The only part that it's not mine—and injector is depending on—is the unrpyc decompiler, which is free to use.

You don't have permission to view the spoiler content. Log in or register now.

The app is not necessary, it would be just a simpler way to make rpl/rps files.
And ofcourse, those can be just done in text editor instead.

Have here the latest version of my injector.

I've also made extractor that extract all labels/screens from the game.
(After launching, all labels/screens from the game are extracted to 'game/ZLZK/' as a txt files.
After extracting, folder 'decompiler' and 'scripts' are removed
from 'game/ZLZK/' folder and the game won't open this time.)
For you to be able to get the text that you want to edit.
 
Last edited:

sleepingkirby

Active Member
Aug 8, 2017
721
1,098
*Edit: I've downloaded your new versions and see that you've included credits. Which makes what I wrote previously almost completely void. Just make sure that the LICENSE file is also included as part of the decompiler. This will cover any stray files that doesn't have the license at the top of the file. (like util.py)*



The app is not necessary, it would be just a simpler way to make rpl/rps files.
And ofcourse, those can be just done in text editor instead.
Just out of curiosity, how did you plan to use an app to automatically generate .rps/rpl files for different games? Or did you plan to just generate it for rogue-like?
 
Last edited:

ZLZK

Member
Modder
Jul 2, 2017
293
771
*Edit: I've downloaded your new versions and see that you've included credits. Which makes what I wrote previously almost completely void. Just make sure that the LICENSE file is also included as part of the decompiler. This will cover any stray files that doesn't have the license at the top of the file. (like util.py)*





Just out of curiosity, how did you plan to use an app to automatically generate .rps/rpl files for different games? Or did you plan to just generate it for rogue-like?
I don't even know if there is even a point in making those comments, because finally I will use compiled files that are striped from comments to make it run faster.

I didn't plan on any auto updating files. Because after injecting, all injecting scripts are deleted with a single use.
Only newly generated rpy files out of rpl/rps files remain that are the cheat/mod itself,
and to remove them you just need to delete 'ZLZK' folder from 'game' folder.

The app would be just for people that want to do injector files for a game.

Yeah, I can do injector for any game with any cheat/mod, but so do you.
I especially made it in that way that anyone can use my injector to apply theirs modifications to ren'py games.
It's just another way of applying modifications to original rpy files.
Which I made it very universal or I think that way.
It should work on any operating system,
because I made it in ren'py and python,
which are used in every ren'py game.

And I did this injector, because I didn't ever seen internal injectors,
every other was external, like the one from this thread that is only for windows.

So the only thing now to do is for you users to test it
on different games and on different systems and report any bugs to me.

The question is if my injecting is that good, and if it really is easier to apply.

Doing my injector I tried to edit game files the least I could.
So injector only edit Label/Screen part of the file that you want to edit
and place it in a new rpy file, and it doesn't reuse whole files like others do.
Because seriously, it's so sloppy to just edit original files and post them.

To update cheats/mods injected by my injector,
you need to remove them from the 'game/ZLZK' folder
in case if new version doesn't include all the Labels/Screens used before,
and unzip injector again.
(I guess I could just add option to remove them before injecting,
but not sure if that is right thing to do.)

I was working on auto updating,
but there is no simple way to detect changes in the game and it's so stupid to try to.
Because what's the point of checking every time you launch the game if there is a change in it.
It's just unnecessary. I decided that you would need to reinject it manually.

The cheats/mods made via my injector should work in a new game versions.
But they are depended on Label/Screen name and the part being edited.
So if those would get changed, you would need to update your cheat/mod.

(This function is only in older version of injector.)
(In newest version you probably need to inject it again with every game update.)
So what's better? Single inject that doesn't leave injector,
or injecting every time you launch the game?
I don't like the second option, because game will always run with libraries
that are no longer needed after launch, but they will be open in ram for nothing.
For me and this game it is ~10% more use in ram by game, and it doesn't go away until you close the game.
Alternative is to detect if game needs another injecting, but this takes also ram
and I don't even have a good way to do it anyway.
So I chose manual injecting over auto.

So my injector is just a tool for mod developers of ren'py games,
to apply their work into a game.

And this game was just a testing ground.
So if the author of this thread doesn't wish
for his work to be used through my injector,
then I can just remove it from here.
But originally I just wanted for thread author to use my injector too or just to include it in his thread.
But didn't got any reaction from him, and now it doesn't matter to me anymore.
 
Last edited:

sleepingkirby

Active Member
Aug 8, 2017
721
1,098
I don't even know if there is even a point in making those comments, because finally I will use compiled files that are striped from comments to make it run faster.
You plan to open source whatever you make, right? Because if, one day, like SLDR, life gets too busy or something, if you only release the compiled bytecode, it'd be a pain to decompile (yeah, there are decompilers out there. But it's still a pain for a lot of reason that's too long to get into). Especially if the work you're doing is dependent off of an open source tool, for an game with an open source engine but you yourself don't open source it. Doubly so if you're forced to use a decompiler but will force someone, one day, to decompile your work to extend/support it. (And this is why I use the GNU GPL when I open source stuff. It states that you have to open source anything derived from my open source work.)

I'm not a python expert (imo, the language was a solution to a problem that was already solved.) But the bytecode compile of python doesn't save you much more time because all interpreted python code gets compiled to bytecode at some point and then ran, last I read. Feel free to correct me if I'm wrong. And if that's the case, the compilation of something that is, by your explicit intent and design, to be small and minimally invasive, you're saving milliseconds at best.

I didn't plan on any auto updating files. Because after injecting, all injecting scripts are deleted with a single use.
Only newly generated rpy files out of rpl/rps files remain that are the cheat/mod itself,
and to remove them you just need to delete 'ZLZK' folder from 'game' folder.
The updater isn't for the perpetual use cases. It's for if someone a) got and older version b) new cheat files are out c) using a version with and old/outdated version of the decompiler. So if you don't have your own repository or trusted source for people to download from, and someone downloads an old copy, the script, on first run, will ensure the latest version is available for the latest version of the game. Heck, even my *nix version will look a copy of rpatool and auto download the latest version.

The app would be just for people that want to do injector files for a game.

Yeah, I can do injector for any game with any cheat/mod, but so do you.
I especially made it in that way that anyone can use my injector to apply theirs modifications to ren'py games.
If just you want an GUI for other people to utilize/make their own injector, which will most likely require some coding on their part, a .bat file or .sh file will suffice. There's very little to be gained from a GUI program that a prompt from a script can't do. That's also leaving things like how GUI programs can be aged out. (ESPECIALLY on windows machines. Doubly so now that ms is trying to shorten the cycle between windows versions AND pushing win11) What we program now (as in which GUI library to use), windows might decide to change or not support in the future. .bat scripts use commands that windows itself still uses to function. And shell scripts have been around since before windows was even a thing.

It's just another way of applying modifications to original rpy files.
Which I made it very universal or I think that way.
It should work on any operating system,
because I made it in ren'py and python,
which are used in every ren'py game.

And I did this injector, because I didn't ever seen internal injectors,
every other was external, like the one from this thread that is only for windows.
It is universal in that the injector you made is simply taking advantage of a property of ren'py, which is that it will look for, and run any .rpy files it sees. Which is why I kept calling on of your file the "initializer". Because you have 1 file that initializes your entire code base.

You don't see internal injectors because if it's part of the game/download of the game (i.e. internal), it doesn't need to be injected. If you can place a .rpy file into the game, you can do injection (hence the beauty of open source. Free modification.). As long as someone need to download a file *outside* of the original game files, it is an external injector. The GUI you're asking about will be the external injector. Anytime you're adding files to a game, you're injecting. Basically, unless your injector is included in every ren'py game, it requires the same work for the end user to do:
1) Download your files
2) unzip it into the proper place.
3) Run the game once and hope the modification worked and worked properly.
And this is the exact same procedure I go through to use un.rpyc.
The only additional thing you can supply that is universal is a hook that allows other people to put in their scripts that modifies the game file. In which case, it's easier and often cleaner to just skip step 3 and just drop in a pre-edited .rpy. Because, you know, it's open source.

So my injector is just a tool for mod developers of ren'py games,
to apply their work into a game.
If they're mod developers, they're going to have to code. In which case, the GUI doesn't make much of a difference. That's also ignoring that a lot of mods include new assets. Which needs to be in the right location. Or they need to modify dialogue (walkthrough mods). Which, your injector won't look for or cover (and really, it shouldn't.).

I think the rest of your post is covered by what I've said above so I won't go into them one by one. But also, like you know ren'py has a developer console, right?

Like, I was going to say that if you want to build a true "internal injector" the best way would be not to write to files, but something that modifies in memory. That way, the original game file doesn't need to be changed, you don't have to worry about writing files out, scanning, conflicts, etc. But then I remembered that developer consoles exist. Like, if there was a way (there probably is, I haven't looked.) to create an in-game trainer from the developer console, that'd be cool and helpful.

Also, when I write my own cheats, I usually (rogue-like's the exception) prefer not to modify anything in game. I usually add a menu option as part of the right-click/save menu that gives me my cheat options. (I can probably do more, but I have no desire to learn python... *sigh*... again.) But if I'm reading your code right, it wouldn't give the option for something like that. Adding the menu option, yes. Making my own menu, no.
 

ZLZK

Member
Modder
Jul 2, 2017
293
771
I was planning on making thread and placing credits there.
And both version of my work, source and compiled.
But really why would you want source, when the only files
that you ever need to make/edit are rpl/rps files,
and those aren't compiled.

Online updater: I don't know anything about it and it's not for me to do.

GUI was just idea to shorter time in doing zip file,
but yeah you can do it manually with text editors and archive compressors.

You got that right, that's exactly how it works in my recent version.
It generates rpy files, because I thought it would be more convenient.

But my older version doesn't. Because ren'py can load script from string.
But HOW IS THAT DIFFERENT than using file, when you load same script???

And the files doesn't get changed in any way. Additional file/script just override loaded script from original file.
So it does the same thing anyway, it's just different method of doing the same thing.

What you are saying is possible, to do injector that do
online check on cheat version and ingame check on game version,
and update/inject if it requires, but that's just too troublesome to make
and you can just do it manually once in a while, what is that bad about it?

And you said that my injector won't be good with (walkthrough mods) or such,
but you just said yourself that you just need to put rpy file.
So why you are not aware that you can also use rpy files with my injector?
I even did so with my latest version posted above.

My injector is for changing small part in a bigger part.
The rest you can do separate, it won't collide.
So you can merge my injector with mods,
to get the best results, which is what I'm aiming for.

And as I said it's work in progress, for now I got my own experience with injector,
but if no one else will share theirs experiences, then how can I came up with better solutions.

I just want to make what works best, and all other potentially good, troublesome,
time consumable things are just waste of my time, when I just need what I need.
Which is collection of people experiences.

If someone have such a inventions in mind, you are free to them yourself.
And only then bring them up for others to try them.

So I have made new method of applying changes to ren'py games trough only python.
If someone is not ok with it, fine just don't use it then.

You always can do, what others always do, which is editing original files.
Takes longer, get broken after update, but gets the job done
for actual version, which is all that matters to you.

So, to sum up my experience:
1. I need to do injector that stays as long valid as possible.
(Which is already what I have done,
because I don't see any other way to do it.)
2. To inject it the least often.
(I could work a little bit more on it.)

But now comes realistic aspect of it.
Don't you download new game every update?
So what's the point in updating injector
when you need to put injector in a game again anyway.

And by doing so old version injector generates updated files from updated game.
So, as you can say, I already covered most of it.
I do practical not theoretical.
And it's always my goal to make my work available for as many people as possible.

By the way, I still don't even know if my injector works
on other operating systems than windows.
And if it works when you don't have administrator privileges.
Because new version of it add removing files, with is mandatory.
I mean if the files won't get removed the game will never open. XD

Those are the things that I might have to work on,
but I can't if won't let me now of them.
 
Last edited:

NeoStarr

Member
Jul 2, 2017
344
333
My Python Injector add this option.
From cheats2 version onwards.
That's for letting me know. I downloaded cheat4 though I don't know how to inject it. Also can this be injected to a game already injector with the files from the OP? What I initially attempted btw was putting the files in _ZLZK_ in the base folder of the game. I've been reading comments though and think I placed them wrong
 

ZLZK

Member
Modder
Jul 2, 2017
293
771
That's for letting me know. I downloaded cheat4 though I don't know how to inject it. Also can this be injected to a game already injector with the files from the OP? What I initially attempted btw was putting the files in _ZLZK_ in the base folder of the game. I've been reading comments though and think I placed them wrong
It's folder sensitive.
You need to put _ZLZK_ folder in 'game' folder.
It can be injected on injected game, it will just override it.
Actually you need to remove cheats with batch file, before using my injector.
 
Last edited:

sleepingkirby

Active Member
Aug 8, 2017
721
1,098
How can you open bat archives in Mac?
Bat archives? You mean like .bat files? They're not archives. They batch scripts. AKA text files containing MS DOS commands. If you're on a mac, and you want to apply the same cheats, you'd have better luck with the linux version I wrote than the windows version.
 

Cramone

Member
May 14, 2018
263
88
Bat archives? You mean like .bat files? They're not archives. They batch scripts. AKA text files containing MS DOS commands. If you're on a mac, and you want to apply the same cheats, you'd have better luck with the linux version I wrote than the windows version.
All bat files are txt with MS DOS command???
 

sleepingkirby

Active Member
Aug 8, 2017
721
1,098
All bat files are txt with MS DOS command???
Not absolutely all, but like 99% of the time, yeah. Try to open it in a text editor, notepad, etc. and you'll see the commands.
 
Last edited:

IamfuckinGod

New Member
Aug 24, 2021
2
0
Which OS are you on and what's the error message? I'm on linux so I can't reproduce. My linux version still works fine.
Windows, I haven't gotten an error message but it just doesn't show up as "Cheats Activated" when the game is opened.

I redid it and this text shows up ( on a fresh install )

"Creating rpatool...

Searching for RPA packages
+ Unpacking "archive.rpa" - 172417091 bytes

Cleaning up temporary files...

Creating cheat...
Access is denied.
Exception calling "ReadAllText" with "1" argument(s): "Could not find file
'C:\Users\-me-\Downloads\Rogue-Like-0.996c-win\Rogue-Like-0.996c-win\_cheat.py.tmp'."
At line:1 char:5
+ & { [IO.File]::WriteAllBytes("C:\Users\-me-\Downloads\Rogue-Like-0.9 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: ( : ) [], MethodInvocationException
+ FullyQualifiedErrorId : FileNotFoundException

C:\Users\-me-\Downloads\Rogue-Like-0.996c-win\Rogue-Like-0.996c-win\lib\windows-i686\python.exe: can't open file 'C:\Users\-me-\Downloads\Rogue-Like-0.996c-win\Rogue-Like-0.996c-win\_cheat.py': [Errno 2] No such file or directory

Cleaning up temporary files...
Could Not Find C:\Users\-me-\Downloads\Rogue-Like-0.996c-win\Rogue-Like-0.996c-win\_cheat.py.tmp
Could Not Find C:\Users\-me-\Downloads\Rogue-Like-0.996c-win\Rogue-Like-0.996c-win\_cheat.py"

If I doxed myself than oops
 

sleepingkirby

Active Member
Aug 8, 2017
721
1,098
Windows, I haven't gotten an error message but it just doesn't show up as "Cheats Activated" when the game is opened.

I redid it and this text shows up ( on a fresh install )

"Creating rpatool...

Searching for RPA packages
+ Unpacking "archive.rpa" - 172417091 bytes

Cleaning up temporary files...

Creating cheat...
Access is denied.
Exception calling "ReadAllText" with "1" argument(s): "Could not find file
'C:\Users\-me-\Downloads\Rogue-Like-0.996c-win\Rogue-Like-0.996c-win\_cheat.py.tmp'."
At line:1 char:5
+ & { [IO.File]::WriteAllBytes("C:\Users\-me-\Downloads\Rogue-Like-0.9 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: ( : ) [], MethodInvocationException
+ FullyQualifiedErrorId : FileNotFoundException

C:\Users\-me-\Downloads\Rogue-Like-0.996c-win\Rogue-Like-0.996c-win\lib\windows-i686\python.exe: can't open file 'C:\Users\-me-\Downloads\Rogue-Like-0.996c-win\Rogue-Like-0.996c-win\_cheat.py': [Errno 2] No such file or directory

Cleaning up temporary files...
Could Not Find C:\Users\-me-\Downloads\Rogue-Like-0.996c-win\Rogue-Like-0.996c-win\_cheat.py.tmp
Could Not Find C:\Users\-me-\Downloads\Rogue-Like-0.996c-win\Rogue-Like-0.996c-win\_cheat.py"

If I doxed myself than oops
So SLDR's .bat files does this pretty cool thing where it actually writes/create a python script that does the actual modding work. Apparently, the .bat file doesn't have/isn't ran with access to create directory and/or the script it needs to run. I would double check the ownership, read/write/read only/etc. permissions of the directory that the .bat file is running in. Also make sure you're running the script with enough permissions to actually write to the directory. I've stopped using windows at home since 7 so I can't tell you where to look, but my brief time with 10 tells me MS setup a bunch of stuff where you have to tell windows basic thing for it to actually execute things like an OS actually should.