As a base, I need to be able to have a button that can both show a screen and a new button, and then that new button will hide itself, and hide the screen. Essentially, a button leads to a screen, and has a button that leads back. I've done this previously in my code with no issues:
Code: Select all
screen quest_button():
if quest_button_visible:
frame:
xalign 1.0
yalign 0.0015
xsize 445
ysize 60
textbutton "View Quest List" xalign 0.5 action [Show("quest_screen"), Hide("quest_button")]
# Define Ren'Py screens to display quest information
screen quest_screen():
frame:
text "Quest List:"
xalign 0.0 # Center the entire frame horizontally
yalign 0.0 # Center the entire frame vertically
xsize 1920 # Set the width of the entire frame to cover the screen
ysize 1080 # Set the height of the entire frame to cover the screen
background Color("#000000") # Set the border color to black
vbox:
xalign -0.008 # Center the entire frame horizontally
yalign 0.04 # Center the entire frame vertically
# Display buttons for each quest title
for quest_id, quest in quests.items():
if quest.current_step > 0:
textbutton quest.title action [Show("QuestDetails", quest_id=quest_id)]
frame:
xalign 1.0
yalign 0.0
xsize 445
ysize 60
textbutton "Return" xalign 0.5 yalign 0.5 action [Show("quest_button"), Hide("quest_screen")]
This displays a constant button unless I tell it not to, and on press, it leads to the screen where it also shows another button leading back. I tried recreating this exact syntax for my squad_screen, but it tells me I am missing a required argument, 'squad_NPCs'. Here's the full function:
Probably not an important part, but I'll include it for clarity:
Code: Select all
squad_NPCs = []
# Create an instance of the Derek character
derek_Instance = Derek("Derek", "Martial", level=1, health_offset=0, power_offset=0, spell_slots_offset=0, ability_offsets=None, strength=4, constitution=4, dexterity=4, intelligence=4, wisdom=4, charisma=4)
# Append the Bandit instance to specific_NPCs list
squad_NPCs.append(derek_Instance)
This is essentially taking information from a massive NPC class, and then making an instance of an NPC I created. This is the base example for testing the squad information screen I am making. Here's the more relevant passage:
Code: Select all
screen squad_screen_button:
frame:
xalign 1.0
yalign 0.195
xsize 445
ysize 60
textbutton "View Squad Screen" xalign 0.5 action [Show("squad_screen", squad_NPCs=squad_NPCs)]
screen squad_screen(squad_NPCs):
frame:
background Color("#C0C0C0") # Grey Background
frame:
xalign 1.0
yalign 0.14
xsize 445
ysize 60
textbutton "Close Squad Screen" xalign 0.5 action [Show("squad_screen_button"), Hide("squad_screen")]
tag menu
# Use a grid to layout the NPC boxes and the Player box
grid 0 0:
spacing 5
# First column for NPCs
grid 0 0:
spacing 5
# First column for NPCs
for i, npc in enumerate(squad_NPCs):
if i % 2 == 0: # If it's an even index, put it in the first column
vbox:
text "[npc.name]"
hbox:
text "Str: [npc.strength] Dex: [npc.dexterity] Con: [npc.constitution]"
hbox:
text "Wis: [npc.wisdom] Int: [npc.intelligence] Cha: [npc.charisma]"
hbox:
# Health bar
frame:
# background "bar_background.png"
bar value "[npc.current_Health / float(npc.total_Health)]" # The bar fill ratio
text "[npc.current_Health]/[npc.total_Health]" at center
# Spell Slots
frame:
# background "bar_background.png"
bar value "[npc.current_Slots / float(npc.total_Slots)]"
text "[npc.current_Slots]/[npc.total_Slots]" at center
# Power Slots
frame:
# background "bar_background.png"
bar value "[npc.current_Power / float(npc.total_Power)]"
text "[npc.current_Power]/[npc.total_Power]" at center
# Second column for NPCs
grid 1 0:
spacing 5
# Second column for NPCs
for i, npc in enumerate(squad_NPCs):
if i % 2 != 0: # If it's an odd index, put it in the second column
vbox:
text "[npc.name]"
hbox:
text "Str: [npc.strength] Dex: [npc.dexterity] Con: [npc.constitution]"
hbox:
text "Wis: [npc.wisdom] Int: [npc.intelligence] Cha: [npc.charisma]"
hbox:
# Health bar
frame:
# background "bar_background.png"
bar value "[npc.current_Health / float(npc.total_Health)]" # The bar fill ratio
text "[npc.current_Health]/[npc.total_Health]" at center
# Spell Slots
frame:
# background "bar_background.png"
bar value "[npc.current_Slots / float(npc.total_Slots)]"
text "[npc.current_Slots]/[npc.total_Slots]" at center
# Power Slots
frame:
# background "bar_background.png"
bar value "[npc.current_Power / float(npc.total_Power)]"
text "[npc.current_Power]/[npc.total_Power]" at center
# Player box at the bottom outside the grid of NPC boxes
vbox:
align (.5, 1.0) # This will center align the player box at the bottom
text "[player.name]"
hbox:
text "Str: [player.characterStrength] Dex: [player.characterDexterity] Con: [player.characterConstitution]"
hbox:
text "Wis: [player.characterWisdom] Int: [player.characterIntelligence] Cha: [player.characterCharisma]"
hbox:
# Health bar for Player
frame:
# background "bar_background.png"
bar value "[player.currentHealth / float(player.totalhealth)]"
text "[player.currentHealth]/[player.totalhealth]" at center
# Spell Slots for Player
frame:
# background "bar_background.png"
bar value "[player.currentSpellSlots / float(player.totalSpellSlots)]"
text "[player.currentSpellSlots]/[player.totalSpellSlots]" at center
# Power Slots for Player
frame:
# background "bar_background.png"
bar value "[player.currentPowerSlots / float(player.totalPowerSlots)]"
text "[player.currentPowerSlots]/[player.totalPowerSlots]" at center
Code: Select all
# Making it a global variable:
init python:
global squad_NPCs
squad_NPCs = []
screen squad_screen(squad_NPCs):
...
for i, npc in enumerate(globals["squad_NPCs"]):
# Calling a "stopgap" label:
textbutton "View Squad Screen" xalign 0.5 action [call show_squad_screen]
label show_squad_screen():
$ renpy.hide("squad_screen_button")
$ renpy.call_screen("squad_screen")
label hide_squad_screen():
$ renpy.hide("squad_screen")
$ renpy.show("squad_screen_button")
# Passing parameters to the stopgap:
label show_squad_screen(squad_NPCs):
$ renpy.hide("squad_screen_button")
$ renpy.call_screen("squad_screen", squad_NPCs=squad_NPCs)
label show_squad_screen():
$ renpy.hide("squad_screen_button")
$ renpy.call_screen("squad_screen", squad_NPCs=squad_NPCs)
Code: Select all
screen squad_screen(squad_NPCs):
Code: Select all
for i, npc in enumerate(squad_NPCs):
Somehow I feel like this is a really simple solution, but it is evading me. I think it might have to do with the syntax of passing a list as a parameter to a screen, but regardless of what I've tried, this is the error it returns:
I'm sorry, but an uncaught exception occurred.
While running game code:
File "game/script.rpy", line 12, in script
menu:
TypeError: missing a required argument: 'squad_NPCs'
-- Full Traceback ------------------------------------------------------------
Full traceback:
File "game/script.rpy", line 12, in script
menu:
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\ast.py", line 1618, in execute
choice = renpy.exports.menu(choices, self.set, args, kwargs, item_arguments)
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\exports.py", line 1109, in menu
rv = renpy.store.menu(new_items)
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\exports.py", line 1364, in display_menu
rv = renpy.ui.interact(mouse='menu', type=type, roll_forward=roll_forward)
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\ui.py", line 301, in interact
rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\display\core.py", line 2165, in interact
repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, pause=pause, pause_start=pause_start, pause_modal=pause_modal, **kwargs) # type: ignore
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\display\core.py", line 2687, in interact_core
root_widget.visit_all(lambda d : d.per_interact())
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\display\displayable.py", line 431, in visit_all
d.visit_all(callback, seen)
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\display\displayable.py", line 431, in visit_all
d.visit_all(callback, seen)
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\display\displayable.py", line 431, in visit_all
d.visit_all(callback, seen)
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\display\screen.py", line 480, in visit_all
callback(self)
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\display\core.py", line 2687, in <lambda>
root_widget.visit_all(lambda d : d.per_interact())
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\display\screen.py", line 491, in per_interact
self.update()
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\display\screen.py", line 697, in update
self.screen.function(**self.scope)
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\parameter.py", line 429, in apply_arguments
return parameters.apply(args or (), kwargs or {}, ignore_errors)
File "C:\Users\6ft5r\Desktop\Ren'py\renpy-8.2.1-sdk\renpy\parameter.py", line 283, in apply
raise TypeError(msg) # from None
TypeError: missing a required argument: 'squad_NPCs'
```
Ignore the part about the script.rpy and the menu, that's just referring to where the crash occurs. Its a debugging statement I use to test a lot of different functionalities. I've looked through and commented everything out, or removed elements. Nothing seems to cause this error on that screen. It just crashes on trying to call squad_screen.
Any help anyone could render would be greatly appreciated. Thank you!