Wow, amazing reply, seriously.
[Note: I'll sometimes talk about my own mods. It's not to brag about them, but because they are practical examples, and the examples that, obviously, I know the most.]
This is your first option for modding RenPy games. Replace the original script files with your own. [...] Save files will be incompatible.
A precision on this point, because it happen often that, when a patch is released in a game thread to fix whatever issue with the current update, it's under this form. The save incompatibility isn't something that will happen every time. Therefore, it's generally safe to use one of these patches.
Here's a list, probably none exhaustive, of the potential problems with such method :
Be noted that all this don't apply only for modders and patchers. (Too) many game authors release updates matching one of those points.
This is your second option for modding. Replace the whole game with a version of your own. [...] Save files will be incompatible.
But if you did it right the save incompatibility will start only once the player started to play your version. Therefore, even if it's not necessarily recommended since you can have made changes prior to this point, a player can use his save files from the original game when playing your version for the first time.
I do some work with the full knowledge that it might not be used...
... but that you'll still learn a lot doing it. You in fact learn more that if you were working on your own project, because you have to understand what the original author did, and to works with his way to do it, that possibly isn't yours. Therefore, you quit was is your comfort zone, and start to use things that you never had to care for before.
Still, the experience sucked some of the fun of helping people out it for me - so I do a lot less these days.
Don't.
I don't talk especially about this person, but there will always be some "idiots" too entitled to their own works, or thinking that they can't be wrong. My own path crossed some of them, but... well, I did what I can, if they want to continue to have a bugged, impossible to maintain after a given amount of works, to hard or long to develop game, it's their problems, not mine.
It sometimes suck when the game was promising, but as I said, I did what I can, and so you did.
The problem with my approach so far has been that the resulting "improved" version is incompatible with the original. The advantage is that it's a lot easier than the alternative.
I tend to disagree with the "easier" thing.
Yes, creating my mod for Corruption needed a lot of time, around two weeks without counting the time to create the tools I use. It's more than what I would have had to use to do it by altering the original code. But once this initial works is done, I can release an update of the mod at most one day after the game was leaked here. Simply because I only need few hours to do it.
Unlike with an alteration of the original code, I don't have to care about the change prior to this version, whatever they are a text correction or an effective change into the code. This unless, obviously, it directly affect a part I modded. Which make my works way easier since I don't have to either apply my changes again to the original, or to import the changes made in the original into my version.
For this game there's even times where I just have to write: "Well, this update don't need that I also update my mod". Therefore, it took what ? 30 minutes of my time to looks at a diff of the update and previous version. This while a mod made by alteration of the original code would still need that you add the content of the update and release a new version of the mod.
I need more time for my mod for Super Powered, because the mod do way more complex things, but globally I still need less than 2 days while some of the mods for this game need a week to be updated.
As for my mod for Rogue Like: evolution, it's a really small thing, but apparently it still works more or less despite the fact that I haven't updated it since probably more than two years.
But this don't necessarily is a suitable option for everyone. Coding is my job, I started doing is when I was around 15 in the mid 80's, and at some time I had a formation in reverse engineering and used it at work. All this help me a lot to mod this way and make it natural for me to just "hook" to the original game.
Firstly, there's something called config.label_overrides
.
What this does is allow you to effectively rename existing labels.
Or, perhaps more explicit for some readers, it's principal interest while modding is to hijack the game flow. While playing, the game will pass through your own label, in place of the label from the original code. Then you can, or not, decide to let Ren'py go back to the said original label. Which mean that either you totally changed the behavior of a label, or just added yourself on top of it.
The latter is one of the way I track seen scenes in my Super Powered mod. I use
config.label_overrides
to hijack the flow, and let my mod know that the player passed this point, then go back to the original label for the scene to be played. In short, I use it just to add a, "you've been here", information.
So this is your third options for modding. Effectively replacing one block of code with another using config.label_overrides
.
I'm not impartial, but it's the option I recommend, unless the wanted changes are as big as those wanted by OP ; here it's mod a "fan version" than an effective mod.
This option present the advantage to be save compatible as long as you don't save the objects used by your mod ; so you need to be creative on the save part. You player can add your mod to the game without the need to restart a new game, as well as he can remove the mod and still continue without problem from his last save. He can use the mod with one update, then not the next one, to finally use it again latter, all this without problems if you did it right.
If the original game rarely uses label {name}:
statements, you may need to duplicate large sections of the original.
Depending of what you want to do, it's not always needed. Ren'py translation feature permit to replace one dialog line by more than one dialog line, and there's way to totally remove (so not even have an empty say box) a dialog line without editing the original code. But the last option is more for advanced modders ; not that it's difficult by itself, but if you don't understand what you do, it can lead to problems.
[...] therefore reduces the chance that your save files will be incompatible. [...]
Which is the most important point that a modder should keep in mind. Whatever the way you mod a game, as long as it's just a mod and not a "fan version",
the save files should be 100% compatible with an unmodded version of the game.
Any label (and therefore section of the code) can be targeted.
Totally not recommended if you don't totally know what you're doing, but this imply that you can
also change Ren'py behavior since part of the core is wrote in Ren'py language.
This method requires a greater understanding of what the original game does and how it does it. But end results are only limited by your own imagination.
More globally, it's the whole Ren'py modding concept that is only limited by your own imagination.
As I said above, it's possible to totally remove a dialog line, and I used it in my Super Powered mod to change many of the in game notifications. They are initially a narrator dialog line, which mean that they are displayed on the "say box" and that the player have to click to advance the game. With the mod, they are notifications that appear in the top or middle of the screen, and automatically disappear after few seconds. As for what was "regular" notifications, they were
renpy.notify
kind of notification, and they now pill up, either at the bottom of the screen, or at the top of the "say box" depend if the said box is present of not. And all this without editing a single line of the original source code and 100% save compatible with the unmodded game.
It's not always easy to do, I needed a full week-end to achieve the dialog-like notification replacement, but globally speaking everything is possible as long as you have an idea regarding how if should be done. And if the none intrusive approach fail, you can fall back to the "fan version" and directly edit the original code.
Python:
[...]
define config.label_overrides = {
"start": "myrepl_start",
"myrepl_start_END": "start"
}
An advice for future, and some already established, modders: Whatever if you add a label or screen, hijack a label or screen, add a variable or a class, always prefer the use of explicitly prefixed, or suffixed, names. My variables, classes, labels and screens all are named "AONsomething" ; or put in an unreachable place, but it's something else. This way, the names will be unique and you'll be sure to never conflict with either the original code or another mod that happen to be compatible with yours.
It can be your initials like for me, or something obviously unique, like the "79" suffix used by 79flavors.
Oh, also, you don't need the
define
.
config.label_overrides
is already defined by Ren'py, so something like :
Code:
init 1 python:
config.label_overrides["somelabel"] = "AONsomelabel"
would works fine.
config.say_menu_text_filter
allows you to specify a function that is called every time a bit of dialogue is shown in-game. The dialogue can be changed before it is shown (or not).
And, as it name imply, it also apply for menu choice.
My mod for Bondage Island use it to add the location of each girl in the main navigation menu. So, it would be a long works, and sometimes need some additional computations, but it can be used for a none intrusive walkthrough mod by example.
I borrowed some code Anne originally wrote for this.
You aren't the only one. Look at the, effectively unofficial, incest mods. There a little something that make obvious that at least half of them use my original code. I don't care, if I don't wanted it to be used, I wouldn't have gave it at first, but thanks for the credits.
Firstly, there is a list of whole lines of dialogue to replaced. Just a straight up replacement, nothing clever. Swapping one line with another. In this case, it was a single line of dialogue - but it could have been hundreds of changes - if that's what I needed.
Be noted that, if you fear that the list of lines to replace will be too big, you can take advantage of the
config.label_overrides
. Something that would looks like :
Python:
init 1 python:
# Define a global list of changes to apply for the whole game.
AONdialogChanges = { "this line": "become that one", [...] }
# Define a list of changes dedicated to some labels.
AONdialogChangesSpecial = {}
# Update the callback to take count of the two lists.
def smtf( text ):
def innerChange( m ):
return regExEquivalent79 [ m.group(0) ]
# The special list take the priority.
if text in AONdialogChangesSpecial: return AONdialogChangesSpecial[text]
# Then if the dialog line wasn't in the special list, proceed as usual.
return AONdialogChanges[text] if text in AONdialogChanges else renpy.re.sub( patchRegEx79, innerChange, text )
# Hijack labels that will have a lot of dialog changes
config.label_overrides["thisLabel"] = "AONthisLabel"
config.label_overrides["AONthisLabelOUT"] = "thisLabel"
label AONthisLabel:
# Define the dialog lines change that apply only for this label.
$ AONdialogChangesSpecial = { "that line": "have to be changed",
"this line also": "but differently" }
# Then go back to the normal flow by playing the label.
jump AONthisLabelOUT