"Cannot fall in to an *else statement." Error Message Confusion

Hi everyone, pardon my interruption. Just a touch confused. Again.

Recurrently when testing the game with Quicktest and Randomtest I get an error message: “It is illegal to fall in to an *else statement; you must *goto or *finish before the end of the indented block.”

I get this message in the same place every time, despite my efforts to correct the problem. I suppose I’m reading the message wrong? Searching through the wiki and the testing help page hasn’t provided me with anything.
Here’s the relevant bit of code, in case it’s needed:

“Well, one was an old man,” he says, squinting.
    *if (home_province = "Little Guntou")
      "The other was a woman, but built like a barge, and with the smell to match.
      Like I said, though, both of them looked serious."
      *goto exit_clinic2
    *elseif (home_province = "Nishina")
      "The other, a lady, might've been local, because she was as big as a house.
      *if (player_class = "Brawny")
        As big as you, even."
        *goto exit_clinic2
      *else
        I didn't get a close look at her, though."
        *goto exit_clinic2
    *else
      "The other was a woman, but as big as a wagon.
      They both looked pretty serious, like I said."
      *goto exit_clinic2

This is just a small issue, when you get down to it, but if I can figure out this message now I’ll know how to prepare for it in the future.

Suggestions most appreciated.

Is it coded like this…



“Well, one was an old man,” he says, squinting.
*if (home_province = "Little Guntou")
  "The other was a woman, but built like a barge, and with the smell to match. Like I
  said, though, both of them looked serious."
  *goto exit_clinic2
*elseif (home_province = "Nishina")
  "The other, a lady, might've been local, because she was as big as a house.
  *if (player_class = "Brawny")
    As big as you, even."
    *goto exit_clinic2
  *else
    I didn't get a close look at her, though."
    *goto exit_clinic2
*else
  "The other was a woman, but as big as a wagon.
  They both looked pretty serious, like I said." 
  *goto exit_clinic2

@Nocturnal_Stillness

That’s it, yeah. Huh. I swear the code had the proper indentation when I pasted it. Did I miss something?

Well, thanks for cleaning it up.

Did you put the pre /pre bits for each line? Because you can just do the pre at the beginning of hte code your pasting and the /pre at the end of the code, and it should look like Noctornal_Stillness’.

Just putting it out there.

Fixed it for you. As Babisko said it’s `

` not ```.

Also, a line number would be useful. If you're not already using it, I'd recommend notepad++ for line numbers.

In testing I get no errors (other than an unallowed increased indent after the first line, but I figured that just a copy/paste problem).

Thanks @Babisko and @Reaperoa. I didn’t know about the < pre > thing. Also, good point about the line number. I should have included that.

Now, a spot of good news: I have since tested the angry code snippet and found it working fine. I didn’t change anything about it, though, which is worrying.

In a similar vein, I have a question concerning *gosub and *return. The error messages I’ve received have stated “you must *goto or *finish before the end,” but couldn’t *return work also? Or am I completely mistaken?

For instance, suppose I wrote something like this:

*label you_met_Nala
*if Nala_approval >= 30
  Nala tolerates your presence.
  *return
*elseif Nala_approval >= 60
  Nala enjoys your company.
  *return
*else
  Nala avoids you whenever possible.
  *return

This (paraphrased) setup is now causing the same error, and if I’ve misunderstood the applicability of *return, well, then I’ve messed up pretty badly.

(No line numbers in the above either, but it’s hypothetical anyway.)

The short, I think you’ve misunderstood what *return does. Return only works within a scene. If that doesn’t help I’ll give an example later. (cannot at the moment)

@Saint_Nicholas: I’m clutching at random straws, here, but (if it isn’t as @Reaperoa says, that the code is trying to leave the scene)…could there be something missing where you call the subroutine, rather than in the subroutine itself? For example:

*if (truething)
   *gosub thesubroutine
   [missing a *goto]
*else
   *goto thenextlabel

Fear not, @Reaperoa, I’m not quite that ignorant. (Barely.) I understand that I can only *return to a *gosub instituted within the same scene. Let me clean up my hypothetical problem:

Blah blah blah
What does Nala think of you?
*gosub you_met_Nala
And that's what she thinks of you.
Blah blah blah
*goto something_completely_different

*label you_met_Nala
*if Nala_approval >= 30
  Nala tolerates your presence.
  *return
*elseif Nala_approval >= 60
  Nala enjoys your company.
  *return
*else
  Nala avoids you whenever possible.
  *return

I’m asking if *return can be called from within an *else statement, basically. Because, at the moment, it appears I cannot.

And thanks for the suggestion, @Carolyne. I double-checked my code, and as far as I can tell I haven’t missed a *goto. Testing and debugging is rather exhausting right now, since Randomtest and Quicktest need a break every time I use them, and sometimes it takes up to ten hours before they reset.

*return should function perfectly fine within an *else statement. I cannot actually produce a you must *goto or *finish before the end error anymore, no matter what I try (I thought the code got changed so that it would almost never popped up anymore), so I am having trouble guessing what is happening.

So, first, when it produces the error, it should give you a line number (I know it does so correctly in Firefox, but other web browsers may be less reliable). It should also display the text that it did manage to run through correctly. (If this still does not help I can give you a few more pointers.) Double check where it’s producing the error, and try to back track it from there. When the game produces an error, it should leave the text sitting there, so you should be able to see what it ran without error easily.

If that doesn’t help I have a few more tricks, but for more direct help, I’ll need to see what code you’re testing, and what the error actually is.

Sure, @Reaperoa, here’s the snippet causing me trouble. I should note that this only causes a problem when I run Quicktest – when I play the game myself and manually test it, no problem occurs.

98*label you_joined_the_warriors
99You met Boss and Nala, and you joined them in their quest to battle discord.
100*if (Boss_died = false)
101  *if (Boss_opinion >= 20)
102    You think Boss likes you well enough.
103    *return
104  *elseif (Boss_opinion >= 70)
105    You think Boss really approves of you.
106    *return
107*else
108  Unfortunately, Boss was killed during a dangerous adventure.
109  He was clearly fond of you.
110  *return

When I run Quicktest, the error I receive says this precisely:

Error: line 107: It is illegal to fall in to an *else statement; you must *goto or *finish before the end of the indented block.

Because this is only a problem when running Quicktest (as far as I can tell), I suppose I might be overreacting. Still, if I don’t fix it then Quicktest will be effectively unavailable to me, which would be quite a pain.

I’m happy to hear that *return works from inside an *else statement, of course.

What happens if Boss_died and Boss_opinion < 20?

There’s nothing to catch that, so there’s the error. (I’m guessing Quicktest flags this even if Boss_opinion can never go below 20 in actual gameplay.)

Also, Boss_opinion >= 70 should be tested before >= 20, since if, for example, the value is 80, the first condition of “>=20” will be true and it won’t go on to test the second.

I think @Carolyne is right on target, but I’m gonna expand a little on it.

You probably have the game set up so that it’s impossible (or at least very rare) to Boss_opinion below 20, so in actual testing that never crops up. Quicktest, to my understanding, does not care about the fact that it’s rare or impossible, it just tests to make sure there’s no error, so it sees the *elseif, and tests what happens if you don’t meet its requirements, which is to keep running past line 106 and into line 107, falling back out of the *if started on line 100, and into the *else, which is illegal (The reason is that the code doesn’t keep tract of the *if/*else relationship. It just finds what branch it’s supposed to go down and keeps going from there).

If you just want to fix for quick test, the simple way is to insert a *return after line 106, on the same indentation level as line 104.

Also, (to reiterate @Carolyne again), (I noticed it in your example codes too, but just skipped past it there) in actual gameplay line 104 will never get run. If Boss_opinion is greater than or equal to 70, it’s gonna be greater than 20, so when the code hits line 101, it’s go down that route no matter what.

Oooooh, you guys are lifesavers.

I did as you asked, and sure enough, it worked. Then I got the same error from later in the game – so I made the same fix there. And then again, then again. Apparently, uh, I made this mistake a lot.

But now it all runs smoothly and Quicktest goes off without a hitch.

Also, I had no idea about the problem I was making for myself placing the >= 20 opinion over the >= 70 opinion. I’ve gone through and fixed all instances resembling that, too. It seems like basic logic – put the bigger numbers first, then go down the chain – but it never occurred to me. So, again, thank you.

I have no errors to speak of now. If I run into any more issues, should I crack open a new discussion thread or resurrect this one?

Wait, I haven’t said thank you enough. Thank you thank you thank you. Better.

Hurrah for happy code!

Assuming it’s a new issue, start a new thread - future readers will find the thread more helpful if it’s problem specific rather than “this forum member’s coding hurdles.”

1 Like

This is important:

This should fix it for most people with the same problem:

add a label after the if/else statement and add a goto (that label) at the end of each if…

so take something like this:

*temp synd_text
*temp own_synd_name
*if synd_own = false
*set own_synd_name “”
*set synd_text “???”
*else
*set own_synd_name synd_name
*set synd_text “Syndicate Name”

*stat_chart
text Name

and change it to this:

*temp synd_text
*temp own_synd_name
*if synd_own = false
*set own_synd_name “”
*set synd_text “???”
*goto chart
*else
*set own_synd_name synd_name
*set synd_text “Syndicate Name”
*goto chart

*label chart
*stat_chart
text Name