*if - *if versus *if - *else/*elseif

Yo Everyone
I was tinkering a 'lil bit with my story, then found something that intrigues me, then go to the wiki
But I found no much regarding *if paired to another *if commands

Well, you see… conditional statement uses *if paired to *elseif/else for different condition

Like this
*set money 100
*label repeat
*choice
   #Buy a PC
      *if (money >= 99)
         *set money -99
         *goto repeat
      *else
         You don't have enough money
         *goto repeat

   #Buy a flashdisk
      *if (money >= 5)
         *set money -5
         *goto repeat
      *else
         You don't have enough money
         *goto repeat
   #I'm good
      *ending

That one uses *else, but *elseif works with some little adjusment otherwise.

I found out, that replacing the *else to another *if still work.


I wonder. How does *if - *if works compared to *if - *elseif/else ?
In what cases both setups work best?

2 Likes

if/elseif/else chooses one of a set.

if/if/if chooses every single one that applies.

There are times when you can use if/if in place of if/else but only if you are abso-smurf-ly positive that both can’t be true.

I find it easier to go back and read code that uses if/else, as a side benefit.

I just remembered something, that when you hit a conditional check with only 1 check, the nested-commands inside the contitional check can be… what is the term… drop out? left out?

Something like this

*set smart true
*if (smart)
   You answered the question correctly.

Ok, that's it
*ending

That code should print,

You answered the question correctly.

Ok that's it

am i right?


If the [smart] value switched into false, the print will just be “Ok that’s it”
*CMIIW

Yes, exactly. You are clearly (smart).

2 Likes

-_-

I think I can make some sense now…
(stare into the monitor thoroughly)


Edit:
I see… Umm… But what’s the point of *elseif if you can simply use *if with *goto nested inside it?

1 Like

I’m not exactly an expert on coding, and certainly not on programming language design, but one reason could be to simplify and make sure nothing gets left out in a sequenced set of *if statements.

For instance:

*if (dapper > 70)
    *set impressive %+20
    You straighten your collar one last time. You are dressed to impress, and everyone will bow before your stylish panache.
    *goto they_love_you
*elseif (dapper > 50)
    *set impressive %+10
    Well, at least you won't stand out amongst the other guests. You glance in the mirror one last time, then head through the double doors.
    *goto you_do_fairly_well
*elseif (dapper > 30)
    *set impressive %-10
    Who did that tailor think you are, anyway? You shift uncomfortably in the ill-fitting clothes and sigh.
    *goto you_do_fairly_well
*else
    *set impressive %-20
    This is an awful muddle, it really is. You look like the last remnants from the dingiest charity shop in the entire city. But it's too late to sort it now.
    *goto everything_is_a_disaster

I’ve also used *if/*elseif/*else when I’m checking various stats for dialogue, in order of what I think would be most interesting, to make sure that no matter what your character will be sure to have a comment.


*if (responsible < 30)
    "Well, it wasn't my idea to give the king a pie full of blackbirds," you retort.
    *goto king_is_mad
*elseif (sarcastic > 70)
    "But the king likes blackbird pie, didn't you know? He always has it with treacle and a single strawberry, and twice on Tuesdays."
    *goto king_is_mad
*else
    "I'm sorry, I really am!" you say, but the cook only glares at you.
    *goto king_is_mad
*label king_is_mad
2 Likes

if/elseif/else makes it so that only one outcome is chosen:

*if strength > 50
    You are strong.
*elseif intelligence > 50
    You are smart.
*elseif stealth > 50
    You are stealthy.

You can only be either strong, smart, or stealthy.


However, with if/if/if statements, anything from one to all outcomes might be chosen:

*if strength > 50
    You are strong.
*if intelligence > 50
    You are smart.
*if stealth > 50
    You are stealthy.

This way, you can be strong, smart, and stealthy at the same time.

5 Likes

Hey there.

Speaking from my own experimentations, I’ve found that I prefer to always use if/if, and never if/else… because if/if can be fallen out of, while if/else cannot.

Setting up if/if/if in a manner of *if value < 4, *if ((value > 3) and (value < 6)), *if value > 5 works great, and in Monsters, there are many instances where I hide something under an *if- making certain points where I want multiple *if statements to happen; they just need to make sense when they flow in any combination, within the story, and when they finish, will fall out back into the script flow.

You can create elseif logic using just if, using the right scripting. An example would be that strong/smart/stealthy UmbraLamia brings up. Here’s a way you can be either strong, smart, and stealthy at the same time, or just strong, smart, or stealthy, using only *if statements.

*if multitalent = 1
 *if strength > 50
  You are strong.
 *if intelligence > 50
  You are intelligent.
 *if stealth > 50
  You are stealthy.
*if multitalent = 0
 *if strength > 50
  You are strong.
 *if ((strength < 51) and (intelligence > 50))
  You are intelligent.
 *if ((strength < 51) and (intelligence < 51)) and (stealth > 50)
  You are stealthy.

Badaboom. sprinkles the salt XD

A great thing about *if statements, is that you can nest them inside other *if statements. Then when finished, the script will fall out to the script as it would happen if the *if condition was not met. So what’s under the *if becomes like ‘extra’ text, used this way.

3 Likes

That was basically what I thinking :confused:

But I believe, as a righteous king should be, that both if/if and if/else/elseif has their own pros-cons and should be treated “equally”

But I’m yet to find the reason why I should use if/else/elseif and can’t replace it with if/if :stuck_out_tongue_winking_eye:

I don’t believe that you “can’t” or even “shouldn’t” replace an *else statement with an *if statement, but that it changes the burden of labor. Depending on your personality, and what you’re trying to accomplish, that may (or may not) be beneficial.

As has been mentioned before, *else automatically “sweeps up” everything preceding *if statements may have left behind, while excluding everything else. Thus, replacing it with another *if requires extra vigilance on your part to ensure nothing is accidentally skipped or accidentally triggering multiple statements. (Obviously, skipping something or triggering multiple statements on purpose isn’t a problem.)

Yes, *else requires a *goto below it, and a matching *label elsewhere, increasing the length of your code. However, duplicating the effect of *else with only *if will make each *if statement longer, somewhat reducing the benefit of skipping *goto. And in situations where you’re planning on using *goto anyway, you’ll be making your code longer.

Looking back at the “dapper” example @Fiogan gave, you could easily replace:

*elseif (dapper > 30)
  *goto you_do_fairly_well
*else
  *goto everything_is_a_disaster

With something like this:

*if (dapper <= 50) and (dapper > 30)
  *goto you_do_fairly_well
*if (dapper <= 30)
  *goto everything_is_a_disaster

Or, assuming your numeric variables will only ever contain integers and never decimals, something like:

*if (dapper < 51) and (dapper > 30)
  *goto you_do_fairly_well
*if (dapper < 31)
  *goto everything_is_a_disaster

You can see how pure *if will save some coding if you don’t need *goto (or only need it on a few of your *if statements but not all,) but becomes less helpful the more you need *goto.

Also, think about what would happen if you accidentally coded *if (dapper < 30) instead of either *if (dapper <= 30) or *if (dapper < 31). An easy enough typo to make, right? But then what happens if an MC has exactly 30 {dapper}? They won’t get the result for “greater than 30,” because 30 isn’t greater than itself. But they won’t get the result for “less than 30” either. It will simply “fall out” of the *if statements without doing anything.

If you take the extra effort to account for situations like that, it should be perfectly fine to use nothing but *if. But that’s exactly what I mean by changing the burden of labor — you’ll save effort on coding *goto and *label, but you’ll spend effort making sure all possible situations are functioning as you intend.

So, should you use *else instead of *if? That’s going to depend partly on which type of effort annoys you more, and partly on whether you’re already using *goto, isn’t it?

I genuinely believe the answer to Should I? is “It’s situational.” I don’t believe either method will always be easier or more reliable. A writer who loves puzzling out how something will work, but dislikes unnecessary typing will likely find great benefit in a chain of pure *if. Clearly, @Shawn_Patrick_Reed is this type of writer, and your comments make me suspect you are as well. However, a writer who doesn’t mind typing but dislikes trying to figure out what the code is actually doing and how that compares to what it needs to be doing will likely find great benefit in *else.

What’s better for you might be worse for someone else, and vice versa.

6 Likes

I actually love efficiency slightly more than I love typing. (If any of my alpha testers read this, you can stop laughing at me now.)

I also love knowing exactly what my code is doing and how. *else (which you summed up much more nicely than I did) has for me three purposes: 1. Precluding bugs. 2. Simplicity when I want only a single check to pass for any given play-through. 3. Simplicity when every possible iteration must redirect to various *labels.

I do sometimes use *if/*elseif/*else and pure *if in concert, too, often in dialogue trees or stat checks, indenting the *ifs further. That way, I can have both multiple inclusive conditions and multiple exclusive conditions which are then redirected to the suitable *label.

I agree the use of *if/*if or *if/*elseif/*else are situational, but I’d think perhaps they’re more situational to the needed mechanics than necessarily to the writer.

3 Likes

Thank you every1 for the response, especially @Minnow that give me the enlightenment :star2:I’m probably looking for

If I’m about to summarize it, the consideration of this *if things is when you’re about to be effective on your code, or when you’re about to be “clear” on what your code’s doing, right?

Else is just the matter of writer’s style

Actually, @Shawn_Patrick_Reed’s example is a good one to use to demonstrate how one can write code to work either way. Using *else (@Shawn_Patrick_Reed and @UmbraLamia , I hope you don’t mind me borrowing your sample), one could also code this passage like so:


*if (multitalent >= 1)
    *if (strength > 50)
        You are strong. 
    *if (intelligence > 50)
        You are intelligent. 
    *if (stealth > 50)
        You are stealthy. 
    *goto such_talent
*else
    *if (strength > 50)
        You are strong.
        *goto such_talent
    *elseif (intelligence > 50)
        You are intelligent.
        *goto such_talent
    *else
        You are stealthy.
        *goto such_talent
*label such_talent

Or it could be coded differently and condensed thusly:


*if (strength > 50)
    You are strong. 
    *if (multitalent = 0)
        *goto such_talent
*if (intelligent > 50)
    You are intelligent.
    *if (multitalent = 0)
        *goto such_talent
*if (stealthy > 50)
    You are stealthy.
*label such_talent

I think that would work too, and achieve the same results, no?

This is why I love glancing at code in published games. Different authors can achieve the same thing in a variety of ways (or the same author might come up with new techniques in subsequent games, too).

6 Likes

TBH, I’m always happy whenever I found a way to even shorten my code, further as smally-tiny as possible xD

Your “borrowed” examples clearly shows yet another intricate smaller-code

1 Like

Else is also useful as a bug catcher. For example, this code runs perfectly fine:


*choice 
  #search the room
    You look around the room and
      *if perception > 50
        spot what you're looking for.
      *if klepto
        find something to steal.
    *comment and... <-- If neither is true?
    *goto somewhere else.
  #other option.

But, we can see a very obvious error in it.

2 Likes

Which is why QuickTest has been designed to prefer *else statements:

My own code acquired a lot more "else"s the first time I ran QuickTest on it!

As for elseif, the main reason I use it is to reduce the frequency with which I have to type something like “*if ((strength < 51) and (intelligence < 51)) and (stealth > 50)”. Or in code like the below from XOR, where I’m picking which NPC is going to be with the MC based on who’s present, it saves me loads of “if not(zv_here)” and so on down the chain:

  *if zv_here
    Zvad
    *goto waraccchoice
  *elseif el_here
    Elery
    *goto waraccchoice
  *elseif bred_here
    Breden
    *goto waraccchoice
  *else
    Alira
    *goto waraccchoice

I know a lot of people seem to prefer minimizing gotos, but from my perspective, I don’t have to type “*goto waraccchoice” each time, that’s a simple CTRL-V. Typing in the variations on who’s not(here) would soak up way more time.

I find this a little harder with *else, actually. But that’s probably because I don’t use gotos efficiently enough, so the “else” can pop up many, many paragraphs of variable indentation below the other choices in the chain, at which point I can’t remember the conditions on the other options without a *comment. If I kept the choice options closer together, which I realize now is good coding practice, it would be more transparent…

4 Likes