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, audio, video)
│ ├── contacts/ # Contact definitions
│ ├── conversations/ # Conversation configurations
│ ├── gallery/ # Gallery item definitions
│ ├── ink/ # Ink script files
│ ├── news/ # News articles (markdown)
│ └── notes/ # Notes/clues (markdown)
├── 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 scriptsContacts 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
{
"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 nameavatar- Filename of avatar image insrc/assets/phoneNumber- Character's phone number (optional, for display)
Naming Convention
Use lowercase, hyphenated IDs (e.g., alex, family-group) for consistency.
Automatic Contact Unlocking
Contacts are automatically unlocked when a conversation containing that contact is unlocked. For example, if you unlock a conversation with #unlockConversation:alex, the contact "alex" will automatically appear in the player's contact list. You only need to use #unlockContact: if you want to unlock a contact separately from any conversation.
Conversations Directory
Conversation files link contacts to Ink scripts. Located in src/conversations/.
Conversation File Format
Individual Conversation: src/conversations/alex.json
{
"id": "alex",
"name": "Alex Thompson",
"type": "individual",
"contacts": ["alex"],
"inkFile": "alex.ink",
"initial": true
}Group Conversation: src/conversations/family-group.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 nametype- Either"individual"or"group"contacts- Array of contact IDs participating in this conversationinkFile- Name of the Ink script file (insrc/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
// 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
-> ENDSee 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
- Audio Files - Voice messages, recordings (e.g.,
message.wav) - Video Files - Video clips, footage (e.g.,
footage.mp4) - Thumbnail - Story cover image (
thumbnail.jpg)
Supported Formats:
- Images:
.jpg,.jpeg,.png,.gif,.webp - Audio:
.wav,.mp3,.ogg,.m4a - Video:
.mp4,.webm,.mov - 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.
News Directory
News articles are written in Markdown and appear in the in-game news feed. Located in src/news/.
Quick Overview
Each .md file in the news directory represents one news article with metadata tags at the top:
#initial
#title:Local Woman Reported Missing
#source:City News Network
#image:news-photo.jpg
#publishedAt:2025-10-22T10:00:00Z
**BREAKING**: A local woman has been reported missing...Key Features
- Markdown formatting - Full support for headings, lists, images, links, etc.
- Metadata tags - Control title, source, images, and publication date
- Initial unlock - Use
#initialtag for articles available from the start - Timed unlocking - Unlock articles via Ink with
#unlockNews:article-id[:delay] - State tracking - Check if articles are unlocked or read with external functions
Learn More
See the complete News System Guide for detailed documentation, examples, and best practices.
Notes Directory
Notes are written in Markdown and appear in the in-game notes app. Located in src/notes/.
Quick Overview
Each .md file in the notes directory represents one note with metadata tags at the top:
#initial
#title:Welcome to Your Notes
# Welcome to Your Notes
This is your personal notes app. Important information will appear here as you progress...Key Features
- Markdown formatting - Full support for headings, lists, tables, code blocks, etc.
- Metadata tags - Control title and initial unlock status
- Initial unlock - Use
#initialtag for notes available from the start - Timed unlocking - Unlock notes via Ink with
#unlockNote:note-id[:delay] - State tracking - Check if notes are unlocked or read with external functions
Common Use Cases
- Clues and evidence - Important details players need to remember
- Locations - Addresses, coordinates, access codes
- Character information - Backgrounds, relationships, profiles
- Timeline tracking - Sequence of events
- Puzzle solutions - Codes, passwords, hints
Learn More
See the complete Notes System Guide for detailed documentation, examples, and best practices.
Gallery Directory
Gallery items (photos and videos) are defined in JSON files. Located in src/gallery/.
Quick Overview
Each .json file defines one gallery item with fields for type, asset, caption, and more:
{
"type": "image",
"asset": "crime-scene.jpg",
"caption": "Evidence found at the warehouse",
"takenAt": "2025-10-22T15:30:00Z",
"initial": false
}Key Features
- Media types - Support for images and videos
- Captions - Add descriptive text to provide context
- Timestamps - Use
takenAtto create a timeline of events - Initial unlock - Use
"initial": truefor items available from the start - Unlock via Ink - Use
#gallery:item-idto unlock during gameplay - Dual display - Items appear in conversations and the gallery app
Common Use Cases
- Evidence photos - Crime scenes, clues, documents
- Security footage - CCTV, recordings, video evidence
- Personal photos - Character selfies, group photos
- Timeline creation - Visual sequence of events
Learn More
See the complete Gallery System Guide for detailed documentation, JSON field reference, and best practices.
Scripts Directory
build-story.cjs
Compiles your story:
- Finds all
.inkfiles - Compiles them to JSON using inkjs or inklecate
- Copies assets to build directory
- Generates manifest files
- Creates
dist/story-build.zip
Usage:
npm run build:storyWatch Mode:
npm run build:story -- --watchpublish-story.cjs
Uploads your built story to an Encounters server:
- Runs the build script
- Reads credentials from
.env - Uploads
story-build.zipvia API
Usage:
npm run publish:storyEnvironment Variables
The .env file stores your publishing credentials. Create it by copying .env.example:
cp .env.example .envThen fill in your details:
BASE_URL=https://encounters.andyh.app
STORY_ID=your-story-uuid-here
API_KEY=your-api-key-hereGetting Your Credentials
Story ID:
- Go to Stories Management
- Create your story
- Copy the UUID from the URL after creation
API Key:
- Go to Manage Passport Tokens
- Create a new token
- 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 uploadThe zip file contains:
- Compiled Ink scripts (
.json) - All assets
- Contact and conversation definitions
- Story metadata
- Manifest files
Recommended Editor Setup
Visual Studio Code with Ink Extension
For the best development experience, use Visual Studio Code with the Ink extension:
Installation:
- Download Visual Studio Code (free)
- Install and open VS Code
- Open Extensions (
Ctrl+Shift+X/Cmd+Shift+X) - Search for "Ink" by inkle
- Click Install
Benefits:
- Syntax highlighting for
.inkfiles - 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:
- Open VS Code
- File → Open Folder
- Select your story project folder
- 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+``) - Runnpm run build:storydirectly 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.jsonshould 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
- Test media files - Ensure audio/video files play correctly before publishing
Content Organization
- News articles - Use realistic news writing style, include publication dates
- Notes - Keep concise and scannable, format important info clearly
- Gallery items - Add descriptive captions, organize by story progression
- Initial content - Mark welcome/tutorial content with
#initialtag
Version Control
Add to .gitignore:
.env
node_modules/
dist/Next Steps
- Learn how to write narrative scripts in the Ink Scripting Guide
- Understand the build process in Build and Publish