104 lines
3.7 KiB
Markdown
104 lines
3.7 KiB
Markdown
# AI Interactive Fiction - Ink Coolify Release
|
|
|
|
This branch is the deployable Ink edition of the AI Interactive Fiction client/server. It contains the browser UI, the Ink server, the Eibenreith Ink source, compiled Ink output, media assets, fonts, locale files, and Docker/Coolify configuration.
|
|
|
|
The full multi-engine development tree lives on `main`. The historical prototype is intentionally not part of this branch; it is preserved on `codex/archive-prototype` and tag `prototype-archive-2026-05-19`.
|
|
|
|
## Local Ink Development
|
|
|
|
Use Node.js 22 LTS.
|
|
|
|
```powershell
|
|
nvm install 22
|
|
nvm use 22
|
|
npm install
|
|
npm run dev
|
|
```
|
|
|
|
`npm run dev` starts the Ink server through `ts-node` and watches `src/`, `data/ink-src/`, and `config/engines/ink.json`. The server compiles the configured Ink source when it starts.
|
|
|
|
Useful commands:
|
|
|
|
```powershell
|
|
npm run build # Compile TypeScript to dist/
|
|
npm run start # Run the compiled Ink server
|
|
npm run dev:debug # Development server with Ink debug logging
|
|
npm run dev:inspect # Development server with Node inspector on 0.0.0.0:9231
|
|
npm run start:debug # Compiled server with Ink debug logging
|
|
npm run start:inspect # Compiled server with Node inspector on 0.0.0.0:9231
|
|
```
|
|
|
|
Set `PORT` to choose the server port. The Docker image defaults to `3000`.
|
|
|
|
## Coolify 4 Deployment
|
|
|
|
Configure Coolify to deploy this branch with the repository `Dockerfile`.
|
|
|
|
Recommended environment:
|
|
|
|
```text
|
|
NODE_ENV=production
|
|
PORT=3000
|
|
INK_CONFIG_FILE=./config/engines/ink.json
|
|
```
|
|
|
|
Coolify can watch `release/coolify-ink` and redeploy on webhook pushes. The intended flow is:
|
|
|
|
1. Write Ink locally in `data/ink-src/`.
|
|
2. Test locally with `npm run dev`.
|
|
3. Commit to the development branch.
|
|
4. Merge or cherry-pick the wanted deployment state into `release/coolify-ink`.
|
|
5. Push `release/coolify-ink` to the Git remote watched by Coolify.
|
|
|
|
The container builds TypeScript during image build and compiles the configured Ink source at server startup.
|
|
|
|
## Ink Configuration
|
|
|
|
The active game is configured in `config/engines/ink.json`.
|
|
|
|
Important paths:
|
|
|
|
- `paths.inkSource`: main Ink source file.
|
|
- `paths.inkCompiled`: compiled Ink JSON target.
|
|
- `paths.mainGameFile`: compiled Ink JSON loaded by the server.
|
|
- `paths.music`: background music directory.
|
|
- `paths.sfx`: sound effect directory.
|
|
- `paths.images`: image directory.
|
|
|
|
Game metadata and language are sent to the client before game start. The client uses game language for hyphenation and TTS language hints; UI locale can still be overridden by the player.
|
|
|
|
## Browser Client
|
|
|
|
The client lives in `public/` and is served as native browser modules. It renders structured `TurnResult` output from the server, including paragraphs, headings, choices, media events, alerts, score messages, achievements, and errors.
|
|
|
|
TTS provider settings, volume controls, savegames, TTS cache, and rendered story history are stored in browser storage. Ink server state is also sent back to the browser save data so a client can recover after reload or server restart without server-side per-player sessions.
|
|
|
|
## Story Tags
|
|
|
|
Ink tags are parsed server-side into structured output objects. The client consumes structured turn data only.
|
|
|
|
Common tags:
|
|
|
|
```text
|
|
#chapter[Title]
|
|
#section
|
|
#image[file.png](landscape|portrait|square, pause=2)
|
|
#music[file.mp3](crossfade|queue|cut, loop=true, lead=5)
|
|
#sfx[file.ogg](duration=4, fade=true)
|
|
#gloss[Term](Explanation shown on hover.)
|
|
#score[Optional score text]
|
|
#achievement[Optional achievement text]
|
|
#alert[Optional player hint]
|
|
#error[Optional error text]
|
|
```
|
|
|
|
Choice-local tags:
|
|
|
|
```text
|
|
#key:x
|
|
#optional
|
|
#action[name]
|
|
```
|
|
|
|
Explicit choice keys are reserved first. Remaining choices receive keys from `1` through `0`, then `a` through `z`.
|