IndexError: list index out of range and infinite looping

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
Aviala
Miko-Class Veteran
Posts: 533
Joined: Tue Sep 03, 2013 8:40 am
Completed: Your Royal Gayness, Love Bug, Lovingly Evil
Organization: Lizard Hazard Games
Tumblr: lizardhazardgames
itch: aviala
Location: Finland
Contact:

IndexError: list index out of range and infinite looping

#1 Post by Aviala »

Hello,

I recently encountered a bug in my randomization code that I can't seem to fix. My code randomizes a variable from a list, and based on that variable chooses a storyline that the game will then start going through, one part per day in the game. I used a looping structure to do this, but the game sometimes says there is an infinite loop.

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/day cycle.rpy", line 231, in script
    $ neutral_stories = random.choice(neutral_stories_list)
Exception: Possible infinite loop.

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

Full traceback:
  File "game/day cycle.rpy", line 231, in script
    $ neutral_stories = random.choice(neutral_stories_list)
  File "C:\Users\Aviala\Desktop\renpy-6.99.11-sdk\renpy\execution.py", line 54, in check_infinite_loop
    raise Exception("Possible infinite loop.")
Exception: Possible infinite loop.
I think it's caused by the fact that the game just goes through the loop until it finds a storyline that hasn't been used. Then I tried to fix it by adding a thing that removes the storyline from the list after it's done, so it can't be picked again. But I got an error that said "IndexError: list index out of range", which apparently usually means that the thing I'm trying to get from a list isn't on the list, but.... why wouldn't it be? I added all the possible storylines on the list in init, and the code says that they'll only be removed if the storyline in question is done already. What am I doing wrong?

There should be enough storylines to last for the entire duration of the demo, but it crashes at seemingly random places - most of the time I can actually get through the whole demo without any problems, but about every 3rd playthrough the game crashes. I haven't found any correlation with any specific storyline and crashing, it seems to be caused by something in the structure, maybe?

I only pasted parts of my code here since I have thousands of lines of it, but this should show you the structure I'm using:

Code: Select all

init python:
    barber = False
    barber_done = False
    barber_end = False
    barber_condition = False
    #this variable tracks if storyline was NOT done today; sort of "inverted" false and true
    barber_not_today = True

    neutral_stories_list = ['barber!', 'cult!', 'glitter!', 'wolf!', 'kittens!', 'libraryfire!', 'turnips!']

label audience_phase_cont:            
    
    #if 2 story parts are done, the day ends
    if stories_today == 2:
        jump audience_phase_ends
    
    #check if there are storylines going on; if so, it fills a slot
label continued_storylines:
    if barber == True:
        if barber_not_today == True:
            $ storyline_slots += 1

    #if all slots aren't full, add a story
    if storyline_slots <= 2:
        jump storyline_starters
    #if all slots are full, start a story
    if storyline_slots == 2:
        jump audience_phase_start

label storyline_starters:
    if len(neutral_stories_list) >= 0:
        $ neutral_stories = random.choice(neutral_stories_list)
    else:
# I added this line to test what was happening, and ended up getting it a lot; apparently the list gets emptied prematurely somehow, but that shouldn't be possible? This prevents the game from crashing because of the list index out of range error, and ends the game prematurely.
        "The neutral_stories_list is empty now."
        "Idk what is happening. It shouldn't be empty."
        return
    
    if neutral_stories == 'barber!':
#if barber storyline isn't already active and it's not done already, make it active
        if barber == False:
            if barber_done == False:
                $ barber = True
                $ storyline_slots += 1
                jump audience_phase_cont
            #if the randomization picks a story that is already done, it tells to pick another
            if barber_done == True:
                if 'barber!' in neutral_stories_list:
                    $ neutral_stories_list.remove('barber!')
                jump storyline_starters
        else:
            jump audience_phase_start

Code: Select all

label audience_phase_start:
    scene bg gameplay
    
    
    if barber and barber_not_today == True:
        if barber_condition == "slaponwrist":
            s "Your Grace. A moment?"
            #etc, text continues but I cut it cause it's not relevant
            jump barber_end
       if barber_condition == False:
            show wizard with dissolve
            show wizard with dissolve
            play music "sounds/gameplay1.mp3" fadein 1.0
            w "Hey, bossss."
            #first part of storyline, text continues but I cut it cause it's not relevant
            $ barber_condition = "slaponwrist"
            jump barber_end

label barber_end:
    if barber_done == True:
        $ storyline_slots -= 1
        $ barber = False
#I tried to put stuff here but commented it out because it didn't work
        #if 'barber!' in neutral_stories_list:
                    #$ neutral_stories_list.remove('barber!')
    $ stories_today += 1
    $ barber_not_today = False
    jump audience_phase_cont
    #"barber storyline part ends"
    #"we're gonna move to the next day now, to the neutral storylines"

I hope I got all of the relevant parts of the code; please tell me if you need more! The storylines each have basically identical code, so it feels redundant to post more than one of them here, but there are other parts of the code I left out. I'd be happy to post them if needed.

I've been trying to solve this for hours and hours, but I have no idea what's causing the "IndexError: list index out of range" error. I would really appreciate any help or ideas on what could be causing this.

User avatar
Alex
Lemma-Class Veteran
Posts: 3094
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: IndexError: list index out of range and infinite looping

#2 Post by Alex »

Instead of declaring all the variables in init block, try to use default statement - https://www.renpy.org/doc/html/python.h ... -statement.
https://www.renpy.org/doc/html/save_load_rollback.html

User avatar
IrinaLazareva
Veteran
Posts: 399
Joined: Wed Jun 08, 2016 1:49 pm
Projects: Legacy
Organization: SunShI
Location: St.Petersburg, Russia
Contact:

Re: IndexError: list index out of range and infinite looping

#3 Post by IrinaLazareva »

may be..

Code: Select all

    if len(neutral_stories_list) >= 0:
to replace on

Code: Select all

    if len(neutral_stories_list) > 0:

User avatar
Aviala
Miko-Class Veteran
Posts: 533
Joined: Tue Sep 03, 2013 8:40 am
Completed: Your Royal Gayness, Love Bug, Lovingly Evil
Organization: Lizard Hazard Games
Tumblr: lizardhazardgames
itch: aviala
Location: Finland
Contact:

Re: IndexError: list index out of range and infinite looping

#4 Post by Aviala »

IrinaLazareva wrote:may be..

Code: Select all

    if len(neutral_stories_list) >= 0:
to replace on

Code: Select all

    if len(neutral_stories_list) > 0:
I tried that already and it didn't help. :/ I wish it were that simple... But thank you anyway! :)

I'm going to try the other suggestion tonight if I have time.

User avatar
Saltome
Veteran
Posts: 244
Joined: Sun Oct 26, 2014 1:07 pm
Deviantart: saltome
Contact:

Re: IndexError: list index out of range and infinite looping

#5 Post by Saltome »

Hmm, this seems interesting. Why don't you attach the script, I'm willing to slog through it.
You are asking a very good question. If the variable shouldn't be empty, why is it? What empties it? Try to find out what is happening to it before the problem occurs. Are you sure the variable isn't referenced anywhere, where it shouldn't be? Maybe you're reusing the variable name by accident. Or maybe you are changing the variable somewhere, you don't realize. Or maybe even a faulty logic in some custom screen.
Deviant Art: Image
Discord: saltome
Itch: Phoenix Start

User avatar
Aviala
Miko-Class Veteran
Posts: 533
Joined: Tue Sep 03, 2013 8:40 am
Completed: Your Royal Gayness, Love Bug, Lovingly Evil
Organization: Lizard Hazard Games
Tumblr: lizardhazardgames
itch: aviala
Location: Finland
Contact:

Re: IndexError: list index out of range and infinite looping

#6 Post by Aviala »

Thanks for the offer, I hope it still stands! I'm attaching the relevant code file here. If you're interested in taking a look at the other files as well/test it in action, I can give you a download link to the whole project file via PM.

Some of my notes are in Finnish, I'm sorry for that... I don't have the time to translate them right now, but please do ask if you need to know what some part of the code is supposed to do.
Sorry for the late answer btw, our kcikstarter campaign is keeping me busy.

If someone else happens to find this and download the script file... you're not allowed to use this code for your own projects, and you probably wouldn't want to anyway cause it's broken. Thanks.
Attachments
day cycle.rpy
(70.64 KiB) Downloaded 101 times

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

Re: IndexError: list index out of range and infinite looping

#7 Post by philat »

I took a quick look through -- from what I can see, assuming you've been running the game as is, it should be literally impossible for the list to be empty as you've commented out the .remove() parts for half the entries. Is this the only script relevant?

Secondly, you can watch variables with the console (shift+O, watch neutral_stories_list) which will keep the list up on your screen as you play through and show you how the list is changing. Perhaps playtest again to see at what point the list is emptying.

naomimyselfandi
Newbie
Posts: 15
Joined: Sun Mar 19, 2017 10:50 pm
Contact:

Re: IndexError: list index out of range and infinite looping

#8 Post by naomimyselfandi »

Hm, this looks interesting. So you're trying to select a storyline from a list at random, but somehow that list can end up emptied? Hm, just to make sure we're on the same page, can you post up the stack trace of the IndexError you were getting? I'm assuming it's from the random.choice call, but it can't hurt to have. Also, you never saw the IndexError before, right? Just the infinite loop error?

...if I'm reading this right, what you really want is for stories to get chosen in a random order. If that's the case, we could just call renpy.random.shuffle on the neutral_stories_list at initialization time, and then have storyline_starters pop the list - think of your stories as a deck of cards that we shuffle as we start the game, and then we just draw cards from that deck (that's what "pop" means in this context) as needed. The big advantage here is that that can't possibly be an infinite loop, since there's no looping involved, period. If you decide to go this route and want any help here, feel free to shoot me a PM (I don't bite, I promise)!

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: IndexError: list index out of range and infinite looping

#9 Post by xela »

1)

Code: Select all

label continued_storylines:
    #Continued storylines
    jump continued_storylines
Even though code cannot make it to this label... don't do this. Just don't, it a bad idea no matter how you look at it. And even in labels with content, you have somewhat similar structure. Do:

Code: Select all

label continued_storylines:
    if config.developer:
        "Continued storylines"
    jump continued_storylines
if you're making placeholders. Takes seconds, will not get in the way and will help you with debugging.


2)

Code: Select all

if len(neutral_stories_list) >= 0:
One of the first things they'll teach you at any decent python tutorial that it is just bad code. It's also not:

Code: Select all

if len(neutral_stories_list) > 0:
which is logically sound but "unpythonic".

Code: Select all

if neutral_stories_list:
is what you should check and it will never steer you wrong.

Code: Select all

if glitter_done == True:
should also be

Code: Select all

if glitter_done:
for the same reason.

3) What is actually causing recursive loop or at least preventing you from debugging it is that your expectations from if/else forks are wrong. At least at two key places you do this:

Code: Select all

if var1:
if var2:
...
if var7:
else:
    "neutral_stories isn't set to any of the storylines."
or
    #"Something is very wrong. All not_today variables are neither False nor True."
which is not how it works. It should be:

Code: Select all

if var1:
elif var2:
...
elif var7:
else:
    "neutral_stories isn't set to any of the storylines."
or
    #"Something is very wrong. All not_today variables are neither False nor True."
Setting up your vars in init phase is also a very bad form:

Code: Select all

init python:
    #temporary testing variable:
    loop_times = 0

    days_since_law = 0 #tracks when was the last time there was an opportunity to pass a law
    days = 0 #tracks what day it is
    storyline_slots = 0 #tracks how many storyline slots are filled
    stories_today = 0
    ...
Just flip init python to a label with a return at the end and call it right after label start: statement (or use default to define them one by one).

==============>>>
Start with elifs cause that may either fix the problem or at least help you to debug through a more coherent gameflow. You should prolly restore all the list.remove() functions. Good luck!
Like what we're doing? Support us at:
Image

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: IndexError: list index out of range and infinite looping

#10 Post by xela »

Oh, and if you're running latest version of Ren'Py, you can just open console and check the state of your list (and/or variables) after you crashed. Might help with debugging as well. Good luck one more time :)
Like what we're doing? Support us at:
Image

naomimyselfandi
Newbie
Posts: 15
Joined: Sun Mar 19, 2017 10:50 pm
Contact:

Re: IndexError: list index out of range and infinite looping

#11 Post by naomimyselfandi »

Setting up your vars in init phase is also a very bad form
Why? EDIT: Ah, the docs point out that they're not saved or loaded - is that what you're referring to?

The else/elif mixup is certainly bad style and should be fixed, but I don't think it's actually the problem here, given that every branch before it ends in a jump statement.

User avatar
Saltome
Veteran
Posts: 244
Joined: Sun Oct 26, 2014 1:07 pm
Deviantart: saltome
Contact:

Re: IndexError: list index out of range and infinite looping

#12 Post by Saltome »

I think you need to change the way your system works.
This isn't really a bug, there are multiple issues in the design itself.
Your conditional branches and loops keep interfering with each other.
storyline_starters keeps looping infinitely whenever a story is completed. Due to the condition branches.
continued_storylines keeps looping infinitely whenever there's only one story left to choose from. Because it's trying to have at least 2.
I also had some other issues here and there. Probably due to my testing.
Deviant Art: Image
Discord: saltome
Itch: Phoenix Start

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: IndexError: list index out of range and infinite looping

#13 Post by xela »

naomimyselfandi wrote:
Setting up your vars in init phase is also a very bad form
Why? EDIT: Ah, the docs point out that they're not saved or loaded - is that what you're referring to?

The else/elif mixup is certainly bad style and should be fixed, but I don't think it's actually the problem here, given that every branch before it ends in a jump statement.
Search the forum for issues with setting up vars in init... it's either the most or one of the most mentioned topics around here that's been discussed and explained to death.

You're right, if/elif is not as big of a deal as I thought here. That index error was prolly due to the bad check of lists length and was thrown before .remove() code was commented out and flags failed lead to the win label before the check for whatever reason.

Branches jumping will happen once if items are not removed from the list, afterwards flags (vars) will prevent those jumps, leading to:

Code: Select all

        else:
            jump audience_phase_start
assuming all stuff in that label fails and final else is triggered:
  • else:
    #"Something is very wrong. All not_today variables are neither False nor True."
    jump audience_phase_cont
we go here:

Code: Select all

label audience_phase_cont:            
    
    #jos päivän kaikki tarinat on käyty läpi; tämä arvo sama kuin slottien määrä
    if stories_today == 2:
        jump audience_phase_ends
    
    #check if there are storylines going on; if so, it fills a slot
label continued_storylines:
if jump to audience_phase_ends is triggered, it doesn't look like after all the flags were set but items are still in the list, that story slots can amount to two or more... in which case this:

Code: Select all

    if storyline_slots <= 2:
        jump storyline_starters
just sends gameflow back to where we started (recursive without any statements to stop it). If not, what goes on at continued_storylines is harder to follow.

Maybe even more obvious endless loop is this:
label storyline_starters:
if neutral_stories == 'glitter!':
if glitter_done == True:
#if 'glitter!' in neutral_stories_list:
# $ neutral_stories_list.remove('glitter!')
jump storyline_starters
If items are not removed from the list but stories have played themselves out, so you don't seem to need to go very far to get screwed over...

In either case, following all of my suggestions will improve code readability/quality, help with debugging and is likely to fix this mess and prevent alike from happening in the future, so all I wrote above stands :)

Shuffling+popping/proper eval of the list with item removal should all work here (it all was suggested in posts above).
Like what we're doing? Support us at:
Image

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: IndexError: list index out of range and infinite looping

#14 Post by xela »

Saltome wrote:I think you need to change the way your system works.
This isn't really a bug, there are multiple issues in the design itself.
Your conditional branches and loops keep interfering with each other.
storyline_starters keeps looping infinitely whenever a story is completed. Due to the condition branches.
continued_storylines keeps looping infinitely whenever there's only one story left to choose from. Because it's trying to have at least 2.
I also had some other issues here and there. Probably due to my testing.
QTF.

Something like:

Code: Select all

default events = ['barber!', 'cult!', 'glitter!', 'wolf!', 'kittens!', 'libraryfire!', 'turnips!']

label storyline_starters:
    if not events:
        jump you_won
    else:
        $ renpy.random.shuffle(events)
        $ story = events.pop()

    if story == 'cult!':
        # ... DO NOT REMOVE FROM THE LIST!
    elif story == 'glitter!':
        # ...
Like what we're doing? Support us at:
Image

User avatar
Saltome
Veteran
Posts: 244
Joined: Sun Oct 26, 2014 1:07 pm
Deviantart: saltome
Contact:

Re: IndexError: list index out of range and infinite looping

#15 Post by Saltome »

xela wrote:
Saltome wrote:I think you need to change the way your system works.
This isn't really a bug, there are multiple issues in the design itself.
Your conditional branches and loops keep interfering with each other.
storyline_starters keeps looping infinitely whenever a story is completed. Due to the condition branches.
continued_storylines keeps looping infinitely whenever there's only one story left to choose from. Because it's trying to have at least 2.
I also had some other issues here and there. Probably due to my testing.
QTF.

Something like:

Code: Select all

default events = ['barber!', 'cult!', 'glitter!', 'wolf!', 'kittens!', 'libraryfire!', 'turnips!']

label storyline_starters:
    if not events:
        jump you_won
    else:
        $ renpy.random.shuffle(events)
        $ story = events.pop()

    if story == 'cult!':
        # ... DO NOT REMOVE FROM THE LIST!
    elif story == 'glitter!':
        # ...
Nice, just what I was thinking. She could even do something like:

Code: Select all

    call expression events.pop()
label barber!:
    ...
label cult!:
    ...
Deviant Art: Image
Discord: saltome
Itch: Phoenix Start

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot]