Ultimate Noob Coding

Imagine your game like a road. If, elseif, and else statements are where this road branches off.

The player is in a car, following the directions on the road signs.

At each sign they will check if their stats mean they need to turn off the main road there.

They will take a turn off the first side road they reach that their stats allow for.

Once they take a turn, branches further down the original road will not be reached unless jumped to using a goto command.

(Will draw some example diagrams when it’s not 4 am)

Edit with the promised diagrams:

This is how your current code would work if everything was correctly indented

This is how you intended it to work

1 Like

No, the solution is to indent the else (and potential accompanying elseifs) on the same level where the if is.

1 Like

Hey, back at it again with another issue involving ifs and elseifs. This time I’m…fairly certain that it shouldn’t be an indentation issue because I’ve been using tabs instead of spaces. I’m still getting an error about falling out of the choice, though. Is it just the values I’m using and I’m too bricked to understand basic math?

        *if (Discipline >= 40)
            Text description.
            *goto_scene wild7
       
        *elseif (Discipline < 40) and (Discipline >= 20)
            Text description.
            *goto_scene wild7
        
        *elseif (Discipline < 20)
            Text Description.
            *set PCohesion %-10
            *goto_scene wild7```

If you’re using elseif, the last command in the list always has to be an else. It’s kind of an “if none of the things above apply, then do this” statement. ChoiceScript gets confused and will throw up errors if it can’t find it.

In this case, replace the

*elseif (Discipline < 20)

with

*else

and you should be good.

1 Like

Can you post the whole code for the choice this segment appears in?

The code you posted works fine for me.

Only modification was removing 2 levels of indents from each line.

I suspect your error is happening in the broader choice, or maybe in wild7.txt.


Is that something ChoiceScript used to require in the past?

Because I use *if/*elseif without a final *else all the time. I typically don’t need–or want–a catchall.

For a really slapdash example:

This compiles and passes both QT and RT.

*create strength 50
*create charisma 50
*create dragon_regard 1
*rand strength 15 85
*rand charisma 15 85

(Strength is ${strength}, Charisma is ${charisma}.)

You meet a dragon.

*if strength > 65
    "I have heard impressive tales of your strength," the dragon says. "I admire that greatly."
    *set dragon_regard + 3
    *goto gold_pile
*elseif charisma > 75
    "People speak highly of your oratory skill," the dragon says. "I'm something of an orator myself."
    *set dragon_regard + 2
    *goto gold_pile
*elseif (strength > 60) and (charisma > 60)
    "People say you are quite a skilled individual," the dragon says.
    *set dragon_regard + 1
    *goto gold_pile

*label gold_pile

The dragon regards you cautiously, basking languidly atop a pile of gold coins.
*ending

In my opinion:

  1. *if/*if/*if... is for outcomes that aren’t mutually exclusive or mandatory. You want to show multiple extra bits to some players.

  2. *if/*elseif(s) is for outcomes that are mutually exclusive but not mandatory. You want to show exactly one of multiple possible extra bits to some players.

    (While you could use a series of *ifs, IMO it’s better coding practice to clearly communicate your intent for the outcomes to be mutually exclusive. For yourself and any reviewers.)

  3. *if/*elseif(s) [optional]/*else is for outcomes that are mutually exclusive and mandatory. Everyone needs to get exactly one bit.

    Some people also use final *elses to throw *bugs or display error text as a debugging strategy.

2 Likes

Fantastic summary, thanks. I always learn from these threads. :slight_smile:

Would you mind if I worked your summary into the relevant bit of the Wiki?

2 Likes

Sure, I wouldn’t mind at all. Glad it was useful; when I start rambling I’m never sure.

1 Like

Excellent, I’ve updated the *if and *elseif pages using your work.

1 Like

It’s never worked for me, but then again I rarely ever use elseif. The else thing is just how I remember learning how to use elseifs.

I use ifs without an else (or gotos) all the time and that’s never been a problem.

1 Like

Whatever coding method works for you is the one you should use. ChoiceScript is for everyone. That’s the first and last thing I’d say about any of this stuff.

There are advantage to getting comfortable with elseifs. Pull out the if/elseifs from Lan’s example:

*if strength > 65
*elseif charisma > 75
*elseif (strength > 60) and (charisma > 60)

If you want to achieve the same results using *ifs alone, I beileve you’d need:

*if (strength > 65)
*if (strength <= 65) and (charisma > 75)
*if ((strength > 60) and (charisma > 60)) and ((strength <= 65) and (charisma <= 75))

That’s a lot more fiddly code-typing and at least double the opportunity for typos.

But that doesn’t mean elseifs are necessary. Some people will no doubt find it easier to keep track of the conditions when they’re all written out like that (rather than implicit in the *elseifs), especially if there are long stretches of text and other code in between the conditional commands. Some people hate *gotos so much that they’d count the extra typing a small price to avoid those three extra *goto nexts. And of course, you can write a perfectly good game that never gives the reader a list of “mutually exclusive but not mandatory” options.

Whatever coding method works for you is the one you should use. ChoiceScript is for everyone.

3 Likes

I just used an *else instead of an *elseif and it still threw an error.

  #You take aim at the officer and pull the trigger.
      *if (Discipline >=30)
          You got him.
          *goto_scene wild7
      
      *elseif (Discipline < 30)
          You missed.
          *goto_scene wild7
      
  #You take aim at the machine gunner and pull the trigger.
      *if (Discipline >= 40)
          You got him but better.
          *goto_scene wild7
       
      *elseif (Discipline < 40) and (Discipline >= 20)
          You got him.          
          *goto_scene wild7
        
      *else
          You missed.
          *set PCohesion %-10
          *goto_scene wild7
        
    #You take aim at one of the riflemen and shoot.
        Rollin' rollin' rollin' rollin
       *goto_scene wild7

    #You shoot over the enemy’s head. You don’t want to kill anyone.
        You escape this time.
       *goto_scene wild7```

