Actions

Difference between revisions of "Markup Based Story Scripting"

From Pirates and Traders 2

(Story, Scenes, and Passages)
(==Calls to internal code ==)
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
The following page describes some ideas for a scripting language for writing interactive text narratives based on [http://daringfireball.net/projects/markdown/ Markdown]. The script language described here is inspired by [http://www.norfolkwinters.com/ficdown/ Ficdown] and [http://docs.textadventures.co.uk/squiffy/ Squiffy] in addition to ideas and constructs from my own "StoryEngine".
+
The following page describes the syntax of the Story Script used in the MicaByte Story Engine. It is based on [http://daringfireball.net/projects/markdown/ Markdown], and heavily inspired by the [http://www.norfolkwinters.com/ficdown/ Ficdown] and [http://docs.textadventures.co.uk/squiffy/ Squiffy] interactive fiction tools.
  
== Text ==
 
  
Paragraphs have no special markup. Paragraphs are separated by blank lines.
 
  
=== Emphasis ===
+
==== Writing Story Script ====
  
<pre>
+
You can write Story Script in any text editor: Notepad, TextEdit, Emacs, Sublime Text, etc. Many of them have highlight support for Markdown, which helps to avoid errors. [http://dillinger.io Dillinger] is an on-line Markdown editor.
*This text will be italic*
+
 
 +
 
 +
==== Stories, Scenes, and Passages ====
 +
 
 +
There are three types of text blocks in Story Script.
  
**This text will be bold**
+
* '''Story''' is the definition of the story itself. Heading level 1 is used to define the story itself. Each file must define exactly one story.
</pre>
+
* '''Scenes''' are the main unit of the story. Moving to a new scene deactivates any links/actions in previous scenes (and may clear the screen). Heading level 2 is used to define a scene.
 +
* '''Passages''' are smaller units of text which occur within a scene. Linking to a passage will display the text from the passage, but other links in the section will remain active. Heading level 3 is used to define a passage.
  
== Story, Scenes, and Passages ==
 
  
<pre>
+
<small><pre>
 
# [Story Title](/first-scene)
 
# [Story Title](/first-scene)
  
Line 27: Line 29:
  
 
A passage is a line of text that is shown when a link is clicked, but which does not change the scene.
 
A passage is a line of text that is shown when a link is clicked, but which does not change the scene.
 +
</pre></small>
 +
 +
 +
Scenes are referenced by a sanitized version of their names; all non-word characters are removed, and spaces are replaced with hyphens (except the last space). Names can be truncated to 16 characters; so e.g. "a very long and convoluted scene name" can be referenced as "a-very-long-and".
 +
 +
 +
==== Links ====
 +
 +
Each scene makes up a single page of text in the game that is ended with at least one link for the player to select. There must be a minimum of one link in each scene, because otherwise the player is going to get stuck in the game interface. Links in Story Script are defined using the inline style.
  
</pre>
 
  
Scenes are referenced by a sanitized version of their names; all non-word characters are removed, and spaces are replaced with hyphens. Names can be truncated to 16 characters; so e.g. "a very long and convoluted scene name" can be referenced as "a-very-long-and-".
+
<small><pre>
 +
[This is Text](/this-is-the-link)
 +
</pre></small>
  
== Linking Scenes ==
 
  
Links can be used to travel between scenes. Lists are used to create a list of links at the bottom of a scene.
+
Links can be used to travel between scenes. We use a list syntax to create a list of links at the end of each scene.  
  
<pre>
+
 
 +
<small><pre>
 
## Second Scene
 
## Second Scene
  
Line 45: Line 57:
 
- [Go back to the first scene](/first-scene)
 
- [Go back to the first scene](/first-scene)
 
- [Repeat this one](/second-scene)
 
- [Repeat this one](/second-scene)
</pre>
+
</pre></small>
  
From the point of view of my game engine, a list of links at the end is the best way to handle this; but in theory there is no reason why such links could not be embedded anywhere in the text.
+
 
 +
Markdown allows links anywhere in the text, but in the context of the Story Engine, links must be defined as a list at the end of the scene. This is primarily due to limitations in the Android game engine (though it also simplifies security not having to block http).
  
 
A link to a passage disappears after that passage has been shown. It returns if you return to the scene later.
 
A link to a passage disappears after that passage has been shown. It returns if you return to the scene later.
  
Section and passage names are only unique within their story or section.
+
Section and passage names are only unique within their story or section. To link to a scene or passage from a separate story (possible within the Story Engine), use a nested link. For example:
  
It should be possible to link across multiple stories. For example:
 
  
<pre>
+
<small><pre>
 
- [Link from another place](/story-title/first-scene/a-passage)
 
- [Link from another place](/story-title/first-scene/a-passage)
</pre>
+
</pre></small>
  
Links can be one of three different possibilities:
 
  
<pre>
+
==== Advanced Link Syntax ====
  
Link to a story, scene or passage:
+
The link syntax is not just used to connect one scene or passage with another, though; it can be used to perform a variety of useful manipulation.
  
 +
Basic link syntax; linking to a story, scene or passage (designated by a backslash):
 +
 +
<small><pre>
 
- [Option 1](/scene-link)
 
- [Option 1](/scene-link)
 +
</pre></small>
 +
 +
 +
The link syntax can also be used to display text conditionally, dependent on the value of a variable or expression. This is denoted using a question mark, as follows.
 +
 +
<small><pre>
 +
[Option 0|Option 1|Option 2](?$picked-up-key)
 +
</pre></small>
  
It can be a conditional:
 
  
- [Option 2|Option3](?picked-up-key)
+
Resolution is very simply "count" based; if $picked-up-key evaluates to 0 or less, "Option 0" is shown, if it evaluates to 1, "Option 1" and for values of 2 or more, "Option 2" is shown. Boolean false evaluates to 0, while Boolean true evaluates to 1.
  
It can be an action:
+
If no variable is specified (as in the following example), then one of the options is picked randomly.
 +
 
 +
<small><pre>
 +
[Option 0|Option 1|Option 2](?)
 +
</pre></small>
 +
 
 +
 
 +
It can be an action (designated by @):
  
 
- [Option 4|Option5](@set picked-up-key)
 
- [Option 4|Option5](@set picked-up-key)
  
It can also be a combination of all three.
+
It can also be a combination of all three (or two).
  
 
- [Option 6|Option7](/new-scene?first-condition&second-condition@set $first-variable =100 @set $second-variable=200)
 
- [Option 6|Option7](/new-scene?first-condition&second-condition@set $first-variable =100 @set $second-variable=200)
  
</pre>
+
</pre></small>
  
== Attributes ==
+
==== Text ====
  
Attributes are always prefixed with $.
+
Text in the Story scripts is just text. Like this one. Paragraphs are separated by blank lines.
  
Attributes can be objects, in which case dot notation can be used; e.g.
+
Text can be beautified, using the basic markdown tags.
  
<pre>
+
 
 +
<small><pre>
 +
*This text will be italic*
 +
 
 +
**This text will be bold**
 +
</pre></small>
 +
 
 +
 
 +
==== Variables ====
 +
 
 +
Variables in the Story Script are always prefixed $. They can be inserted directly in the text, and the parser will try - as best it can - to translate the variable to a meaningful text string (e.g., an integer variable gets converted to the number it represents, a string will be replaced by the actual string, etc).
 +
 
 +
Variables can also be objects in the Story Engine, in which case dot notation can be used to extract more detailed information; e.g.
 +
 
 +
 
 +
<small><pre>
 
$object.attribute
 
$object.attribute
</pre>
+
</pre></small>
 +
 
 +
 
 +
Actions can be performed using the @ to set, unset, and otherwise manipulate variables.
  
 
Set attribute inside text:
 
Set attribute inside text:
  
<pre>
+
 
 +
<small><pre>
 
@set $variable = 1000
 
@set $variable = 1000
</pre>
+
</pre></small>
 +
 
  
 
Unset attribute
 
Unset attribute
  
<pre>
+
 
 +
<small><pre>
 
@uns $variable
 
@uns $variable
</pre>
+
</pre></small>
 +
 
  
 
Increase and decrease number values
 
Increase and decrease number values
  
<pre>
+
 
 +
<small><pre>
 
@inc $number1
 
@inc $number1
 
@dec $number2
 
@dec $number2
</pre>
+
</pre></small>
 +
 
  
 
Also:
 
Also:
  
<pre>
+
 
 +
<small><pre>
 
@set $variable += 1
 
@set $variable += 1
 
@set $variable = $variable + 1
 
@set $variable = $variable + 1
Line 121: Line 174:
 
@set $variable /= 4
 
@set $variable /= 4
 
@set $variable = $variable / 4
 
@set $variable = $variable / 4
</pre>
+
</pre></small>
 +
 
  
 
Random numbers:
 
Random numbers:
  
<pre>
 
  
Random number between 0 and 10 (both inclusive)
+
<small><pre>
 +
%Random number between 0 and 10 (both inclusive)
 
@set $variable ~ 0 10
 
@set $variable ~ 0 10
  
Standard d6:
+
%Standard d6:
 
@set $variable ~ 1 6
 
@set $variable ~ 1 6
  
Random number from 0 to 10 (both inclusive), increment of 2
+
%Random number from 0 to 10 (both inclusive), increment of 2
 
@set $variable ~ 0 10 2
 
@set $variable ~ 0 10 2
 +
</pre></small>
  
  
</pre>
+
====Calls to internal code ====
  
== Calls to internal code ==
+
<small><pre>
 
 
<pre>
 
 
@act do_something
 
@act do_something
</pre>
+
</pre></small>
  
  
== Conditional ==
+
==== Conditional ====
  
<pre>
+
StoryScript allows conditional evaluation of entire blocks of script using the @if, @elif, @else evaluation
{if $gender=male | You are a man.}
 
{elif $gender=female | You are a woman.}
 
{else You are non-gendered.}
 
</pre>
 
  
This can be extended over multiple lines and include other constructs.
 
 
<pre>
 
{if $gender=male |
 
  
 +
<small><pre>
 +
@if $gender = male
 
You are a man.
 
You are a man.
 +
@elif $gender=female
 +
You are a woman.
 +
@else
 +
None of your business.
 +
@endif
 +
</pre></small>
  
}
 
{elif $gender=female |
 
You are a woman.
 
}
 
{else
 
You are non-gendered.
 
  
@act set_nongendered
+
Each block is implicitly its own paragraph. Note that the if-then-else block must always be closed with an @endif statement. You cannot nest one @if statement within another @if statement.
}
 
</pre>
 
  
  
== Text Manipulation ==
+
==== Text Manipulation ====
  
<pre>
+
<small><pre>
Switch randomly between the various text entries:
+
%Switch randomly between the various text entries:
  
 
[TEXT0|TEXT1|TEXT2|...](?)
 
[TEXT0|TEXT1|TEXT2|...](?)
  
Select a text based on the value of the variable:
+
%Select a text based on the value of the variable:
  
 
[TEXT0|TEXT1|TEXT2|...](?$variable)
 
[TEXT0|TEXT1|TEXT2|...](?$variable)
</pre>
+
</pre></small>
  
== Images ==
+
 
 +
==== Images ====
  
 
Background image
 
Background image
  
<pre>
+
<small><pre>
 
![bkg](image-uri)
 
![bkg](image-uri)
</pre>
+
</pre></small>
  
 
Overlay images (used for visual novel style compositions):
 
Overlay images (used for visual novel style compositions):
  
<pre>
+
 
 +
<small><pre>
 
Centered
 
Centered
  
Line 207: Line 254:
  
 
![gfx](image-uri)
 
![gfx](image-uri)
</pre>
+
</pre></small>
  
 
== Comments ==
 
== Comments ==
  
 
Any line starting on % will be ignored by the parser.
 
Any line starting on % will be ignored by the parser.

Latest revision as of 03:17, 27 October 2014

The following page describes the syntax of the Story Script used in the MicaByte Story Engine. It is based on Markdown, and heavily inspired by the Ficdown and Squiffy interactive fiction tools.


Writing Story Script

You can write Story Script in any text editor: Notepad, TextEdit, Emacs, Sublime Text, etc. Many of them have highlight support for Markdown, which helps to avoid errors. Dillinger is an on-line Markdown editor.


Stories, Scenes, and Passages

There are three types of text blocks in Story Script.

  • Story is the definition of the story itself. Heading level 1 is used to define the story itself. Each file must define exactly one story.
  • Scenes are the main unit of the story. Moving to a new scene deactivates any links/actions in previous scenes (and may clear the screen). Heading level 2 is used to define a scene.
  • Passages are smaller units of text which occur within a scene. Linking to a passage will display the text from the passage, but other links in the section will remain active. Heading level 3 is used to define a passage.


# [Story Title](/first-scene)

Heading level 1 is used to define the story itself. The story title should be an anchor that links to the first scene.

## First Scene

Heading level 2 is used to define the scene.

### A passage

A passage is a line of text that is shown when a link is clicked, but which does not change the scene.


Scenes are referenced by a sanitized version of their names; all non-word characters are removed, and spaces are replaced with hyphens (except the last space). Names can be truncated to 16 characters; so e.g. "a very long and convoluted scene name" can be referenced as "a-very-long-and".


Links

Each scene makes up a single page of text in the game that is ended with at least one link for the player to select. There must be a minimum of one link in each scene, because otherwise the player is going to get stuck in the game interface. Links in Story Script are defined using the inline style.


[This is Text](/this-is-the-link)


Links can be used to travel between scenes. We use a list syntax to create a list of links at the end of each scene.


## Second Scene

This is scene number two.

What would you like to do?

- [Go back to the first scene](/first-scene)
- [Repeat this one](/second-scene)


Markdown allows links anywhere in the text, but in the context of the Story Engine, links must be defined as a list at the end of the scene. This is primarily due to limitations in the Android game engine (though it also simplifies security not having to block http).

A link to a passage disappears after that passage has been shown. It returns if you return to the scene later.

Section and passage names are only unique within their story or section. To link to a scene or passage from a separate story (possible within the Story Engine), use a nested link. For example:


- [Link from another place](/story-title/first-scene/a-passage)


Advanced Link Syntax

The link syntax is not just used to connect one scene or passage with another, though; it can be used to perform a variety of useful manipulation.

Basic link syntax; linking to a story, scene or passage (designated by a backslash):

- [Option 1](/scene-link)


The link syntax can also be used to display text conditionally, dependent on the value of a variable or expression. This is denoted using a question mark, as follows.

[Option 0|Option 1|Option 2](?$picked-up-key)


Resolution is very simply "count" based; if $picked-up-key evaluates to 0 or less, "Option 0" is shown, if it evaluates to 1, "Option 1" and for values of 2 or more, "Option 2" is shown. Boolean false evaluates to 0, while Boolean true evaluates to 1.

If no variable is specified (as in the following example), then one of the options is picked randomly.

[Option 0|Option 1|Option 2](?)


It can be an action (designated by @):

- [Option 4|Option5](@set picked-up-key)

It can also be a combination of all three (or two).

- [Option 6|Option7](/new-scene?first-condition&second-condition@set $first-variable =100 @set $second-variable=200)

Text

Text in the Story scripts is just text. Like this one. Paragraphs are separated by blank lines.

Text can be beautified, using the basic markdown tags.


 
*This text will be italic*

**This text will be bold**


Variables

Variables in the Story Script are always prefixed $. They can be inserted directly in the text, and the parser will try - as best it can - to translate the variable to a meaningful text string (e.g., an integer variable gets converted to the number it represents, a string will be replaced by the actual string, etc).

Variables can also be objects in the Story Engine, in which case dot notation can be used to extract more detailed information; e.g.


$object.attribute


Actions can be performed using the @ to set, unset, and otherwise manipulate variables.

Set attribute inside text:


@set $variable = 1000


Unset attribute


@uns $variable


Increase and decrease number values


@inc $number1
@dec $number2


Also:


@set $variable += 1
@set $variable = $variable + 1
@set $variable -= 2
@set $variable = $variable - 2
@set $variable *= 3
@set $variable = $variable * 3
@set $variable /= 4
@set $variable = $variable / 4


Random numbers:


%Random number between 0 and 10 (both inclusive)
@set $variable ~ 0 10

%Standard d6:
@set $variable ~ 1 6

%Random number from 0 to 10 (both inclusive), increment of 2
@set $variable ~ 0 10 2


Calls to internal code

@act do_something


Conditional

StoryScript allows conditional evaluation of entire blocks of script using the @if, @elif, @else evaluation


@if $gender = male
You are a man.
@elif $gender=female
You are a woman.
@else
None of your business.
@endif


Each block is implicitly its own paragraph. Note that the if-then-else block must always be closed with an @endif statement. You cannot nest one @if statement within another @if statement.


Text Manipulation

%Switch randomly between the various text entries:

[TEXT0|TEXT1|TEXT2|...](?)

%Select a text based on the value of the variable:

[TEXT0|TEXT1|TEXT2|...](?$variable)


Images

Background image

![bkg](image-uri)

Overlay images (used for visual novel style compositions):


Centered

![gfx](image-uri)

Centered

![gfx](image-uri)

Centered

![gfx](image-uri)

Comments

Any line starting on % will be ignored by the parser.