~nromdotcom/gemif

0661a68757e5de04e963cc5d7b23a618e5303966 — Norm MacLennan 11 months ago acbff04
Initial story compiler with two examples
M Makefile => Makefile +13 -3
@@ 34,14 34,25 @@ upgrade_deps: ## Upgrade versions of dependencies
	go get -u

##@ Build
build: clean generate ## Build the application for your native architecture
gemif-build: clean generate ## Build GemIF server for your native architecture
	go build -o ./bin/gemif -ldflags=$(ldflags) gemif/cmd/gemif

build-all: clean generate ## Build the application for linux and mac
gemif-build-all: clean generate ## Build GemIF server for linux and mac
	GOOS=darwin GOARCH=amd64 go build -o ./bin/darwin-amd64/gemif -ldflags=$(ldflags) gemif/cmd/gemif
	GOOS=linux GOARCH=amd64 go build -o ./bin/linux-amd64/gemif -ldflags=$(ldflags) gemif/cmd/gemif
	GOOS=linux GOARCH=arm64 go build -o ./bin/linux-arm64/gemif -ldflags=$(ldflags) gemif/cmd/gemif

gemifc-build: clean ## Build story copiler for your native architecture
	go build -o ./bin/gemifc -ldflags=$(ldflags) gemif/cmd/gemifc

gemifc-build-all: clean ## Build story compiler for linux and mac
	GOOS=darwin GOARCH=amd64 go build -o ./bin/darwin-amd64/gemifc -ldflags=$(ldflags) gemif/cmd/gemifc
	GOOS=linux GOARCH=amd64 go build -o ./bin/linux-amd64/gemifc -ldflags=$(ldflags) gemif/cmd/gemifc
	GOOS=linux GOARCH=arm64 go build -o ./bin/linux-arm64/gemifc -ldflags=$(ldflags) gemif/cmd/gemifc

build: gemif-build gemifc-build ## Build gemif and gemifc for native architecture
build-all: gemif-build-all gemifc-build-all ## Build gemif and gemifc for linux and mac

clean: ## Delete any compiled artifacts
	rm -rf ./bin



@@ 61,6 72,5 @@ nonmegalint: ## do a regular golint

megalint: ## Run several linters in parallel (requires docker)
	docker run --rm -v $(PWD):/app -w /app golangci/golangci-lint:latest golangci-lint run \
	--skip-dirs bcrypt \
	--skip-files pkger.go \
	--enable-all
\ No newline at end of file

A cmd/gemifc/main.go => cmd/gemifc/main.go +139 -0
@@ 0,0 1,139 @@
package main

// yaml.v3 doesn't serialize multi-line strings
// correctly for some reason, so we use v2.
import (
	"fmt"
	"gemif/pkg/gamemanager"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"

	"gopkg.in/yaml.v2"
)

func readFile(path string) (string, error) {
	contents, err := ioutil.ReadFile(path)
	if err != nil {
		return "", fmt.Errorf("couldn't read file: %w", err)
	}

	return string(contents), nil
}

func findFilesWithExtension(root, pattern string) ([]string, error) {
	var matches []string

	err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if info.IsDir() {
			return nil
		}

		if matched, err := filepath.Match(pattern, filepath.Base(path)); err != nil {
			return err
		} else if matched {
			matches = append(matches, path)
		}

		return nil
	})

	if err != nil {
		return nil, err
	}

	return matches, nil
}

