Best practice -- *choice vs *fake_choice

Both can be. But if I’ve understood rightly, the original intent of *fake_choice was to only be for the first kind. Flavor choices still require setting variables, and the original CoGs used *choice for that.

But the desire to skip *gotos all the time led to an ever-broadening use of *fake_choice, until it became a total misnomer. Any writer who uses it for Flavor Choices has no reason not to use it to set primary or secondary variables as well.

5 Likes

I was just quoting the article, where Jason states both are produced using *fake_choice.

A Fake Choice and a *fake_choice aren’t necessarily the same thing, though they can be.

(…)

A variant on the Fake Choice is the Flavor Choice .

I don’t know anything about the original intent or whatnot.


But you’re right in saying they can be. You could make fake and flavour choices with the *choice command as well. The only difference is that (without implicit control flow turned on) you’d have to add a *goto at the end of every *choice body, even if all options lead to the following block of text.

My take on it is that *fake_choice was labelled so because of two things:

1 - Apparently before you couldn’t use any command inside *fake_choices (I’m unsure if it was actually this way at any point) so for this reason they were always “fake” because they didn’t do anything.

2 - It was assumed that previously the actual “difference” or “branching” was only possible if a *goto was used since only by going to another place of the code would the user experience any sort of changes in their gameplay. It didn’t take into consideration that these *fake_choices could set stats, have other choices inside them, gosubs, or even that some *fake_choice options could have *gotos while others didn’t. Use of these could provide “difference” or “branching” in other ways so they are still choices at the end of the day.

Another difference I remember is that there seems to be an issue if you nest *fake_choices inside another, while such a problem does not happen while using *choice, so that makes *choice more viable and consistent imo. If ICF is being used, then I’d say always use *choice and forget about *fake_choice.

I don’t even mind the *goto requirement at the end much, what really angers me is the need for *gotos at *elses. I studied some languages and frameworks and work with some daily but ChoiceScript is the only one that has this requirement or that uses *gotos at all, leading to an immense redundancy of unnecessary *labels and *gotos.

2 Likes

Amen to that. It took me a long time to figure out that *else at the bottom of a stack needed a *goto. Logically, it shouldn’t, but that’s how CS rolls… :roll_of_toilet_paper:

2 Likes

I mean, in the hands of someone who knows what they’re doing, I am fine with implicit control flow. I train my authors to use *fake_choice primarily, and to do as much clever nesting as they can for story branches rather than having a bunch of labels for routing. I consider *fake_choice best practice for more or less uncomplex narratives, and strongly prefer to see *fake_choice and *gosub wielded well for code efficiencies.

7 Likes

If you notice, there’s no *choice anywhere in that article. The “Establishing Choice” example also uses *fake_choice, and after that Jason stops typing in any commands at all.

It’s a good example of how the ChoiceScript command *fake_choice, whiich was originally the way to represent Fake Choices that set no variables, has turned into the default command for just about any kind of choice because of its greater convenience.

I’ve been waiting for years for Dan to deprecate *fake_choice because it’s become inaccurate and thus confusing. For a coding language whose main goal is helping non-programmers use it effectively (which is if I’ve understood rightly the reason for the abundance of *gotos) the non-fakeness of fake_choice seems like something worth changing…

Why not change *choice to do what *fake_choice does now, rather than train authors to use *fake_choice as much as possible?

4 Likes

If I’d take a shot at guessing, it’s because CS is promoted as “writer first, coder later.” *choice*goto and *fake_choice is much more human readable than *choice without *goto but *set implicit_control_flow true.

It’d be janky to teach newcomers of CS “Welcome! You can use *choice, but put this *goto, but you can not putting it by using ICF instead.”

1 Like

I think the current solution is enough. Newcomers can use *choice with *gotos and *labels. And as people get more comfortable they can switch to implicit control flow. Like bicycle training wheels.

That being said, I do understand the concern with non-coders, but I think it’s not really necessary. Anyone who has ever learned Python or Java or JavaScript or PHP or Kotlin or what-have-you had to get used to implicit control flow. Programmers are not a different species, they are not super genius people—at least not solely for the fact of learning a programming language—, and all of them had to get used to implicit control flow.

Although, it does lower the risk of errors for beginners, making sure every choice is explicitly redirected. So… :man_shrugging:

I’m not a fan, but I get why it’s there, and I’m grateful there’s an option for implicit control.

3 Likes

I tend to use fake_choice most of the time, but use choice for places where the narrative truly branches as a reminder for myself.

4 Likes

I disagree with this; if one can understand what *fake_choice does (code continuing down) then they can understand implicit_control_flow. It’s the same thing, there’s nothing “advanced” about it.

When I learned programming it was always like that; this wasn’t even an issue at all since there are a lot more other complex things in programming than “code continuing down”.

4 Likes

I know. It’s very easy to understand it even if you only ever scraped the surface of programming. However, many others are simply go “What? Coding? I’m out.” I’ve seen numbers of it happening in this forum.

*fake_choice might be an old thing, and *setref is also a proof that CS is unafraid of evolving. However, this one is a pretty finicky case where even Dan isn’t unsure if ICF is bug free and whether to have it on by default on that cost.


So, yeah. Maybe the wiki needs some massive revamps? :grimacing:

It was always optional to use; if the fact that they were there might scare newcomers then one might as well remove *gosubs, *params and arrays.

You mean “arrays”, right? :wink::joy:

2 Likes

Just to clarify: That’s a comment on whether ICF will cause more bugs, due to the higher chance of user error. It’s not a comment on the “ICF” behaviour itself containing bugs. Though the argument stands.

2 Likes

I’ve never used a *choice before(and I’m three games in), but I don’t remember the last time I made a fake choice. I don’t know why I do that, though. I guess I just enjoy the irony of it.

1 Like

Wait, am I reading this correctly, lol? Or is this a joke that flew over my head? :sweat_smile:

It’s true. I always write *fake_choice instead of *choice, but I always end each individual choice with a *goto.

Oh, I was being dumb–I thought you were saying you’ve never done a *choice, but you also don’t remember the last time you did a *fake_choice (like the actual command), so I was like, “…but then how do you program your… choices?”

I’m an idiot, just ignore me

I’ve also been doing *fake_choice in place of where *choice is traditionally used lately, and I have implicit control turned on (and it’s a lifesaver)! I don’t use *goto unless it’s going to actual separate branches anymore, it’s been very nice in terms of saving time.

6 Likes

I predominantly use ICF and *choice because my choices don’t tend to branch out far until the middle and the end. I can focus more on writing than trying to route code through labels, and it looks better than *fake_choice. I usually recommend the ICF-*choice combo to those who consider themselves more of a writer than a coder. By no means am I talented coder, and the less I have to futz with code, the better!

2 Likes

I use implicit control flow because it massively neatens up my *if / *elseif / *else stacks, which I like to use rather than a stack of *ifs for more precise bug finding and typo avoidance. Because of using ICF, I tend to go for *choice if I’m doing a lot of nesting or using *goto to go somewhere wildly elsewhere in the file. But if it’s a set of options with stat changes and different text that then leads to the same place, I’d use *fake_choice.

8 Likes