01
Every tool invents its own format.
Studios can’t move content between tools without a rewrite.
An open standard for interactive stories
Open Story Foundation is an open, versioned format for dialogues, characters and translations, stored as plain text. Build on it, ship it to any engine, and stop writing exporters.
Spec status: draft v1
Versions {
language = "1"
story = "v1"
dialogue = "v1"
i18n = "v1"
}
Dialogue 01_intro_scene {
Node node_03 {
speaker: protagonist
text: "Am I dreaming?"
Option node_03_option_01 {
next: node_04
set: { is_dreaming: true }
text: "Yes, you are."
}
Option node_03_option_02 {
next: Dialogue.02_shadows_speak
text: "No. Fool"
}
}
}apiVersion: dialogue/v1
kind: Dialogue
data:
id: 01_intro_scene
nodes:
node_03:
content:
speaker: Character.protagonist
text: Am I dreaming?
options:
node_03_option_01:
next: node_04
set:
is_dreaming: true
content:
text: Yes, you are.
node_03_option_02:
next: Dialogue.02_shadows_speak
content:
text: No. Foolosf build should emit for engines is an open question in draft v1.The problem
01
Studios can’t move content between tools without a rewrite.
02
The same integration work is repeated by every vendor, for every engine.
03
So they hesitate to adopt new tools, including yours.
From studios: [Demand evidence TBD, e.g. a quote or numbers from LoreHub v1 customers]
How OSF works
People write the .osf language, a brace-based syntax like Terraform’s HCL. It compiles to OSF resources: one YAML file per resource with apiVersion, kind and data, like Kubernetes manifests, described by a JSON Schema. A tool only has to read and write one of the two layers to interoperate.
Readable by people, diffable in Git, parseable by machines and AI. YAML resources get completion and validation in VS Code, JetBrains and Neovim through the JSON Schema.
@@ arc_1_war/01_intro_scene.osf @@
Option node_03_option_02 {
next: Dialogue.02_shadows_speak
- text: "No. Fool"
+ text: "No, fool."
}Every resource’s apiVersion is <plugin>/<version>. One Versions block pins them all, so an upgrade is a one-line change, and a compiler that doesn’t support a listed version stops instead of guessing.
Versions {
language = "1" // version of this syntax
story = "v1" // built in
dialogue = "v1" // built in
i18n = "v1" // plugin
}Every text has a stable key. Translations live in one folder per language. Per language, choose whether a missing line is an error or falls back to the source.
I18n {
source = Eng
Locale Rus "Russian" { enforce = true }
Locale Jpn "Japanese"
}| key | Engsource | Rusenforce = true | Jpnfalls back |
|---|---|---|---|
| Dialogue.01_intro_scene.nodes.node_01.content.text | Where am I? | Где я? | → Where am I? |
| Dialogue.01_intro_scene.nodes.node_03.options.node_03_option_01.content.text | Yes, you are. | Да, спишь. | → Yes, you are. |
| Dialogue.01_intro_scene.nodes.node_04.content.text | Strange | Странно | → Strange |
One CLI checks schema, references, variable types and translations, formats files for clean diffs, and compiles .osf to OSF YAML resources. Until it ships, the working checker is tools/validate.py.
$ osf validate example
example/arc_1_war/01_intro_scene.osf:34:3: warning: Node node_04 in Dialogue 01_intro_scene is never reached
example/story.osf:11:3: warning: Jpn: 15 of 15 texts untranslated (not enforced)
example/arc_1_war/01_intro_scene.osf:23:13: error: Node node_03, Option node_03_option_01: next: node "node_05" does not exist in Dialogue 01_intro_scene
1 error, 2 warnings.
$ osf build example # after fixing the typo
example/story.osf:11:3: warning: Jpn: 15 of 15 texts untranslated (not enforced)
Built 12 resources into example/build (2 dialogues, 2 characters, 1 variable, 15 texts).Why join
This is an invitation, not a sale. One shared format grows everyone’s market, and nobody has to build it alone.
Studios adopt your tool without migrating content, and can leave without fear, which makes them more willing to come in.
Support OSF once and read content written in every other OSF tool.
OSF is already split into versioned plugins (story, dialogue, i18n). Your tool’s own features belong in a plugin of their own, not a fork. [How third-party plugins are named and registered is not in the spec yet]
The v1 spec is a draft. Members help settle its open questions: gender and plural agreement in references, inline media, stable ids for save files, and the build output engines read.
Once your tool’s output passes validation, it appears on the members page. [How “OSF compatible” is granted: open decision]
Plain text with a strict schema is easy for language models to write, and every change can be validated before it merges.
Already built on OSF
1Dialogue 01_intro_scene {23 Node node_01 {4 next: node_025 speaker: protagonist6 title: "..."7 text: "Where am I?"8 }910 Node node_02 {11 next: node_0312 text: "Total Darkness surrounds you."13 }1415 Node node_03 {16 speaker: protagonist17 text: """18 What is it all about?19 Am I dreaming?20 """21 ...01_intro_scene.osf in VS Code (code only, with the OSF Language extension for syntax highlighting) and in LoreHub (visual node editor).How to join
docs/spec.md and schema/osf-v1.schema.json. The format is small: Story, Character, Variable and Dialogue, plus the i18n plugin.
To your tool or engine. Read and write OSF YAML resources, the .osf language, or both.
Run python3 tools/validate.py on your output and on osf/example.
Send the form below and get listed as compatible.
Join the foundation
Engine teams and narrative tool makers welcome. Sending the form opens your email app with the details filled in.
Goes to [email protected][Join address is a placeholder until the mailbox exists]
FAQ
OSF is an open project started by Lostwood Games, the makers of LoreHub, inviting other tools to co-govern the spec. [Governance and what “Foundation” means: open decision]
[License TBD] for the spec and tools. The OSF Language extension for VS Code is MIT.
Not yet. The spec is draft v1. It is versioned so upgrades are explicit: a project pins every plugin version, and a compiler that doesn’t support a pinned version stops instead of guessing.
No. LoreHub is the first visual editor built on OSF, and one implementation among the ones we hope to list here. Any editor that reads and writes the format works.
Yes, that is what plugins are for: story, dialogue and i18n are themselves plugins. [Third-party plugin rules are still to be written into the spec]
[Membership terms TBD: free or paid, any obligations]
Not yet. osf validate, osf build and osf fmt are in development. Today, tools/validate.py checks a project.