[
{
"url": "/posts/blocks",
"title": "Blocks and States",
"content": "<h1 id=\"blocks-and-states\">Blocks and States</h1><p>The core foundation of Storymatic is the block and state system.</p><h2 id=\"overview\">Overview</h2><p>A block is a collection of statements to run and text to output. <code class=\"language-plaintext highlighter-rouge\">State</code> is an alternative name for <code class=\"language-plaintext highlighter-rouge\">block</code>, but it is usually used to describe the names of blocks, and the internal state that the program is in, while <code class=\"language-plaintext highlighter-rouge\">block</code> is used to describe the statements inside.</p><h2 id=\"example\">Example</h2><pre><code class=\"language-storymatic\">start Hello Bob! What would you like to do today?</code></pre><p>The first line (<code class=\"language-plaintext highlighter-rouge\">start</code>) is the state (name). A state can only contain letters, numbers, and underscores, and must have no indentation.The indented text (<code class=\"language-plaintext highlighter-rouge\">Hello $name...</code>) is the block (content). A block must be indented. The block can have several lines, but they must all be indented.</p><p>The part of the story that contains the states and blocks is called the <code class=\"language-plaintext highlighter-rouge\">root section</code>, or the <code class=\"language-plaintext highlighter-rouge\">root</code>.</p><p><strong>The root should always contain a state called <code class=\"language-plaintext highlighter-rouge\">start</code>, which is where your story should start.</strong></p><h2 id=\"more-examples\">More Examples</h2><p>Here is another example with two states (<code class=\"language-plaintext highlighter-rouge\">chocolate</code> and <code class=\"language-plaintext highlighter-rouge\">vanilla</code>):</p><pre><code class=\"language-storymatic\">chocolate Wow! Chocolate is also my favorite ice cream flavor! Would you like to buy some?vanilla I also love vanilla!</code></pre><p>Notice how both states have no indentation, while the blocks have indentation.</p><p>You can have different levels of indentation for different blocks; thus, this example is valid Storymatic code:</p><pre><code class=\"language-storymatic\">chocolate Wow! Chocolate is also my favorite ice cream flavor! Would you like to buy some?vanilla I also love vanilla!</code></pre>",
"group": "Basics",
"keyword": " blocks"
},
{
"url": "/posts/boolean",
"title": "Boolean Expressions",
"content": "<h1 id=\"boolean-expressions\">Boolean Expressions</h1><p>This article explains what boolean expressions are and how to write them.</p><h2 id=\"overview\">Overview</h2><p>A boolean expression is something that evaluates to <code class=\"language-plaintext highlighter-rouge\">true</code> or <code class=\"language-plaintext highlighter-rouge\">false</code>. You always write them in this format: <code class=\"language-plaintext highlighter-rouge\">${varname} {operator} {value}</code>.</p><p>The <code class=\"language-plaintext highlighter-rouge\">operator</code> can be <code class=\"language-plaintext highlighter-rouge\"><</code>, <code class=\"language-plaintext highlighter-rouge\">></code>, <code class=\"language-plaintext highlighter-rouge\"><=</code>. <code class=\"language-plaintext highlighter-rouge\">>=</code>, <code class=\"language-plaintext highlighter-rouge\">=</code>, or <code class=\"language-plaintext highlighter-rouge\">!=</code>. <code class=\"language-plaintext highlighter-rouge\">!=</code> means “doesn’t equal”.If <code class=\"language-plaintext highlighter-rouge\">operator</code> is <code class=\"language-plaintext highlighter-rouge\"><</code>, <code class=\"language-plaintext highlighter-rouge\">></code>, <code class=\"language-plaintext highlighter-rouge\"><=</code>, or <code class=\"language-plaintext highlighter-rouge\">>=</code>, then <code class=\"language-plaintext highlighter-rouge\">value</code> must be a number.</p><h2 id=\"examples\">Examples</h2><div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>$money > 500$money <= 800</code></pre></div></div><p>In the first example, we are checking whether the <code class=\"language-plaintext highlighter-rouge\">money</code> variable is less than <code class=\"language-plaintext highlighter-rouge\">500</code>.In the second example, we are checking whether the <code class=\"language-plaintext highlighter-rouge\">money</code> variable is greater than or equal to <code class=\"language-plaintext highlighter-rouge\">800</code>.</p><h2 id=\"advanced-expressions\">Advanced Expressions</h2><p>You can also join together several simple conditions with <code class=\"language-plaintext highlighter-rouge\">and</code>, <code class=\"language-plaintext highlighter-rouge\">or</code>, and <code class=\"language-plaintext highlighter-rouge\">not</code>.In advanced expressions, <code class=\"language-plaintext highlighter-rouge\">not</code> has higher precedence than <code class=\"language-plaintext highlighter-rouge\">and</code>, which has higher precedence than <code class=\"language-plaintext highlighter-rouge\">or</code>, meaning <code class=\"language-plaintext highlighter-rouge\">not</code> is evaluated before <code class=\"language-plaintext highlighter-rouge\">and</code>, and <code class=\"language-plaintext highlighter-rouge\">and</code> is evaluated before <code class=\"language-plaintext highlighter-rouge\">or</code>.</p><p>For example, you can check whether <code class=\"language-plaintext highlighter-rouge\">money</code> is between 300 and 800 with <code class=\"language-plaintext highlighter-rouge\">$money > 300 and $money < 800</code>.Note that <code class=\"language-plaintext highlighter-rouge\">300 < $money and $money < 800</code> will always evaluate to <code class=\"language-plaintext highlighter-rouge\">false</code> because the variable should come before the value.</p><h2 id=\"usage\">Usage</h2><p>Booleans are used in <a href=\"if-block\">if blocks</a>, <a href=\"for-loop\">for loops</a>, <a href=\"while-loop\">while loops</a>, and <a href=\"while-loop\">do-while loops</a>.</p>",
"group": "Flow",
"keyword": " boolean"
},
{
"url": "/posts/context",
"title": "Contexts",
"content": "<h1 id=\"contexts\">Contexts</h1><p>This article explains how to use contexts.</p><h2 id=\"overview\">Overview</h2><p>A context is a clone of the current story with all local variables reset, but keeping all global variables.You can run statements in a different context by writing <code class=\"language-plaintext highlighter-rouge\">@context</code> and putting statements inside the <code class=\"language-plaintext highlighter-rouge\">@context</code> command.</p><h2 id=\"example\">Example</h2><pre><code class=\"language-storymatic\">@global $money = 500$name = Stevestart $name = Annie $money = 700 name: $name, money: $money @context name: $name, money: $money</code></pre><p>should output</p><div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>name: Annie, money: 700name: Steve, money: 700</code></pre></div></div><p>because name is local, but money is global.</p>",
"group": "Flow",
"keyword": " context"
},
{
"url": "/posts/exit",
"title": "Stop and Kill",
"content": "<h1 id=\"stop-and-kill\">Stop and Kill</h1><p>The <code class=\"language-plaintext highlighter-rouge\">stop</code> and <code class=\"language-plaintext highlighter-rouge\">kill</code> statements are key to using the block system.</p><h2 id=\"overview\">Overview</h2><p>The <code class=\"language-plaintext highlighter-rouge\">@stop</code> statement exits the current context. To use it, just write <code class=\"language-plaintext highlighter-rouge\">@stop</code>.The <code class=\"language-plaintext highlighter-rouge\">@kill</code> statement exits the current story (all contexts). TO use it, just write <code class=\"language-plaintext highlighter-rouge\">@kill</code>.</p><h2 id=\"example\">Example</h2><pre><code class=\"language-storymatic\">start Welcome to my text adventure! @menu Do you want to leave? Yes @stop No @pass Goodbye!</code></pre><p>In the example above, the user can exit early by selecting Yes.</p>",
"group": "Flow",
"keyword": " exit"
},
{
"url": "/posts/for-loop",
"title": "For Loops",
"content": "# For LoopsThis article explains how to use for loops, which are a shortened and more advanced version of [while loops](while-loop).## OverviewRemember [while loops](while-loop)? What if we want to increment a variable each time? We could do:``` storymaticstart $i = 0 @while $i < 5 @nowait $i $i++```or we could use a `for` loop.A for loop runs a declaration, and repeats some statements while a condition is true. Each time the statements inside are run, an increment is run.You write `@for {declaration};{condition};{increment}` and then put statements inside. The first example above could be rewritten with for loops like this:```start @for $i = 0; $i < 5; $i++ @nowait $i```Note that there is no type of for loop that acts like a do-while loop.",
"group": "Loops",
"keyword": " for-loop"
},
{
"url": "/posts/goto-run",
"title": "@goto and @run",
"content": "# @goto and @runBy helping keep your story neat, and opening up more possibilites, `@goto` and `@run` are essential parts of Storymatic.## OverviewBoth `@goto` and `@run` help you transition between blocks. There is a slight difference, which is that `@goto` goes to a block and exits the current one, while `@run` goes to a block, and when stopped, continues the current one.You write them like this:```@goto {blockname}@run {blockname}```## ExampleRemember our example from [`@menu`](menu)? We can improve this by using seperate blocks.``` storymaticstart Welcome to the ice cream store! @menu What flavor would you like to buy? Chocolate @goto chocolate Vanilla You bought vanilla! Strawberry You bought strawberry! Goodbye!chocolate @menu Would you like milk or dark chocolate? Dark Chocolate You bought dark chocolate! Milk Chocolate You bought milk chocolate!```In the example above, if the user selects `Chocolate`, we go to the state `chocolate`.## Goto vs. RunIn the example above, the user will not see `Goodbye!` if they selected `Chocolate` because we used `goto`, meaning that when the `chocolate` state ends, the story will end.However, in``` storymaticstart Welcome to the ice cream store! @menu What flavor would you like to buy? Chocolate @run chocolate Vanilla You bought vanilla! Strawberry You bought strawberry! Goodbye!chocolate @menu Would you like milk or dark chocolate? Dark Chocolate You bought dark chocolate! Milk Chocolate You bought milk chocolate!```we use `@run`, so when the `chocolate` state ends, it will continue the current state, meaning it will show `Goodbye!`.",
"group": "Flow",
"keyword": " goto-run"
},
{
"url": "/posts/if-block",
"title": "If, Else, and Elseif",
"content": "# If, Else, and ElseifAs the most common use of [booleans](boolean), if blocks are a quick and easy way to check if a boolean expression is `true`.## OverviewIf blocks run statements inside if a boolean expression is `true`. You begin by writing `@if {condition}`, and then put statements inside.## Example``` storymatic$money = 300start @if $money < 500 You have less than $500.```## @elseYou can also specify statements to run if the condition is `false`.You do this by typing `@else` at the same level of indentation that your `@if` had, and putting statements inside it.``` storymatic$money = 300start @if $money < 500 You have less than $500. @else You do not have less than $500.```Using nested `@if`s with `@else`, you can do several `@if` clauses:``` storymatic$money = 300start @if $money < 500 You have less than $500. @else @if $money < 1000 You have less than $1000. @else @if $money < 2000 You have less than $2000. @else You do not have less than $2000.```However, this can get a bit messy, so let's learn about `@elseif`.## @elseif`@elseif` is an alternative method to using nested `@if`s. You use it similar to `@if`, but it must follow an `@if` or `@elseif` statement.You can always put `@else` after a group of `@elseif`s or one `@elseif`.Here's the example from above, written using `@elseif`:``` storymatic$money = 300start @if $money < 500 You have less than $500. @elseif $money < 1000 You have less than $1000. @elseif $money < 2000 You have less than $2000. @else You do not have less than $2000.```",
"group": "Flow",
"keyword": " if-block"
},
{
"url": "/posts/input",
"title": "Inputs",
"content": "# InputsYou can ask the user to type a custom value for a variable. This article explains how.## Asking for TextTo input for text, use `${varname} = @input`. You can optionally provide a question.``` storymaticstart $name = @input What is your name? Hi, $name!```## Asking for NumbersTo input for a number, use `${varname} = @number`. You can optionally provide a question.``` storymaticstart $name = @input What is your name? $money = @number How much money do you have? Hi, $name! You have $$money.```",
"group": "Variables, Input",
"keyword": " input"
},
{
"url": "/posts/menu",
"title": "Menus",
"content": "# MenusThis article explains how to ask the user to choose between several options.## OverviewA menu has several options, and different statements will run depending on which option the user selects. For example, you might want to ask the user what their favorite flavor of ice cream is.A menu starts with the `@menu` command, which can optionally have a question provided. Inside the `@menu` command, there must be a list of options, all indented. Each option must also have some statemants inside.## Example``` storymaticstart Welcome to the ice cream store! @menu What flavor would you like to buy? Chocolate You bought chocolate! Vanilla You bought vanilla! Strawberry You bought strawberry!```In the above example, a menu will run with the options `Chocolate`, `Vanilla`, and `Strawberry`, and depending on which item you select, the program will say which flavor you bought!Note that menus can have more than one statement inside each option, and can even have sub-menus, which this example uses:``` storymaticstart Welcome to the ice cream store! @menu What flavor would you like to buy? Chocolate @menu Would you like milk or dark chocolate? Dark Chocolate You bought dark chocolate! Milk Chocolate You bought milk chocolate! Vanilla You bought vanilla! Strawberry You bought strawberry!```",
"group": "Input",
"keyword": " menu"
},
{
"url": "/posts/raw",
"title": "Raw Text, @pass, and @base",
"content": "# Raw Text, @pass, and @baseThis article explains how to print raw text without \"evaluating\" it.## OverviewYou can put a space before text to force it to be raw:``` storymatic$money = 500start This line will print the value of $money. This line will actually print $money.```The above example should print:```This line will print the value of 500.This line will actually print $money.```The problem is when you put a space before each line, because then the level of indentation changes, and all of your statements are now non-raw. How do we fix this?## @baseWe can fix it by putting a line that prints nothing as the first line, such as `$var = for indent`.However, this is a messy way to do it, so we need a statement that does nothing. Meet `@base`!`@base` on a line by itself will literally do nothing, but it can help place the indentation level:``` storymatic$money = 500start @base This line will print $money. This line will also print $money.```## @passThere is a second statement like `@base`: `@pass`. `@pass` also does nothing.## @base vs. @pass@base is meant to be used to set the level of indentation, while `@pass` is meant to aid in creating blank blocks, such as a blank option inside an `@menu` block.They can be used interchangeably, but please respect their semantic meanings.",
"group": "Basics",
"keyword": " raw"
},
{
"url": "/posts/repeat-loop",
"title": "The Repeat Loop",
"content": "# The Repeat LoopThe article explains how to use the most basic loop, the repeat loop, which repeats some statements a specified number of times.## OverviewYou write `@repeat {number}` and put statements inside to use it. `number` must be a whole number between `1` and `99`.## Example``` storymatic$money = 0start @repeat 5 $money += 500 @nowait $money```The above example will increment `money` by `500` `5` times.",
"group": "Loops",
"keyword": " repeat-loop"
},
{
"url": "/posts/story",
"title": "Storymatic",
"content": "# Storymatic - [`story` Object](#story-object) - [`story` Static Methods](#story-static-methods)## `story` ObjectTo create a new `story` object, initialize it with `story(code)`. The `code` should be the source code for your story.### `.state`This is the current state (block name) that the story is in.### `.states`This is a dictionary of all the different states and their blocks.### `.localVars`This is a dictionary of all the local variables (variables that get reset with `.newContext()`).### `.globalVars`This is a dictionary of all the global variables (variables that are NOT reset with `.newContext()`).### `.runfrom`The state that ran the `@run` command for a new context, or `start`. It is stored in `@runfrom`.### `.reference`The state that went to the current one with `@goto`. It is stored in `@reference`.### `.source[\"text\"]`The original text put into `story()`.### `.source[\"globalVars\"]`The original global variables.### `.source[\"localVars\"]`The original local variables.### `.newContext([runfrom, [state]])`Creates a new context of the story and returns it, keeping global variables, but resetting local variables.### `.text(text)`Formats the given `text`. Note that if it starts with a space, the rest is treated as raw text, and does not get formatted.### `.runState(state)`Runs the given `state`.### `.run(code)`Runs the given code.### `.varExists(var as str)`Returns `True` or `False` based of whether `var` exists.### `.varExists(var as list, tuple, set)`Return a dictionary containing whether each variable in `var` exists.### `.getVariable(var as str)`Returns the value of `var`, or `False`.### `.getVariable(var as list, tuple, set)`Return a dictionary containing the value of each variable in `var`, or `False`.### `.setVariable(var as str)`Resets the value of `var`.### `.setVariable(var as str,val)`Sets the value of `var` to the string value of `val`.### `.setVariable(var as list, tuple, set)`Resets the value of all variables in `var`.### `.setVariable(var as dict)`Sets the value of each variable in `var` to the value of it.### `.simpleCondition(condition)`Returns the value of a simple condition.### `.test(condition)`Returns the value of a condition.## `story` Static MethodsThese are some methods you can call on the `story` class itself.### `story.removeIndent(text)`This function removes as many spaces as possible from the left side of `text`, in an equal amount of columns.### `story.number(text)`This function tries to convert `text` to a `float`. If it fails, returns `False`.### `story.ask(question,option 0,option 1,...)`This function asks the user to select an option, and then return the key (0, 1, ...) of the option selected.### `story.ask(question,list of options)`This function is like the first `story.ask`, except is takes a list of options instead of spread out options.### `story.ask(question,answer as `str`)`This function asks the user to input an answer to `question`, then returns whether their answer matched your `answer`.### `story.ask(question)`This function returns `True` or `False` based on whether the user selects `Yes` or `No`.",
"group": "For Developers",
"keyword": " story"
},
{
"url": "/posts/text",
"title": "Text",
"content": "# TextThis article explains how to display (print) text to the user.## Waiting for EnterTo print text, just add it to your block:``` storymaticstart Welcome to my first story!```Using this method will wait for the user to press Enter before executing the next command. For example, in``` storymaticstart Welcome to my first story! Do you like it?```the user will have to press Enter after seeing `Welcome to my first story!` to view the next line.## @nowaitThere is a simple way to print the text without waiting for Enter, which is by using the `@nowait` command. Just type `@nowait` before your text to make sure that it instantly prints.### Example``` storymaticstart On this line, the user has to press Enter to go to the next line. @nowait This line will print and skip the Enter key.```## @waitA good thing to use with `@nowait` is `@wait`, which waits for the specified amount of seconds. You write it like this: `@wait {time}`.`time` can be a whole number from 1 to 10, or a decimal number from `0.1` to `9.9` with one decimal digit.### Example``` storymaticstart On this line, the user has to press Enter to go to the next line. @nowait This line will print and skip the Enter key. @wait 2 @nowait This line will print and skip the Enter key after 2 seconds. @wait 1 @nowait This line will print and skip the Enter key after 1 second. @wait 5.7 @nowait This line will print and skip the Enter key after 5.7 seconds.```",
"group": "Basics",
"keyword": " text"
},
{
"url": "/posts/variables",
"title": "Variables",
"content": "# VariablesVariable are an amazing way to store data about the user! Learn how to work with them in this article!## OverviewA variable contains data. It can either be declared as a [global or local variable](#global-vs-local), and can be declared as a local from within a block.To set a local variable, use `${varname} = {value}`.To set a global variable, use `@global ${varname} = {value}`.## Example``` storymatic@global $money = 500$name = Stevestart $name has $money dollars.```In the example above, we declared `money` as a global variable with the value `500`, and `name` as a local variable with the value `Steve`.To use variables, you just type `${varname}` in your text. To make sure that the parser isn't confused, you can also use `{${varname}}`. Ex: `{$name}`.## Redeclaring VariablesYou can change variable by redeclaring them in a block:``` storymatic@global $money = 500$name = Stevestart $name has $money dollars. $money = 1000 Now $name has $money dollars!```Note that when redeclaring, you do not use `@global`, even if the variable is global. You can also declare variable from within a block:``` storymatic@global $money = 500$name = Stevestart $friend = Annie $name has $money dollars. $money = 1000 Now $name has $money dollars! $name's friend $friend also has $money dollars!```When declaring a variable from within a block, you can also use the names of variables within the value:``` storymatic@global $money = 500$name = Stevestart $friend = $name's friend Annie $name has $money dollars. $money = 1000 Now $name has $money dollars! $friend also has $money dollars!```## Changing VariablesYou can also add, subtract, multiply, or divide the current value of a variable to another value by using different operators. - For `+`, use `+=`: `$money += 20`. - For `-`, use `-=`: `$money -= 20`. - For `*`, use `*=`: `$money *= 20`. - For `/`, use `/=`: `$money /= 20`.``` storymatic@global $money = 500$name = Stevestart $friend = $name's friend Annie $name has $money dollars. $money += 630 Now $name has $money dollars! $friend also has $money dollars!```There's also shortcuts for adding and subtracting one: `${varname}++` and `${varname}--`.### Appending TextYou can also append text to a variable with `.=`. For example,``` storymatic$text = astart $text $text .= b $text $text .= c $text```## Global vs. LocalGlobal variables are not reset when the program switches to a different context, while local variables are.## Special VariablesThere are two special variables: `@runfrom` and `@reference`.When you use `@goto` or `@run` to run a different block, `@reference` is set to the state that ran `@goto` or `@run`.When you use `@context`, `@runfrom` is set to the state that ran `@context`.",
"group": "Variables",
"keyword": " variables"
},
{
"url": "/posts/while-loop",
"title": "While Loops and Do-While Loops",
"content": "# While Loops and Do-While LoopsWhile loops execute a statement while a condition is `true`. This article explains how to make them.## OverviewA while loop executes some statements while a condition is `true`. If the condition was originally `false`, a while loop will not run.A do-while loop will always run at least once, even if the condition starts out as `false`.You can write a while loop by writing `@while {condition}`, and putting statements inside.You can write a do-while loop by writing `@dowhile {condition}`, and putting statements inside.## Example``` storymatic$money = 0start @while $money <= 500 $money += 50 @nowait $money```The example above will increment `money` by `50` until it is greater than `500`. However, if `money` is already greater than `500`, it will not run.The example below will do the same thing, but will always increment `money` at least once.``` storymatic$money = 0start @dowhile $money <= 500 $money += 50 @nowait $money```",
"group": "Loops",
"keyword": " while-loop"
}
]
The stop and kill statements are key to using the block system.
Overview
The @stop statement exits the current context. To use it, just write @stop.
The @kill statement exits the current story (all contexts). TO use it, just write @kill.
Example
start
Welcome to my text adventure!
@menu Do you want to leave?
Yes
@stop
No
@pass
Goodbye!
In the example above, the user can exit early by selecting Yes.