A guide to more advanced features in the ChoiceScript programming language. Please post on the ChoiceScript google group if you have questions about this document.
Be sure to read our basic ChoiceScript Introduction page before reading this advanced documentation
*image: This command inserts an image. Place the image in the “mygame” folder, and type the name of the image file, like this:
*image beauty.jpg
If you like, you can specify the alignment ("left" or "right") after the image name, like this:
*image beauty.jpg left
By default, the image appears centered on a line by itself, but if you align the image left or right, the text will flow around the image. (In CSS terms, the image will "float" left or right.)
*comment: This command does nothing; any text you put after *comment will be ignored. It's helpful to put remarks in the text that only the author should read.
*comment TODO We should make this scene more interesting!
*page_break: Put in a "Next" button with no radio buttons. The game will continue on the subsequent page.
You turn the corner slowly. Blood rushes through your ears. As you open the door...
*page_break
... the masked murderer attacks!
*line_break: Put just one line break in your text, like a <br> in HTML. ChoiceScript automatically converts single line breaks to spaces, and double line breaks to paragraphs.
So
this
is
all
one
line.
But this is a new paragraph.
And this
*line_break
is two lines.
That code would display like this:
So this is all one line
But this is a new paragraph.
And this
is two lines
*input_text: Provides a text box for the user to specify the value of a variable, e.g. the user's name.
Please enter your name.
*input_text name
Your name is ${name}
*input_number: Just like *input_text, but only numbers are allowed in the text box. Specify a variable name as well as a minimum and a maximum.
How many coins?
*input_text coins 0 30
You asked for ${coins} coins.
*fake_choice: This convenience command behaves exactly like *choice, but no commands are allowed in the body of the choice; thus no *goto/*finish is required.
What color do you prefer?
*fake_choice
#Red
Red is the color of roses.
#Blue
Blue is the color of the sea.
#Green
Green is the color of spring.
What an excellent choice! And what flavor of ice cream would you like?
*fake_choice
#Vanilla
#Chocolate
#Strawberry
Mmm, delicious!
*finish
*rand: Set a variable to a random number. You set the minimum and maximum, we do the rest. For example, this would set the variable die_roll to a value from 1 to 6 inclusive:
*rand die_roll 1 6
Beware! It can be very hard to adequately test games that use randomness.
*stat_chart: Use this command to create a table of stats, suitable for displaying when the player clicks the "Show Stats" button. This command is so complicated it deserves a page all by itself. Customizing the ChoiceScript Stats Screen
*ending: Use this command to insert a "Play Again" button; when the player clicks that button, all stats will reset and the game will start over from the beginning. (The *ending command is very different from the *finish command; *finish adds a "Next Chapter" button, and does not reset anything.)
*share_this_game: Use this command to invite the player to share your game on Facebook, Twitter, StumbleUpon, etc. On iPhone/Android, *share_this_game will invite the user to rate/review the game. Therefore, be cautious in how you use this command. We recommend using *share_this_game at the end of the game, and only when the player has reached a "good" ending. Don't use the command if the player has reached a "bad" ending (e.g. if they have just died). Players who reach good endings tend to give positive reviews; players who reach bad endings tend to give negative reviews.
*finish buttons say "Next Chapter" and *page_break buttons say "Next". You can make the button say something else, instead:
*page_break On with the show!
*finish The show is over!
How will you handle this?
*choice
#Try to talk them out of it.
They cannot be dissuaded.
*finish
#Force them to relent.
They back down, for now.
*finish
*if (president) #Abuse my presidential powers to silence them
This works; you will never hear from them again.
*finish
In this case, players have the option to abuse their presidential power only if they are president; if they are not president, then the option is completely hidden. (Note that the parentheses around "president" are required.)
You can also use nested blocks of conditionals, but this technique is pretty advanced; it's hard to get the indentation exactly right.
*choice
#Rattle my saber.
They rattle back.
*finish
*if republican
*if president
#Declare open war.
Congress refuses to approve funding.
*finish
*else
#Ask other Republicans to help out.
Talk radio is on your side.
*finish
*else
*if president
#Work with the United Nations.
Russia vetoes your plan.
*finish
*else
#Ask other Democrats to help out.
They do their best, but the party is divided.
*finish
How will you handle this?
*choice
#Try to talk them out of it.
They cannot be dissuaded.
*finish
#Force them to relent.
They back down, for now.
*finish
*selectable_if (president) #Abuse my presidential powers to silence them
This works; you will never hear from them again.
*finish
If you aren't president, you'll see the option to abuse presidential power, but it will appear in grey; it won't highlight if you click on it. This gives players a hint that if they play the game again, they might be able to choose that option, by making different choices earlier on.
*temp unused_1
*temp unused_2
*set unused_1 true
*set unused_2 true
*label start
*choice
*if (unused_1) #One.
*set unused_1 false
The loneliest number that you'll ever do.
*goto start
*if (unused_2) #Two.
*set unused_2 false
Two can be as bad as one.
*goto start
#I can't decide!
Well, think it over.
*goto start
#Done.
OK!
*finish
But there's an easier way. You can use the *hide_reuse command to mark commands as non-reusable. You can use it in the middle of a *choice, like this:
*label start
*choice
*hide_reuse #One.
The loneliest number that you'll ever do.
*goto start
*hide_reuse #Two.
Two can be as bad as one.
*goto start
#I can't decide!
Well, think it over.
*goto start
#Done.
OK!
*finish
Or you can make all options non-reusable, by adding *hide_reuse to the top of your ChoiceScript file. Then you can use the *allow_reuse command to allow certain options to be reused.
*hide_reuse
*label start
*choice
#One.
The loneliest number that you'll ever do.
*goto start
#Two.
Two can be as bad as one.
*goto start
*allow_reuse #I can't decide!
Well, think it over.
*goto start
#Done.
OK!
*finish
You can also use the *disable_reuse command instead of *hide_reuse to disable used options; instead of hiding them, the disabled options will be greyed out and unselectable.
*set leadership 50
*set leadership %+ 20
*set leadership %- 40
The "%+" and "%-" operators are called the "fairmath" operators. The idea is that as your leadership score gets higher, it becomes harder to increase, and easier to decrease. According to fairmath:
(x %+ y) = (x + (100-x)*(y/100))(90 %+ 20) = (90 + 2) = 92
(10 %+ 20) = (10 + 18) = 28
(x %- y) = (x - x*(y/100))
(90 %- 20) = (90 - 18) = 72
(10 %- 20) = (10 - 2) = 8
(50 %+ 20) = (50 + 10) = 60
(50 %- 20) = (50 - 10) = 40
Fairmath is great in expressions like: *set leadership %+ 20. The player will get anywhere from 0 to 20 more points of leadership, depending on how high leadership is currently.
round(). For example, this will set the variable "foo" to 3: *set foo round(2.5)
You can also use the modulo operator "%" to calculate the remainder after taking a division. Modulo is pretty weird, but it's has two particularly interesting uses. First, you can check whether a number X is evenly divisible by a number Y by checking whether X % Y = 0. Second, you can use it to get the fractional part of a number X, the stuff that comes after the decimal point, by calculating X % 1. For example, 3.14 % 1 = 0.14.
*if statements: You can do a lot more with *if statements than leadership > 15. Here's a few tricks:
leadership = 40 (Is leadership equal to forty?)
leadership != 40 (Is leadership different from forty?)
leadership >40 (Is leadership greater than forty?)
leadership <40 (Is leadership less than forty?)
leadership >=50 (Is leadership greater than or equal to fifty?)
leadership <=40 (Is leadership less than or equal to forty?)
(leadership > 30) and (strength > 40)
(leadership > 60) or (strength > 70)
not(strength > 70)
((leadership > 60) and (agility > 20)) or (strength > 80)
lover_name = "Jamie"
"2" = 2 (this is true!)
true or false:
*set finished false
*set correct guess = "blue"
Behold! $!{He} is capitalized.
*set murder "red"&"rum". You can use variables in the same way: *set title "Dr. " & last_name
*set joke "she said it was "ironic"!"
If you write ${joke}, you'll get:
she said it was "ironic"!
*set slashy "Here's one backslash: \ and here's two backslashes: \\"
If you write ${slashy}, you'll get:
Here's one backslash: and here's two backslashes: \
*print: This command is no longer necessary; it just prints the value of the variable you specify. Use ${} variable substitution instead.*goto command, you can use the *gosub command to go to a label, and then use the *return command to jump back to the line where you called *gosub.
*choice
#Happy.
You're happy!
*gosub saying
Hopefully, you'll be happy for a very long time!
*finish
#Sad.
You're sad.
*gosub saying
Maybe you'll be happier soon!
*finish
*label saying
This, too, shall pass.
*return
If you choose "Happy," the game will write:
You're happy! This, too, shall pass. Hopefully, you'll be happy for a very long time!
It's great for snippets of code that you would have copied and pasted all over the place.
"Subroutines" are tiny sub-programs that you run in the middle of your program. *gosub is so-called because it activates a subroutine. It is possible to nest subroutines, by using *gosub twice or more before using *return command.
Start One,
*gosub two
End One.
*finish
*label two
Start Two,
*gosub three
End Two.
*return
*label three
Three.
*return
That code would display:
Start One, Start Two, Three. End Two. End One.
WARNING: Generally speaking, the simpler your ChoiceScript is, the better. It's possible to abuse *gosub to create extremely complex programs. This is rarely a good idea; complex games aren't any more fun than simple games, but complex games are a lot harder to make. If you think you need a lot of subroutines, consider whether your game might be better if it were simpler.
*setref: Set a variable by name, e.g. *setref "leadership" 30 sets leadership to 30. Use it in crazy code like this:
*set virtue "courage"
*setref virtue 30
This code would set courage to 30. If this still doesn't seem useful, consider that virtue could have been determined by earlier choices, so it might have set honesty to 30 instead.
Still not convinced? Don't worry about it; you'll probably never need it.
*gotoref: Goto a label by name, like this:
*temp superpower
*set superpower "invisibility"
Your super power is:
*gotoref superpower
flight!
*finish
*label invisibility
invisibility.
*set honesty 30
*set virtue "honesty"
*set score {virtue}
Your ${virtue} score is ${score}
This would print:Your honesty score is 30
Please post on the ChoiceScript google group if you have questions about this document.
©2012 Choice of Games