I dunno what this can be classified as. It's not like a mod or a tool... but more of a concept, so I'll just put it in general discussions. I was tired of incest games that are coded poorly, where the son/daughter just keeps on calling the mom by her first name because the dev keeps using [mom_name] instead of [mom_relationship] in the dialogues. So I was having my first vibe coding experience, and there was A LOT of shit that didn't work (and Gemini making up some bullshit), but I ended up with something that actually works, although it's not very elegant. You need to insert some code into screens.rpy, and it's kinda tricky to place it in the correct spot, but it does work for the games I tried it on.
This is the general concept. The main use case is for those situations where a dev's incest patch or user input incest definitions are routinely ignored due to poor coding. Mainly, the MC (and his sister) calling their parent by their first names.
And here's an example of the code in action.
This is actually for the second use case. I used it on Deserk Stalker. I wanted the daughters to use daddy, but I didn't want Igor to say shit like "your daddy bla bla." By using father as the mc's relationship with the girls, everyone will use that term, but when the daughters say father, it's replaced by daddy.
I couldn't for the life of me get Gemini to produce anything that would make this less invasive. Like it would be nice if this function can be done from a replacer_patch.rpy that I can drop into game folder, but those attempts never ended up working.
My dream would be if this idea of speaker specific word replacement can be incorporated into URM, but I dunno if that's possible. This shit doesn't seem very generalized. Like different games could have different screens.rpy coding and what not.
Code:
# PASTE THIS HELPER BLOCK AT THE VERY TOP OF THE FILE
init -1 python:
import re
def preserve_case_replace(replacement_word):
def replacer(match):
original_word = match.group(0)
if original_word.isupper():
return replacement_word.upper()
elif original_word.istitle():
return replacement_word.title()
else:
return replacement_word.lower()
return replacer
# THIS GOES RIGHT BEFORE if who is not None:
# Under screen say(who, what):, and after window: section, indented one more step
python:
# ==================================================================
# --- CUSTOMIZE YOUR REPLACEMENTS HERE ---
# ==================================================================
# --- Speaker 1 ---
TARGET_SPEAKER_1_NAME = "john"
# --- Speaker 2 ---
TARGET_SPEAKER_2_NAME = "jane"
# ==================================================================
processed_text = renpy.substitute(what)
speaker_name_string = renpy.substitute(who)
# Check for Speaker 1
if speaker_name_string.lower() == TARGET_SPEAKER_1_NAME:
# --- ADD REPLACEMENTS FOR SPEAKER 1 HERE ---
processed_text = re.sub(r'\bXXX\b', preserve_case_replace("mom"), processed_text, flags=re.IGNORECASE)
processed_text = re.sub(r'\bYYY\b', preserve_case_replace("dad"), processed_text, flags=re.IGNORECASE)
# Check for Speaker 2
elif speaker_name_string.lower() == TARGET_SPEAKER_2_NAME:
# --- ADD REPLACEMENTS FOR SPEAKER 2 HERE ---
processed_text = re.sub(r'\XXX\b', preserve_case_replace("mom"), processed_text, flags=re.IGNORECASE)
# ======================================================================
if who is not None:
window:
id "namebox"
style "namebox"
text who id "who"
# THIS IS CRITICAL: REPLACE text what id "what"
text processed_text id "what"
And here's an example of the code in action.
Code:
screen say(who, what):
style_prefix "say"
window:
id "window"
background im.Alpha(Image("gui/dialogue/textbox.png", xalign=0.5, yalign=1.0), persistent.textbox_opacity)
python:
# ==================================================================
# --- CUSTOMIZE YOUR REPLACEMENTS HERE ---
# ==================================================================
# --- Speaker 1 ---
TARGET_SPEAKER_1_NAME = "ain"
# --- Speaker 2 ---
TARGET_SPEAKER_2_NAME = "shani"
# ==================================================================
# This is the proven logic.
processed_text = renpy.substitute(what)
speaker_name_string = renpy.substitute(who)
# Check for Speaker 1
if speaker_name_string.lower() == TARGET_SPEAKER_1_NAME:
# --- ADD REPLACEMENTS FOR SPEAKER 1 HERE ---
processed_text = re.sub(r'\bfather\b', preserve_case_replace("daddy"), processed_text, flags=re.IGNORECASE)
# Check for Speaker 2
elif speaker_name_string.lower() == TARGET_SPEAKER_2_NAME:
# --- ADD REPLACEMENTS FOR SPEAKER 2 HERE ---
processed_text = re.sub(r'\bfather\b', preserve_case_replace("daddy"), processed_text, flags=re.IGNORECASE)
# This part displays the results.
if who is not None:
window:
id "namebox"
style "namebox"
text who id "who"
# THIS IS CRITICAL: REPLACE text what id "what"
text processed_text id "what"
I couldn't for the life of me get Gemini to produce anything that would make this less invasive. Like it would be nice if this function can be done from a replacer_patch.rpy that I can drop into game folder, but those attempts never ended up working.
My dream would be if this idea of speaker specific word replacement can be incorporated into URM, but I dunno if that's possible. This shit doesn't seem very generalized. Like different games could have different screens.rpy coding and what not.
Last edited: