Finding indentation or choice body error/bug in a nested choice

Hello together,

I’m really having trouble with understanding wtf Im supposed to be doing wrong with the nested choices. Ive read and re - read the tutorials, but the very second I even so much as look at any type of nested choice, it always bugs out. I have a fairly simple piece of code/text here, which in my mind should work, but it absolutely doesn’t. No matter how much i fiddle around, the IDE insists on there being a missing *goto command. I have no Idea where Im supposed to be falling out the choice command and NOTHING i tried is working. I changed the indentations to god knows how many, tried the autoindenter, changed the order of the choices, nothing seems to help.

The error I’m getting is:
Error: training_war line 138: It is illegal to fall out of a *choice statement; you must *goto or *finish before the end of the indented block.

Hint: Line 138 is the bit after # Introduce them to two your best friends…
My code looks like this:

*label alley_fight_2
*choice
  *if (knife) # You quickly grab your grandfathers knife from your belt and
    *choice
      # throw it at the leader of the gang.
        *if (ranged >= 10) 
         Your training paid off. Despite your throw being an act of instinct, you hit the criminal right in the throat. Incredulously he looks at his neck, coughs up some blood and collapses on the spot. Just like that you have killed your first man. (you gained +2 to ranged)
         *set ranged +2 
         *goto beatdown
        *if (ranged < 10)
          It wasn't a bad attempt, but unfortunately you whiff it. The knife goes wide and you miss the man by a few centimeters. 
          *goto beatdown
      # charge the leader of the gang with it. 
        *if (armed >= 15) 
          Your training paid off. With a surprisingly quick motion you rush at the thug and manage to stab his belly multiple times, before anyone can really react to it. Incredulously he presses his fingers over his bleeding guts and collapses. His body convulses on the floor and as he starts to vomit blood you realize: You just killed your first man. (you gained +2 to armed)
          *set armed +2
          *goto beatdown
        *if (armed < 15)
          You got destroyed. 
          *goto beatdown
  # Introduce them to your two best friends: pain and suffering. (Fists) 
    *if ((strength >= 20) and (unarmed >= 15))
      hulk smash!  
      *goto beatdown
    *if ((strength < 20) or (unarmed < 15))
      you lost.
      *goto beatdown


*label beatdown

If anyone has an idea, please help me out here. Im desperating over these nested choices forever now.

Cheers
Chris

2 Likes

First, welcome to the community.

Now, to identify what i think is tripping you up:

This if statement is missing a *goto label.

Sometimes the line numbering of the testing is off.

Hopefully, this addresses your issue.

2 Likes
*label alley_fight_2
*choice
  *if (knife) # You quickly grab your grandfathers knife from your belt and
    *choice
      # throw it at the leader of the gang.
        *if (ranged >= 10) 
          Your training paid off. Despite your throw being an act of instinct, you hit the criminal right in the throat. Incredulously he looks at his neck, coughs up some blood and collapses on the spot. Just like that you have killed your first man. (you gained +2 to ranged)
          *set ranged +2 
          *goto beatdown
        *if (ranged < 10)
          It wasn't a bad attempt, but unfortunately you whiff it. The knife goes wide and you miss the man by a few centimeters. 
          *goto beatdown
      # charge the leader of the gang with it. 
        *if (armed >= 15) 
          Your training paid off. With a surprisingly quick motion you rush at the thug and manage to stab his belly multiple times, before anyone can really react to it. Incredulously he presses his fingers over his bleeding guts and collapses. His body convulses on the floor and as he starts to vomit blood you realize: You just killed your first man. (you gained +2 to armed)
        *if (armed < 15)
          You got destroyed. 
          *goto beatdown
  # Introduce them to your two best friends: pain and suffering. (Fists) 
    *if ((strength >= 20) and (unarmed >= 15))
      hulk smash!  
      *goto beatdown
    *if ((strength < 20) or (unarmed < 15))
      you lost.
      *goto beatdown


*label beatdown

There is an indentation problem there… Try this one.

Also, you should use if else, and not if if.

2 Likes

Hi, thank you so much for your quick reply. I noticed this one as well after I uploaded the post, but I havent yet managed to change that in the post.
However, in the Code im running the *goto label is NOT missing.
I cant seem to upload screenshots here, so Ive uploaded a quick one to

if you can be bothered to check it.

Thank you so much again for your help!

Hi, thank you so much for the quick response.
I have tried your code (+added the missing label), but it still does not seem to work. I keep getting the same error message.

Whats the downside of if if? I have used many if else or elseif in previous chapters, but I have used if if just as much, didnt seem to ever change anything tbh.
Thanks in advance

fyi

this is how it looks for me in the IDE

This time, there is no *goto command on line 142.

Have you corrected that since your screenshot?

1 Like

From what I can see the label beatdown doesn’t have anything. And the next label has just 3 letters. You have to plug a *finish or *ending at the end of the game if you don’t want to have any errors.

You either need to swap out your second *if for an *else or put a third *goto in those blocks, indented to the same level as the *ifs.

The auto-testers have a limited ability to parse your code. They don’t know that between ranged => 10 and ranged < 10, you’ve exhausted all logically possible options. An *else would reassure them (that’s the main thing the command is for); otherwise you’ve got to include some way for the choice block to resolve if ranged is somehow neither => 10 nor < 10. Neither Randomtest nor the player would ever reach that third *goto, but it would stop QT from crashing.

Ultimately your code will be a little bit more bug resistant if you use *else in these cases. It makes typos less likely; it’s easy to mistype something in e.g. *if ((strength < 20) or (unarmed < 15)) which would leave you not exhausting all logical possibilities and causing a real crash. And it makes your intent clear at a glance to you and anyone testing your code.

2 Likes

I’d also recommend not nesting too deeply if you can, as you’re seeing it makes parsing the code difficult and can hide subtle bugs.

You can use *temp variables to store the result of prior choices in order to change what is displayed later (as if the code was nested). You can also use label blocks or subroutines to pull out some of the nested code.

E.g.

*choice
    *if (knife) # Use knife...
        *goto knife_description
    # Use fists...
        *goto fists_description

*label knife_description
*temp threw_dagger
*choice
    # Throw it...
        *set threw_dagger true
    # Attack with it...
        *set threw_dagger false

*if threw_dagger
    *if ranged > 10 
       Hit description 
       *goto end_fight
    *else
       Missed description 
       *goto end_fight
*if armed > 10
        ....
        *goto end_fight
    *else
        ....
        *goto end_fight

*label fists_description
strength + unarmed code
*goto end_fight

*label end_fight
*finish
1 Like

Yes, thanks. Turns out the labe and gotos weren’t the issue.
It was the autotester that was causing the problem, as explained by Havenstone somewhere down the threat. :slight_smile: Thank you all so much for your fast answers guys.

1 Like

This was it. Changing it to *else really did the trick. Thank you so much for your explanation :slight_smile: I really couldnt figure this out by myself, being a total non coder newbie and all.
Now you have convinced me to drop if if for good I guess :smiley:
Really I cant thank you enough. It just didnt occur to me that the auto tester might be the issue.

1 Like

Just the second *if in each of your choices. You need to keep the first *ifs to set up the *elses. :slight_smile:

Of course you know that already, given that your code is now working…I’m writing this for anyone else who reads the thread with similar problems, so they don’t just find-replace if with else. :slight_smile:

And glad I could help. I’m also a non-coder who learned this stuff the hard way…

3 Likes

This topic was automatically closed 24 hours after the last reply. If you want to reopen your WiP, contact the moderators.