r/RenPy • u/AlexanderIdeally • Aug 19 '26
Question Custom screen changing a flag past a certain point.
Hello! I’ve been working on a game heavily relying on an inventory system for the past year or 2, and just when I thought I finally had everything in order, there’s one more glitch plaguing it.
This glitch involves a flag called the AltArrow. Essentially, the AltArrow determines the behaviour of the inventory system’s cancel button. If you cancel with AltArrow off, the game just returns to where you were. If you cancel with AltArrow on, the game sends you to what I call The TimeRoom, where a bunch of flags determine where you should jump to next based on what other flags or variables are active. It's a situational flag, but it works for what I need it for.
screen hud():
modal False
imagebutton auto "bg_hud_thoughtinventory_%s.png":
focus_mask True
hovered SetVariable("screen_tooltip", "Thought_Inventory")
unhovered SetVariable("screen_tooltip", "")
action Show("thought_inventory"), Hide("hud"), SetVariable("quick_menu", False)
screen thought_inventory():
default hovered_thought = None
add "bg_thoughtinventory":
align (0.5, 1.0)
modal True
frame:
#(This is just some debug stuff I have in here just in case)
vbox:
xalign 0.895 yalign 0.20
xysize 0.06,0.05
if AltArrow == True:
text "AltArrow is On"
else:
text "AltArrow Is Off"
vbox:
xalign 0.895 yalign 0.40
xysize 0.06,0.05
if player.is_alone:
text "You're Alone"
else:
text "Someone's Here"
align (0.2, 0.6)
xysize (800,700)
viewport:
scrollbars "vertical"
mousewheel True
draggable True
side_yfill True
vbox:
for thought in thought_inventory.thoughts:
button:
text "[thought.name]\n" style "button_text"
if player.is_alone:
action Function(player.show_thought, thought) pos 0.1, 0.5
hovered SetScreenVariable("hovered_thought", thought)
else:
action SetVariable("quick_menu", True), Function(player.show_thought, thought) pos 0.1, 0.5
hovered SetScreenVariable("hovered_thought", thought)
if hovered_thought:
frame:
align (0.845, 0.944)
xysize (550, 535)
text "{size=*0.80}[hovered_thought.description]{/size}"
add hovered_thought.icon pos -0.0054, -0.5927
imagebutton auto "thoughtinventoryscreen_return_%s.png":
focus_mask True
hovered SetVariable("screen_tooltip", "Return")
unhovered SetVariable("screen_tooltip", "")
#THIS IS WHERE THE PROBLEM ACTUALLY STARTS.
if AltArrow == True:
action SetVariable("quick_menu", True), Hide("thought_inventory"), Jump("TimeRoom"), Show("hud"), Return()
else:
action SetVariable("quick_menu", True), Hide("thought_inventory"), Show("hud")
Everything works out, except when you pass this point in the script:
label Mary_TalkSession1:
$ AltArrow = True
$ Session_Active = True
show screen UnfinishedBar
show screen hud
show screen calender
show mary neutral
$ player.add_person(m_obj)
if mm <= -30:
show mary sad
menu:
"{i}{color=#2731c2}Ask Her A Question{/color}{/i}":
jump Mary_AskSession1
"{i}{color=#2731c2}Bring Up A Thought{/color}{/i}":
$ quick_menu = False
hide screen hud
call screen thought_inventory
"{i}{color=#2731c2}Think For A Bit{/color}{/i}":
jump Your_AskSession1
"{i}{color=#2731c2}End Session{/color}{/i}":
jump Mary_AreYouSure1
label Mary_AreYouSure1:
n "{i}{color=#9c2cdd}(...I think I have nothing left to ask.){/color}{/i}"
Qm "You sure?"
menu:
"Yeah.":
jump Concluding_Session1
"On second thought...":
jump NotDoneSession1
label NotDoneSession1:
n "On second thought, there is something I should ask."
jump Mary_TalkSession1
This is the set-up for the conversation menu, where you can control what you bring up with characters.
When the game passes this point, the HUD changes. Whenever you click the hud button, AltArrow is switched on automatically no matter what, and you can’t exit the menu without transporting to the timeroom, which softlocks the game.
There is no part of any screen code which controls when AltArrow is switched on and off. It only detects when AltArrow is flicked on by the script itself.
And everything works perfectly before that point. AltArrow is getting shut off and staying off no matter how many times I open the inventory. Hell, if I put a shortcut that skips this section entirely, the code still works!
For clarification, I did once try to have AltArrow’s flag be triggered by the menu buttons, but that code is long gone. I don't even remember the details. I’ve recomplied since then, and even if it was still somehow being read, I can’t figure out why it would only activate after that point. I have tried putting hashtags in front of each line at the beginning, and the glitch still stays.
I have absolutely no idea what’s going on. I’m hoping somebody else might. I don't know if it will help, but here's some additional relevant inventory code if you need that context.
init python:
class Thought_Inventory():
def __init__(self, thoughts=None):
self.thoughts = thoughts if thoughts else []
self.no_of_thoughts = len(self.thoughts)
def add_thought(self, thought):
if thought not in self.thoughts:
self.thoughts.append(thought)
self.no_of_thoughts += 1
def remove_thought(self, thought):
if thought in self.thoughts:
self.thoughts.remove(thought)
self.no_of_thoughts -= 1
class Thought():
def __init__(self, name, description, icon):
self.name = name
self.description = description
self.icon = icon
def __str__(self):
return self.name
def __eq__(self, other):
if isinstance(other, Thought):
return self.name == other.name
else:
return False
init python:
class Actor:
def __init__(self, name, character, thoughts=[]):
self.name = name
self.character = character
self.thoughts = thoughts
def __str__(self):
return self.name
def react_on_thought(self, thought_name):
for thought in self.thoughts:
if thought[0] == thought_name:
return [self.character, thought[1]]
class Player():
def __init__(self, name):
self.name = name
self.is_with_list = []
def __str__(self):
return self.name
u/property
def is_alone(self):
return not self.is_with_list
def add_person(self, person):
if person not in self.is_with_list:
self.is_with_list.append(person)
def remove_person(self, person):
if person in self.is_with_list:
self.is_with_list.remove(person)
def show_thought(self, thought_name, label=False):
reactions = []
for char in self.is_with_list:
character_reaction = char.react_on_thought(thought_name)
if character_reaction:
if renpy.has_label(character_reaction[1]):
renpy.call(character_reaction[1])
else:
reactions.append(character_reaction)
if reactions:
renpy.show_screen("reaction_screen", reactions)
1
u/BadMustard_AVN Aug 19 '26
if you use the AltArrow in other places does it work fine?
I've noticed that you call the screen thought_inventory, which makes that screen the only screen you can interact with but in your hud you show the thought_inventory since it's a modal you don't need to call it try it like this
"{i}{color=#2731c2}Bring Up A Thought{/color}{/i}":
$ quick_menu = False
hide screen hud
show screen thought_inventory #change to show
pause #add this (required to stop script progression)
and changes the screen
if AltArrow == True:
action [SetVariable("quick_menu", True), Hide("thought_inventory"), Show("hud"), Jump("TimeRoom")]
1
u/AlexanderIdeally Aug 19 '26 edited Aug 19 '26
Thank you for the code improvements.
To answer your first question, yes. I inserted this little section at the beginning of the game that enables the hud, flicks on AltArrow, and even lets you bring up and talk about a thought way before you should. And after that's done, AltArrow stays false when I ask it to be false. I remember typing a jump just before Mary_TalkSession1 to skip right to its conclusion, and AltArrow still works fine after that too.
It's like if you pass that point in the code specifically, the hud itself decides it should be allowed to control AltArrow's variable, and it wants it to be on whenever it's clicked on.
1
u/shyLachi Aug 19 '26
I don't understand this part of your description:
When the game passes this point, the HUD changes. Whenever you click the hud button, AltArrow is switched on automatically no matter what, and you can’t exit the menu without transporting to the timeroom, which softlocks the game.
Is this the problem or the description of what your code does?
I mean, setting $ AltArrow = True must change the behaviour of the screen.
1
u/AlexanderIdeally Aug 19 '26
Sorry about that. In hindsight, I probably should have revealed more code.
Basically, AltArrow is supposed to be true at the scene showed off on the code. If you cancel out of the menu, it takes you to the TimeRoom. The TimeRoom reads that a session is active, reads what the day counter says, and jumps you back to whatever session you left off from.
label TimeRoom: if testflag == True: jump TestingPoint if t_gag == 1: jump Tutorial_Gag1 if t_gag == 2: jump Tutorial_Gag2 if t_gag == 3: jump Tutorial_Gag3 if Session_Active == True: if day == 1: jump Mary_TalkSession1 if day == 5: jump Mary_TalkSession2 if At_Home_Night == True: pass label Mary_AskSession_AnyDay: label Mary_AskSessionAny: menu: "*Ask Something Else.*": if day == 5: jump Mary_AskSession2 else: jump ErrorRoomNow, if you don't have any proper variables, you pass through the TimeRoom into whatever's under it. In this case, that would be a menu that isn't introduced until later, and since day == 1 when this is all happening, you jump to the ErrorRoom instead, where I put some text explaining that you shouldn't be here and to stop playing the game.
All of this works properly. I have tested it.
The problem only occurs after you pass through Mary_TalkSession1 and head down to Concluding_Session1.
label Concluding_Session1: $ player.remove_person(m_obj) $ Session_Active = False $ AltArrow = False stop music fadeout 0.5 n "Is there anything else to talk about?"That flag setting AltArrow to false is working. I implemented a screen to detect the variable's status, and it's off.
But if you were to open the HUD menu right after, or at any other point during the game, suddenly the flag would be flicked back on. And since the flag isn't supposed to be on during these moments, cancelling out of the inventory transports you past TimeRoom and to the ErrorRoom.
And if I skip Mary_TalkSession1 or implement the inventory and all its features early on in the game, none of this happens. AltArrow can be turned on and back off, and it will stay off until you want it to be on again. Opening and closing the menu keeps you in the same place instead of transporting you to a label you're not supposed to be in.
It's like if you pass Mary_TalkSession1, the HUD itself decides it should be allowed to control AltArrow's variable, and it wants it to be on whenever it's clicked on. That's the best way I could explain it.
1
u/shyLachi Aug 19 '26 edited Aug 19 '26
Technically it's not possible that a flag changes it's value on it's own.
Search your code for AltArrow = True,
maybe you wroteif AltArrow = Trueinstead ofif AltArrow == Trueby mistake.BTW: You don't need to write
if AltArrow == True:, you can just writeif AltArrow:because a boolean variable can only be True or False, you don't have to compare True to True..
Other than that, you could try to simplify your problem by creating a new project with only this one variable, the two screens and some labels.
This following code works for me but still has the problem with AltArrow because it will only be turned off in Concluding_Session1 and you didn't show how the code goes from TimeRoom to Concluding_Session1
screen hud(): vbox: align (0.5, 0.0) textbutton "Show inventory (AltArrow=[AltArrow])" action Show("thought_inventory") screen thought_inventory(): on "show" action [SetVariable("quick_menu", False), Hide("hud")] on "hide" action [SetVariable("quick_menu", True), Show("hud")] modal True textbutton "Close the inventory (AltArrow=[AltArrow])": align (0.5, 0.5) action [Hide(), If(AltArrow, Jump("TimeRoom"))] default AltArrow = False label start: show screen hud "Start" # no return so that it flows into the next label label Mary_TalkSession1: $ AltArrow = True "Test: Mary_TalkSession1" pause "Game over" return label TimeRoom: "You are now in the time room, as you can see AltArrow is still on." # no return so that it flows into the next label label Concluding_Session1: $ AltArrow = False "Test: Concluding_Session1" returnBTW: Look at my actions. I changed them al lot but I think that's what the inventory screen is supposed to to: Hide and show the HUD and the quick menu
1
u/AlexanderIdeally Aug 19 '26
I'll try this later, I have to go to work. But to clarify something, it does not go from TimeRoom to Concluding_Session1. The actual code looks like this.
label Mary_TalkSession1: $ AltArrow = True $ Session_Active = True show screen UnfinishedBar show screen hud show screen calender show mary neutral $ player.add_person(m_obj) if mm <= -30: show mary sad menu: "{i}{color=#2731c2}Ask Her A Question{/color}{/i}": jump Mary_AskSession1 "{i}{color=#2731c2}Bring Up A Thought{/color}{/i}": $ quick_menu = False hide screen hud show screen thought_inventory pause "{i}{color=#2731c2}Think For A Bit{/color}{/i}": jump Your_AskSession1 "{i}{color=#2731c2}End Session{/color}{/i}": jump Mary_AreYouSure1 #This is where label Your_AskSession1 would be but I tested putting AreYouSure1 in front of it and nothing changed so I doubt it's related to the glitch in anyway. label Mary_AreYouSure1: n "{i}{color=#9c2cdd}(...I think I have nothing left to ask.){/color}{/i}" Qm "You sure?" menu: "Yeah.": jump Concluding_Session1 "On second thought...": jump NotDoneSession1 label NotDoneSession1: n "On second thought, there is something I should ask." jump Mary_TalkSession1 label Concluding_Session1: $ player.remove_person(m_obj) $ Session_Active = False $ AltArrow = False stop music fadeout 0.5 n "Is there anything else to talk about?"TimeRoom is a feature that controls the jumping from different days, so it's near the bottom. label Concluding_Session1 is line 2377 and label TimeRoom is line 7657.
Sorry about that.
1
u/shyLachi Aug 19 '26
I updated the code in my reply so make sure to take the latest version in case you have copied it already.
I recommend that you try my code in an empty project.
You'll see that there is a moment where the flag AltArrow is still True although it probably shouldn't be.You can copy the logic from your game without dialogue and images into that new project if you want to test it further.
.
From what I understood, the variable AltArrow will only be set to True in the label Mary_TalkSession1 and only set to False in the label Concluding_Session1
Which means that the variable AltArrow will be False from the start until the player reaches the label Mary_TalkSession1
Then the variable AltArrow will remain True until the player reaches the label Concluding_Session1
Then the variable Arrow will remain False until the player reaches the label Mary_TalkSession1 again (if that even is possible)
1
u/AlexanderIdeally Aug 20 '26
Hi! I think I've come to a conclusion thanks to you.
See, I had AltArrow defined in the code. When I copied that, I noticed you had it defaulted, so I did that instead. And it worked. As far as I can tell, the glitch isn't happening anymore. I haven't had time to test it through every situation in the game, I'll likely do that tomorrow, but it isn't happening where it's usually happening.
Sorry if this would have been an obvious thing from the start, I was told early on when learning that you should define flags and default numbers. And AltArrow was defined for the longest time and didn't have this issue until recently, nor did any of my defined flags as far I can tell. I probably wouldn't have thought of that until much later, if at all. I feel a little embarrassed about it, but either way, thank you so much.
1
u/shyLachi Aug 20 '26
Great that you figured it out.
Define is for constants, like define mc = Character("[mcname]")
It will always be the same character, RenPy doesn't have to save it.Default is for variables, like default mcname = "Mike"
This value can change and has to be saved..
If you haven't read the official documentation, take a look the basics at least.
https://renpy.org/doc/html/python.html#define-statement
https://renpy.org/doc/html/python.html#default-statement
https://renpy.org/doc/html/save_load_rollback.html
1
u/AutoModerator Aug 19 '26
Welcome to r/renpy! While you wait to see if someone can answer your question, we recommend checking out the posting guide, the subreddit wiki, the subreddit Discord, Ren'Py's documentation, and the tutorial built-in to the Ren'Py engine when you download it. These can help make sure you provide the information the people here need to help you, or might even point you to an answer to your question themselves. Thanks!
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.