ChoiceScript Full Tutorial (finished!)

Oh, this looks great! I haven’t used CS in ages and I’m gonna try and re-learn things I’ve forgotten. I’ll definitely try this out: good work!

1 Like

Followed through on @nightcap 's suggestion and added different types of design structures to the Design Strategies page. I tried to pull different types of structures from different guides, but if anyone has any other kinds of structures they’d like to throw into the ring, I’d be willing to diagram it as well.

Also, do you think it would be useful to give examples of the different types of games? I’m not sure if I want to look like I’m endorsing one game while ignoring another.

3 Likes

I don’t know what to say, this is Excellent @Lglasser

I am really impressed at how deeply you engaged with this topic and am learning from your tutorial as I speak. . .


First structures landing page -

A typo:
The examples shown represent of several scenes with tens of thousands of words.

Sentence structure:
How well the game has a satisfactory introduction

3 Likes

Thanks for pointing out those typos! Ironed them out (page might need a refresh to see them.)

And glad the tutorial was helpful! I’m definitely trying to wrangle all the info I can into this one accessible place.

4 Likes

Small update:

  • Added the *link command as its own page
  • Better described what’s on the templates page (strings of choices / larger choices / stat tests / choice hubs / handling pronouns / stat page example)
  • Added a break-the-game example to the numbers page
  • Tidied up one of the examples for text variables.
4 Likes

The *fake_choice page claims that you can’t use any *if or *selectable_if options in the selection lines. But in fact you can; it works exactly like a *choice block, except that you can’t nest *choice or *fake_choices, or use any terminal commands (*finish, *goto, *goto_scene, etc), within a *fake_choice. Of course, this last restriction is because game flow simply falls out of the *fake_choice to the next line.

Specifically, for both types of *choices:

  1. *if statements must get their own line, with their corresponding #option indented one level over below them;
  2. *selectable_if, *hide_reuse, and *disable_reuse modifier flags must appear on the same line as their corresponding #option; and
  3. *if statements’ tests don’t need to be enclosed in parentheses (but they can be), whereas *selectable_ifs’ must be enclosed in parentheses. Even if it’s just *selectable_if varname or *selectable_if not (varname), it needs to be *selectable_if (varname) or *selectable_if (not (varname)) instead.

I agree that *ifs are usable, but *selectable_ifs aren’t. They will break in live conditions.

1 Like

I’ve found that *selectable_if and *if statements can work on fake choices… until they don’t. I’ve had a lot of difficulty nailing down the exact conditions under which they do / don’t work, so I played it safe and said just not to use them. That seemed like the safest option.

However, should I include *if ? And is their needing their own line accurate?

That’s always been annoyingly inconsistent. *selectable_if does only ever work on the option’s own line, *if will always work on the above line, and will (sometimes) seem to work on the same line.

Hmm… I’ll see about adding that, although I think it’s too bad it muddies an otherwise simple rule to remember.

I almost feel like I need to add a new header to go along with “Basic Commands” and “Get Fancy” : “Use at Your Own Peril”.

Thanks for the additional info, @Chris_Conley and @CJW

3 Likes

Does this explain how to create an inventory?

So, *selectable_ifs in *fake_choices won’t work once it’s published, even if they do during testing? That’s good to know.

I found some more things… I hope you don’t mind if I list them as I go through this!

(Never mind what was here–thanks Vendetta!)

I think it’s also worth explicating the two types of *if statements which exist. (Maybe on the Variables (General) page.)

  • The first type is the single block, without an *else (or an *elseif). This type can end with a terminal command, but if not, gameflow simply falls through to the next line after the block.
  • Then there’s the multi-conditional block (*if/*else or *if/*elseif/*else). Every one of these blocks, including the *if block, must end with a terminal command.

The FishingVillage example in Variables (General) has a typo: the *set and *goto lines aren’t indented enough under their #option.

You taught me something new! I did not realize you could nest *if statements, or use *else blocks, inside of *choice blocks. I almost don’t want to, but it would improve legibility of some of my code…

Variables can, in fact, change kinds. You can’t perform mismatched calculations, so you can’t add 1 to a string or *if a number, but you can set a text variable to 1.
*temp num 50 *set num "OK"
is perfectly valid. (You shouldn’t do this, but you can…)

Text Variables (Strings) lacks the third printing option. $!!{varname} capitalizes every character in the string.

Not entirely accurate. The following will work just fine -

*hide_reuse *selectable_if (var = 1) #This option is perfectly valid

It’s just a matter of using them the right way around. I’ve never used *disable_resuse in the same way but I wouldn’t be surprised if it also works.

3 Likes

Ah, thanks! I must have been trying to mix *ifs and selection line effects, way back when, and came to the wrong conclusion thanks to the finicky nature of same-line *ifs. Or else I just had them in the wrong order.

So; it looks like you can have one (or no) selection line modifier, followed by one (or no) *if or *selectable_if statement, per #option.

2 Likes

Please do go through them! I love all the tricks you know about, and it’s really helpful rounding this out. Finding typos is especially valuable. The raw code for this guide isn’t easy to copy-paste into a file and test it.

I’m working on updates today, I’ll let you know when it’s updated.

All that said, I think I’m going to keep “change variable kinds” under “break the game”. Even if it’s technically possible, it almost shouldn’t be. <_<

1 Like

I didn’t know that. I’d been using the boonlean trick too. Thanks for letting me know! I’ll work on that update.

1 Like

Almost… bear in mind it’s still possible to impose an overriding *if condition on one or more *selectable_if (or *hide_reuse, etc.) options, as follows:

*choice
    *if (var1 > 50)
        *selectable_if (var2 = 1) #This is a valid option only if both conditions are true
6 Likes

Yes, you’re right, of course—I should have said “on the same line.” *ifs can always be placed standalone on the line before.

3 Likes

I updated the program! Lots of updates, thanks to @Chris_Conley and @Vendetta.

  • Added an Inventory template page ( Hope this helps you, @Sovereign2Lilith ! )
  • Added 2 template pages explaining how to have stat tests reference variables instead of static numbers. (“Managing Game Difficulty”)
  • The *fake_choice page now mentions that you can use *if statements (maybe someone wants to double-check I got the description correct.)
  • The Randomtest page mentions that it won’t catch the error of using *selectable_if on a *fake_choice
  • *choice now has an example for using multiple commands on the same line of selection line.
  • *The Quicktest page explains an error code that can appear from using multiple commands on the same *choice selection line incorrectly.
  • Text Variables page got $!!{}
  • Text Variables page got info on how to type special characters
  • Expanded on how *else / *elseif chains change an *if statement (in Variables (General))
  • Fixed typos

Thanks for all the help improving this guide!

4 Likes