Showing game stats on file slots?

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
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.
Message
Author
User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Showing game stats on file slots?

#16 Post by hell_oh_world »

Adrian_DVL wrote: Sun May 03, 2020 6:03 am Guys, I've tried just by giving the variable save_name a string with all the variables and even a few interpolated images, but the outcome is just about the same as with Alex's code. Seems the problem here are the variables themselves, as they won't be stored and be displayed while in the main menu.
Here's what I got in the save screen inside the game:
Image
Here's what I got in the load screen in the main menu:
Image
Clearly my problem is that I'm not able to access game variables outside the game. If I was, then I'd be able to implement Alex's code, as it's the fanciest and most functional way to do this.
It seems my best choice is to use FileJson somehow as MaydohMaydoh suggested, since I'm sure that way the variables will be accessed outside the game, but I don't know how to use it properly to display different things in a file slot. Can someone help me?
That should not happen, imo. The save name is dependent on the save name stored in each save file. I know there are already a lot of suggestions, but this is how I'll make something like this. This code should auto update the save_name variable before saving...

Code: Select all

init python:
	class Player:
		def __init__(self, money, attitude=10, fame=5):
			self.money = money
			self.attitude = attitude
			self.fame = fame

	import json
	
	def encodeSaveName(player, *includes):
		save_name = dict()
		
		for key, value in player.__dict__.items():
			if key in includes:
				try:
					json.dumps({key: value})
					save_name.update({key: value})
				except:
					pass
		
		store.save_name = json.dumps(save_name)
	
	def decodeSaveName(save_name):
		try:
  			save_name = json.loads(save_name)
		except:
  			save_name = dict()
  			
		return save_name
	
default player = Player(100)

screen file_slots():
	# some codes above...
		button:
                        action [
                        	Function(encodeSaveName, player, "money", "attitude"), # add here the other variables for the player that you want to get saved... doing Function(encodeSaveName, player) means nothing will be saved...
                        	FileAction(slot)
                        ]

                        has vbox

                        add FileScreenshot(slot) xalign 0.5

                        text FileTime(slot, format=_("{#file_time}%A, %B %d %Y, %H:%M"), empty=_("empty slot")):
                            style "slot_time_text"

			for key, value in decodeSaveName(FileSaveName(slot)).items(): # loop through the saved data...
                        	text "{}: {}".format(key, value):
                            		style "slot_name_text"
	# some codes below...
	
Edit: just tested it, and its working, even while going back to the main menu the save name stays...
in the load screen while in game...
sample2.png
in the load screen while in main menu
sample.png
Last edited by hell_oh_world on Sun May 03, 2020 8:32 am, edited 1 time in total.

User avatar
Imperf3kt
Lemma-Class Veteran
Posts: 3791
Joined: Mon Dec 14, 2015 5:05 am
itch: Imperf3kt
Location: Your monitor
Contact:

Re: Showing game stats on file slots?

#17 Post by Imperf3kt »

Sorry, completely forgot about this.
You need to use a JSON file, which I think was explained by another poster.

I'll look up my projects later to check what mineclooks like (I only display game playtime, so I'm not sure if I could help, but it might give you an idea)
Warning: May contain trace amounts of gratuitous plot.
pro·gram·mer (noun) An organism capable of converting caffeine into code.

Current project: GGD Mentor

Twitter

Adrian_DVL
Regular
Posts: 141
Joined: Fri Mar 15, 2019 8:46 am
Completed: Clockwork Poison
Projects: Melodic Dates, Clockwork Poison: Salvation
Contact:

Re: Showing game stats on file slots?

#18 Post by Adrian_DVL »

hell_oh_world wrote: Sun May 03, 2020 6:37 am That should not happen, imo. The save name is dependent on the save name stored in each save file. I know there are already a lot of suggestions, but this is how I'll make something like this. This code should auto update the save_name variable before saving...

