[Solved] Song is not always unlocked after seeing persistent

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.
Post Reply
Message
Author
User avatar
kostek00
Regular
Posts: 131
Joined: Wed Mar 28, 2018 5:54 pm
Contact:

[Solved] Song is not always unlocked after seeing persistent

#1 Post by kostek00 »

Code: Select all

    playerList = [
        ("bgm/M01.ogg", "images/bgm/M01.png"),
        ("bgm/M02.ogg", "images/bgm/M02.png"),
        ("bgm/M03.ogg", "images/bgm/M03.png"),
        ("bgm/M04.ogg", "images/bgm/M04.png"),
    ]

    if persistent.credits_seen:
        playerList += [
            ("bgm/ED.ogg", "images/bgm/ED.png")
        ]

    mr = MusicRoom(fadeout=0.0, shuffle=False)

    for (track, image) in playerList:
        mr.add(track, always_unlocked=True, action=SetVariable("my_image", image))

    playerList = dict(playerList)

init:
    default my_image = "images/bgm/M01.png"

screen extra:
    tag menu
    add "images/gui/menu_ground.png"

    modal True

    on "replaced" action Play("music", "bgm/M01.ogg")

    imagemap:
        auto "images/gui/extra_%s.png"

        alpha False

        hotspot(302,53,31,27) action mr.Previous()
        hotspot(346,53,25,27) action mr.Play() selected renpy.music.is_playing()
        hotspot(379,53,27,27) action mr.Stop()
        hotspot(415,53,27,27) action mr.ToggleSingleTrack()
        hotspot(454,53,32,27) action mr.Next()
        hotspot(25,534,149,40) action Return()

    add my_image pos(509,43)
This is part of my "extra" menu that contains music player. For unknown to me reason game not always unlocks song "ED.ogg". Sometimes it does sometimes it doesn't, totally random. Also while playing you can't miss "persistent.credits_seen". Any ideas?

Code: Select all

$ persistent.credits_seen = True
This persistent is right before "return" when completing game. I also checked different persistent but result was the same.
Last edited by kostek00 on Sat Sep 29, 2018 8:43 am, edited 1 time in total.

User avatar
kostek00
Regular
Posts: 131
Joined: Wed Mar 28, 2018 5:54 pm
Contact:

Re: Song is not always unlocked after seeing persistent

#2 Post by kostek00 »

It seems like song is never unlocked the way I coded it which is strange because any change in game's code unlocks it immidately. Even not related to this code.

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Song is not always unlocked after seeing persistent

#3 Post by Remix »

The important code would be the lines just before what you showed, something to show what context the "if persistent.credits_seen:" is ran in... Is it a label, a screen, a python init?

The most likely explanation is that that line only runs once, so is only evaluated once
Frameworks & Scriptlets:

User avatar
kostek00
Regular
Posts: 131
Joined: Wed Mar 28, 2018 5:54 pm
Contact:

Re: Song is not always unlocked after seeing persistent

#4 Post by kostek00 »

It's in init python block.

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Song is not always unlocked after seeing persistent

#5 Post by Remix »

... which runs Once, at init time... so the persistent variable check only runs when you launch the game...

Move it to a context that is re-evaluated each time it is accessed, like a label or screen.
Alternatively, recode the concept so the playerList is persistent (using default, not init) and just append to it once game completed once.
Frameworks & Scriptlets:

User avatar
kostek00
Regular
Posts: 131
Joined: Wed Mar 28, 2018 5:54 pm
Contact:

Re: Song is not always unlocked after seeing persistent

#6 Post by kostek00 »

Unfortunately when I move this code to label at the and of game i got this error:

Code: Select all

While running game code:
  File "game/S015.rpy", line 779, in script
    python:
  File "game/S015.rpy", line 782, in <module>
    ("bgm/ED.ogg", "images/bgm/ED.png")
TypeError: unsupported operand type(s) for +=: 'RevertableDict' and 'RevertableList'

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

Full traceback:
  File "game/S015.rpy", line 779, in script
    python:
  File "C:\Programy\Ren'Py\renpy\ast.py", line 882, in execute
    renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
  File "C:\Programy\Ren'Py\renpy\python.py", line 1913, in py_exec_bytecode
    exec bytecode in globals, locals
  File "game/S015.rpy", line 782, in <module>
    ("bgm/ED.ogg", "images/bgm/ED.png")
TypeError: unsupported operand type(s) for +=: 'RevertableDict' and 'RevertableList'
I searched for method that would allow me to add this song to RevertableDict but it's too complicated for me.

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Song is not always unlocked after seeing persistent

#7 Post by Remix »

Show the code, both setting up the persistent and the adding to it
Frameworks & Scriptlets:

User avatar
kostek00
Regular
Posts: 131
Joined: Wed Mar 28, 2018 5:54 pm
Contact:

Re: Song is not always unlocked after seeing persistent

#8 Post by kostek00 »

Code is the same as in first post except the piece that is adding that one song as I moved it into python block inside label in script.

Code: Select all

label add_song:
    $ persistent.credits_seen = True
    python:
        if persistent.credits_seen:
            playerList += [
                ("bgm/ED.ogg", "images/bgm/ED.png")
            ]
I didn't changed playerList to persistent. I don't have idea how could I change this whole code like that.

Meanwhile I also tried playerList.update(dict(playerList)) but it wasn't doing anything (yea, I'm running around like headless chicken trying random stuff that most likely won't work.)

To be honest it doesn't even need to check for persistent if it could add when it's at the end of script:

Code: Select all

label add_song:
    python:
        playerList += [
            ("bgm/ED.ogg", "images/bgm/ED.png")
        ]

philat
Eileen-Class Veteran
Posts: 1900
Joined: Wed Dec 04, 2013 12:33 pm
Contact:

Re: Song is not always unlocked after seeing persistent

#9 Post by philat »

Why not just use append?

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Song is not always unlocked after seeing persistent

#10 Post by Remix »

unsupported operand type(s) for +=: 'RevertableDict' and 'RevertableList'
means you are trying to add a list to a dict, which (IF it references the line you posted earlier, just didn't post alongside the traceback) means playerList has been defaulted or changed to a dict somewhere and then you're trying to add a list to that

Each (every, not just the first) time you start a new game, non persistent variables will be set to their defaults...
So, each (every, not just the first) time you start or restart, playerList is set to your 4 items
In your code, it Only changes to 5 if label add_song is accessed, so you would need to jump/call that both at the start and end of the game, to check if persistent.credits_seen was good... realistically, you'd even want to call/jump it before main_menu... which is why I part suggested just persisting the list instead...

Something like:

Code: Select all

# at start
default persistent.playerList = [
        ("bgm/M01.ogg", "images/bgm/M01.png"),
        ("bgm/M02.ogg", "images/bgm/M02.png"),
        ("bgm/M03.ogg", "images/bgm/M03.png"),
        ("bgm/M04.ogg", "images/bgm/M04.png"),
    ]

# game stuff

label end_of_game_credits:

    e "Well done"

    $ persistent.playerList.append(
            ("bgm/ED.ogg", "images/bgm/ED.png") )

    return
Sub-note: If the pretext comes across as miffed it is because the code you've posted simply cannot produce the error you posted, so either you changed the code and didn't mention or re-post it or you omitted to show other relevant parts
Frameworks & Scriptlets:

User avatar
kostek00
Regular
Posts: 131
Joined: Wed Mar 28, 2018 5:54 pm
Contact:

Re: Song is not always unlocked after seeing persistent

#11 Post by kostek00 »

@philat
Ren'Py throws error that RevertableDict has no attribute append.

@Remix
It looks like I'm not capable to understand that. I changed playerList to default persistent.playerList but that throwed error that playerList is not defined (in for loop). So I changed all playerList to persistent.playerList but that didn't worked. It throws that it have too many values to unpack.

User avatar
Randomiser
Newbie
Posts: 7
Joined: Fri Sep 28, 2018 2:07 pm
Contact:

Re: Song is not always unlocked after seeing persistent

#12 Post by Randomiser »

This is why you're getting the RevertableDict error:

Code: Select all

    playerList = [
        ("bgm/M01.ogg", "images/bgm/M01.png"),
        ("bgm/M02.ogg", "images/bgm/M02.png"),
        ("bgm/M03.ogg", "images/bgm/M03.png"),
        ("bgm/M04.ogg", "images/bgm/M04.png"),
    ]

	... (trimmed) ...
	
    playerList = dict(playerList)
You're changing playerList to a dictionary after declaring it, but treating it like it's still a list when you go to add to it later. In the code you've shown I don't see a reason for it to be a dict at all, so unless you're using it for something else I would bet removing that line fixes your issue.

However...
Ren'py's Music Room should be able to handle detecting which music tracks you've unlocked automatically. You could probably simplify this if you add the track to the music room at startup with the others, but leave always_unlocked as False for this track. The track will only unlock when it's encountered in the game, in your case at the end, which will achieve the same thing as a persistent variable.

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Song is not always unlocked after seeing persistent

#13 Post by Remix »

Randomiser wrote: Sat Sep 29, 2018 5:52 am

Code: Select all

    playerList = dict(playerList)
You're changing playerList to a dictionary after declaring it
Just saw that myself.
If you do need to continue using that list as a dict, renaming it as player_dict would make great sense.

Just looking at MusicRoom, the unlocked state tests renpy.game.persistent._seen_audio so just playing the track unlocks it. So maybe set locks based on persistence at the beginning and let the engine do the rest...

Code: Select all

    playerList = [
        ("bgm/M01.ogg", "images/bgm/M01.png", True),
        ("bgm/M02.ogg", "images/bgm/M02.png", True),
        ("bgm/M03.ogg", "images/bgm/M03.png", True),
        ("bgm/M04.ogg", "images/bgm/M04.png", True),
        ("bgm/ED.ogg", "images/bgm/ED.png", persistent.credits_seen)
        ]

    mr = MusicRoom(fadeout=0.0, shuffle=False)

    for (track, image, unlocked) in playerList:
        mr.add(track, always_unlocked=unlocked, action=SetVariable("my_image", image))

    ### ??? player_dict = dict([ (k[0],k[1]) for k in playerList]) ### if you are going to use this, at least call it a "dict" in the name
    
label end_credits:
     "..."
     python:
         persistent.credits_seen = True
         # renpy.game.persistent._seen_audio.append("bgm/ED.ogg") # maybe add()
         # If the track has not actually played   
Frameworks & Scriptlets:

User avatar
kostek00
Regular
Posts: 131
Joined: Wed Mar 28, 2018 5:54 pm
Contact:

Re: Song is not always unlocked after seeing persistent

#14 Post by kostek00 »

Remix wrote: Sat Sep 29, 2018 7:37 am

Code: Select all

    playerList = [
        ("bgm/M01.ogg", "images/bgm/M01.png", True),
        ("bgm/M02.ogg", "images/bgm/M02.png", True),
        ("bgm/M03.ogg", "images/bgm/M03.png", True),
        ("bgm/M04.ogg", "images/bgm/M04.png", True),
        ("bgm/ED.ogg", "images/bgm/ED.png", persistent.credits_seen)
        ]

    mr = MusicRoom(fadeout=0.0, shuffle=False)

    for (track, image, unlocked) in playerList:
        mr.add(track, always_unlocked=unlocked, action=SetVariable("my_image", image))
God dammit. Yesterday I was doing something simillar and yet I derped so much to not realize I could just do that. Ech...

Remix wrote: Sat Sep 29, 2018 7:37 am
Randomiser wrote: Sat Sep 29, 2018 5:52 am

Code: Select all

    playerList = dict(playerList)
You're changing playerList to a dictionary after declaring it
Just saw that myself.
If you do need to continue using that list as a dict, renaming it as player_dict would make great sense.
Removeing "playerList = dict(playerList)" isn't crashing game and player works the same so it seems it doesn't needs to be dictionary.


Thank you all for keeping up with such a noob. I really appreciate your help. :D

Post Reply

Who is online

Users browsing this forum: Ocelot