Mod Ren'Py Universal Ren'Py Mod / URM [2.2.1] (mod any Ren'Py game yourself)

5.00 star(s) 33 Votes

Obiyo

Member
Aug 5, 2016
233
466
Freeze option always disabled on my part. Tried on few games even with simple "money" and "energy" value can't be enabled.
Right now I'm using CE for long run to freeze most value eventhough it is quite a hassle with pointers and so on.
 
  • Angry
Reactions: Iorinari

0x52

Ren'Py Magician
Modder
Donor
Game Developer
May 23, 2019
1,593
6,038
That was my original understanding, as I've previously altered values (money, stats, etc.) in other games without incident. No such luck with this particular game (Shut Up & Dance) however. I have tried multiple times using multiple saves. The values are fine for the current session, but when I restore from a save they're back to default.


View attachment 2609141


View attachment 2609142
The dev probably reinitialized the characters every game start. In this case you should just use URM's renaming feature.

Hello
Motivated to play more with the tool and its features now
and taking a ride on the questions above I ask:
Is it possible to list all the labels of a game where the URM is installed without conflicts? If yes, how should I proceed please.



View attachment 2610660

View attachment 2610661

View attachment 2610671



; FOM (Foot of Mountain) - see query print:




Obviously in the game no there are only 11 records for "ann", 3 for "rhonda" and nothing (none) for "melinda". What am I missing and not "seeing" here?
And yes my goal at the moment (besides renaming) is mainly to visualize scenes from the game itself (complete and functional) where the URM is well installed.
No need to unzip or extract anything. Just list.

thanks in advance
If I understand correctly you want to list all labels in a game?
You can do that by using "Wildcard search" (the W at the right top) and searching for *. Like this:
1683733730143.png

Freeze option always disabled on my part. Tried on few games even with simple "money" and "energy" value can't be enabled.
Right now I'm using CE for long run to freeze most value eventhough it is quite a hassle with pointers and so on.
You mean the "Freeze" and "Monitor" headers are red in the "Variables" tab? (stating it failed to initialize)
Which games? which OS?
 

Obiyo

Member
Aug 5, 2016
233
466
You mean the "Freeze" and "Monitor" headers are red in the "Variables" tab? (stating it failed to initialize)
Which games? which OS?
Game : A Very Full House / W10.
Most of the variable can't be frozen.
Maybe I'm doing it wrong. Also this is not gamebreaking to me as the tool works flawlessly. Just a little bit inconvenience after some time I had to input the value manually.
Untitled.png
 
  • Angry
Reactions: Iorinari

0x52

Ren'Py Magician
Modder
Donor
Game Developer
May 23, 2019
1,593
6,038
Game : A Very Full House / W10.
Most of the variable can't be frozen.
Maybe I'm doing it wrong. Also this is not gamebreaking to me as the tool works flawlessly. Just a little bit inconvenience after some time I had to input the value manually.
View attachment 2611093
Aah... those are properties of variables and cannot be frozen (might be possible in the future).

There something about this kind of variables in the FAQ:
1683744049524.png
 

jasad

Active Member
Dec 14, 2021
768
595
View attachment 587373

Overview:
Easiest installation, open mod by pressing Alt+M

This mod is a great tool to cheat or debug Ren'Py games. See full Features list below for details.

Some features in short:
Find, change, freeze and monitor variables, detect hidden choices, detect paths, rename any character, find/save/replay scenes, watch variables, skip splashscreen

Updated: 2023-05-10
Game/Creator: Any Ren'Py game using Ren'Py engine 6.99.14 or newer
Modder: 0x52 -
Mod Version: 1.14.1

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

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

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

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

After developing Ren'Py mods for almost a year now. I thought is was time to create the mod of all mods.
So here is what I call URM (or Universal Ren'Py Mod). The goal of this mod is to enable anyone (even without any programming knowledge) to be able to quickly and easily mod any Ren'Py game.
Just drop the mod file into your favorite game's "game" directory and start modding!

Please let me know what you think. I really appreciate any feedback, so I know I'm not doing this for nothing.
Or maybe consider supporting me or .

WARNING!
You could break your game modifying any variable. Use at your own risk!
Breaking the game depends on the game's programming. You could create set of values the game doesn't expect. Which for example could prevent you to progress in the game or miss certain scenes. I would recommend saving before modifying. So you could always go back if something unexpected happens.


Screenshots:
View attachment 1083993 View attachment 2227883 View attachment 1083995 View attachment 1083998 View attachment 1556197 View attachment 1084000 View attachment 1781739 View attachment 2477575


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

Download:
or Attachment below​
thx for the update~ :giggle:
 

yamabear

Member
Dec 27, 2020
208
93
New videos? The last is from December, the first from March 2020 :D

Sorry,
But the only video) reference of the mod that I was aware of here at f95zone was this one


These ''old'' for you (of course.kkk) for me they are brand new and a pleasant surprise.Very much. :cool:
 

abrabunny2023

New Member
Jan 19, 2023
7
4
0x52, this is a great tool, thanks for sharing it!

I had a couple of suggestions after using it and taking a look at the source code.

This is the expected behavior.
Without wildcard search it searches whatever contains linda. If you wanted the same result with wildcard search you would have to search for *linda*. (if you want everything that ends with linda you would search *linda)
In other words; wildcard search searches for exact matches, unless you use a wildcard of course.
For wildcard searches, is there a specific reason why you made it so that *<term>* is necessary for searching for variables that contain <term>? From the source code, you're using regex on the query and restricting it by surrounding the query with ^ and $ to denote start and end of string. I think it would probably be better to use the query as-is for wildcard search since it is more intuitive and more flexible.

Also, restricting support to only * and ? for wildcard/regex characters limits advanced searches (e.g. most variables that start with __ in python are implementation details that are irrelevant when modding). Full regex in the query would make it easy to get all variables and exlude those that start with __, just use the query: ^(?!__).*$.

On that note, it would be good to have such variables (those that start with __) excluded by default from the results (e.g. __name__, __package__, etc). Maybe you can have an additional search option to show/hide them? You could probably expand this to python's built in types/functions (str, xrange, python_set.__doc__, etc.) so that URM excludes them by default and makes it easier to find relevant variables.

One final suggestion that would be nice to have is sorting the results alphabetically - this would make it easier to jump between pages when there are multiple pages of results (e.g. when searching for all variables).

Just wanted to bring up some thoughts I had while using the tool and hopefully help make this even better. Not sure what your policy is on having others contribute but I could probably attempt updating the code to address some of this stuff if it helps.

Please don't take this as complaining or saying the tool is bad because it is really awesome! Makes it very easy to mod a lot of games :)
 

abrabunny2023

New Member
Jan 19, 2023
7
4
Aah... those are properties of variables and cannot be frozen (might be possible in the future).
Haven't had a chance to look into how you currently handle frozen variables, but there's a simple way to freeze variables that will work regardless of whether the variable is in a class, dict, or in globals() via destructors and a helper class.

Basic idea is to replace current value with a wrapper class. Whenever the value is changed, the wrapper class is destroyed. During class destruction, call into a helper class which will check whether the variable should still be frozen, and if so, it just re-assigns the old value wrapped by a new wrapper class.

I made a POC for int, you could easily adapt this to float, str, bool, etc.
See code paste . Password:
You don't have permission to view the spoiler content. Log in or register now.
 

Dksdncoias

New Member
May 13, 2023
5
4
Hi, I got a weird error whilst trying to save a urm file so that i don't have to constantly manually search the variables, and I got this.
While running game code:
File "game/script.rpy", line 23147, in script call
call outcastto
File "game/script.rpy", line 23860, in script
ym "Since you don't have the necessary {color=#ff696999}100{/color} Arkhe to acquire a new house, you were forced to wander the colony..."
File "renpy/common/00nvl_mode.rpy", line 383, in do_display
**display_args)
File "game/0x52/classes/loader.rpy", line 20, in saveDir
TypeError: object of type 'NoneType' has no len()

-- Full Traceback ------------------------------------------------------------

Full traceback:
File "game/script.rpy", line 23147, in script call
call outcastto
File "game/script.rpy", line 23860, in script
ym "Since you don't have the necessary {color=#ff696999}100{/color} Arkhe to acquire a new house, you were forced to wander the colony..."
File "renpy/ast.py", line 921, in execute
renpy.exports.say(who, what, *args, **kwargs)
File "renpy/exports.py", line 1373, in say
who(what, *args, **kwargs)
File "renpy/character.py", line 1266, in __call__
self.do_display(who, what, cb_args=self.cb_args, dtt=dtt, **display_args)
File "renpy/common/00nvl_mode.rpy", line 383, in do_display
**display_args)
File "renpy/character.py", line 666, in display_say
rv = renpy.ui.interact(mouse='say', type=type, roll_forward=roll_forward)
File "renpy/ui.py", line 299, in interact
rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
File "renpy/display/core.py", line 3377, in interact
repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, pause=pause, pause_start=pause_start, pause_modal=pause_modal, **kwargs) # type: ignore
File "renpy/display/core.py", line 3810, in interact_core
root_widget.visit_all(lambda i : i.per_interact())
File "renpy/display/core.py", line 582, in visit_all
d.visit_all(callback, seen)
File "renpy/display/core.py", line 582, in visit_all
d.visit_all(callback, seen)
File "renpy/display/core.py", line 582, in visit_all
d.visit_all(callback, seen)
File "renpy/display/core.py", line 582, in visit_all
d.visit_all(callback, seen)
File "renpy/display/screen.py", line 451, in visit_all
callback(self)
File "renpy/display/core.py", line 3810, in <lambda>
root_widget.visit_all(lambda i : i.per_interact())
File "renpy/display/screen.py", line 462, in per_interact
self.update()
File "renpy/display/screen.py", line 653, in update
self.screen.function(**self.scope)
File "0x52/screens/vars.rpy.x52", line 270, in execute
File "0x52/screens/vars.rpy.x52", line 270, in execute
File "0x52/screens/vars.rpy.x52", line 283, in execute
File "0x52/screens/main.rpy.x52", line 278, in execute
File "0x52/screens/main.rpy.x52", line 278, in execute
File "0x52/screens/main.rpy.x52", line 288, in execute
File "0x52/screens/main.rpy.x52", line 296, in execute
File "0x52/screens/main.rpy.x52", line 301, in execute
File "0x52/screens/main.rpy.x52", line 312, in execute
File "0x52/screens/main.rpy.x52", line 313, in execute
File "0x52/screens/vars.rpy.x52", line 283, in execute
File "0x52/screens/vars.rpy.x52", line 295, in execute
File "0x52/screens/vars.rpy.x52", line 299, in execute
File "0x52/screens/vars.rpy.x52", line 299, in keywords
File "0x52/screens/vars.rpy.x52", line 299, in <module>
File "game/0x52/classes/loader.rpy", line 20, in saveDir
File "/home/tom/ab/renpy-build/tmp/install.linux-x86_64/lib/python2.7/ntpath.py", line 65, in join
File "/home/tom/ab/renpy-build/tmp/install.linux-x86_64/lib/python2.7/ntpath.py", line 115, in splitdrive
TypeError: object of type 'NoneType' has no len()
 

