Tool Ren'Py LiveCheatMaker mod v0.3.3b (browse variables & generate a cheat menu)

5.00 star(s) 1 Vote

agregen

Member
Oct 28, 2019
162
103
1626905307690.png

Version: 0.3.3b
Release Date: 2023-09-06
Ren'Py version: v6.99.13 and above (alt. download: v6.18 and above)
Language: English
Links: ,

So, I've taken a look at Ren'Py Cheat Generator, and I found that while the idea of a generic-purpose cheat maker was good, it has at least two issues: 1) it has extra requirements for the system (being able to run the game is not enough to use the tool), and 2) figuring out which variables need to be updated by the cheat – which is the bulk of the job – is left entirely to the user. Both of which can be resolved if the tool is written as a Ren'Py mod (intended to work with any game, in theory)…

And since that felt like a doable challenge, I hereby present the result of my latest Sunday spent on coding (and a couple more evenings of testing/fixing various issues), which I named LiveCheatMaker.

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

Full readme file is included in the download. Most important part: use [0], [o], [k], [K], [m], or [M] hotkey to toggle the menu (can be changed by editing the file).
Here's also a download for older versions of Ren'Py (v6.18-6.99.12).
(If you have issues with downloading the file, right click on the link and pick “Save as…” option)

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

; I uploaded it as a gallery with text comments for each image as that seemed like the most convenient way of browsing it.

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

Note: keeping the v0.3.3a links as well for now, just in case.

 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,136
14,818
1) With what version of Ren'py is this compatible ?
Regarding Ren'py itself, it stop throwing errors with the 6.99.13, but I'm far to be sure that the compatibility of the pure Python code goes effectively this far.

2) 685 numbers, 58 collections, 154 functions, 179 type...
Wow... Why not limit what you're dealing with to the variables related to the game, and more especially the ones that effectively are significant to the users, those that will be saved ? You don't need to deal with the Ren'Py's internals. In fact, you also don't need to deal with functions, modules and anything that is purely code like curried, transforms and all.
As it is, your tools end being more confusing for the users, because they are flooded by totally useless information that they'll probably don't understand, but see as important since you present them.

3) Got this with too many games to list them
File "game/-LiveCheatMaker.rpy", line 492, in script
label _live_cheat_maker_input(prompt, then, default="", convert=lambda x: x):
Exception: Required parameter then has no value.
Considering that the label is called from a Function screen action built in a method that have then as mandatory argument, it's a pretty impressive error that you achieved to get here. This should just be impossible, yet you achieved to do it :/ Note that it's both reproducible and not reproducible ; it will happen, but it's purely random even when redoing the exact same process.
What fallback to my question at point 1, with what version of Ren'py is this compatible ? There's clearly some that don't complain about the few Ren'py code you use, but still don't like the Python code.

4) renpy.call_in_new_context(_.SHOW)
In addition to be totally useless, because the label just call a method that will call a screen, using a new context risk to make you loose part of the information.

5) I've got a funny track back log when testing the backward compatibility with older version of Ren'py, see the attached file.
The error itself have the same origin than the trace back on point 3. The variable not being provided, Ren'py failed to delete it when it tried to clean the context. What is even more impressive, because it should have thrown the exception when the label is called, not when Ren'py was cleaning after it.
As for the astounding number of reference to the same line, it's due to the fact that you display your menu with renpy.call_screen, but never cared to quit them properly ; in fact I'm not even sure that you quit them. Without the error that effectively triggered Ren'py, I wouldn't have noticed it, but I wonder how many called screens you can stack before Ren'py start to loose its mind.


This being said, the idea is good, and you really should stick to it. But the realization is really to reworks. And I would even say, to restart from scratch.
You're doing in a very complicated way something that is difficult, but not really complicated. By example, you don't need your Var class, and even less your Value one. As for your CustomMenu, a basic list with a goodly designed screen would be enough, in addition to be rollback compliant.
My extended variables viewer track the changes in all variables related to the game, and keep the memory of the last value, with four functions for a total of 126 lines ; what would be reduced to something like 80 lines if wrote in your style. Everything else is the for UI. And I can assure you that you don't need more. In 3 years of existence, in its 2.x version, not once I or its users, encountered a case where it wasn't enough. We caught bugs because of shitty made games, like this one that have a list embedding list up to a depth higher to 27, and leading to a repr of more than 150 000 characters, or really deep circular references in objects, but not once there was a missing value or one that can't be displayed.

Think about it, in less than 1 hour and around 50 games tried, I achieved to throw an exception 23 times ; almost half of the time. I admit that I was search for this to happen, but still it shouldn't have happened so often. Especially since what I was seeking was to see if your code can deal with the second hands bugs that I know, what it do... while failing on something totally different that defy all logic.
Regarding this error, my guess goes for a mix between too many game context, too many stacked called screen, and the fact that most of your code, especially your CustomMenu class, is absolutely not rollback compliant.
And this error, coupled to my last point, make me wonder what problems I haven't caught because they need more time to be effectively triggered than the 1 minute (in average) I dedicated to each test.
 
Last edited:

rambo25

Member
Sep 13, 2020
101
48
Sorry but im a noob at this.could some one explain in a simple easy for some one with no coding knowledge as to how i can download file.when i click on link it opens another page with code wich i have no idea what to do with it.thanks in advance gals/guys/others
 

agregen

Member
Oct 28, 2019
162
103
First of all – if you found errors, can you share which games those were in, instead of being all mysterious about it? Any piece of software has bugs (moreso a quick hack pieced together over a single day), to figure out what can be done about those I need to actually reproduce them first.

1) With what version of Ren'py is this compatible ?
Regarding Ren'py itself, it stop throwing errors with the 6.99.13, but I'm far to be sure that the compatibility of the pure Python code goes effectively this far.
Without modification, it works fine for all Ren'Py versions since v6.99.13 (from 2017) up till the newest one (v7.4.6); with minor modifications (commenting out certain lines in screen definition – see Q&A) it appears to work fine with versions since v6.18 (from 2014). Issues with Python start only with v6.17, as far as I've seen.
On the other hand, it's perfectly possible for the game dev to mess up default Ren'Py settings (for no apparent reason other than “being creative”), so there's no guarantee everything will work at 100% functionality for any particular game (in theory, anyway).

2) 685 numbers, 58 collections, 154 functions, 179 type...
Wow... Why not limit what you're dealing with to the variables related to the game, and more especially the ones that effectively are significant to the users, those that will be saved ? You don't need to deal with the Ren'Py's internals. In fact, you also don't need to deal with functions, modules and anything that is purely code like curried, transforms and all.
As it is, your tools end being more confusing for the users, because they are flooded by totally useless information that they'll probably don't understand, but see as important since you present them.
…I've added a filter to hide unsaved variables (on by default), but I'm not going to lock users out of the option to browse whichever variables they may need.

3) Got this with too many games to list them

Considering that the label is called from a Function screen action built in a method that have then as mandatory argument, it's a pretty impressive error that you achieved to get here. This should just be impossible, yet you achieved to do it :/ Note that it's both reproducible and not reproducible ; it will happen, but it's purely random even when redoing the exact same process.
What fallback to my question at point 1, with what version of Ren'py is this compatible ? There's clearly some that don't complain about the few Ren'py code you use, but still don't like the Python code.
Well I didn't get that with any games so far, so this “too many to list” thing is kinda useless. Name some, will ya?
And as I mentioned, no game newer than 2014 I've tried so far had an issue with Python section of the code (that wasn't fixed yet).

4) renpy.call_in_new_context(_.SHOW)
In addition to be totally useless, because the label just call a method that will call a screen, using a new context risk to make you loose part of the information.
  1. “can't start an interaction without creating new context”
  2. this one was taken directly from the original (Ren'Py Cheat Generator)
  3. Ren'Py docs say this refers to UI context, and that the previous one is restored once this new interaction is completed

5) I've got a funny track back log when testing the backward compatibility with older version of Ren'py, see the attached file.
The error itself have the same origin than the trace back on point 3. The variable not being provided, Ren'py failed to delete it when it tried to clean the context. What is even more impressive, because it should have thrown the exception when the label is called, not when Ren'py was cleaning after it.
…Well, at least there is a name of a game in that traceback (in the folder name). That's actual usable information. Care to tell how you achieved this effect tho?
As for the KeyError: 'then' thing, it indeed shouldn't be possible to happen, as this variable name is only declared in Ren'Py section of the code as a label parameter (thus in theory it should either raise this error always, or never). And no, it shouldn't have thrown an error there because a variable of that name is never created in the code (other than being declared as part of label parameters). Sounds like a Ren'Py bug to me, really…
…I haven't manged to reproduce it, but I suspect it's not gonna happen in the new version, at the very least because I moved all dialog data back into the mod object.

As for the astounding number of reference to the same line, it's due to the fact that you display your menu with renpy.call_screen, but never cared to quit them properly ; in fact I'm not even sure that you quit them. Without the error that effectively triggered Ren'py, I wouldn't have noticed it, but I wonder how many called screens you can stack before Ren'py start to loose its mind.
Dunno about Ren'Py, but last time I checked, Python call stack limit was set to 1000 by default. Either way, good catch, I totally forgot to check what the call stack looks like.
…I fiddled around with code to discard the stacking (which incidentally turned out to require jumping back to the menu label after every interaction).

You're doing in a very complicated way something that is difficult, but not really complicated. By example, you don't need your Var class, and even less your Value one. As for your CustomMenu, a basic list with a goodly designed screen would be enough, in addition to be rollback compliant.
I don't need any inner classes in the first place, but without grouping that code it becomes really messy – which is the reason why I added the grouping after I finished functionality implementation.
And no, a basic list is only good if you have a very small amount of items to deal with. If you take Kingmaker, for example, it has 36 separate skills alone – hopefully you don't think that dumping that many items in the middle of a menu without grouping is a good thing? Not to mention that having to modify all these values one-by-one just because the menu doesn't support grouping them is hardly convenient for the user at all.
So no, I don't think I'm gonna be reducing the code size by means of discarding functionality.

…As for rollback compliance, the only problem I encountered was rolling back from the menu to the last dialogue line and not the one before it (fixed that). If there's anything else, you'll have to provide more specific examples (though if anything, the menu should be ignored by rollbacks… and why single out that piece of code in the first place?). Or rather, for all the issues you want fixed, as merely knowing that they can happen (in certain – unmentioned – circumstances) is rarely enough to actually deal with those.

Think about it, in less than 1 hour and around 50 games tried, I achieved to throw an exception 23 times ; almost half of the time. I admit that I was search for this to happen, but still it shouldn't have happened so often. Especially since what I was seeking was to see if your code can deal with the second hands bugs that I know, what it do... while failing on something totally different that defy all logic.
I can't help but notice you don't seem to list any of those “bugs that you know”… Did none of those come up? Or did you intend for me to discover all of them on my own, since hardship builds character?

And this error, coupled to my last point, make me wonder what problems I haven't caught because they need more time to be effectively triggered than the 1 minute (in average) I dedicated to each test.
I certainly fixed all the errors I encountered so far. Not surprised there's more of those, though the ones you actually described should indeed not even be possible (aside from the call stack thing, that one sounds believable alright).
 

agregen

Member
Oct 28, 2019
162
103
Sorry but im a noob at this.could some one explain in a simple easy for some one with no coding knowledge as to how i can download file.when i click on link it opens another page with code wich i have no idea what to do with it.thanks in advance gals/guys/others
Oh, that's a bug of the site; I believe it thinks this is a text file.

Right click on the link and choose “Save as…” from the popup menu (the actual wording may vary depending on your browser/locale).
 
  • Red Heart
Reactions: rambo25
Jul 22, 2019
247
369
anne O'nymous Ok so I do think you come from a place of genuinely wanting to help the developer. But I personally think it would be of more utility to the developer if you made formal bug reports with descriptions, steps to recreate and then after that maybe recommendations on how to fix the bug. Right now I can't help but sense some "passive-aggressiveness" or "taunt" from your post which is never a good thing :).
 
  • Like
Reactions: agregen

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,136
14,818
First of all – if you found errors, can you share which games those were in, instead of being all mysterious about it?
There's no real meaning in naming games when, as I said, the problem isn't directly linked to them and can't be reproduced by following a given pattern. What is important is what I did, explain why it happen and how to solve it.
Because yes, the explanation and solution are in what I wrote. It's not explicitly said, but it's far to be something difficult to understand for someone with enough knowledge regarding Ren'py to consider making a code that will interact with its internals.


Without modification, it works fine for all Ren'Py versions since v6.99.13 (from 2017) up till the newest one (v7.4.6); with minor modifications (commenting out certain lines in screen definition – see Q&A) it appears to work fine with versions since v6.18 (from 2014).
So, apart from commenting the two scrollbar property that appeared in the version 6.99.13, what does it need for, Babe Runner (6.99.12.4), by example, to have clickable menus ? And it's not the sole 6.99.12.4 game with which I had this issue, just the one I remember right now.


…I've added a filter to hide unsaved variables (on by default), but I'm not going to lock users out of the option to browse whichever variables they may need.
  • There's one, and only one, way to tell if a variable will be saved or not. It's to look at the ever_been_changed store's set. You are not doing it, therefore, at no time your code is able to hide unsaved variables.
  • The menu show us attributes that can not even be saved (Pickles would throw an exception), like the modules by example. Therefore, at no time the filter is "on by default".


  1. “can't start an interaction without creating new context”
  2. this one was taken directly from the original (Ren'Py Cheat Generator)
  3. Ren'Py docs say this refers to UI context, and that the previous one is restored once this new interaction is completed
Documentation regarding : "The call screen statement shows a screen, and then hides it again at the end of the current interaction".
Documentation regarding the function you used: "The screen is hidden at the end of the interaction, [...]".
They both tell why there's the error, and give you a strong lead regarding how to solve it.


Care to tell how you achieved this effect tho?
I said it in my initial comment.

There's no precise steps to follow, and it don't explicitly depend of the game. Just pass enough time wandering in your menu, going up and down, searching value, adding some, that's all.
It's a pure structural flaw in your tool. And like any pure structural flaw, whatever if it's a piece of code wrongly designed, or a steel pillar with a crack, there's no path to it, it will happen at one time, dot.


As for the KeyError: 'then' thing, it indeed shouldn't be possible to happen, as this variable name is only declared in Ren'Py section of the code as a label parameter (thus in theory it should either raise this error always, or never). And no, it shouldn't have thrown an error there because a variable of that name is never created in the code (other than being declared as part of label parameters). Sounds like a Ren'Py bug to me, really…
If it was a due to Ren'py, a game like Super Powered, that massively rely on label arguments (since near to 5 years that it's Ren'py version exist) and have thousands of players for each updates, would have triggered it a long time ago. And like it's far to be the sole game codded that way, the problem would be known and solved since a long time.

What is happening is a fatal combination between the lack of rollback compliance of your CustomMenu class, and the fact that you create a new context each time the user click. You are using objects that can only evolve in the future, to handle attributes that can evolve both in the future and in the past.
And it happen that each time that Ren'py finally return from a context, those attributes are reverted to their value in this context ; a value that can be "do not exist at all". In the same time, the CustomeMenu objects that host them stay the exact same, hosting attributes that should have disappeared because, in term of game context, they are coming from a future that never existed.
It's not a problem for the attributes themselves, being rollback compliant they are designed to deal with this. It's also not a problem for the prompt argument, because it rely on information that are independent of the context ; either because not rollback compliant themselves, or because they come from the top level context. But it become a problem for the then argument, because suddenly it refer to something that never existed in the current context. What lead to the error.

And, this is just the verbose version of what I already said in my first comment.


Dunno about Ren'Py, but last time I checked, Python call stack limit was set to 1000 by default. Either way, good catch, I totally forgot to check what the call stack looks like.
Well, back to the documentation and the two lines I already quoted. The screen is shown, then Ren'py wait the end of the interaction before hiding it. There's, in this, an explicit implication that there's no stack behind it, because there's just no need for it.


…I fiddled around with code to discard the stacking (which incidentally turned out to require jumping back to the menu label after every interaction).
Each time you're creating a new context, you are creating a whole copy of the game context inside the actual (copy) of the game context. It's another form of stacking.
By the way, jumping to called labels imply that you are totally messing with the return stack. The only thing saving the user from a forced return to the main screen is the fact that each stack is forgot once Ren'py return from a context.

And all this for a problem that could have been solved by one 10 characters long line and the use of the right function. All you needed to do is to put modal True at the start of your screen, then use renpy.show_screen, that's all.


And no, a basic list is only good if you have a very small amount of items to deal with.
Fuck, near to 40 years of coding that I have to throw to the trash can.

A list can be as good as any other structure to handle large amount of data. Simply because the structure matter less than the algorithm using it. It doesn't mean that a list is always the best solution, but it will always be a better solution than an over complicated option.


If you take Kingmaker, for example, it has 36 separate skills alone – hopefully you don't think that dumping that many items in the middle of a menu without grouping is a good thing?
You understand the difference between his and your list, right ?
In your tool, the only information that are relevant are the information at the actual level. What mean that the grouping is already performed naturally by the algorithm.

But anyway, your whole thing could have been handled with two lists, small, and absolutely no objects. For what would probably have been less than 200 lines:
[It's wrote on the fly, so it's to be seen as a structure more than an effective code, but really, there's absolutely no need for more complex.]
Code:
def openObject( attr, name ):
    store.pathToNow.append( ( name, attr, level_list ) )
    store.baseName += "."+name
    store.baseAttr = attr
    store.level_list = [ e for e in attr.__dict__ ]
    renpy.show_screen( "myScreen" )

def throwMeBack():
    store.baseName, store.baseAttr, store.level_list = pathToNow.pop()
    renpy.show_screen( "myScreen" )

define allActions = { "type": openObject, "int": addToMenu, [... ] }

screen myScreen():
    modal True
    vbox:
        hbox:
            text "[baseName]"
            textbutton "back" action throwMeBack
            textbutton "close" action Hide( "myScreen" )

        viewport:
            for e in level_list:
                if matchFilter( e ):
                    $ attr = getattr( baseAttr, e )
                    $ kind = str( type( attr ) )[7:-2]
                    textbutton "[e] [[kind]":
                        action Function( allAction[kind], attr, name )
The only thing to effectively change is the assignation for kind. It would be easier to have a function that will return a more abstract value, than having to deal with the effective type of the attribute. But as I said, this show the structure more than the code.
And really, in the case of your menu, there's no real need for anything more complex. Just extend throwMeBack if you want to handle list/dict as a list of entries. And take care of the first level, that take it's entry from the ever_been_changed set.
Everything else is totally useless in your code, because totally useless for a cheat menu generator.



I can't help but notice you don't seem to list any of those “bugs that you know”… Did none of those come up?
The answer was in the sentence where I talked about them:
"to see if your code can deal with the second hands bugs that I know, what it do..."



But I personally think it would be of more utility to the developer if you made formal bug reports with descriptions, steps to recreate and then after that maybe recommendations on how to fix the bug.
My report was explicit enough for anyone having enough knowledge regarding Ren'py to consider interacting with its internal mechanisms. And, interacting with Ren'py's internal mechanisms is what this tool do.

It happened that I was overestimating, and I'm sure that now you see an even greater level of passive-aggressiveness in my answer that can be summarized by: RTFM
 

agregen

Member
Oct 28, 2019
162
103
There's no real meaning in naming games when, as I said, the problem isn't directly linked to them and can't be reproduced by following a given pattern. What is important is what I did, explain why it happen and how to solve it.
Because yes, the explanation and solution are in what I wrote. It's not explicitly said, but it's far to be something difficult to understand for someone with enough knowledge regarding Ren'py to consider making a code that will interact with its internals.
“I gave a proper bug report, it's just implicit.” Er… What?
What you did write is a claim that you did some (entirely undescribed) manipulations which resulted in errors. Which is – as I mentioned – not quite helpful at all.

So, apart from commenting the two scrollbar property that appeared in the version 6.99.13, what does it need for, Babe Runner (6.99.12.4), by example, to have clickable menus ? And it's not the sole 6.99.12.4 game with which I had this issue, just the one I remember right now.
(Whoa, an actual example…)
I suspect that the issue in question is specific to the game (problems caused by global styles, as mentioned in Q&A), and based on description alone I'm pretty sure it's due to the button having zero width (which doesn't stop the text from rendering – probably due to layout overflow): I encountered a case like that yesterday.
Either way, that particular issue was fixed in yesterday's release (and yes, I checked just now if the buttons work in this particular game (they do)).

  • There's one, and only one, way to tell if a variable will be saved or not. It's to look at the ever_been_changed store's set. You are not doing it, therefore, at no time your code is able to hide unsaved variables.
  • The menu show us attributes that can not even be saved (Pickles would throw an exception), like the modules by example. Therefore, at no time the filter is "on by default".
…Condescending wording aside, you clearly didn't bother looking at the new code of the yesterdays release which I was talking about. And I'm guessing you haven't even noticed that there was a new release in the first place, judging from your answer.

Also, while there's some truth to this (as ever_been_changed is indeed used in determining what gets saved), it's not the only way to obtain that list (and not even the most convenient one). …Incidentally, it also doesn't show all in-game variables that get saved – only those that would be saved in the current game state (which is another reason I decided against hardcoding this filter: it's perfectly possible for the game dev to introduce variables in such a way that they don't get added to savefile until their first change from initial value).

Documentation regarding : "The call screen statement shows a screen, and then hides it again at the end of the current interaction".
Documentation regarding the function you used: "The screen is hidden at the end of the interaction, [...]".
They both tell why there's the error, and give you a strong lead regarding how to solve it.
This is some superb inability at reading text you're showing here…
Either that, or your idea of responding involves quoting the text and giving an entirely unrelated response to it.

I said it in my initial comment.

There's no precise steps to follow, and it don't explicitly depend of the game. Just pass enough time wandering in your menu, going up and down, searching value, adding some, that's all.
It's a pure structural flaw in your tool. And like any pure structural flaw, whatever if it's a piece of code wrongly designed, or a steel pillar with a crack, there's no path to it, it will happen at one time, dot.
Incredible. “Your code is bad, so you will stumble upon it eventually if you use it.” Don't tell me you actually believe that I never tried running the code that I wrote, or that I hadn't fiddled with it more than a tiny bit to see if it actually works.
(Also: did you perhaps mean “period”? The word ‘dot’ has no applicable meaning in that context.)

If it was a due to Ren'py, a game like Super Powered, that massively rely on label arguments (since near to 5 years that it's Ren'py version exist) and have thousands of players for each updates, would have triggered it a long time ago. And like it's far to be the sole game codded that way, the problem would be known and solved since a long time.
You… don't sound like someone familiar with bugs, or large software in general.
FYI: not all bugs come up immediately in a code related to them in some way; some only happen randomly and in rare specific circumstances. They still are bugs though.

What is happening is a fatal combination between the lack of rollback compliance of your CustomMenu class, and the fact that you create a new context each time the user click. You are using objects that can only evolve in the future, to handle attributes that can evolve both in the future and in the past.
And it happen that each time that Ren'py finally return from a context, those attributes are reverted to their value in this context ; a value that can be "do not exist at all". In the same time, the CustomeMenu objects that host them stay the exact same, hosting attributes that should have disappeared because, in term of game context, they are coming from a future that never existed.
It's not a problem for the attributes themselves, being rollback compliant they are designed to deal with this. It's also not a problem for the prompt argument, because it rely on information that are independent of the context ; either because not rollback compliant themselves, or because they come from the top level context. But it become a problem for the then argument, because suddenly it refer to something that never existed in the current context. What lead to the error.

And, this is just the verbose version of what I already said in my first comment.
First of all. “[Y]ou create a new context each time the user click[s ]”. That statement is false, and/or you don't quite understand what you said here. Did you not read my code properly? Or do you have your own definition of “context” which doesn't match the Ren'Py one (and which you abstained from describing before using)?

Second. Judging from what you say about “rollback compliance”, I'm positive you're also either using your own personal definition of the word, or you misunderstand the Ren'Py term. Because “rollback“ of Ren'Py has nothing to do with what's happening in the code you're talking about.

Third. What in the blazes does CustomMenu class have to do with input/confirm dialogs?! It contains data and functions for in-memory representation of the custom menu; no part of it has anything to do with user input itself.

…And of course, no matter how you (mis)explain it, buggy behaviour remains buggy behaviour.

Well, back to the documentation and the two lines I already quoted. The screen is shown, then Ren'py wait the end of the interaction before hiding it. There's, in this, an explicit implication that there's no stack behind it, because there's just no need for it.
0_o
I dunno what method of interpretation you used to read the docs, but your third sentence in this paragraph directly contradicts the second one (and is also blatantly wrong, as this is exactly the place where the stack is being used).

Each time you're creating a new context, you are creating a whole copy of the game context inside the actual (copy) of the game context. It's another form of stacking.
By the way, jumping to called labels imply that you are totally messing with the return stack. The only thing saving the user from a forced return to the main screen is the fact that each stack is forgot once Ren'py return from a context.
…So you don't understand how this works, huh. Hell, you didn't even notice a tautology in your own statement (which kinda renders it nonsensical).
I'm just gonna say that no, call_screen does not create a new context (it's actually a regular, singular function call – which is where stacking in the old version of the code comes from), and no, jumping does not mess with “return stack” (specifically because it's done in the new context – the one created explicitly during the opening of the menu after hitting [k]).

And all this for a problem that could have been solved by one 10 characters long line and the use of the right function. All you needed to do is to put modal True at the start of your screen, then use renpy.show_screen, that's all.
(What are you doing?! Don't give direct pointers, it kills all of the mystery you so carefully built up!)
I've tried both of those already – together and separate; but regardless of what I did to the code, replacing call_in_new_context and/or call_screen with show_screen resulted in the screen immediately closing… which kinda matches the description of these commands in the docs… or, occasionally, in breaking UI interaction altogether.

Fuck, near to 40 years of coding that I have to throw to the trash can.
…Yanno… I've seen this exact claim fairly recently… And this time I'm having the same strong urge to respond in fashion similar to the talker's and question what exactly he spent all that time doing if he has so little understanding of the trade he's supposedly got lots and lots of experience in.
(And no, I haven't had much insight into your software development ability so far, but the attempt of asserting your authority instead of addressing the statement is telling… not to mention annoying.)

A list can be as good as any other structure to handle large amount of data. Simply because the structure matter less than the algorithm using it. It doesn't mean that a list is always the best solution, but it will always be a better solution than an over complicated option.
Oh, I get it now. You didn't actually understand the first thing about my code, and got it in your head that I created a bunch of custom data structures to represent whichever data I need instead of using ones provided by the language.

Well, the answer is no, that never happened. The “classes” in there are specifically for namespacing functions (and the few related data values). Both variable names and menu items are stored and processed as plain Python data. The “objects” I'm using to access them are merely convenience interfaces (again, namespacing, not gratuitous OOP nonsence).

You understand the difference between his and your list, right ?
In your tool, the only information that are relevant are the information at the actual level. What mean that the grouping is already performed naturally by the algorithm.


…What are you even talking about?
Judging from the context, you seem to be referring to the variable lookup here – but it has zero releveance to any data structures you were talking of before, as it's not stored anywhere other than immediate rendering information (i.e. as UI buttons data for the current menu window state). CustomMenu is only related to, well, custom menu (as in, the part that is customized by the user, as opposed to being generated at runtime based on game state and user input).
Also, while I'm guessing that the “level” is depth of variable being inspected, I've got no damn clue what “grouping” (and by which “algorithm”) you're referring to here. Is it grouping-by-type which happens in exactly one place in the whole menu? But what does it have to do with current topic of discussion?

But anyway, your whole thing could have been handled with two lists, small, and absolutely no objects. For what would probably have been less than 200 lines:
[It's wrote on the fly, so it's to be seen as a structure more than an effective code, but really, there's absolutely no need for more complex.]

[…]

The only thing to effectively change is the assignation for kind. It would be easier to have a function that will return a more abstract value, than having to deal with the effective type of the attribute. But as I said, this show the structure more than the code.
And really, in the case of your menu, there's no real need for anything more complex. Just extend throwMeBack if you want to handle list/dict as a list of entries. And take care of the first level, that take it's entry from the ever_been_changed set.
Everything else is totally useless in your code, because totally useless for a cheat menu generator.
…Alright, I'll ignore how you're barbarically polluting global namespace in what's supposed to be a mod intended for any game whatsoever, and will simply give the same response as the last time over: I'm not gonna reduce the code size by means of discarding functionality.

And, to elaborate, here you seem to be reverting to the thing I was talking of back then (which is clearly unrelated to what you responded to it with above… so this change back is somewhat unexpected): you're both a) oversimplifying the interface (at the cost of UX), and b) suggesting to discard functionality that is convenient for some users at the very least simply because you, personally, for whatever reason don't consider it particularly useful.

The answer was in the sentence where I talked about them:
"to see if your code can deal with the second hands bugs that I know, what it do..."
Unfortunately as I'm male, I can't speak in the tongue of implications. Me, being the brute I am, needs a straight and unambiguous answer: does this “what it [did]” mean “no, you looked for those issues but only the ones actually named came up and you talked about that large list of potential bugs for no good reason”, or “yes, there were some but you only care about those other things you encountered”?

My report was explicit enough for anyone having enough knowledge regarding Ren'py to consider interacting with its internal mechanisms. And, interacting with Ren'py's internal mechanisms is what this tool do.
You're repeating yourself. Did you like this particular sentence that much? (Also, as mentioned before, at least half of it was less of a report and more of an abstract rambling which contained no tangible, usable information.)

It happened that I was overestimating, and I'm sure that now you see an even greater level of passive-aggressiveness in my answer that can be summarized by: RTFM
Well, this response of yours – the final sentense at the very least – clearly does indeed contain an indirect insult wrapped into a wee tad of pathos. Which is kind of ironic as it also attepts to imply (by means of sarcasm) that your response is completely level-headed. (And your response to “you're not being helpful” is also ironic, as you switch between showing lack of understanding of the topic, and insisting that not being helpful is “the way”.)

And yes, I realise this second response of mine gets visibly sarcastic at times, but it certainly does feel like an appropriate level here.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,136
14,818
“I gave a proper bug report, it's just implicit.” Er… What?
What you did write is a claim that you did some (entirely undescribed) manipulations which resulted in errors. Which is – as I mentioned – not quite helpful at all.
I described and explained what I did, and also explained why the exact step process is totally useless. The fact that you don't like it, or don't understood it, doesn't mean that it's not helpful. As I said, what matter is the reason of the bug, and the way to solve it. I gave you both.

After, it's you who decided, I don't care. There's tons of buggy software all around the world, and it never prevented people to use them. In fact, most of the time they just think it's normal, not seeing this as a bug, but as the result of their wrong use.
 

agregen

Member
Oct 28, 2019
162
103
…New release: v0.3.1.
Replaced boolean input (for current value editing) with a toggle button. Also added input hints for quick values in menu editor (mainly for booleans).
 

zhausJack

Newbie
Apr 29, 2017
65
57
This script are amazing, and definitely deserve more love.
In first not worked for me, but after some pokes, (changed TOGGLE_KEY = 'k' to TOGGLE_KEY = '0' [zero]), worked like a charm, and i have no idea why. Just telling of for someone with same trouble.
You are breathtaking dude ♥.
1641556539776.png
 
  • Like
Reactions: agregen

agregen

Member
Oct 28, 2019
162
103
This script are amazing, and definitely deserve more love.
In first not worked for me, but after some pokes, (changed TOGGLE_KEY = 'k' to TOGGLE_KEY = '0' [zero]), worked like a charm, and i have no idea why. Just telling of for someone with same trouble.
You are breathtaking dude ♥.
View attachment 1584488
Why, thank you… By now I was wondering if I've missed something crucial about usefulness of the mod :D
…I was also meaning to make cheat menus with it for some games that could use those (like Lab Rats 2) but I had little time for games lately.

As for your problem – did it happen with one game, or multiple? Which one(s)? Or did you have a non-latin keyboard layout? (Caps Lock?)
Superb way of handling it, BTW :) All settings were placed to the top of the file so that they could be adjusted easily if need be (like UI_LAYER which I've mentioned in Q&A section); though most of them are GUI parameters.
 
Last edited:
  • Like
Reactions: zhausJack

zhausJack

Newbie
Apr 29, 2017
65
57
Why, thank you… By now I was wondering if I've missed something crucial about usefulness of the mod :D
…I was also meaning to make cheat menus with it for some games that could use those (like Lab Rats 2) but I had little time for games lately.

As for your problem – did it happen with one game, or multiple? Which one(s)? Or did you have a non-latin keyboard layout? (Caps Lock?)
Superb way of handling it, BTW :) All settings were placed to the top of the file so that they could be adjusted easily if need be (like UI_LAYER which I've mentioned in Q&A section); though most of them are GUI parameters.
My keyboard layout, is latin, but not the spainish one, i'm from Brazil, we have an own type, (kbdlayout.info/KBDBR/)
I making test in games, old and new versions...

Games who worked at default set so far:

PaprikaTrainer-1.1.0.5
SuperPowered_v0.44.00(even modded)
HaremHotel-v0.14
TakeOver-0.44-pc

Games who not worked in TOGGLE_KEY = 'k', (don't know why), and worked with zero so far:

AstralLust-0.2.1c
LewdTownAdventures-0.9.2

Strange special case are iNSight_Of_You, v0.9b worked from first, but v0.10 need set TOGGLE_KEY = '0'. It was because of this game that I started poking at the code, because it didn't make sense to work on the old one but not the new one.

My difficulty when dealing with sub-menus was exactly moving a variable into this one. For example: I found the variable 'a', a shortcut to it in the main menu, then I created the sub-menu 'b'. Now, to put the variable 'a' in the sub-menu 'b' through the edit menu is a bit confusing. Even now, after having done this several times, it still gets complicated. My suggestion would be to add a "put in - (and list the created sub-menus)", or put information in the text above saying "variable 'a' selected" when trying to move , maybe both.

Finally, a utility that would be interesting would be to "freeze" the value of a variable, like cheat engine does, preventing the value of a variable from being incremented or decremented, perhaps setting a default value every time an event accesses it.
 

agregen

Member
Oct 28, 2019
162
103
My keyboard layout, is latin, but not the spainish one, i'm from Brazil, we have an own type, (kbdlayout.info/KBDBR/)
I making test in games, old and new versions...

Games who worked at default set so far:

PaprikaTrainer-1.1.0.5
SuperPowered_v0.44.00(even modded)
HaremHotel-v0.14
TakeOver-0.44-pc

Games who not worked in TOGGLE_KEY = 'k', (don't know why), and worked with zero so far:

AstralLust-0.2.1c
LewdTownAdventures-0.9.2

Strange special case are iNSight_Of_You, v0.9b worked from first, but v0.10 need set TOGGLE_KEY = '0'. It was because of this game that I started poking at the code, because it didn't make sense to work on the old one but not the new one.
If it works with some games but not the others, then it's not a system-wide thing; my off-hand guess would be that these games bind [k] to some action (or something to the effect). Since there's no guarantee for any (bindable) key that some or other game won't bind it, I suppose custom-editing is the only real choice here. …Well, I could also try adding an option to change it in the menu, but if you can access it you don't really need it :D

My difficulty when dealing with sub-menus was exactly moving a variable into this one. For example: I found the variable 'a', a shortcut to it in the main menu, then I created the sub-menu 'b'. Now, to put the variable 'a' in the sub-menu 'b' through the edit menu is a bit confusing. Even now, after having done this several times, it still gets complicated. My suggestion would be to add a "put in - (and list the created sub-menus)", or put information in the text above saying "variable 'a' selected" when trying to move , maybe both.
Adding directly to a selected submenu… well, that would take some effort to implement; I'll think of it though.
Displaying the name of the variable (or possibly of the menu item) being moved sounds doable alright; I'll probably get to it when I have time to do some coding.

Finally, a utility that would be interesting would be to "freeze" the value of a variable, like cheat engine does, preventing the value of a variable from being incremented or decremented, perhaps setting a default value every time an event accesses it.
I haven't used Cheat Engine but my guess is it overrides new value whenever the selected bytes in memory are changed by the game… I could try implementing this but it might have some unpleasant side-effects depending on how Ren'Py reacts to such invasive behaviour (and possibly on which variable is being force-reverted); it's also unclear how this will (or should) interact with save/load mechanism. Bottom line is, if I implement it, it'll still be a highly experimental feature…
Also, not sure if I can make this agree with boolean menu items, UX-wise. (I haven't touched this in a while but IIRC the current version doesn't have a submenu for editing saved booleans, toggling them instead upon selection.)
 
  • Like
Reactions: zhausJack

agregen

Member
Oct 28, 2019
162
103
…New release: v0.3.2.
Added extra toggle keys (the entire 0-o-k-m key column, with K and M uppercase added; didn't add O as it's the dev console binding).
Also added information to display in Edit mode: menu item currently being relocated (previously simply marked window title with *), and the name of the saved variable (previously only displayed the value).
 
  • Like
Reactions: zhausJack

agregen

Member
Oct 28, 2019
162
103
…New release: v0.3.3.
Had an idea for a quick “add a var into a submenu” implementation: create a regular var menu item, then switch to Edit mode and select said menu item for relocation. (You can also do any other desired edits while you're at it – like setting up quick update & range bar. The downside is, after you're done editing there's no direct shortcut to go back to the variable search view. fixed in patch v0.3.3a)
 
Last edited:
  • Like
Reactions: zhausJack

zhausJack

Newbie
Apr 29, 2017
65
57
…New release: v0.3.2.
Added extra toggle keys (the entire 0-o-k-m key column, with K and M uppercase added; didn't add O as it's the dev console binding).
Also added information to display in Edit mode: menu item currently being relocated (previously simply marked window title with *), and the name of the saved variable (previously only displayed the value).
Hello Agregen, how are you? Well I've been out of time for games after the last few posts but here I am again. About the shortcuts error, I was looking more calmly now, and I saw that the problem was never your code, as it always occurs with games that are not written in regional character standards, (not unicode), it seems like something in that game code is missing. The game can't even start. I can't explain, I didn't understand anything about python at the time, (nor now), but I'm thinking about learning, not just renpy, but the python itself. Just out of curiosity, do you know why this happens?
Here the bug happening again:
 

X3gold

New Member
Oct 6, 2017
11
16
Hello Agregen, how are you? Well I've been out of time for games after the last few posts but here I am again. About the shortcuts error, I was looking more calmly now, and I saw that the problem was never your code, as it always occurs with games that are not written in regional character standards, (not unicode), it seems like something in that game code is missing. The game can't even start. I can't explain, I didn't understand anything about python at the time, (nor now), but I'm thinking about learning, not just renpy, but the python itself. Just out of curiosity, do you know why this happens?
Here the bug happening again:
This is due to the renpy version I just unzipped the rpa data and opened with the renpy SDK and see if it works with my version. For me it is renpy 7.4.11 if it works, I recreated the project as Win in my case, then copied the data from livecheatmaker into it and it worked.
 
  • Like
Reactions: zhausJack
5.00 star(s) 1 Vote