You need all the #Options to be at the same indent level.

And here:

*if (Discipline >=30)
*elseif (Discipline < 30)

You can just use *else instead of *elseif (Discipline < 30), because that covers all the logical possibilities.

If you do use an *if/*elseif after an #Option, you’ve got to make sure there’s somewhere for the code to go – either an *else or a *goto indented at the same level as the *if/*elseif. Right now you don’t have that.

Got it. Do *if commands need to be part of a choice or can I use them to display certain text based on if a variable is true or not?

You can use *if to display text without a *goto. This will work:

You went to school, took the exam, 
*if (exam_passed) 
        passed it, 
and then went to lunch

If you use *elseif or *else with your *if, though, each bit needs to end with a *goto. You do it correctly in the “take aim at the machine gunner” segment.

For your “shoot the officer” bit, any of these three ways could work:

#You take aim at the officer and pull the trigger.
      *if (Discipline >=30)
          You got him.
          *goto_scene wild7
      *else
          You missed.
          *goto_scene wild7
#You take aim at the officer and pull the trigger.
      *if (Discipline >=30)
          You got him.
          *goto_scene wild7
      *elseif (Discipline < 30)
          You missed.
          *goto_scene wild7
      *goto_scene wild7
#You take aim at the officer and pull the trigger.
      *if (Discipline >=30)
          You got him.
      *if (Discipline < 30)
          You missed.
      *goto_scene wild7

The first way is simplest and least bug-prone.

I should elaborate- this is for a different section. Your previous fix didn’t trip any more errors, this is just a hypothetical.

Yep, just giving you illustrations of what the *gotos need to be doing with the if/else, if/elseif, and if/if approaches when they’re part of an #Option block.

Quick minor question, how do I set one variable to equal another? Like if I wanted variable1 to be set to variable2, would I not use [*set variable1 = variable2]? It turned up an error when I tried this. I also tried [*set variable1 = “${variable2}”]

(I’m sure it’s been asked before but I couldn’t find the appropriate posts)

Do it without the = sign: *set variable1 variable2

1 Like

That fixed it, thank you!

I’ve been having an issue on the stats screen where some of the text isn’t displayed in the bar. It is an opposed stat, and the text on the left side appears, but the text on the right does not.

        Rebelliousness
    opposed_pair Merciful
        Ruthless```

For context, it is specifically the "Merciful" variable that does not appear. Everything else does.