Is it possible to access the default value of an array after it has changed?
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Is it possible to access the default value of an array after it has changed?
Specifically, I was wondering about updating an array between versions of a game. Let's say the default value for the array is [0,1,2] in version 0.1 and [0,1,2,3,4] in version 0.2. Is it possible to compare the saved array size with the new default one, and if they are different, appending the new values?
- m_from_space
- Eileen-Class Veteran
- Posts: 1057
- Joined: Sun Feb 21, 2021 3:36 am
- Contact:
Re: Is it possible to access the default value of an array after it has changed?
Is the array constant over a game or does it change when the player progresses? (If it changes, you have to know what it could look like.)
You can always check for the current value of a variable after the player loads a game via the special label "after_load":
You can always check for the current value of a variable after the player loads a game via the special label "after_load":
Code: Select all
# renpy jumps here after loading a game and before the game resumes
label after_load:
if array == [0, 1, 2]:
$ array = [0, 1, 2, 3, 4]
return
Re: Is it possible to access the default value of an array after it has changed?
I figured something like that would work, but I was hoping there would be a way to actually check the default value rather than copy the full array below the "after_load" label (I have a class for quests, and I keep them in an array to store info for a questlog, so it's going to become quite large as I add more quests to the game). It's not a big problem though, and if there is no way to directly check the default values, then a variant of this is perfectly fine, Thanks!m_from_space wrote: ↑Tue May 31, 2022 6:51 am Is the array constant over a game or does it change when the player progresses? (If it changes, you have to know what it could look like.)
You can always check for the current value of a variable after the player loads a game via the special label "after_load":
Code: Select all
# renpy jumps here after loading a game and before the game resumes label after_load: if array == [0, 1, 2]: $ array = [0, 1, 2, 3, 4] return
- m_from_space
- Eileen-Class Veteran
- Posts: 1057
- Joined: Sun Feb 21, 2021 3:36 am
- Contact:
Re: Is it possible to access the default value of an array after it has changed?
Well, you could easily just check for the length of the "array" (in this case actually called a list) or parts of its contents. And you could define a "new_array" and just keep the old default one.mdqp wrote: ↑Wed Jun 01, 2022 3:00 amI figured something like that would work, but I was hoping there would be a way to actually check the default value rather than copy the full array below the "after_load" label (I have a class for quests, and I keep them in an array to store info for a questlog, so it's going to become quite large as I add more quests to the game). It's not a big problem though, and if there is no way to directly check the default values, then a variant of this is perfectly fine, Thanks!
Code: Select all
default array = [1, 2, 3]
default new_array = [1, 2, 3, 4, "newquest"]
label after_load:
if len(array) == 3:
$ array = new_array
# or something like
if "newquest" not in array:
$ array = new_array
Re: Is it possible to access the default value of an array after it has changed?
Oh, don't worry, I already have a solution pretty similar to the one you suggest. I don't like the idea of maintaining two copies of the same array (I still need to update the default value, and I define a copy to check against, now). It's hardly a big deal, and yes, I do check the length against the number of quests I have in the game (since that's a known quantity) and if there is a discrepancy I loop and add quests until everything is fine (I do this to avoid replacing the values in quests that are already in the game, since the player might have started those already).m_from_space wrote: ↑Wed Jun 01, 2022 5:35 amWell, you could easily just check for the length of the "array" (in this case actually called a list) or parts of its contents. And you could define a "new_array" and just keep the old default one.
Code: Select all
default array = [1, 2, 3] default new_array = [1, 2, 3, 4, "newquest"] label after_load: if len(array) == 3: $ array = new_array # or something like if "newquest" not in array: $ array = new_array
I just wanted to know if I could access the default value, because it would have been "cleaner" to handle (I am always afraid to introduce some minor mistakes when I copy/paste something).
Re: Is it possible to access the default value of an array after it has changed?
What is the array you have, and what changes do you want to make to it? There are a couple of possible answers:
1) If it's fixed content that doesn't change during play, just create it with 'define' instead of 'default'. Then it won't be written to the save file and when you update the code, you'll always have the up-to-date value, no "old versions" to worry about.
2) If you're just adding new content, you don't have to track what the old version was, just test if the new values are there, and if not, add them. This probably is easier if you have a dict rather than a list:
You can always recover a list from a dict with
1) If it's fixed content that doesn't change during play, just create it with 'define' instead of 'default'. Then it won't be written to the save file and when you update the code, you'll always have the up-to-date value, no "old versions" to worry about.
2) If you're just adding new content, you don't have to track what the old version was, just test if the new values are there, and if not, add them. This probably is easier if you have a dict rather than a list:
Code: Select all
label after_load:
if not "new_quest_id" in all_quests.keys():
all_quests["new_quest_id"] = new_quest_data()
Code: Select all
quest_list = list(quest_dict.values())
colin r
➔ if you're an artist and need a bit of help coding your game, feel free to send me a PM
➔ if you're an artist and need a bit of help coding your game, feel free to send me a PM
Re: Is it possible to access the default value of an array after it has changed?
Really sorry for the late reply, I didn't check the forum in a while. The way I currently use the array, I also need to update some of the entries (for example, when an objective is visible, invisible, failed or completed), so I need to keep the data from old saves "as is" while adding new entries for new quests as I introduce them to the game (I make my money on Patreon, which means incremental updates each month).zmook wrote: ↑Wed Jun 01, 2022 12:39 pm What is the array you have, and what changes do you want to make to it? There are a couple of possible answers:
1) If it's fixed content that doesn't change during play, just create it with 'define' instead of 'default'. Then it won't be written to the save file and when you update the code, you'll always have the up-to-date value, no "old versions" to worry about.
2) If you're just adding new content, you don't have to track what the old version was, just test if the new values are there, and if not, add them. This probably is easier if you have a dict rather than a list:
You can always recover a list from a dict withCode: Select all
label after_load: if not "new_quest_id" in all_quests.keys(): all_quests["new_quest_id"] = new_quest_data()
Code: Select all
quest_list = list(quest_dict.values())
To do this, I effectively have a second copy of the array I check under the after_load label.
Code: Select all
# fixing savefiles after loading
################################
label after_load:
while len(questlog) < 2:
$ questlog_fix = [Quest("Homecoming", "started",
"You are trying to learn how and when the brainwashing started to affect you. Even if ALICE is not a problem anymore,"
"you can't just ignore this situation. A visit to your home planet and your family might help you uncover what's going on.",
[[0, True, "Meet with your father and sister."], [0, False, "Ask them about unusual behaviour from you while you were still on Caldora."], [0, False, ""]]),
Quest("Friendly Visit", "hidden",
"A gang of small time criminals stole a family heirloom and the owner wants it back. Time to pay a visit to their hideout, and see what you can do.",
[[0, True, "Go to the location."], [0, True, "Find a way inside the hideout."], [0, True, "Find the item."], [0, True, "See if you can find other valuables. (optional)"]])
]
$ quest_pos = len(questlog)
$ questlog.append(questlog_fix[quest_pos])
- m_from_space
- Eileen-Class Veteran
- Posts: 1057
- Joined: Sun Feb 21, 2021 3:36 am
- Contact:
Re: Is it possible to access the default value of an array after it has changed?
You definitely should use a dictionary here. It's perfectly made for it. Use a simple internal word as the dictionary key (e.g. "homecoming") and it's very easy to check if this quest exists. Or updating data of this quest. Checking for the length of the array here is less manageable. My example just wanted to point you to using after_load.
Using a dictionary is pretty simple, since you don't have to use "append()" or anything special. You also don't need the keys() function in Python3 as @zmook suggested.
Using a dictionary is pretty simple, since you don't have to use "append()" or anything special. You also don't need the keys() function in Python3 as @zmook suggested.
Code: Select all
default quests = {}
if "homecoming" not in quests:
quests["homecoming"] = [0, "hide", "text"...]
Re: Is it possible to access the default value of an array after it has changed?
I see. Thanks a lot at you and @zmook for taking your time to reply. I am still using Ren'Py 7.3.5 which I think means no Python 3 for me (I am slowly working on this game's demo as I develop my "main" game at the time, and I didn't want to update mid-development, especially after an update did cause me some issues in the past).m_from_space wrote: ↑Sat Jul 23, 2022 1:05 pm You definitely should use a dictionary here. It's perfectly made for it. Use a simple internal word as the dictionary key (e.g. "homecoming") and it's very easy to check if this quest exists. Or updating data of this quest. Checking for the length of the array here is less manageable. My example just wanted to point you to using after_load.
Using a dictionary is pretty simple, since you don't have to use "append()" or anything special. You also don't need the keys() function in Python3 as @zmook suggested.
Code: Select all
default quests = {} if "homecoming" not in quests: quests["homecoming"] = [0, "hide", "text"...]
I do have some qualms about switching to a dictionary, mainly because I already have a working questlog screen and all of that, but I'll give it a go and see if I can make things easier for myself. I'll leave the code here, in case anyone is interested.
Code: Select all
class Quest(store.object):
def __init__(self, name, status, desc, objectives):
self.name = name
self.desc = desc
self.status = status
self.objectives = objectives
def reveal_quest(quest):
if questlog[quest].status == "hidden":
questlog[quest].status = "started"
def hide_quest(quest):
questlog[quest].status = "hidden"
def fail_quest(quest):
questlog[quest].status = "failed"
def complete_quest(quest):
questlog[quest].status = "complete"
def reveal_objective(quest, *objv):
for obj in objv:
if questlog[quest].objectives[obj][1] == False:
questlog[quest].objectives[obj][1] = True
def hide_objective(quest, *objv):
for obj in objv:
if questlog[quest].objectives[obj][1] == True:
questlog[quest].objectives[obj][1] = False
def complete_objective(quest, *objv):
for obj in objv:
questlog[quest].objectives[obj][0] = 2
def fail_objective(quest, *objv):
for obj in objv:
questlog[quest].objectives[obj][0] = 1
def reset_objective(quest, *objv):
for obj in objv:
questlog[quest].objectives[obj][0] = 0
default questlog = [Quest("Homecoming", "started",
"You are trying to learn how and when the brainwashing started to affect you. Even if ALICE is not a problem anymore,"
"you can't just ignore this situation. A visit to your home planet and your family might help you uncover what's going on.",
[[0, True, "Meet with your father and sister."], [0, False, "Ask them about unusual behaviour from you while you were still on Caldora."], [0, False, ""]]),
Quest("Friendly Visit", "hidden",
"A gang of small time criminals stole a family heirloom and the owner wants it back. Time to pay a visit to their hideout, and see what you can do.",
[[0, True, "Go to the location."], [0, True, "Find a way inside the hideout."], [0, True, "Find the item."], [0, True, "See if you can find other valuables. (optional)"]])
]
default questlog_text = 0
default questlog_page = "started"
screen questlog:
key "mouseup_2" action NullAction()
key "h" action NullAction()
key "noshift_K_h" action NullAction()
zorder 110
add "gui/extranet_background.png"
modal True
frame:
area (16,48,358,674)
background Solid("#0000FF00")
side ("c r"):
viewport id "my_questlog_scroller": #REMEMBER YOUR VIEWPORT ID SO THE SCROLLBAR IS PLACED FOR IT
draggable True mousewheel True
vbox:
for quest in questlog:
if quest.status == questlog_page:
textbutton quest.name action SetVariable("questlog_text", questlog.index(quest))
vbar value YScrollValue("my_questlog_scroller") #TAKES YOUR VIEWPORT ID AS THE ARG
null height 20 #just a height set.
vbox:
style_prefix "pers"
xpos 424
ypos 64
xmaximum 1056
ymaximum 800
spacing 30
if questlog_text >= 0:
if questlog[questlog_text].status == questlog_page:
text questlog[questlog_text].desc
vbox:
style_prefix "pers"
xpos 1568
ypos 64
xmaximum 320
ymaximum 640
spacing 30
if questlog_text >= 0:
if questlog[questlog_text].status == questlog_page:
for obj in questlog[questlog_text].objectives:
if obj[1] == True:
if obj[0] == 0:
text "{=default}♦{/=default} " + obj[2]
elif obj[0] == 1:
text "{color=#e60000}{=default}{color=#e60000}♦{/color}{/=default} " + obj[2] + "{/color}"
else:
text "{color=00ff00}{=default}{color=00ff00}♦{/color}{/=default} " + obj[2] + "{/color}"
else:
text "error"
add "gui/extranet_foreground.png"
hbox:
spacing 10
xalign 0.5 yalign 0.85
textbutton "Active" action SetVariable("questlog_page", "started") padding (0,0)
textbutton "Complete" action SetVariable("questlog_page", "complete") padding (0,0)
textbutton "Failed" action SetVariable("questlog_page", "failed") padding (0,0)
hbox:
xalign 0.5 yalign 0.95
textbutton "Back" action [ Show('hologlasses_button'), Hide("questlog")]
Who is online
Users browsing this forum: Google [Bot]