So..

Afflyction

Member
Game Developer
May 7, 2017
190
616
Ok, so my game is close to being released. I'm shooting for the first week of January however I want to get ahead of Patreon before I release. I have been searching all over and trying different things for weeks but I can't find anything that works. I'm trying to use a text replacer kind of like what dreams of desire uses for his patch but I don't want to straight up take his code so as a last ditch effort, I'm asking here for some much needed help. I'm still a bit of a noob with coding.
 
R

RWaites

Guest
Guest
Ok, so my game is close to being released. I'm shooting for the first week of January however I want to get ahead of Patreon before I release. I have been searching all over and trying different things for weeks but I can't find anything that works. I'm trying to use a text replacer kind of like what dreams of desire uses for his patch but I don't want to straight up take his code so as a last ditch effort, I'm asking here for some much needed help. I'm still a bit of a noob with coding.
Not sure if it's the sort of thing you are looking for but have you tried the Lewd Patcher link at the top of the page
 

Afflyction

Member
Game Developer
May 7, 2017
190
616
Not sure if it's the sort of thing you are looking for but have you tried the Lewd Patcher link at the top of the page
thats where i can submit my patch. i need to make one first from my understanding
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,978
16,236
Like you talk about Dreams of Desires, I assume that you use Ren'py. So the easiest way to patch it if it's only dialog lines is to use the translation feature.
If there's no translation for a given line, the default text will be used, so either it will work fine without the patch, and you'll have to "translate" only the needed lines.
Add a rpy file with this, which define the language at "init 99" and it's done.
 

Afflyction

Member
Game Developer
May 7, 2017
190
616
would that work with just words? its not a line per say. my game is an incest game so i just want to swap out key words so i can avoid the patreon police
 

Cyan

Member
Jul 25, 2017
126
551
would that work with just words? its not a line per say. my game is an incest game so i just want to swap out key words so i can avoid the patreon police
I don't believe that behavior is in ren'py natively. You'll have to either create a module to do that, or just create the patreon-safe version yourself.
 

Afflyction

Member
Game Developer
May 7, 2017
190
616
I don't believe that behavior is in ren'py natively. You'll have to either create a module to do that, or just create the patreon-safe version yourself.
its not i dont think, based on my research, its more python based, i have do have this code i found while searching the interwebs, im just not sure how durable it is. it uses the same principal as dreams of desire (the dictionary replace) but not his exact coding ill show it

Code:
init python:
    import re
    def word_replace(text):
        """
        take a text and replace words that match the key in a dictionary
        with the associated value, return the changed text
        """

        def translate(match):
            word = match.group(0)
            return replace_dict.get(word, word)
      
        return re.sub(r"\b[A-Za-z_]\w*\b", translate, text)

# create a dictionary of key_word:replace_with pairs
    replace_dict = {
        "apple" : "grape",
        "radish" : "carrot"
    }

define config.say_menu_text_filter =  word_replace
i had help from the lemmasoft forums to get it to work i just dont know if it can handle a potentially(over time) large game
 

Cyan

Member
Jul 25, 2017
126
551
I probably wouldn't do simple word replaces. It's more work but I would probably create the bulk of safe version from scratch. I'm not sure how you're changing the story though; if it's just sister -> step-sister or what have you. There are number of different contexts depending on the story that could change the grammar/meaning of the story quite drastically, and won't be covered by a simple word switch.
 

Studio Errilhl

Member
Game Developer
Oct 16, 2017
315
237
I do something like this
Basically, in the real game-files, I define a check for a patch - if that is present, it will use one set or words, if not, it will use another. It's not 100%, of course, since the code actually contains the offending phrases, words, but I'm sure you could put everything in the patch itself. Here's the current code I use:

This is for checking for the patch:
Code:
init -30 python:
    from datetime import time
    persistent.patch_installed = False
init -10 python:
    if persistent.patch_installed and not persistent.patch_first_time:
        persistent.patch_enabled = True
        persistent.patch_first_time = True
    elif not persistent.patch_installed:
        persistent.patch_first_time = False
        persistent.patch_enabled = False
The patch.rpy file itself:
Code:
init -20:
    $ persistent.patch_installed = True