0x52

Ren'Py Magician
Modder
Donor
Game Developer
May 23, 2019
1,593
6,038
0x52, this is a great tool, thanks for sharing it!

I had a couple of suggestions after using it and taking a look at the source code.



For wildcard searches, is there a specific reason why you made it so that *<term>* is necessary for searching for variables that contain <term>? From the source code, you're using regex on the query and restricting it by surrounding the query with ^ and $ to denote start and end of string. I think it would probably be better to use the query as-is for wildcard search since it is more intuitive and more flexible.

Also, restricting support to only * and ? for wildcard/regex characters limits advanced searches (e.g. most variables that start with __ in python are implementation details that are irrelevant when modding). Full regex in the query would make it easy to get all variables and exlude those that start with __, just use the query: ^(?!__).*$.

On that note, it would be good to have such variables (those that start with __) excluded by default from the results (e.g. __name__, __package__, etc). Maybe you can have an additional search option to show/hide them? You could probably expand this to python's built in types/functions (str, xrange, python_set.__doc__, etc.) so that URM excludes them by default and makes it easier to find relevant variables.

One final suggestion that would be nice to have is sorting the results alphabetically - this would make it easier to jump between pages when there are multiple pages of results (e.g. when searching for all variables).

Just wanted to bring up some thoughts I had while using the tool and hopefully help make this even better. Not sure what your policy is on having others contribute but I could probably attempt updating the code to address some of this stuff if it helps.