func main() {
	correctNumArguments := 3
	if len(os.Args) != correctNumArguments {
		log.Fatal("Usage: gemifc [input_path] [output_path]")
	}

	inputPath := os.Args[1]
	outputPath := os.Args[2]

	fmt.Printf("Compiling story %s to %s\n", inputPath, outputPath)

	fileContents, err := readFile(fmt.Sprintf("%s/metadata.yml", inputPath))
	if err != nil {
		log.Fatalf("Couldn't read metadata file: %s", err)
	}

	var metadata *gamemanager.StoryMetadata
	if err := yaml.Unmarshal([]byte(fileContents), &metadata); err != nil {
		log.Fatalf("Malformed metadata.yml: %s", err)
	}

	files, err := findFilesWithExtension(inputPath, "*.gemif")
	if err != nil {
		log.Fatalf("Couldn't load *.gemif files %s", err)
	}

	storyRooms := []gamemanager.Room{}

	for _, file := range files {
		thisFile, err := readFile(file)
		if err != nil {
			log.Fatalf("Couldn't read .gemif file: %s", err)
		}

		isMetadata := false
		currentRoom := gamemanager.Room{}

		for _, filePiece := range strings.Split(thisFile, "---") {
			if filePiece == "" {
				isMetadata = !isMetadata

				continue
			}

			if isMetadata {
				if err := yaml.Unmarshal([]byte(filePiece), &currentRoom); err != nil {
					log.Fatalf("Couldn't parse story metadata from yaml: %s", err)
				}
			} else {
				currentRoom.Description = filePiece
				storyRooms = append(storyRooms, currentRoom)
				currentRoom = gamemanager.Room{}
			}

			isMetadata = !isMetadata
		}
	}

	story := gamemanager.Story{
		Metadata: *metadata,
		Rooms:    storyRooms,
	}

	fmt.Printf(`
Finished loading story:
  Name: %s
  Author: %s
  Descriptions: %s
  Number of Rooms: %d

`, story.Metadata.Name, story.Metadata.Author, story.Metadata.Description, len(story.Rooms))

	fmt.Println("Serializing and writing to disk...")

	storyOut, err := yaml.Marshal(story)
	if err != nil {
		log.Fatal("Couldn't load story metadata")
	}

	err = ioutil.WriteFile(fmt.Sprintf("%s/%s.yml", outputPath, story.Metadata.ID), storyOut, 0644) // #nosec G306
	if err != nil {
		log.Fatalf("Couldn't write compiled output: %s", err)
	}

	fmt.Println("Done!")
}

M go.mod => go.mod +1 -0
@@ 12,5 12,6 @@ require (
	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
	google.golang.org/protobuf v1.25.0
	gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
	gopkg.in/yaml.v2 v2.2.7
	gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
)

M pkg/gamemanager/room.go => pkg/gamemanager/room.go +4 -4
@@ 4,8 4,8 @@ package gamemanager
type Room struct {
	ID          string `yaml:"room_id" json:"room_id" binding:"uuid"`
	Name        string `yaml:"room_name" json:"room_name"`
	Description string `yaml:"room_description" json:"room_description"`
	Exits       []Exit `yaml:"exits" json:"exits"`
	Description string `yaml:"room_description,omitempty" json:"room_description"`
	Exits       []Exit `yaml:"exits,omitempty" json:"exits"`
}

// Exit describes actions applied to GameState as part of leaving a Room.


@@ 13,6 13,6 @@ type Exit struct {
	ID           string `yaml:"exit_id" json:"exit_id" binding:"uuid"`
	Description  string `yaml:"exit_description" json:"exit_description"`
	Destination  string `yaml:"destination_id" json:"destination_id" binding:"uuid"`
	SetCondition string `yaml:"set_condition" json:"set_condition"`
	IfCondition  string `yaml:"if_condition" json:"if_condition"`
	SetCondition string `yaml:"set_condition,omitempty" json:"set_condition"`
	IfCondition  string `yaml:"if_condition,omitempty" json:"if_condition"`
}

R stories/house-tour.yml => stories/compiled/house_tour.yml +58 -51
@@ 4,79 4,86 @@ metadata:
  description: Take a walk through my house
  author: Norm MacLennan
rooms:
- room_id: 2824028c-d71c-49cd-9289-c349a640ed9a
  room_name: Living Room
  room_description: >
    You are in the living room. It is a cozy area with
    a couch, loveseat, and big chair with ottoman. The seats are separated by end tables.
    There is a coffee table in the middle and an entertainment center with TV across from
    the seats.