And this is how this is used in the game itself:
Code:
 python:
        fPinput = renpy.input("First, we'll need to know your name (default, Marten):")
        fPinput = fPinput.strip()
        if not fPinput:
            fPinput = "Marten"
        if persistent.patch_enabled:
            fMinput = renpy.input("Second, we'll need to know the name of your mother (default, Mother)")
        else:
            fMinput = renpy.input("Second, we'll need to know the name of your landlady (default, Anne):")
        fMinput = fMinput.strip()
        if not fMinput:
            if persistent.patch_enabled:
                fMinput = "Mother"
            else:
                fMinput = "Anne"
        if persistent.patch_enabled:
            fSinput = renpy.input("Third, the name of your sister (default, Sister)")
        else:
            fSinput = renpy.input("Third, the name of your housemate (default, Juliette):")
        fSinput = fSinput.strip()
        if not fSinput:
            if persistent.patch_enabled:
                fSinput = "Sister"
            else:
                fSinput = "Juliette"
        if fMinput.upper() == "MOM".strip() or fMinput.upper() == "MOTHER".strip():
            fMinput = fMinput.lower()
            shortfM = "mom"
            yourfM = "your "+fMinput+""
            yourshortfM = "your "+shortfM+""
            myfM = "my "+fMinput+""
            myshortfM = "my "+shortfM+""
            shortCapsfM = shortfM.capitalize()
            yourCapsfM = yourfM.capitalize()
            CapsfM = fMinput.lower().capitalize()
            yourshortCapsfM = yourshortfM.capitalize()
            myCapsfM = myfM.capitalize()
            myshortfM = myshortfM.capitalize()
            fMrole = "mother"
            myfMrole = "my "+fMrole+""
        else:
            shortfM = fMinput
            yourfM = fMinput
            yourshortfM = shortfM
            myfM = fMinput
            myshortfM = fMinput
            shortCapsfM = shortfM.capitalize()
            yourCapsfM = yourfM.capitalize()
            yourshortCapsfM = yourshortfM.capitalize()
            CapsfM = fMinput.lower().capitalize()           
            myCapsfM = myfM.capitalize()
            myshortfM = myshortfM.capitalize()
            fMrole = "landlady"  
            myfMrole = "my "+fMrole+""         
        if fSinput.upper() == "SIS".strip() or fSinput.upper() == "SISTER".strip():
            fSinput = fSinput.lower()
            shortfS = "sis"   
            yourfS = "your "+fSinput+""
            yourshortfS = "your "+shortfS+""
            myfS = "my "+fSinput+""
            myshortfS = "my "+shortfS+""
            shortCapsfS = shortfS.capitalize()
            yourCapsfS = yourfS.capitalize()
            yourshortCapsfS = yourshortfS.capitalize()
            CapsfS = fSinput.lower().capitalize()
            myCapsfS = myfS.capitalize()
            myshortfM = myshortfM.capitalize()
            fSrole = "sister"
            myfSrole = "my "+fSrole+""
        else:
            if fSinput == "Juliette":
                shortfS = "Jules"
            else:
                shortfS = fSinput
            yourfS = fSinput
            yourshortfS = shortfS
            myfS = fSinput
            myshortfS = fSinput
            shortCapsfS = fSinput.capitalize()
            yourCapsfS = fSinput.capitalize()
            yourshortCapsfS = yourshortfS.capitalize()
            CapsfS = fSinput.lower().capitalize()
            myCapsfS = myfS.capitalize()
            myshortfM = myshortfM.capitalize()           
            fSrole = "housemate"
            myfSrole = "my housemate"
There's a lot of redundancy in that last bit of code, I'm aiming to make it slightly more condensed, but I have a lot of different variables defined, so not to create weird wording or missing prepositions when changing from things like "my sister" to "Juliette" and such.
 

Cyan

Member
Jul 25, 2017
126
551
That's.... one way to do it. I do think it's a little weird how you (and plenty of other games) leave the default names for sister/mother/brother as 'sister', 'mother' or 'brother'. People typically don't refer to their relatives with their full titles. I like how you specifically put in parameters to change 'Mother' to 'mom' - shows some real attention to detail. Props

P.S. - Your variable names/conventions really bug me lol it's really messing with my OCD
 

Studio Errilhl

Member
Game Developer
Oct 16, 2017
315
237
Haha - it was mostly done to differentiate between certain specific types, and adding to those variable names in updates and such, without having to rewrite stuff. But yeah, those are probably gonne be normalised when I get around to it :D
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,978
16,236
would that work with just words? its not a line per say. my game is an incest game so i just want to swap out key words so i can avoid the patreon police
No, it can't work for simple words, you have to translate the whole line of dialog.

As for the code you posted for words replacement, I don't recommend you, or anyone else, to use it. It works blindly, so unless you really know what you do and how to write strong RegEx, it will change a lots of things you don't want to see changed.
For the example, lets say it works on the other way, incest->none incest, and you want to replace "mom" by "laura". You'll use this code, and the player will see things like, "one lauraent, I finish what I'm doing and come help you." (because of "moment" ).
Even if you have strong RegEx, it's still not the best option. There's more variety on a way than on the other. A none incest line can be "I can't, it's Laura", but the incest line can't be "I can't, it's mom". It should be something like "I can't, it's my mom", or even better, "I can't, it's my mother". But in the same time, "Laura, come here please", can be "Mom, come here please".

