Examples

plotknot ships with example stories in the examples/ directory. Each demonstrates specific features. All examples are used in the test suite — they compile, load, and run through the runtime.

hello.plotknot

Demonstrates: sections, choices, conditional choices, variables, call, if/else, goto.

A simple forest branching story — the "hello world" of plotknot:

# The Forest

set courage = 5

You stand at the edge of a dark forest. The path ahead splits in two.

choice:
- Take the left path -> left_path
- Take the right path -> right_path
- Turn back -> turn_back [if courage < 3]

## Left Path

You follow the mossy trail deeper into the woods.

call check_weather() -> weather

if weather == "rain":
  Rain patters on the canopy above.
else:
  Sunlight filters through the leaves.

-> ending

## Right Path

The right path leads to a sunlit clearing. A deer watches you pass.

-> ending

## Turn Back

Courage fails you today. The forest can wait.

-> ending

## Ending

Your journey through the forest ends here.

Key concepts:

characters.plotknot

Demonstrates: character metadata, dialogue attribution.

A tavern scene with named speakers:

character: Mara
character: Aldric
character: Narrator

# The Tavern

Narrator: The tavern is warm and loud. Mara sits alone.

Mara: You look lost, traveler.
Aldric: Just passing through.
Mara: Nobody just passes through Thornwall.

choice:
- Ask about the road -> road_info
- Ask about the town -> town_info

Key concepts:

variation.plotknot

Demonstrates: variation blocks, cycle and once modes.

A crossroads that changes description on revisit:

# The Crossroads

variation: cycle

You arrive at a weathered crossroads.
The crossroads again. The signpost's paint is peeling.
You know this crossroads by heart now.

choice:
- Take the forest path -> forest
- Take the river path -> river
- Rest here -> rest

## Rest

variation: once

You sit on the milestone and catch your breath.

-> the_crossroads

Key concepts:

conditions.plotknot

Demonstrates: built-in functions, visited tracking, resource management.

A dungeon crawl with state-dependent content:

# Dungeon Entrance

set torches = 3
set depth = 0

The dungeon mouth yawns before you.

choice:
- Descend -> descend
- Turn back -> turn_back

## Descend

set depth = depth + 1

if torches > 0:
  set torches = torches - 1
  Your torch flickers, casting long shadows.
else:
  Darkness presses close.

if visited("descend"):
  You recognize this stretch of corridor.
else:
  The corridor is new. Every shadow could hide danger.

choice:
- Go deeper -> descend
- Search for treasure -> treasure [if depth >= 3]
- Retreat to surface -> surface

Key concepts:

functions.plotknot

Demonstrates: custom functions, built-in math functions.

An alchemist shop with calculations:

function: calculate_dosage(2)

# Alchemist Shop

set gold = 50
set reputation = 10
set herb_count = 5
set potency = 3

call calculate_dosage(herb_count, potency) -> dose

if dose > 10:
  "A potent mix," the alchemist mutters.
else:
  "Mild stuff. Good for beginners."

choice:
- Buy healing potion (20 gold) -> buy_potion [if gold >= 20]
- Ask about rare ingredients -> rare_info [if reputation >= 15]
- Leave -> leave

## Buy Potion

set gold = gold - 20
set health = min(health + 30, 100)

The potion glows faintly blue.

-> alchemist_shop

Key concepts:

interpolation.plotknot

Demonstrates: text interpolation, inline tags, character properties, dismissible choices, nested choice content, stop.

A cafe scene with dynamic dialogue and styling cues:

declare gold = 50
declare visited_cafe = false

# The Cafe

set barista.friendship = 0

<ambient> The cafe hums with quiet conversation. Steam curls from the espresso machine.

cycle
  You push through the door for the first time. A bell chimes.
--
  The bell chimes again. The barista looks up.
--
  You walk in like you own the place.

$barista polishes a glass behind the counter.

choice:
-- Ask about the special blend -> special
  set barista.friendship = barista.friendship + 1
- Order a coffee -> order
- Leave -> leave

## Special

<friendly> "The special? You've got good taste," says $barista.

set gold = gold - 8
You sip something extraordinary. Worth every coin.

-> the_cafe

## Order

A plain coffee. Reliable. You have $gold gold left.

choice:
- Another round -> order [if gold >= 3]
  set gold = gold - 3
- Leave -> leave

## Leave

if gold <= 0:
  <tense> Your pockets are empty. Time to go.
  stop

You step back into the street. Maybe tomorrow.

stop

Key concepts:

variation_blocks.plotknot

Demonstrates: all five variation modes (sequence, cycle, once, pick, shuffle).

A guard post and market square showing each mode:

# Guard Post

sequence
  The guard eyes you suspiciously. "First time in town?"
--
  The guard nods. "Back again?"
--
  The guard waves you through without a word.

-> market

## Market

shuffle
  A merchant hawks fresh bread.
--
  Children chase a stray dog between the stalls.
--
  A musician plays a lilting tune by the fountain.
--
  Two old women argue about the price of turnips.

choice:
- Browse the stalls -> browse
- Visit the fountain -> fountain

## Browse

pick
  You find a dusty old map.
--
  A vendor offers you a free sample of cheese.
--
  Someone's dropped a shiny button.

-> market

## Fountain

once
  The fountain burbles peacefully. You toss in a coin.
--
  The fountain again. Your coin glints at the bottom.

cycle
  Pigeons coo on the fountain's rim.
--
  A child splashes in the shallows.
--
  An old man fills his waterskin.

choice:
- Return to the market -> market
- Leave town -> leave

## Leave

You pass the guard one last time.

-> guard_post

Key concepts:

imports.plotknot

Demonstrates: multi-file imports, namespaced section IDs.

A story split across files. The main file imports two modules:

import characters
import "scenes/tavern.plotknot"

# Village Square

declare reputation = 0

The village square bustles with morning activity.

choice:
- Visit the tavern -> scenes.tavern
- Talk to the elder -> characters.elder
- Leave the village -> leave

## Leave

You wave goodbye. Your reputation here is $reputation.

stop

The imported characters.plotknot file:

# Elder

The elder sits on a weathered bench, feeding pigeons.

set elder.wisdom = 10

if elder.wisdom > 5:
  "Sit," the elder says. "Let me tell you about this place."

-> village_square

The imported scenes/tavern.plotknot file:

# Tavern

The tavern is warm and loud. A fire crackles in the hearth.

choice:
- Order a drink -> drink
- Return to the square -> village_square

## Drink

set reputation = reputation + 1
The ale is good. The company is better.

-> tavern

Key concepts:

complete.plotknot

Demonstrates: all features combined in a substantial story.

A sci-fi narrative ("The Awakening") with 15 sections exercising:

This is the best reference for how all features compose in a real story. Read it in examples/complete.plotknot.

Running examples

Compile any example:

./plotknot compile examples/hello.plotknot --output /tmp/

Run through the Lua runtime:

local plotknot = require("plotknot")
local data = require("hello")
local story = plotknot.load(data)
story:start()

for _, line in ipairs(story:current()) do
  if line.type == "text" then print(line.text) end
end

All examples are verified in the test suite (tests/test_runtime.lua) — they compile, load, start, and produce expected output.