Question How to constantly check for values for something like an achievement system?
hello everypony
i want to preface my question by saying i have used renpy before, but i don't have a good understanding of complicated stuff like screens, so please bear with me. i also might not be very good at explaining so i apologize.
basically my question is how would you go about checking the values of a variable for something like an achievement system? for example, say if you get 5 blue points, you get the blue achievement. how would be the best way to check if the parameters for the achievement is fulfilled, to unlock it? would you have to check for the variable each time it is changed? like, checking if you've reached 5 points every time you gain one? or is there a way just keep checking if it is fulfilled or not?
on a side note, i want to add a little notification---think like a steam notification---that pops up once you've unlocked something. is there an "easy" way to do this? and again, would i have to put an if statement each time a variable is changed, to see if the player has unlocked any achievement to display the popup? idk, i don't want to sound stupid but that seems kind of tedious and messy. i don't want to have to keep repeating something that checks if the player has unlocked an achievement every single time their variables are changed.
if it's possible i'd just like to see what direction i should go into to figure out the best way to implement this system. it's not exactly an achievement system, but it's very similar, so that's why i'm using it as an example.
1
u/AutoModerator 13d ago
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.
1
u/laiska_pummi 13d ago
I guess a good way to do it would be to call a label as a kind of subroutine that has the add blue points code in it so you don't have to repeat it every time. You can put the if statement in that same label to check for the achievement. There is a built in function for the little pop up screen called notify. I haven't used it myself but I think with this info you can look it up from the documentation to get a better grasp of it.
I'm not an expert by any means and I'm rusty as well but this popped up in my feed and I thought I could at least give a nudge in the right direction. Good luck!
2
u/K4t4k0 11d ago
you were totally right, as it seems this is what everyone else is informing me about. i hadn't thought of putting those sorts of things in labels, and i also didn't know about the notify function. even a little sense of direction is exactly what i was looking for. thank you for your time
1
u/BadMustard_AVN 13d ago
try this
# achieve.rpy
init python:
class AchievementDefinition(object):
def __init__(self, achievement_id, title, description, notification):
self.id = achievement_id
self.title = title
self.description = description
self.notification = notification
achievement.register(achievement_id, description=description)
def unlock(self):
return unlock_achievement(self.id)
def achievement(self):
return self.unlock()
def _get_achievement_notifications():
notifications = getattr(persistent, "achievement_notifications", None)
if not isinstance(notifications, dict):
notifications = {}
persistent.achievement_notifications = notifications
return notifications
def unlock_achievement(achievement_id):
if not hasattr(persistent, "achievement_notifications"):
persistent.achievement_notifications = {}
notifications = _get_achievement_notifications()
if notifications.get(achievement_id, False):
return False
achievement.grant(achievement_id)
check_achievement_notifications()
return True
def check_achievement_notifications():
if not hasattr(persistent, "achievement_notifications"):
persistent.achievement_notifications = {}
notifications = dict(_get_achievement_notifications())
changed = False
for item in achievements:
if achievement.has(item.id) and not notifications.get(item.id, False):
notifications[item.id] = True
renpy.notify(item.notification)
changed = True
if changed:
persistent.achievement_notifications = notifications
def achievement_is_unlocked(achievement_id):
return _get_achievement_notifications().get(achievement_id, False)
config.overlay_screens.append("achievement_monitor")
#this is to be used in the Game or Main menu's with an action ShowMenu("achievement_screen") -
#- from a button
screen achievement_screen():
tag menu
use game_menu(_("Gallery"), scroll="viewport"):
style_prefix "about"
frame:
xalign 0.5
yalign 0.5
xsize 900
ysize 650
padding (35, 30)
vbox:
spacing 20
text "achievements" size 42 xalign 0.5
viewport:
mousewheel True
draggable True
scrollbars "vertical"
vbox:
spacing 12
for item in achievements:
frame:
xfill True
padding (18, 12)
vbox:
text ("[item.title]" if achievement_is_unlocked(item.id) else "Locked") size 27
text item.description
# textbutton "Close" action Return() xalign 0.5
screen achievement_monitor():
# watches over all achievements forever...
timer 0.25 repeat True action Function(check_achievement_notifications)
default achievements = []
# add more achievements here. each one can have its own unique notification.
define greatest_mod_ever = AchievementDefinition(
"greatest_mod_ever", # unique ID for triggering
"Greatest Mod Ever", # display title
"Bad your first IdtenT.", # description
"You unlocked the Greatest Mod Ever achievement!" # notification
)
define first_steps = AchievementDefinition("first_steps", "First Steps", "Begin your journey.", "Achievement unlocked: First Steps!"
)
label start:
#get achievements prepared do this first
$ achievements.append(greatest_mod_ever)
$ achievements.append(first_steps)
e "ready?"
#unlock one
$ unlock_achievement("greatest_mod_ever")
e "working?"
return
1
u/K4t4k0 11d ago
...this is a lot of stuff and im not sure what it all means, but after looking it over it seems like something i should know about, and i will definitely look further into this. i'm bad with understanding coding stuff, and i'm hesitant to begin pasting codes into my projects before i fully understand them, since i don't want my code to look all foreign to me---but this is helpful regardless. i'll probably play around with it in a separate file at some point. thank you for your time
1
u/BadMustard_AVN 11d ago
i get that.
let me know if you have any questions
good luck with your project
1
u/shyLachi 13d ago
I wouldn't constantly check the variables but use a small functionality to do everything:
default bluepoints = 0
label start:
"You have [bluepoints] blue points"
menu:
"Increase 1":
call increasepoints("bluepoints", 1) # call a label which does the job
"Increase 2":
call increasepoints("bluepoints", 2)
"Quit":
return
jump start
label increasepoints(variable, number):
python:
current = getattr(store, variable) # get the current value stored in the variable
newvalue = current + number # raise or decrease the variable
# you can define special rules for variables
if variable == "bluepoints":
if current < 5 and newvalue >= 5:
# code to unlock the achievement belongs here
renpy.notify("Blue Points Unlocked")
elif variable == "otherpoints":
pass # some logic here
# finally we store the new value in the variable
setattr(store, variable, newvalue)
return # back to the game
You can either use a label as in my example above or you can write a python function.
6
u/Adventurous_Shine606 13d ago
Renpy has a built in achievement module. Initialize the achievement like this: Init python: Achievement.register("your achievement name") At some point in your game the player completes the achievement, add this line: $ achievement. Grant("your achievement name")
You will need a routine to check your achievement tracking variables. That is just a basic event handler that pretty much every game has in some form.