- room_id: 478f88b7-88fe-4f2d-8b76-35d5f190c4d1
  room_name: Back Porch
  room_description: |2

    There's a nice back yard here.

    On the porch there's a greenhouse with several young plants, as well as a couple outdoor chairs. Beyond the porch is an overgrown lawn and a big rock retaining wall. Everything past that is woods.
  exits:
  - exit_description: The kitchen lies to the north.
    destination_id: 9dabb186-6046-4570-a585-2fbaadfab3cc
    exit_id: 85a71759-5c70-4fc4-8178-8ad8a3bef2d6
  - exit_description: To the west is a sliding door that leads to a porch
    destination_id: 478f88b7-88fe-4f2d-8b76-35d5f190c4d1
    exit_id: 478f88b7-88fe-4f2d-8b76-35d5f190c4d1
  - exit_description: To the east is the front door, leading to the yard.
    destination_id: cb178734-dd94-4333-87bd-731f8e8ac1ed
    exit_id: e4e23c7e-3f54-4bb9-a76e-c899034bc327
  - exit_id: ff9d5ca2-14da-44ea-8a86-bd46dfdf2db4
    exit_description: You can go back inside into the living room.
    destination_id: 2824028c-d71c-49cd-9289-c349a640ed9a
- room_id: cb178734-dd94-4333-87bd-731f8e8ac1ed
  room_name: Front Hall
  room_description: >
  room_description: |2-

    You're standing in the front hall. The door is open and you can see the yard.

    There's a cute little shed and a raised bed garden out there. The lawn is dying.
  exits:
  - exit_id: a0cf11d1-a651-4bd9-a731-ca549048a176
    destination_id: 2824028c-d71c-49cd-9289-c349a640ed9a
    exit_description: The living room is to the west
    destination_id: 2824028c-d71c-49cd-9289-c349a640ed9a
  - exit_id: a22d76c7-3d74-4a9f-a958-06e85d05b033
    destination_id: 52d7babe-8de3-4202-8e6c-097c73ecd918
    exit_description: Oooh, looks like a bunch of fun stuff in the game room!
  - exit_description: You can go upstairs to the second floor hall.
    destination_id: 52d7babe-8de3-4202-8e6c-097c73ecd918
  - exit_id: b4756738-2ec3-4a4a-b229-ac7f80816deb
    exit_description: You can go upstairs to the second floor hall.
    destination_id: ee8bdc39-c471-4cdd-9241-5f5cf43143d5
    exit_id: b4756738-2ec3-4a4a-b229-ac7f80816deb
- room_id: ee8bdc39-c471-4cdd-9241-5f5cf43143d5
  room_name: Upstairs Hallway
  room_description: >
    All the doors upstairs are closed. Weird.
  exits:
  - exit_id: 5e5b296e-68da-4e35-8da6-4a160e3435ee
    destination_id: cb178734-dd94-4333-87bd-731f8e8ac1ed
    exit_description: Might as well go back downstairs
- room_id: 52d7babe-8de3-4202-8e6c-097c73ecd918
  room_name: Game Room
  room_description: >
    This room has a bunch of cool stuff in it. The walls are covered in bookshelves
    full of boardgames, lego set, and fun little knick-knacks. In the center of the
    room is a gaming table topped with green speed cloth and 6 chairs.
  room_description: |2-

    This room has a bunch of cool stuff in it.

    The walls are covered in bookshelves full of boardgames, lego set, and fun little knick-knacks. In the center of the room is a gaming table topped with green speed cloth and 6 chairs.
  exits:
  - exit_id: a197cc68-8830-452a-9e95-289031574951
    destination_id: cb178734-dd94-4333-87bd-731f8e8ac1ed
    exit_description: There's a nice breeze blowing in from the open front door
    destination_id: cb178734-dd94-4333-87bd-731f8e8ac1ed
  - exit_id: cedb26f5-9760-4027-af24-eac92ddd71f7
    destination_id: 9dabb186-6046-4570-a585-2fbaadfab3cc
    exit_description: You can see the kitchen through a doorway.
    destination_id: 9dabb186-6046-4570-a585-2fbaadfab3cc
- room_id: 9dabb186-6046-4570-a585-2fbaadfab3cc
  room_name: Kitchen
  room_description: >
    The kitchen is fairly well-appointed. It borders the Living Room
    with a peninsula and two stools. There is a kitchen and stove in the corner, with a fridge
    on the right and a sink on the left. There appears to be adequate cabinet space.
  room_description: |2-


    The kitchen is fairly well-appointed. It borders the Living Room with a peninsula and two stools. There is a kitchen and stove in the corner, with a fridge on the right and a sink on the left. There appears to be adequate cabinet space.
  exits:
  - exit_description: You can see the living room from where you are.
  - exit_id: 15c33397-b5ee-4d05-8d66-fdbf556f9c2d
    exit_description: You can see the living room from where you are.
    destination_id: 2824028c-d71c-49cd-9289-c349a640ed9a
    exit_id: 15c33397-b5ee-4d05-8d66-fdbf556f9c2d
  - exit_id: cc322095-46cf-401b-a5e5-3d17b767d634
    destination_id: 52d7babe-8de3-4202-8e6c-097c73ecd918
    exit_description: There's a fun-looking game room through a doorway
- room_id: 478f88b7-88fe-4f2d-8b76-35d5f190c4d1
  room_name: Back Porch
  room_description: >
    There's a nice back yard here. On the porch there's a greenhouse with
    several young plants, as well as a couple outdoor chairs. Beyond the porch is an overgrown lawn
    and a big rock retaining wall. Everything past that is woods.
    destination_id: 52d7babe-8de3-4202-8e6c-097c73ecd918
- room_id: 2824028c-d71c-49cd-9289-c349a640ed9a
  room_name: Living Room
  room_description: |2


    You are in the living room. It is a cozy area with a couch, loveseat, and big chair with ottoman. The seats are separated by end tables.

    There is a coffee table in the middle and an entertainment center with TV across from the seats.
  exits:
  - exit_description: You can go back inside into the living room.
    destination_id: 2824028c-d71c-49cd-9289-c349a640ed9a
    exit_id: ff9d5ca2-14da-44ea-8a86-bd46dfdf2db4
  - exit_id: 85a71759-5c70-4fc4-8178-8ad8a3bef2d6
    exit_description: The kitchen lies to the north.
    destination_id: 9dabb186-6046-4570-a585-2fbaadfab3cc
  - exit_id: 478f88b7-88fe-4f2d-8b76-35d5f190c4d1
    exit_description: To the west is a sliding door that leads to a porch
    destination_id: 478f88b7-88fe-4f2d-8b76-35d5f190c4d1
  - exit_id: e4e23c7e-3f54-4bb9-a76e-c899034bc327
    exit_description: To the east is the front door, leading to the yard.
    destination_id: cb178734-dd94-4333-87bd-731f8e8ac1ed
- room_id: ee8bdc39-c471-4cdd-9241-5f5cf43143d5
  room_name: Upstairs Hallway
  room_description: |2-


    All the doors upstairs are closed. Weird.
  exits:
  - exit_id: 5e5b296e-68da-4e35-8da6-4a160e3435ee
    exit_description: Might as well go back downstairs
    destination_id: cb178734-dd94-4333-87bd-731f8e8ac1ed

R stories/sample-story.yml => stories/compiled/sample_story.yml +35 -27
@@ 6,66 6,72 @@ metadata:
rooms:
- room_id: the_beginning
  room_name: The Beginning
  room_description: |+
   ┌─────────────╥─────────────┐
   │░░░░░╔═══╗░░░║░╔══╦═══╗░░░░╞╗
   │░░░░░║╔═╗║░░░║░╚╣╠╣╔══╝░░░░│║
   │░░░░░║║░╚╬══╦╗╔╗║║║╚══╗░░░░│║
   │░░░░░║║╔═╣║═╣╚╝║║║║╔══╝░░░░│║
   │░░░░░║╚╩═║║═╣║║╠╣╠╣║░░░░░░░│║
   │░░░░░╚═══╩══╩╩╩╩══╩╝░░░░░░░│║
   └╥────────────╨─────────────┘║
    ╚═══════════════════════════╝
    Welcome to GemIF - The Interactive Fiction Engine.
  room_description: |2

    ┌─────────────╥─────────────┐
    │░░░░░╔═══╗░░░║░╔══╦═══╗░░░░╞╗
    │░░░░░║╔═╗║░░░║░╚╣╠╣╔══╝░░░░│║
    │░░░░░║║░╚╬══╦╗╔╗║║║╚══╗░░░░│║
    │░░░░░║║╔═╣║═╣╚╝║║║║╔══╝░░░░│║
    │░░░░░║╚╩═║║═╣║║╠╣╠╣║░░░░░░░│║
    │░░░░░╚═══╩══╩╩╩╩══╩╝░░░░░░░│║
    └╥────────────╨─────────────┘║
     ╚═══════════════════════════╝
    Welcome to GemIF - The Interactive Fiction Engine.

    Here you are in the beginning of the story. Make a choice below!
  exits:
  - exit_description: I want to make choice a
  - exit_id: make_choice_a
    exit_description: I want to make choice a
    destination_id: made_choice_a
    exit_id: make_choice_a
    set_condition: choice_a
  - exit_description: I want to make choice b
  - exit_id: make_choice_b
    exit_description: I want to make choice b
    destination_id: made_choice_b
    exit_id: make_choice_b
    set_condition: choice_b
  - exit_description: If you choose not to decide you still have made a choice
  - exit_id: make_no_choice
    exit_description: If you choose not to decide you still have made a choice
    destination_id: made_no_choice
    exit_id: make_no_choice
    set_condition: no_choice
- room_id: made_choice_a
  room_name: Doing Choice A
  room_description: >
  room_description: |2+

    You made choice a!

    Something specific probably happens because of this.

  exits:
  - exit_id: go_to_end
    destination_id: the_end
    exit_description: Or maybe choice is an illusion
    destination_id: the_end
- room_id: made_choice_b
  room_name: Doing Choice B
  room_description: >
  room_description: |2+

    You made choice b!

    Is anything really different than if you did choice a?

  exits:
  - exit_id: go_to_end
    destination_id: the_end
    exit_description: Or maybe choice is an illusion
    destination_id: the_end
- room_id: made_no_choice
  room_name: A coward who makes no choice
  room_description: >
  room_description: |2-

    You didn't make any choice!

    But something still happens - that's how the world works.
  exits:
  - exit_id: go_to_end
    destination_id: the_end
    exit_description: Or maybe choice is an illusion
    destination_id: the_end
- room_id: the_end
  room_name: The End
  room_description: |
  room_description: |2+

    Though because this is a simple demo, you always end up in the same place.

    {{- if .ConditionMet "choice_a"}}


@@ 81,14 87,16 @@ rooms:
    wow you're soooo cool and mysterious, making no choice.
    you really thing that makes you interesting? well it doesn't.
    {{- end}}

  exits:
  - exit_id: bonus_round
    exit_description: oh, what's this?
    destination_id: secret_level
    if_condition: no_choice
    exit_description: oh, what's this?
- room_id: secret_level
  room_name: Bonus Round!
  room_description: >
  room_description: |2-

    We're all so proud of you for being so cool and awesome that you didn't make a choice.

    Nobody else got this ending!
\ No newline at end of file
    Nobody else got this ending!

A stories/src/house_tour/back_porch.gemif => stories/src/house_tour/back_porch.gemif +11 -0
@@ 0,0 1,11 @@
---
room_id: 478f88b7-88fe-4f2d-8b76-35d5f190c4d1
room_name: Back Porch
exits:
- exit_description: You can go back inside into the living room.
  destination_id: 2824028c-d71c-49cd-9289-c349a640ed9a
  exit_id: ff9d5ca2-14da-44ea-8a86-bd46dfdf2db4
---
There's a nice back yard here.

On the porch there's a greenhouse with several young plants, as well as a couple outdoor chairs. Beyond the porch is an overgrown lawn and a big rock retaining wall. Everything past that is woods.

A stories/src/house_tour/front_hall.gemif => stories/src/house_tour/front_hall.gemif +17 -0
@@ 0,0 1,17 @@
---
room_id: cb178734-dd94-4333-87bd-731f8e8ac1ed
room_name: Front Hall
exits:
- exit_id: a0cf11d1-a651-4bd9-a731-ca549048a176
  destination_id: 2824028c-d71c-49cd-9289-c349a640ed9a
  exit_description: The living room is to the west