What you can do is to create an object for each character, and you use it to perform the replacement in real time.
Code:
    class Names( object ):
          def __init__( self, **kwargs ):
              for k, v in kwargs:
                  setattr( self, k, v )
                  setattr( self, k.capitalize(), v.capitalize() )
   [incest way]
   mom.names = Names( formal="mother", informal="mom", fullFormal="my mother" )
   [none incest way]
   mom.names = Names( formal="teacher", informal="laura", fullFormal="my teacher" )
   [...]
   "I can't, she's [mom.names.fullFormal] !"
   "[mom.names.Informal], come here please."
And you'll have :
"I can't, she's my teacher !"
"Laura, come here please."
or
"I can't, she's my mother !"
"Mom, come here please."

It give you more flexibility and control over what you want to display and on how it's changed. Plus side, put this on a rpy file, at "init 99 python" and this file will be the only change you need to patch your game.
The only limitation of this method is that you can't have names defined by the user. But it's because I'm lazy and will not write a full class as just an example. If you want I can write it to handle this as well. It's easy and I already have a code reusable for this somewhere.

For me, it's definitively the best of all the options because it's the simplest of them all. You have full control over the change, it's soft patching (put the rpy file, it's an incest game, remove the rpy file it's a none incest game), it's extendable and once you've done the configuration (created the object for each character) you don't have to think about it, just use the right field from the right object.
 

Afflyction

Member
Game Developer
May 7, 2017
190
616
No, it can't work for simple words, you have to translate the whole line of dialog.

As for the code you posted for words replacement, I don't recommend you, or anyone else, to use it. It works blindly, so unless you really know what you do and how to write strong RegEx, it will change a lots of things you don't want to see changed.
For the example, lets say it works on the other way, incest->none incest, and you want to replace "mom" by "laura". You'll use this code, and the player will see things like, "one lauraent, I finish what I'm doing and come help you." (because of "moment" ).
Even if you have strong RegEx, it's still not the best option. There's more variety on a way than on the other. A none incest line can be "I can't, it's Laura", but the incest line can't be "I can't, it's mom". It should be something like "I can't, it's my mom", or even better, "I can't, it's my mother". But in the same time, "Laura, come here please", can be "Mom, come here please".

What you can do is to create an object for each character, and you use it to perform the replacement in real time.
Code:
    class Names( object ):
          def __init__( self, **kwargs ):
              for k, v in kwargs:
                  setattr( self, k, v )
                  setattr( self, k.capitalize(), v.capitalize() )
   [incest way]
   mom.names = Names( formal="mother", informal="mom", fullFormal="my mother" )
   [none incest way]
   mom.names = Names( formal="teacher", informal="laura", fullFormal="my teacher" )
   [...]
   "I can't, she's [mom.names.fullFormal] !"
   "[mom.names.Informal], come here please."
And you'll have :
"I can't, she's my teacher !"
"Laura, come here please."
or
"I can't, she's my mother !"
"Mom, come here please."

It give you more flexibility and control over what you want to display and on how it's changed. Plus side, put this on a rpy file, at "init 99 python" and this file will be the only change you need to patch your game.
The only limitation of this method is that you can't have names defined by the user. But it's because I'm lazy and will not write a full class as just an example. If you want I can write it to handle this as well. It's easy and I already have a code reusable for this somewhere.

For me, it's definitively the best of all the options because it's the simplest of them all. You have full control over the change, it's soft patching (put the rpy file, it's an incest game, remove the rpy file it's a none incest game), it's extendable and once you've done the configuration (created the object for each character) you don't have to think about it, just use the right field from the right object.
This actually seems like the best option for me. Do you mind if I use it? There are 2 chars that are user defined, maybe more. I can search around to see if I can incorporate it in.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,978
16,236
This actually seems like the best option for me. Do you mind if I use it? There are 2 chars that are user defined, maybe more. I can search around to see if I can incorporate it in.
I don't mind, else I wouldn't have given a working example for the code. And if you can wait the 27/28 December, I can provide a better code taking user's defined name in account. It's not a lot of works, but there's really busy days which approach, so I prefer to not rush it.
It will works in the same way, ( [m.something], and [m.Something] for capitalized first letter ), only the configuration will change. So you can already think about it in regard of your own project.
 

Afflyction

Member
Game Developer
May 7, 2017
190
616
I don't mind, else I wouldn't have given a working example for the code. And if you can wait the 27/28 December, I can provide a better code taking user's defined name in account. It's not a lot of works, but there's really busy days which approach, so I prefer to not rush it.
It will works in the same way, ( [m.something], and [m.Something] for capitalized first letter ), only the configuration will change. So you can already think about it in regard of your own project.
Awesome, much appreciated. I dont mind waiting. I'm looking at the first week of January for release so I have time.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,978
16,236
Awesome, much appreciated. I dont mind waiting. I'm looking at the first week of January for release so I have time.
Alright, yesterday and today were less busy than expected, so I found the time to make it, even better than I planed at first. Like you're probably not the only game developer interested by this, I made a new thread about it :
 
  • Like
Reactions: Afflyction