Edit: just tested it, and its working, even while going back to the main menu the save name stays...
in the load screen while in game...
sample2.png
in the load screen while in main menu
sample.png
I'm really sorry to tell you this, but I have the same problem, but translated to our current code: every variable is displayed correctly in the save screen and even in the load screen inside the game, but when I try to load the game from the main menu, it gives me a traceback saying that "player" (in my case "saved") is not defined:

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "renpy/common/00start.rpy", line 309, in script call
    call expression "before_main_menu"
  File "game/script.rpy", line 417, in script
    call screen main_menu
  File "renpy/common/000statements.rpy", line 531, in execute_call_screen
    store._return = renpy.call_screen(name, *args, **kwargs)
  File "game/screens.rpy", line 694, in execute
    screen load():
  File "game/screens.rpy", line 694, in execute
    screen load():
  File "game/screens.rpy", line 698, in execute
    use file_slots(_("Load"))
  File "game/screens.rpy", line 706, in execute
    screen file_slots(title):
  File "game/screens.rpy", line 706, in execute
    screen file_slots(title):
  File "game/screens.rpy", line 710, in execute
    use game_menu(title):
  File "game/screens.rpy", line 514, in execute
    screen game_menu(title, scroll=None, yinitial=0.0):
  File "game/screens.rpy", line 514, in execute
    screen game_menu(title, scroll=None, yinitial=0.0):
  File "game/screens.rpy", line 523, in execute
    frame:
  File "game/screens.rpy", line 526, in execute
    hbox:
  File "game/screens.rpy", line 532, in execute
    frame:
  File "game/screens.rpy", line 535, in execute
    if scroll == "viewport":
  File "game/screens.rpy", line 567, in execute
    transclude
  File "game/screens.rpy", line 710, in execute
    use game_menu(title):
  File "game/screens.rpy", line 712, in execute
    fixed:
  File "game/screens.rpy", line 732, in execute
    grid gui.file_slot_cols gui.file_slot_rows:
  File "game/screens.rpy", line 741, in execute
    for i in range(gui.file_slot_cols * gui.file_slot_rows):
  File "game/screens.rpy", line 744, in execute
    button:
  File "game/screens.rpy", line 744, in keywords
    button:
NameError: name 'saved' is not defined

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "renpy/common/00start.rpy", line 309, in script call
    call expression "before_main_menu"
  File "game/script.rpy", line 417, in script
    call screen main_menu
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\ast.py", line 1949, in execute
    self.call("execute")
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\ast.py", line 1937, in call
    return renpy.statements.call(method, parsed, *args, **kwargs)
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\statements.py", line 277, in call
    return method(parsed, *args, **kwargs)
  File "renpy/common/000statements.rpy", line 531, in execute_call_screen
    store._return = renpy.call_screen(name, *args, **kwargs)
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\exports.py", line 2905, in call_screen
    rv = renpy.ui.interact(mouse="screen", type="screen", roll_forward=roll_forward)
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\ui.py", line 297, in interact
    rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\display\core.py", line 2702, in interact
    repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, **kwargs)
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\display\core.py", line 3094, in interact_core
    root_widget.visit_all(lambda i : i.per_interact())
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\display\core.py", line 541, in visit_all
    d.visit_all(callback, seen)
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\display\core.py", line 541, in visit_all
    d.visit_all(callback, seen)
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\display\core.py", line 541, in visit_all
    d.visit_all(callback, seen)
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\display\core.py", line 541, in visit_all
    d.visit_all(callback, seen)
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\display\screen.py", line 430, in visit_all
    callback(self)
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\display\core.py", line 3094, in <lambda>
    root_widget.visit_all(lambda i : i.per_interact())
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\display\screen.py", line 440, in per_interact
    self.update()
  File "H:\Archivos de Programa\Renpy-7.2.0-sdk\renpy\display\screen.py", line 625, in update
    self.screen.function(**self.scope)
  File "game/screens.rpy", line 694, in execute
    screen load():
  File "game/screens.rpy", line 694, in execute
    screen load():
  File "game/screens.rpy", line 698, in execute
    use file_slots(_("Load"))
  File "game/screens.rpy", line 706, in execute
    screen file_slots(title):
  File "game/screens.rpy", line 706, in execute
    screen file_slots(title):
  File "game/screens.rpy", line 710, in execute
    use game_menu(title):
  File "game/screens.rpy", line 514, in execute
    screen game_menu(title, scroll=None, yinitial=0.0):
  File "game/screens.rpy", line 514, in execute
    screen game_menu(title, scroll=None, yinitial=0.0):
  File "game/screens.rpy", line 523, in execute
    frame:
  File "game/screens.rpy", line 526, in execute
    hbox:
  File "game/screens.rpy", line 532, in execute
    frame:
  File "game/screens.rpy", line 535, in execute
    if scroll == "viewport":
  File "game/screens.rpy", line 567, in execute
    transclude
  File "game/screens.rpy", line 710, in execute
    use game_menu(title):
  File "game/screens.rpy", line 712, in execute
    fixed:
  File "game/screens.rpy", line 732, in execute
    grid gui.file_slot_cols gui.file_slot_rows:
  File "game/screens.rpy", line 741, in execute
    for i in range(gui.file_slot_cols * gui.file_slot_rows):
  File "game/screens.rpy", line 744, in execute
    button:
  File "game/screens.rpy", line 744, in keywords
    button:
  File "<screen language>", line 746, in <module>
NameError: name 'saved' is not defined

Windows-8-6.2.9200
Ren'Py 7.3.5.606
Melodic Dates 0.1
Sun May 03 13:49:19 2020
I assume this is exactly the same problem as before, but I don't rightly understand it now, as we're using json encoder and decoder to pass the variables...

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Showing game stats on file slots?

#19 Post by hell_oh_world »

Adrian_DVL wrote: Sun May 03, 2020 7:56 am
hell_oh_world wrote: Sun May 03, 2020 6:37 am That should not happen, imo. The save name is dependent on the save name stored in each save file. I know there are already a lot of suggestions, but this is how I'll make something like this. This code should auto update the save_name variable before saving...

Edit: just tested it, and its working, even while going back to the main menu the save name stays...
in the load screen while in game...
sample2.png
in the load screen while in main menu
sample.png
I'm really sorry to tell you this, but I have the same problem, but translated to our current code: every variable is displayed correctly in the save screen and even in the load screen inside the game, but when I try to load the game from the main menu, it gives me a traceback saying that "player" (in my case "saved") is not defined:

Code: Select all


NameError: name 'saved' is not defined

Windows-8-6.2.9200
Ren'Py 7.3.5.606
Melodic Dates 0.1
Sun May 03 13:49:19 2020
I assume this is exactly the same problem as before, but I don't rightly understand it now, as we're using json encoder and decoder to pass the variables...
well, don't use old saves... after applying my suggestion, i suggest, deleting the persistent data and save files in the game directory and by going to launcher and pressing delete persistent and making a new save and loading that instead. also make sure that you have removed all the variables that are not necessary or that was previously included because you were trying others' suggestions, the error says that the saved variable is not defined which is not included in my code, prolly it belongs to the other codes that you've tried before.

if the saved variable is your player variable then it must be defaulted just like in my example. always default your variables.

Adrian_DVL
Regular
Posts: 141
Joined: Fri Mar 15, 2019 8:46 am
Completed: Clockwork Poison
Projects: Melodic Dates, Clockwork Poison: Salvation
Contact:

Re: Showing game stats on file slots?

#20 Post by Adrian_DVL »

hell_oh_world wrote: Sun May 03, 2020 8:02 am well, don't use old saves... after applying my suggestion, i suggest, deleting the persistent data and save files in the game directory and by going to launcher and pressing delete persistent. also make sure that you have removed all the variables that are not necessary or that was previously included because you were trying others' suggestions, the error says that the saved variable is not defined which is not included in my code, prolly it belongs to the other codes that you've tried before.
I've deleted persistent and saved games and the issue is still the same. Regarding the saved variable, the thing is that not all the variables that I want to display in the file slot are parameters of the same class, so I made another class to store all the variables that I want to display in the file slot and named it "Saved", which is equivalent to your "Player". In fact, as I said, all of the variables are correctly shown on the save screen inside the game. Regarding others' suggestions, I'm pretty sure it's all removed.

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Showing game stats on file slots?

#21 Post by hell_oh_world »

Adrian_DVL wrote: Sun May 03, 2020 8:11 am
hell_oh_world wrote: Sun May 03, 2020 8:02 am well, don't use old saves... after applying my suggestion, i suggest, deleting the persistent data and save files in the game directory and by going to launcher and pressing delete persistent. also make sure that you have removed all the variables that are not necessary or that was previously included because you were trying others' suggestions, the error says that the saved variable is not defined which is not included in my code, prolly it belongs to the other codes that you've tried before.
I've deleted persistent and saved games and the issue is still the same. Regarding the saved variable, the thing is that not all the variables that I want to display in the file slot are parameters of the same class, so I made another class to store all the variables that I want to display in the file slot and named it "Saved", which is equivalent to your "Player". In fact, as I said, all of the variables are correctly shown on the save screen inside the game. Regarding others' suggestions, I'm pretty sure it's all removed.
edited my earlier post... added some information on what should be done.

The thing is the code that I've provided should work in any objects of any class, and you can use the saved class object that you made without a problem, you just need to specify what attributes to save in the `Function(encodeSaveName, saved, "attr1", "attr2") # and more attributes... as many as you want`

Adrian_DVL
Regular
Posts: 141
Joined: Fri Mar 15, 2019 8:46 am
Completed: Clockwork Poison
Projects: Melodic Dates, Clockwork Poison: Salvation
Contact:

Re: Showing game stats on file slots?

#22 Post by Adrian_DVL »

hell_oh_world wrote: Sun May 03, 2020 8:15 am
Adrian_DVL wrote: Sun May 03, 2020 8:11 am
hell_oh_world wrote: Sun May 03, 2020 8:02 am well, don't use old saves... after applying my suggestion, i suggest, deleting the persistent data and save files in the game directory and by going to launcher and pressing delete persistent. also make sure that you have removed all the variables that are not necessary or that was previously included because you were trying others' suggestions, the error says that the saved variable is not defined which is not included in my code, prolly it belongs to the other codes that you've tried before.
I've deleted persistent and saved games and the issue is still the same. Regarding the saved variable, the thing is that not all the variables that I want to display in the file slot are parameters of the same class, so I made another class to store all the variables that I want to display in the file slot and named it "Saved", which is equivalent to your "Player". In fact, as I said, all of the variables are correctly shown on the save screen inside the game. Regarding others' suggestions, I'm pretty sure it's all removed.
edited my earlier post... added some information on what should be done.

The thing is the code that I've provided should work in any objects of any class, and you can use the saved class object that you made without a problem, you just need to specify what attributes to save in the `Function(encodeSaveName, saved, "attr1", "attr2") # and more attributes... as many as you want`
Okay, we've made progresses here. The thing is that I somehow had defaulted "save" instead of "saved" with the "d". Now it's FINALLY working. It's working except for what I was afraid for: the name and other plain variables are shown correctly even in the main menu, but the variables that are obtained from a function inside the game are not. So I have this in the load screen from the main menu (obviously, without having formatted it yet):
Image
The variables that are not properly shown are job, which is obtained like this:

Code: Select all

def jobname():
        global job
        if jobn == 1:
            job = __("Trainee music teacher") # Name of the job
        elif jobn == 2:
            job = __("Associate music professor")
        elif jobn == 3:
            job = __("Senior lecturer")
        elif jobn == 4:
            job = __("Full music professor")
        elif jobn == 5:
            job = __("Music Faculty Dean")
Hours and minutes, which are obtained like this:

Code: Select all

def calc_total_run():
        persistent.runtime += renpy.get_game_runtime()
        renpy.clear_game_runtime()

Code: Select all

$ minutes, seconds = divmod(int(persistent.runtime), 60)
$ hours, minutes = divmod(minutes, 60)
And metnum and maxnum, which are obtained setting them to the result of a class module:

Code: Select all

$ metnum = glist.metnum()
$ maxnum = glist.maxnum()
I execute all of these upon entering the game main flow, where the player can save.
I could change the way some of these variables like "job" are obtained, but I'm afraid I can't do that with, for instance, "hours" and "minutes".

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Showing game stats on file slots?

#23 Post by hell_oh_world »

Adrian_DVL wrote: Sun May 03, 2020 8:53 am
I've deleted persistent and saved games and the issue is still the same. Regarding the saved variable, the thing is that not all the variables that I want to display in the file slot are parameters of the same class, so I made another class to store all the variables that I want to display in the file slot and named it "Saved", which is equivalent to your "Player". In fact, as I said, all of the variables are correctly shown on the save screen inside the game. Regarding others' suggestions, I'm pretty sure it's all removed.

I execute all of these upon entering the game main flow, where the player can save.
I could change the way some of these variables like "job" are obtained, but I'm afraid I can't do that with, for instance, "hours" and "minutes".
I'm seeing that the hours, minutes, and maxnums are not complex variables at all... if they're are just numbers then it should work. if not the encoder might throw an error as the data is not serializable, for that, i edited my code to prevent that error from happening, non-saveable data will not be included in the save_name. What you can save: lists, dicts, ints, floats, strings, etc... the job is just a string so it should be saved together with all of your concern with the rest of the variables. and of course those variables must be an attribute of your saved object, since the function bases on the object that you input as a parameter, so if the job is not declared as something like `self.job` then it wouldn't be saved at all... so all in all, the functions that you said must be included in the save class instead...

Code: Select all

class Save:
	def __init__(self):
		self.job = None
		# other variables must be here such as self.hours etc...
	def setJob(self, value):
		self.job = value
default saved = Save()
label start:
	$ saved.setJob("something")
	# saving from this point and onwards will set the job to something rather than none...

Adrian_DVL
Regular
Posts: 141
Joined: Fri Mar 15, 2019 8:46 am
Completed: Clockwork Poison
Projects: Melodic Dates, Clockwork Poison: Salvation
Contact:

Re: Showing game stats on file slots?

#24 Post by Adrian_DVL »

hell_oh_world wrote: Sun May 03, 2020 9:07 am I'm seeing that the hours, minutes, and maxnums are not complex variables at all... if they're are just numbers then it should work. if not the encoder might throw an error as the data is not serializable, for that, i edited my code to prevent that error from happening, non-saveable data will not be included in the save_name. What you can save: lists, dicts, ints, floats, strings, etc... the job is just a string so it should be saved together with all of your concern with the rest of the variables. and of course those variables must be an attribute of your saved object, since the function bases on the object that you input as a parameter, so if the job is not declared as something like `self.job` then it wouldn't be saved at all... so all in all, the functions that you said must be included in the save class instead...

Code: Select all

class Save:
	def __init__(self):
		self.job = None
		# other variables must be here such as self.hours etc...
	def setJob(self, value):
		self.job = value
default saved = Save()
label start:
	$ saved.setJob("something")
	# saving from this point and onwards will set the job to something rather than none...
Okay, well, I've been trying a whole lot of things, starting for this. So many things that now I barely know which variables I have in my game and which I haven't. I took many different approaches and the problem is always, and I mean ALWAYS the same. The variables aren't stored and displayed in the file slot in the main menu. Like I said, I tried many things and learned a lot about python in a few hours but, for instance regarding your last post, I made a setJob module inside the class. Then I set $ saved.setJob("something"). Worked. I set $ saved.setJob("[job]"). Didn't work, I got None as the value for job in the main menu. Luckily, there are only a few jobs and I can make conditions to set the job properly, but it's not the case of the rest of the variables. In fact, I was worried about a few of them, but I don't know what I've done that now even name, money or clef are displayed as by default in main menu. I'm really starting to think of giving up, and I'm sure this is not that complex at all.

Adrian_DVL
Regular
Posts: 141
Joined: Fri Mar 15, 2019 8:46 am
Completed: Clockwork Poison
Projects: Melodic Dates, Clockwork Poison: Salvation
Contact:

Re: Showing game stats on file slots?

#25 Post by Adrian_DVL »

Alright, I can say I FINALLY did it! And it was just as simple as using the JSON. I've known since the beginning this was the best way to do this, but I wasn't sure about how to do it properly. Turns out that I was retrieving the json data in a wrong way. Now I just have it like this:

Code: Select all

def saveinfo(d):
        persistent.runtime += renpy.get_game_runtime()
        renpy.clear_game_runtime()
        minutes, seconds = divmod(int(persistent.runtime), 60)
        hours, minutes = divmod(minutes, 60)
        d["scrname"] = name
        d["scrjob"] = job
        d["scrmoney"] = money
        d["scrclef"] = clef
        d["scrmetnum"] = glist.metnum()
        d["scrmaxnum"] = glist.maxnum()
        d["scrsongs"] = songs
        d["scrhours"] = hours
        d["scrminutes"] = minutes
    config.save_json_callbacks = [saveinfo]
And I retrieved it in file_slots screen like this:

Code: Select all

$ scrname = FileJson(slot, "scrname", empty="", missing="")
$ scrjob = FileJson(slot, "scrjob", empty="", missing="")
$ scrmoney = FileJson(slot, "scrmoney", empty=0, missing=0)
$ scrclef = FileJson(slot, "scrclef", empty=0, missing=0)
$ scrmetnum = FileJson(slot, "scrmetnum", empty=0, missing=0)
$ scrmaxnum = FileJson(slot, "scrmaxnum", empty=0, missing=0)
$ scrsongs = FileJson(slot, "scrsongs", empty=0, missing=0)
$ scrhours = FileJson(slot, "scrhours", empty=0, missing=0)
$ scrminutes = FileJson(slot, "scrminutes", empty=0, missing=0)

text "[scrname], [scrjob]":
	style "savename"
text "[scrmoney]":
	style "savevars"
text "[scrclef]":
	style "savevars"
text "[scrmetnum]":
	style "savevars"
text "[scrmaxnum]":
	style "savevars"
text "[scrsongs]":
	style "savevars"
text "[scrhours] [scrminutes]":
  	style "savevars"
I'm writing this in the middle of giving the thing format, but it'd be pretty much like this.
I'm leaving this thread open to new suggestions or new doubts that I might have, but I officially confirm that now all the variables are stored properly. I must say thank you so much guys, for giving me those ideas and helping me learn more about the whole thing, especially hell_oh_world and Alex!

Post Reply

Who is online

Users browsing this forum: No registered users