- exit_id: a22d76c7-3d74-4a9f-a958-06e85d05b033
  destination_id: 52d7babe-8de3-4202-8e6c-097c73ecd918
  exit_description: Oooh, looks like a bunch of fun stuff in the game room!
- exit_description: You can go upstairs to the second floor hall.
  destination_id: ee8bdc39-c471-4cdd-9241-5f5cf43143d5
  exit_id: b4756738-2ec3-4a4a-b229-ac7f80816deb
---
You're standing in the front hall. The door is open and you can see the yard.

There's a cute little shed and a raised bed garden out there. The lawn is dying.
\ No newline at end of file

A stories/src/house_tour/game_room.gemif => stories/src/house_tour/game_room.gemif +14 -0
@@ 0,0 1,14 @@
---
room_id: 52d7babe-8de3-4202-8e6c-097c73ecd918
room_name: Game Room
exits:
- exit_id: a197cc68-8830-452a-9e95-289031574951
  destination_id: cb178734-dd94-4333-87bd-731f8e8ac1ed
  exit_description: There's a nice breeze blowing in from the open front door
- exit_id: cedb26f5-9760-4027-af24-eac92ddd71f7
  destination_id: 9dabb186-6046-4570-a585-2fbaadfab3cc
  exit_description: You can see the kitchen through a doorway.
---
This room has a bunch of cool stuff in it.

The walls are covered in bookshelves full of boardgames, lego set, and fun little knick-knacks. In the center of the room is a gaming table topped with green speed cloth and 6 chairs.
\ No newline at end of file

A stories/src/house_tour/kitchen.gemif => stories/src/house_tour/kitchen.gemif +13 -0
@@ 0,0 1,13 @@
---
room_id: 9dabb186-6046-4570-a585-2fbaadfab3cc
room_name: Kitchen
exits:
- exit_description: You can see the living room from where you are.
  destination_id: 2824028c-d71c-49cd-9289-c349a640ed9a
  exit_id: 15c33397-b5ee-4d05-8d66-fdbf556f9c2d
- exit_id: cc322095-46cf-401b-a5e5-3d17b767d634
  destination_id: 52d7babe-8de3-4202-8e6c-097c73ecd918
  exit_description: There's a fun-looking game room through a doorway
---

The kitchen is fairly well-appointed. It borders the Living Room with a peninsula and two stools. There is a kitchen and stove in the corner, with a fridge on the right and a sink on the left. There appears to be adequate cabinet space.
\ No newline at end of file

A stories/src/house_tour/living_room.gemif => stories/src/house_tour/living_room.gemif +18 -0
@@ 0,0 1,18 @@
---
room_id: 2824028c-d71c-49cd-9289-c349a640ed9a
room_name: Living Room
exits:
- exit_description: The kitchen lies to the north.
  destination_id: 9dabb186-6046-4570-a585-2fbaadfab3cc
  exit_id: 85a71759-5c70-4fc4-8178-8ad8a3bef2d6
- exit_description: To the west is a sliding door that leads to a porch
  destination_id: 478f88b7-88fe-4f2d-8b76-35d5f190c4d1
  exit_id: 478f88b7-88fe-4f2d-8b76-35d5f190c4d1
- exit_description: To the east is the front door, leading to the yard.
  destination_id: cb178734-dd94-4333-87bd-731f8e8ac1ed
  exit_id: e4e23c7e-3f54-4bb9-a76e-c899034bc327
---

You are in the living room. It is a cozy area with a couch, loveseat, and big chair with ottoman. The seats are separated by end tables.

There is a coffee table in the middle and an entertainment center with TV across from the seats.

A stories/src/house_tour/metadata.yml => stories/src/house_tour/metadata.yml +5 -0
@@ 0,0 1,5 @@
---
id: house_tour
name: House Tour
description: Take a walk through my house
author: Norm MacLennan
\ No newline at end of file