Please don't take this as complaining or saying the tool is bad because it is really awesome! Makes it very easy to mod a lot of games :)
Long story short. You would like to have a regexp search option? That's already on my todo list (see here)
And for your other suggestion, sorting on the search tab is also on my todo list (see here).

Haven't had a chance to look into how you currently handle frozen variables, but there's a simple way to freeze variables that will work regardless of whether the variable is in a class, dict, or in globals() via destructors and a helper class.

Basic idea is to replace current value with a wrapper class. Whenever the value is changed, the wrapper class is destroyed. During class destruction, call into a helper class which will check whether the variable should still be frozen, and if so, it just re-assigns the old value wrapped by a new wrapper class.

I made a POC for int, you could easily adapt this to float, str, bool, etc.
See code paste . Password:
You don't have permission to view the spoiler content. Log in or register now.
Unfortunately this approach will break saves. And I think it might cause even more issues aside from that.

as the videos are mentioned :

some ppl asked me for an updated "rename" video
as its from the very beginning of the tool

...so if you got time :cool:

edit :
i made an attempt - see if its good enough 0x52
Thanks. But the renaming still works exactly the same right? It's only a new design?
I do want to make a new "full tour" video at some point.

Hi, I got a weird error whilst trying to save a urm file so that i don't have to constantly manually search the variables, and I got this.
While running game code:
File "game/script.rpy", line 23147, in script call
call outcastto
File "game/script.rpy", line 23860, in script
ym "Since you don't have the necessary {color=#ff696999}100{/color} Arkhe to acquire a new house, you were forced to wander the colony..."
File "renpy/common/00nvl_mode.rpy", line 383, in do_display
**display_args)
File "game/0x52/classes/loader.rpy", line 20, in saveDir
TypeError: object of type 'NoneType' has no len()

-- Full Traceback ------------------------------------------------------------

