Documentation menu

Tutorials

Your first project

In this tutorial you write a small story in .osf, check it, and build it into OSF resources. It takes four files.

Install the CLI

The osf CLI is in development and is built from source. It needs Go 1.22 or newer.

$ git clone https://github.com/lostwood-games/open-story
$ cd open-story/cli
$ go build -o osf .

Write the project

A project is a folder. Every .osf file in it is read, and which file a block lives in does not matter. Start with the Versions block, which pins the language and plugin versions:

my-story/versions.osf
Versions {
  language = "1"
  story    = "v1"
  dialogue = "v1"
}

Then the story itself, with one variable:

my-story/story.osf
Story my_story {
  name  = "My Story"
  start = Dialogue.intro
}

Variable has_key: Boolean = false
my-story/characters.osf
Character guard {
  name = "Guard"
}

And the dialogue. The guard asks a question; one answer leads on and sets has_key, the other ends the dialogue:

my-story/intro.osf
Dialogue intro {

  Node gate {
    speaker: guard
    text: "Halt! Who goes there?"

    Option friend {
      next: let_in
      set: { has_key: true }
      text: "A friend."
    }

    Option leave {
      text: "Nobody. Bye."
    }
  }

  Node let_in {
    speaker: guard
    text: "Then take this key, {{ Character.guard }} trusts you."
  }
}

Check it

osf fmt rewrites files in the canonical style; with -check it only reports, and exits with status 3 when a file would change. osf validate checks the whole project:

$ osf fmt -check my-story
$ osf validate my-story
Success! The project is valid (1 dialogue, 1 character, 1 variable, 6 texts).

Mistakes are reported with the file, line and column. Here next points at a node that does not exist:

$ osf validate my-story
my-story/intro.osf:18:3: warning: Node let_in in Dialogue intro is never reached
my-story/intro.osf:8:13: error: Node gate, Option friend: next: node "let_inn" does not exist in Dialogue intro

1 error, 1 warning.

Build it

osf build validates, then writes one YAML resource per Story, Character, Variable and Dialogue into build/:

$ osf build my-story
Built 4 resources into my-story/build (1 dialogue, 1 character, 1 variable, 6 texts).
my-story/build/
  guard.yaml
  intro.yaml
  story.yaml
  variables/has_key.yaml

Each file is one resource, described on its page in the format reference. Next, build a dialogue player that plays this story.