A stories/src/house_tour/upstairs_hallway.gemif => stories/src/house_tour/upstairs_hallway.gemif +10 -0
@@ 0,0 1,10 @@
---
room_id: ee8bdc39-c471-4cdd-9241-5f5cf43143d5
room_name: Upstairs Hallway
exits:
- exit_id: 5e5b296e-68da-4e35-8da6-4a160e3435ee
  destination_id: cb178734-dd94-4333-87bd-731f8e8ac1ed
  exit_description: Might as well go back downstairs
---

All the doors upstairs are closed. Weird.
\ No newline at end of file

A stories/src/sample_story/01-start.gemif => stories/src/sample_story/01-start.gemif +29 -0
@@ 0,0 1,29 @@
---
room_id: the_beginning
room_name: The Beginning
exits:
- exit_description: I want to make choice a
  destination_id: made_choice_a
  exit_id: make_choice_a
  set_condition: choice_a
- exit_description: I want to make choice b
  destination_id: made_choice_b
  exit_id: make_choice_b
  set_condition: choice_b
- exit_description: If you choose not to decide you still have made a choice
  destination_id: made_no_choice
  exit_id: make_no_choice
  set_condition: no_choice
---
┌─────────────╥─────────────┐
│░░░░░╔═══╗░░░║░╔══╦═══╗░░░░╞╗
│░░░░░║╔═╗║░░░║░╚╣╠╣╔══╝░░░░│║
│░░░░░║║░╚╬══╦╗╔╗║║║╚══╗░░░░│║
│░░░░░║║╔═╣║═╣╚╝║║║║╔══╝░░░░│║
│░░░░░║╚╩═║║═╣║║╠╣╠╣║░░░░░░░│║
│░░░░░╚═══╩══╩╩╩╩══╩╝░░░░░░░│║
└╥────────────╨─────────────┘║
 ╚═══════════════════════════╝
Welcome to GemIF - The Interactive Fiction Engine.

Here you are in the beginning of the story. Make a choice below!

A stories/src/sample_story/02-middle.gemif => stories/src/sample_story/02-middle.gemif +35 -0
@@ 0,0 1,35 @@
---
room_id: made_choice_a
room_name: Doing Choice A
exits:
- exit_id: go_to_end
  destination_id: the_end
  exit_description: Or maybe choice is an illusion
---
You made choice a!

Something specific probably happens because of this.

---
room_id: made_choice_b
room_name: Doing Choice B
exits:
- exit_id: go_to_end
  destination_id: the_end
  exit_description: Or maybe choice is an illusion
---
You made choice b!

Is anything really different than if you did choice a?

---
room_id: made_no_choice
room_name: A coward who makes no choice
exits:
- exit_id: go_to_end
  destination_id: the_end
  exit_description: Or maybe choice is an illusion
---
You didn't make any choice!

But something still happens - that's how the world works.
\ No newline at end of file

A stories/src/sample_story/03-end.gemif => stories/src/sample_story/03-end.gemif +32 -0
@@ 0,0 1,32 @@
---
room_id: the_end
room_name: The End
exits:
- exit_id: bonus_round
  destination_id: secret_level
  if_condition: no_choice
  exit_description: oh, what's this?
---
Though because this is a simple demo, you always end up in the same place.

{{- if .ConditionMet "choice_a"}}

oh cool, you made choice a! nice work.
{{- end}}
{{- if .ConditionMet "choice_b"}}

oh you made choice b, that's too bad :(
{{- end}}
{{- if .ConditionMet "no_choice"}}

wow you're soooo cool and mysterious, making no choice.
you really thing that makes you interesting? well it doesn't.
{{- end}}

---
room_id: secret_level
room_name: Bonus Round!
---
We're all so proud of you for being so cool and awesome that you didn't make a choice.

Nobody else got this ending!
\ No newline at end of file

A stories/src/sample_story/metadata.yml => stories/src/sample_story/metadata.yml +5 -0
@@ 0,0 1,5 @@
---
id: sample_story
name: Sample Story
description: A sort of hello world
author: Norm MacLennan
\ No newline at end of file