~nromdotcom/gemif

ref: 914458c58f6158ecb8e30fdfc595e50df9e5eaba gemif/stories/compiled/tutorial.yml -rw-r--r-- 10.2 KiB
914458c5Norm MacLennan Update to fully-qualified module path to enable go get-ing 1 year, 1 month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
metadata:
  id: tutorial
  name: Writing Tutorial
  description: Documentation on writing GemIF stories
  author: Norm MacLennan
rooms:
- room_id: the_basics
  room_name: The Basics
  room_description: |-
    Welcome to GemIF! Gemini's Interactive Fiction engine.

    In this tutorial, we'll walk through writing your own stories using the .gemif file format. While stories can technically be written directly in the "compiled" YAML format, gemif format provides a much more user-friendly experience and allows authors to write without worrying about a lot of semantic whitespace.
  exits:
  - exit_description: Cool, let's get started!
    destination_id: get_started
  - exit_description: Carry on with the tutorial
    destination_id: simple_demo
    if_condition: seen_demo
- room_id: get_started
  room_name: The Basics pt 2
  room_description: |-
    A GemIF story is made up of `Scenes` that you moved between through the use of `Transitions`.

    ## Scenes

    Scenes are where the action happens. Each scene has the following attributes:

    * ID: A scene's ID is its unique identifier within the story. The ID is used in Transitions to move the user from scene to scene.
    * Name: A scene's Name is a user-friendly identifier for the page. It is displayed at the top of the page. This scene's Name is `The Basics pt 2`.
    * Description: A scene's description is free-text describing what's happening in the scene. A description can optionally be rendered as a Golang `text/template`, which can be used along with advanced GemIF features to provide dynamic story-telling.
    * Transitions: Each scene has 0 or more transitions. These transitions are represented as reader choices and move the user to the next scene. Not all scenes need transitions, but these are "terminal" state of the story.

    A scene can, of course, be as many lines as you want and you can use Gemini text formatting freely.

    ## Transitions

    A transition's job is to move the reader from one scene to another. A transition can also point back at its own scene, using advanced features to change the content.

    Each transition has the following attributes:

    * Destination: A transition's destination must be the ID of the scene the reader should move to.
    * Description: A transition's description is the text presented to the reader for the given choice.
    * Condition Options: Conditions are an advanced feature of GemIF that we'll cover in detail later. Suffice it to say, transitions can add or remove conditions from the reader's game which can be used to build dynamic stories.

    Each transition must exist on a single line (that is, descriptions must not have newline characters).
  exits:
  - exit_description: What do scenes and transitions look like?
    destination_id: simple_demo
- room_id: simple_demo
  room_name: The Basics pt 3
  room_description: "So now that you're somewhat familiar with the building blocks
    of a story - scenes and transitions - we can discuss what they actually look like.\n\n##
    GemIF Format\n\nStories are best and most easily written in GemIF format. This
    is a plaintext format that looks a lot like Gemini format.\n\nEach story is made
    up of one or more `.gemif` file with whatever names you want. And each file can
    contain or more scene (with associated transitions).\n\n### Scenes\nLet's look
    back at the first page of this tutorial for a simple example. The \"source\" of
    that scene looks like:\n\n```\n  ---\n  # the_basics The Basics\n\n  Welcome to
    GemIF! Gemini's Interactive Fiction engine.\n\n  In this tutorial, we'll walk
    through writing your own stories using the .gemif\n  file format. While stories
    can technically be written directly in the \"compiled\"\n  YAML format, gemif
    format provides a much more user-friendly experience and allows \n  authors to
    write without worrying about a lot of semantic whitespace.\n\n  => get_started
    Cool, let's get started!\n```\n\nEach scene must start with a triple-dash (`---`).
    Within files, the triple-dash is used as a scene separator.\n\nThe first line
    of a scene contains the scene's ID and Name, prefixed with an `#`.\n\n```\n  #
    <SceneID> <SceneName>\n```\n\n### Transitions\nThe other piece of special syntax
    in a scene are the transitions. Transitions look a lot like Gemini links, but
    have a few advanced features we'll talk about later.\n\n```\n  => <DestinationID>
    <TransitionDescription>\n```\n\nAnd that's basically all there is to it (we'll
    get into advanced features shortly)."
  exits:
  - exit_description: If you want to see the first page again for reference, choose
      this.
    destination_id: the_basics
    set_condition: seen_demo
  - exit_description: Or continue on...
    destination_id: story_metadata
- room_id: story_metadata
  room_name: The Basics pt 4
  room_description: |-
    One last thing before we carry on to advanced features.

    ## Story Metadata
    In addition to the .gemif files, GemIF stories require a single file named `metadata.yml`. This file contains basic information (well, metadata) about the story for GemIF to display to the reader.

    The format is pretty simple and self-explanatory, but for completeness, your `metadata.yml` must contain:

    * id: a server-unique id of your story
    * name: a user-friendly name of your story
    * description: a brief description of what you're story is about
    * author: name or other identifier of the story author.

    Here's the `metadata.yml` of this story, for reference.

    ```
      ---
      id: sample_story
      name: Sample Story
      description: A sort of hello world
      author: Norm MacLennan
    ```
  exits:
  - exit_description: Alright, I get it, I get it. Bring on the advanced features!
    destination_id: conditions
- room_id: conditions
  room_name: Advanced Features pt 1
  room_description: |-
    Now you know the basics of creating stories. You should be able to use these basics to create plenty of linear or branching narratives. But what if you need just a _little_ more power?

    ## Conditions
    Conditions are "tags" that can be attached to the reader's game to denote that they have made (or not made) a particular choice.

    Conditions can be attached or removed from game state through transitions. You can also use conditions to decide whether or not to present a given transition to a user.

    ### With Transitions
    Conditions work with transitions through the use of condition directives on the transition itself. These directives are placed between curly-braces in between the destination and description.

    It looks like this:

    ```
      => <destination> {<condition directives>} <description>
    ```

    Did you notice in the previous scene, that if you moved back to the first scene you could suddenly jump right back to where you were? That was done with transitions.

    On the GemIF demo scene, the transition back to the intro scene looks like:

    ```
      => the_basics {+seen_demo} If you want to see the first page again for reference, choose this.
    ```

    That little `{+seen_demo}` attaches the `seen_demo` condition to the game state.

    Then, back in the first scene there is a conditionally-hidden transition that didn't show up until you had that condition:

    ```
      => simple_demo {~seen_demo} Carry on with the tutorial
    ```

    `{~seen_demo}` will only show the transition option if the reader's state has the `seen_demo` condition.

    There are a handful of condition directives you can use, and you can provide as many as you like for each transition, separated with a space.

    * `+condition`: adds `condition` to the user's state
    * `-condition`: removes `condition` from the user's state
    * `~condition`: only presents the transition to the user when they have `condition`
    * `!condition`: only presents the transition to the user when they DON'T have `condition`
  exits:
  - exit_description: What else can I do with conditions?
    destination_id: template
- room_id: template
  room_name: Advanced Features pt 2
  room_description: "In the previous scene, you learned how to use conditions to track
    information about the story state and conrol which choices the reader is presented
    with.\n\n## Templates\n\nYou can also use conditions to conditionally render different
    parts of room templates. Scene descriptions are rendered as Golang `text/template`s.
    \n\nTemplates have a `.Conditions` list in scope and some utility functions available.\n\nIf
    you returned to the first scene previously and gained the `seen_demo` condition,
    you should see `[seen_demo]` printed below, otherwise you may just see `[]:\n\n{{.Conditions}}\n\nThat
    was produced with the token {{\"`{{.Conditions}}`\"}}.\n\nA utility function,
    `ConditionMet` is in-scope to check if a reader has met a condition. Below you
    should see `true` or `false` based on whether or not you have the condition:\n\n{{.ConditionMet
    \"seen_demo\"}}\n\nThis was produced with the token `{{\"{{.ConditionMet \\\"seen_demo\\\"}}\"}}`.\n\nYou
    can check the Golang text/template documentation for ways you can use templates
    to write if statements and other advanced conditional rendering."
  exits:
  - exit_description: Cool, well what's next?
    destination_id: whats_next
- room_id: whats_next
  room_name: Compiling Your Story
  room_description: |-
    Once you've written your story (or probably more like as you write your story), you can use `gemifc` to compile your story to YAML format for use by the `gemif` server.

    ```
    $ gemifc [input directory] [output directory]
    ```

    So to compile this story:

    ```
    $ gemifc ./stories/src/tutorial ./stories/compiled
    Compiling story ./stories/src/tutorial to ./stories/compiled/

    Finished loading story:
      Name: Writing Tutorial
      Author: Norm MacLennan
      Descriptions: Documentation on writing GemIF stories
      Number of Rooms: 7

    Serializing and writing to disk...
    Done!
    ```

    If you want to publish your story, just drop it in the configured stories directory of your GemIF server. If you don't want to run it yourself, feel free to email it to the GemIF mailing list at `~nromdotcom/gemif@lists.sr.ht` and I'd almost certainly be happy to host it for you.

    THE END