Y.A.R.N. HTML5

A browser remake of Y.A.R.N. (Yet Another Random Narrative), the collaborative story-writing parlor game from GameSpy Arcade, with optional LLM-driven bots.

Players take turns adding one sentence to a shared story, vote for their favourite entry each round, and score points. The finished story is saved to disk.

Quick start

npm install
npm start
# open http://localhost:3000

Create or pick a room on the menu, share the /game/<room> URL, and the host can start once at least 3 players (humans + bots) are present.

Configuration

Variable Default Purpose
PORT 3000 HTTP port
YARN_STORIES_DIR ./stories Where finished stories are written
OPENAI_API_KEY – Enables LLM bots (any OpenAI-compatible endpoint)
OPENAI_MODEL meta-llama/Llama-3.2-3B-Instruct-Turbo Default model

Bots can also be configured with bots/llm_config.json (same shape as the OpenAI JS client's options, e.g. { "apiKey": "...", "baseURL": "...", "model": "..." }). Copy bots/llm_config.example.json to get started. This file is gitignored.

If the LLM client cannot be created (no key/config), bots automatically fall back to RandomBot, so a game always starts. A bot request that fails or times out degrades to a fallback sentence (or an empty entry) and the game continues.

Game rules

  • The host picks the round limit, score limit, time per round, bot count and starting text. Settings sync live to everyone in the lobby.
  • Writing phase: each player submits one sentence (max 280 chars).
  • Voting phase: 10 seconds per entry (minimum 15s). You cannot vote for your own entry, and empty entries are not voteable.
  • Scoring: 1 point per vote received. The single most-voted entry gets +3 bonus points. On a tie the longest tied entry gets +2 and the others +1. The final round is worth double points.
  • The game ends when a player reaches the score limit, or when the round limit is reached (highest score wins). The story is saved automatically.
  • The host can skip a stalled writing/voting phase and remove idle players. If a player drops, the round advances immediately when everyone remaining has submitted/voted.

Project layout

server.js              Express + Socket.IO server and the YarnGame state machine
bots/BotFactory.js     Bot construction (LLM with RandomBot fallback) + unique names
bots/LLMBot.js         OpenAI-compatible bot (write/vote/banter, optional config)
bots/RandomBot.js      Deterministic offline bot
public/menu.html       Room browser, past-story archive, about
public/game.html       Game client (lobby, writing, voting, results, game over)
tests/                 node:test unit + socket integration tests
stories/               Saved stories (gitignored, created on demand)

Tests

npm test

The suite (node --test tests/*.test.js) covers:

  • tests/yarn-game.test.js – scoring (incl. final-round doubling and tie breaks), vote validation, phase transitions/timers, reconnection, story assembly and persistence.
  • tests/bots.test.js – factory fallback, unique names, concurrent bot writing/voting, invalid bot votes, banter wiring.
  • tests/validation.test.js – room/player-id sanitisation, settings clamping, text cleaning.
  • tests/socket-flow.test.js – full end-to-end game over real Socket.IO: two humans + one bot, writing → voting → results → game over, story saved, plus immediate phase advance when the last unsubmitted player disconnects.
  • tests/client-ui.test.js – loads game.html and menu.html in jsdom and drives the real client code: input preservation, score-limit 0, refresh resync, HUD, own-vote blocking, results table, game-over controls, host skip/kick, room list and past-story archive.

Manual verification checklist

The jsdom suite covers the client logic; a few visual/browser checks are still worth doing by hand:

  1. Open two browser windows on the same room and confirm the live chat, player highlight colours and host ★ marker look right.
  2. Hover a story segment and confirm the author name appears.
  3. On game over, use Download/Copy Story and check the file/clipboard contents.
  4. Confirm the results table is readable on a narrow (mobile) viewport.
  5. Start a game with 2 humans and 4 bots and confirm the round flow feels right (LLM latency, banter in chat, no stalled rounds).
S
Description
HTML5 + Node implementation of the classic GameSpy parlor game Y.A.R.N.
Readme
224 KiB
0 Stars 1 Watchers 0 Forks
Languages
JavaScript 68.3%
HTML 31.7%