~nromdotcom/gemif

d1e689012fce6d4ad5f1f67f1ef2f625d5f0d628 — Norm MacLennan a year ago c517833
Update README
1 files changed, 88 insertions(+), 20 deletions(-)

M README.md
M README.md => README.md +88 -20
@@ 9,10 9,12 @@ engine which runs as a [Gemini](https://gemini.circumlunar.space/) server.

## Install

There's no simple installation process at the moment.
Compiled binaries for several architectures are automatically generated on each
tagged commit. You can [find the latest one](https://git.sr.ht/~nromdotcom/gemif/refs)
and download it

For now, you'll need to clone this repo and build or run `cmd/gemif`
with something like `make build-all`, `go build gemif/cmd/gemif`, or whatever.
Otherwise, you can clone this repo and use the regular golang toolchain to build (check
the `Makefile` for examples).

### Configure



@@ 27,7 29,7 @@ In production, you might use [certbot](https://certbot.eff.org/docs/using.html#s
in standalone mode to generate a LetsEncrypt cert.

Otherwise, since most (all?) Gemini clients use TOFU for TLS certificates,
you can also feel free to [generate a self-signed cer](https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs)
you can also feel free to [generate a self-signed cert](https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs)
in whatever way is appropriate for you.

#### Step Two: Gather up your stories


@@ 38,37 40,103 @@ or change them, go ahead and do that now.
#### Step Three: Make a config file

GemIF configures itself based on the contents of `./config.toml`.
Take `sample.config.toml` and rename it. Change the configuration to match
Take `sample.config.toml` and copy it. Change the configuration to match
your desired values.

### Run it

That's it. Go ahead and run the binary.

## Managing Your Stories
```
$ ./bin/gemif-linux-amd64/gemif
Starting GemIF 0.1.1 (bd561ac) - built 2020.12.05.210341

[gig-debug] ⇨ gemini server started on [::]:1965
time="2020-12-05T21:29:40-05:00" path=/ status=20 duration=0.28
```

## Writing Stories

GemIF loads stories from YAML files (from the directory named in `engine.stories_dir` in `config.toml`),
but authors have the option to write their stories in GemIF format using `.gemif` files.

### .gemif files and gemifc
`.gemif` files are a lighweight abstraction on top of the YAML files. Honestly it's still not 
the most pleasant writing experience, but it's generally better than writing the YAML by hand.

You can see some examples in [stories/src/](stories/src/).

Each story directory will contain:
* `metadata.yml` - With story and author information
* An arbitrary number of `.gemif` files - These files contain the rooms and exits

Each `.gemif` contains one or more different rooms. Room metadata is presented as YAML 
frontmatter (or, uh midmatter in the case of multiple rooms in a file) while each description
template is presented as plaintext.

```
# metadata.yml
---
id: simple
name: Simple Demo
description: A simple demo
author: Norm MacLennan

# room.gemif
---
room_id: inside
room_name: Inside
exits:
- exit_id: leave
  exit_description: You're right, let's seize the day!
  destination_id: outside
---
You're inside, but it's such a lovely day out.

---
room_id: outside
room_name: Outside
---
You made it outside. Now you can get on with your life.

THE END
```

Once you're ready to test your story, you can use `gemifc` to "compile" it to YAML.

```
$ gemifc ./path/to/my/story/ ./my/compiled/stories/
Compiling story ./path/to/my/story/ to ./my/compiled/stories/

Finished loading story:
  Name: Simple Demo
  Author: Norm MacLennan
  Descriptions: A simple demo
  Number of Rooms: 2

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

By default, stories live in the `./stories` directory in your working directory.
You can change this with `engine.stories_dir` in your `config.toml`.
Then you can load it up with `gemif` as usual.

Each `*.yml` file in that directory represents a separate story to be loaded
up by the engine. The top-level index page will allow the user to choose which
of these stories they'd like to play, so you have have as many as you want
(within other technical constraints).
## Object specification

The file must contain two top-level properties: `metadata` and `rooms`.
Whether you're writing in gemif format or right in a YAML file, here are the object
specifications for the things you're building.

`metadata` provides information about the story:
`metadata` comes from the `metadata.yml` file in gemif format or the `metadata` key in YAML:
* `id`: is a unique id (within your instance) for the story
* `name`: is a human-friendly title of the story
* `description`: is a brief description of the story
* `author`: a name or other identifier of the author(s)

The `rooms` object holds a list of your rooms/scenes.
`rooms` objects are described by your `.gemif` files or as the `rooms` object in your YAML.

Each room has:
* `room_id`: a unique id for the room, I recommend a GUID
* `room_id`: a story-unique id for the room
* `room_name`: a human-readable name
* `room_description`: a description of the room (what is printed to the screen when the user is there)
* `room_description`: a description of the room (in `.gemif` format this is outside of the frontmatter in plaintext)
* `exits`: an array of exit objects

Each exit contains:


@@ 102,9 170,9 @@ The following struct is in scope within your template:

```
type GameState struct {
	StoryID     string   `json:"si"`
	CurrentRoom string   `json:"cr"`
	Conditions  []string `json:"cn"`
	StoryID     string
	CurrentRoom string
	Conditions  []string
}
```