Skip to content

Project Structure

Understanding the structure of an Encounters story project is essential for creating and organizing your content.

Directory Overview

your-story-project/
├── src/                    # Source files for your story
│   ├── assets/            # Media files (images, avatars)
│   ├── contacts/          # Contact definitions
│   ├── conversations/     # Conversation configurations
│   └── ink/              # Ink script files
├── scripts/               # Build and publish scripts
│   ├── build-story.cjs   # Compiles and packages your story
│   └── publish-story.cjs # Uploads to Encounters server
├── dist/                  # Build output (generated)
├── .env                   # Environment variables (not committed)
├── .env.example          # Template for environment variables
└── package.json          # Node.js dependencies and scripts

Contacts Directory

Contact files define the characters in your story. Each contact is a JSON file in src/contacts/.

Contact File Format

Example: src/contacts/alex.json

json
{
  "id": "alex",
  "name": "Alex Thompson",
  "avatar": "alex-avatar.jpg",
  "phoneNumber": "+44 7700 900124"
}

Fields:

  • id - Unique identifier (must match filename without .json)
  • name - Character's display name
  • avatar - Filename of avatar image in src/assets/
  • phoneNumber - Character's phone number (optional, for display)

Naming Convention

Use lowercase, hyphenated IDs (e.g., alex, family-group) for consistency.

Conversations Directory

Conversation files link contacts to Ink scripts. Located in src/conversations/.

Conversation File Format

Individual Conversation: src/conversations/alex.json

json
{
  "id": "alex",
  "name": "Alex Thompson",
  "type": "individual",
  "contacts": ["alex"],
  "inkFile": "alex.ink",
  "initial": true
}

Group Conversation: src/conversations/family-group.json

json
{
  "id": "family-group",
  "name": "Family",
  "type": "group",
  "contacts": ["mum", "dad", "sister"],
  "inkFile": "family-group.ink",
  "initial": false
}

Fields:

  • id - Unique identifier (must match filename)
  • name - Conversation display name
  • type - Either "individual" or "group"
  • contacts - Array of contact IDs participating in this conversation
  • inkFile - Name of the Ink script file (in src/ink/)
  • initial - Whether this conversation starts immediately when the story begins

Ink Directory

Contains your narrative scripts written in Ink. Each .ink file corresponds to a conversation.

Example: src/ink/alex.ink

ink
// Variables
VAR police_contacted = false
VAR alex_knows_player = false

-> start

== start ==
Hey Sarah, have you seen my keys? #initial #read
Sarah? You were supposed to meet me an hour ago. #initial
-> conversation_choices

== conversation_choices ==
* [Hi, I found Sarah's phone]
  -> found_phone_response
* [Where was Sarah last seen?]
  -> last_seen_response
-> END

See the Ink Scripting Guide for detailed information.

Assets Directory

Store all media files in src/assets/:

  • Avatars - Character profile images (e.g., alex-avatar.jpg)
  • Story Images - Images referenced in messages
  • Thumbnail - Story cover image (thumbnail.jpg)

Supported Formats:

  • Images: .jpg, .jpeg, .png, .gif, .webp
  • Recommended avatar size: 200x200px to 500x500px
  • Recommended thumbnail size: 1200x630px

File References

When referencing assets in Ink scripts or JSON files, use just the filename (e.g., "alex-avatar.jpg"), not the full path.

Scripts Directory

build-story.cjs

Compiles your story:

  1. Finds all .ink files
  2. Compiles them to JSON using inkjs or inklecate
  3. Copies assets to build directory
  4. Generates manifest files
  5. Creates dist/story-build.zip

Usage:

bash
npm run build:story

Watch Mode:

bash
npm run build:story -- --watch

publish-story.cjs

Uploads your built story to an Encounters server:

  1. Runs the build script
  2. Reads credentials from .env
  3. Uploads story-build.zip via API

Usage:

bash
npm run publish:story

Environment Variables

The .env file stores your publishing credentials. Create it by copying .env.example:

bash
cp .env.example .env

Then fill in your details:

env
BASE_URL=https://encounters.andyh.app
STORY_ID=your-story-uuid-here
API_KEY=your-api-key-here

Getting Your Credentials

Story ID:

  1. Go to Stories Management
  2. Create your story
  3. Copy the UUID from the URL after creation

API Key:

  1. Go to Manage Passport Tokens
  2. Create a new token
  3. Copy the API key immediately (you won't see it again!)

Security

Never commit .env to version control! It contains sensitive API keys. Always add .env to your .gitignore file.

Build Output

After running npm run build:story, the dist/ directory contains:

dist/
└── story-build.zip       # Packaged story ready for upload

The zip file contains:

  • Compiled Ink scripts (.json)
  • All assets
  • Contact and conversation definitions
  • Story metadata
  • Manifest files

Visual Studio Code with Ink Extension

For the best development experience, use Visual Studio Code with the Ink extension:

Installation:

  1. Download Visual Studio Code (free)
  2. Install and open VS Code
  3. Open Extensions (Ctrl+Shift+X / Cmd+Shift+X)
  4. Search for "Ink" by inkle
  5. Click Install

Benefits:

  • Syntax highlighting for .ink files
  • Error detection as you type
  • Auto-completion for Ink keywords
  • File navigation - jump to knot definitions
  • Integrated terminal - run build commands without leaving the editor

Opening Your Project:

  1. Open VS Code
  2. File → Open Folder
  3. Select your story project folder
  4. All files will appear in the sidebar

Useful VS Code Features:

  • Explorer (left sidebar) - Browse all project files
  • Search (Ctrl+Shift+F / Cmd+Shift+F) - Find text across all files
  • Terminal (Ctrl+`` / Cmd+``) - Run npm run build:story directly in VS Code
  • Split view - Edit multiple files side-by-side

Best Practices

Organization

  • One contact per file - Keep contact definitions separate
  • Match IDs to filenames - alex.json should have "id": "alex"
  • Group related conversations - Use clear naming for group chats

Naming Conventions

  • IDs: lowercase-with-hyphens (e.g., family-group)
  • Display Names: Proper Case (e.g., "Alex Thompson")
  • Files: Match the ID (e.g., alex.json, alex.ink)

Asset Management

  • Optimize images - Compress before adding to reduce file size
  • Consistent naming - Use descriptive names (e.g., alex-avatar.jpg)
  • Organize by type - Consider subdirectories for large projects

Version Control

Add to .gitignore:

.env
node_modules/
dist/

Next Steps

Released under the MIT License.