USER=25819]@bossapplesauce[/USER] and
@anne O'nymous can explain this far better than I can.
It rely on the
You must be registered to see the links
callback, which is called each time a line of text will be displayed, either as dialog line or as menu.
Taking your code (simplified and corrected) as explanation :
Code:
init python:
# Here are defined the string that will be completely changed.
# Before the ':' is the original string, and after it is the replacement one.
# So, when the game want to display, "je dis des choses", it's "I hope
# everything will be ok between me and [sister_name]." that will be
# effectively shown to the player. Note that the presence of
# "[sister_name]" imply that the string substitution will be performed
# AFTER the call to the /callback/, not before.
hardChanged = {
"Je dis des choses.":"I hope everything will be ok between me and [sister_name].",
"Ha c'est la sista ":"It's [sister_name]",
"{i}Je ne regrette rien de ce qui c'est passé blalal.":"{i}I do not regret anything that happened.",
"Cool, j'vais me poser sur l'canap": "Neither do I, that's a relief, I need to sit down for a bit."
}
# Here is the /callback/ itself. It take the text to display as parameter,
# and MUST return the string that will be displayed.
def TwoWeeks (text):
# This is an internal function, it can only be called from inside the
# /TwoWeeks/ function. Doing so help to keep it clean.
# This function is called by "renpy.re.sub", and pass the result of
# the RegEx as parameter.
# Then, he return the value to replace according to the value
# effectively found. See bellow.
def lang (t):
# If the keyword found is /lydia/, it will be replaced by the
# value of /friend_name/.
if t.group(0) == "lydia": return friend_name
# If the keyword is inside the given list (so either /sister/ or
# /sista/), it will be replaced by the value of /sister_name/.
if t.group(0) in [ "sister", "sista"] : return sister_name
# Here the /callback/ will first test if the string to display exist
# in the /hardChanged/ dictionary defined above. If yes, it will
# return the replacing value.
if text in hardChanged:
return hardChanged[text]
# If not, the /callback/ will search for a list of keyword expressed
# as a RegEx. If one of the keyword is found, the function /lang/
# will be called to perform the replacement before returning the
# string. Else the string will be returned as it.
else:
# The list of keyword is what inside the parenthesis. So,
# here the callback will replace /lydia/, /sister/ and /sista/.
return renpy.re.sub(r'(?:lydia|sister|sista)', lang, text)
# Finally, here we tell to Ren'py to use the /TwoWeeks/ function as
# callback.
config.say_menu_text_filter = TwoWeeks
Now, for what
@FallenDuke want, it's this code :
Code:
init python:
def noSister(text):
def lang (t):
if t.group(0) in [ "sister", "sis"] : return sister_name
return renpy.re.sub(r'(?:sister|sis)', lang, text)
config.say_menu_text_filter = noSister
define sister_name = "xyz"
Yeah, Regex... I would use that for string editing or to avoid certain input (like allowing only numbers), I would not really use it for something that can be replaced only once by the dev manually.
The regEx's implementation is less effective in Python than in Perl, or even Ruby (while being clearly designed for optimized regEx), still it's fast enough for being transparent and not affecting the game speed. This even taking in count that it use
re.sub instead of working directly with a
re object ; which imply that the regEx is recompiled every single time a line is displayed. On a seven years old computer, the regEx used in
@bossapplesauce 's incest patch for
Freeloading Family take less than 0.2 milliseconds to understand that none of the 16 keywords defined are in an average string, against around 0.05 milliseconds when one is present.
This said, beyond the speed problem, there's a practical reason to use this callback, and so a regEx, in place of hard replacement directly on the source : here, games are released update by update.
With the callback, just put it in a
rpy file, and put this file inside the
game directory, it will works every times. This while a hard change generally imply that you must start by extracting each file from the
rpa archive, eventually un.rpyc the source, then edit each one of the
rpy files to make the change.
For an average game, count more or less 15 minutes for this. So, the game need 4 500 000 lines displayed for the callback method to be slower on a seven years old computer ; without talking about the fact that it imply less manipulations coming from the player.