Full traceback:
File "game/script.rpy", line 23147, in script call
call outcastto
File "game/script.rpy", line 23860, in script
ym "Since you don't have the necessary {color=#ff696999}100{/color} Arkhe to acquire a new house, you were forced to wander the colony..."
File "renpy/ast.py", line 921, in execute
renpy.exports.say(who, what, *args, **kwargs)
File "renpy/exports.py", line 1373, in say
who(what, *args, **kwargs)
File "renpy/character.py", line 1266, in __call__
self.do_display(who, what, cb_args=self.cb_args, dtt=dtt, **display_args)
File "renpy/common/00nvl_mode.rpy", line 383, in do_display
**display_args)
File "renpy/character.py", line 666, in display_say
rv = renpy.ui.interact(mouse='say', type=type, roll_forward=roll_forward)
File "renpy/ui.py", line 299, in interact
rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
File "renpy/display/core.py", line 3377, in interact
repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, pause=pause, pause_start=pause_start, pause_modal=pause_modal, **kwargs) # type: ignore
File "renpy/display/core.py", line 3810, in interact_core
root_widget.visit_all(lambda i : i.per_interact())
File "renpy/display/core.py", line 582, in visit_all
d.visit_all(callback, seen)
File "renpy/display/core.py", line 582, in visit_all
d.visit_all(callback, seen)
File "renpy/display/core.py", line 582, in visit_all
d.visit_all(callback, seen)
File "renpy/display/core.py", line 582, in visit_all
d.visit_all(callback, seen)
File "renpy/display/screen.py", line 451, in visit_all
callback(self)
File "renpy/display/core.py", line 3810, in <lambda>
root_widget.visit_all(lambda i : i.per_interact())
File "renpy/display/screen.py", line 462, in per_interact
self.update()
File "renpy/display/screen.py", line 653, in update
self.screen.function(**self.scope)
File "0x52/screens/vars.rpy.x52", line 270, in execute
File "0x52/screens/vars.rpy.x52", line 270, in execute
File "0x52/screens/vars.rpy.x52", line 283, in execute
File "0x52/screens/main.rpy.x52", line 278, in execute
File "0x52/screens/main.rpy.x52", line 278, in execute
File "0x52/screens/main.rpy.x52", line 288, in execute
File "0x52/screens/main.rpy.x52", line 296, in execute
File "0x52/screens/main.rpy.x52", line 301, in execute
File "0x52/screens/main.rpy.x52", line 312, in execute
File "0x52/screens/main.rpy.x52", line 313, in execute
File "0x52/screens/vars.rpy.x52", line 283, in execute
File "0x52/screens/vars.rpy.x52", line 295, in execute
File "0x52/screens/vars.rpy.x52", line 299, in execute
File "0x52/screens/vars.rpy.x52", line 299, in keywords
File "0x52/screens/vars.rpy.x52", line 299, in <module>
File "game/0x52/classes/loader.rpy", line 20, in saveDir
File "/home/tom/ab/renpy-build/tmp/install.linux-x86_64/lib/python2.7/ntpath.py", line 65, in join
File "/home/tom/ab/renpy-build/tmp/install.linux-x86_64/lib/python2.7/ntpath.py", line 115, in splitdrive
TypeError: object of type 'NoneType' has no len()
What OS are we talking about? Is it with all games? Please check the "reporting an issue" section in this post.
 
  • Like
Reactions: Boehser Onkel

abrabunny2023

New Member
Jan 19, 2023
7
4
Unfortunately this approach will break saves. And I think it might cause even more issues aside from that.
I *may* have taken that as a challenge ;). I decided to try my hand at implementing it by building upon your recent 1.14.1 release.

I uploaded the final result of my attempt to mod your mod (mod-ception? meta-mod?) .

Changes:
  • Use my wrapper class approach for freezing variables.
    • Any int, float, or string variable can be frozen. Frozen variables may change value momentarily when the game updates it, however they will return to the old frozen value within a few seconds (exact timing depends on python's garbage collection).
    • I've tested it and there are no issues with saving to/loading from save files when using the new variable freeze implementation
  • Added Regex support
  • Hide Ren'py/python internal variables by default (can toggle on/off via search options). Currently only hides variables starting with "_" as well as python & Ren'py reserved variable names
    • When searching for all variables via * this significantly improves search performance
  • Added full name search option - this allows you to search for class properties using the dot syntax (e.g. can now search for player.points)
  • Added search exclude field. Can now exclude results that start with a given prefix.
    • Exclude field takes a space separated list of prefixes to filter search results
    • E.g. can now search for all variables (* with wildcard/regex enabled) and use exclude field to eliminate all results that start with "menu" or "zoom" by setting exclude to menu zoom

I did this mostly as an exercise to see if it could be done (I had/still have no familiarity with Ren'py) so I'm surprised I made as much progress as I did.

From my limited testing, everything works without problems. Please try it out and if you like it, feel free to incorporate these changes back into the original mod! (Don't have high expectations for code quality - I hacked stuff together so it may not be the most efficient or readable).


Note: I would have sent this as a DM/PM but I have no clue how to do that on this forum...
 

headhunter32

Member
May 15, 2018
148
161
did a previous version worked?
are you running the game with admin rights?
have you tried a different drive to install the game?
(i recommend this , especially for steam)
Yes
Yes
Yes

I tried all the above.

Its the first time i seen this kind of error, ad the moment testing it on the non steam version.
 
Last edited:
  • Thinking Face
Reactions: Boehser Onkel
5.00 star(s) 33 Votes