Hawking Cove — GM Tool
A Fate Condensed co-GM assistant for running live sessions.
Overview
This tool acts as a real-time GM assistant during Fate Condensed tabletop sessions. It loads your campaign data from YAML files and gives you fast access to AI-generated suggestions — compels, NPC dialogue, scene twists, session prep, and more.
Everything runs in the browser. No accounts, no data sent anywhere except to the AI worker when you click a button. YAML files are your source of truth; edit them between sessions to update characters, scenes, and threads.
Layout
The tool uses a three-panel layout:
| Panel | Contents |
|---|---|
| Left — PARTY | Player character cards with fate points, stress boxes, and aspects |
| Center — SCENE / ACTIONS / LOG | Current scene, AI action buttons, AI response panel, session log |
| Right — INTEL | Story Pulse dashboard, NPC quick-select, story threads |
The left and right panels can be collapsed by clicking the arrow button (‹ / ›) in each panel header. This gives the center panel full width. Click the initials icons in the collapsed strip to re-expand.
Column widths are draggable — click and drag the dividers between panels to resize them.
Data & YAML
All campaign data lives in /src/data/ as YAML files. The tool loads them fresh each time you open or refresh the page. Changes you make between sessions (editing YAML directly) will appear on next load.
Runtime changes — fate points, stress, session events, tension level, aspect usage — are saved to localStorage and restored across refreshes.
Player Characters Panel
Each PC card shows:
- Name and high concept — in the card header
- Trouble — shown on hover (desktop) or tap-to-expand (touch)
- Aspects — shown on hover; click any aspect to instantly trigger a compel suggestion
- Fate points (FP) — 7 pips in the top-right of each card; click a pip to set the PC's current FP count
- Stress — PH (physical) and MN (mental) checkboxes; click to mark/unmark
- ⚡ Compel — generates a compel suggestion focused on this character
Aspect usage is tracked visually: invoked aspects are dimmed with a strikethrough; compelled aspects show in red. Click "✓ Mark as Compelled" in the AI response panel to record it.
Scene Panel
The scene panel (top of center column) shows the current scene from scene.yaml:
- Scene name — italic title
- Scene aspects — clickable tags; click any to trigger a compel suggestion on that aspect
- Stakes — what's at risk if the party fails
Scene aspects are fed into every AI request as context. Update scene.yaml between scenes to keep the tool in sync.
Action Bar
Six AI action buttons appear below the scene block:
| Button | What it does | Best used when… |
|---|---|---|
| 🎭 Generate Compel | Suggests 3 compels grounded in PC aspects, scene aspects, and recent events. Prefers unused aspects. | FP economy is low; you want to create drama for a specific character. |
| 💬 NPC Dialogue | Opens a modal to select an NPC and describe the situation. Returns 3 dialogue options (reveal / deflect / pressure). | A named NPC is in the scene and needs to speak. |
| 📝 Summarize Session | Generates a structured session summary (what happened, character moments, thread updates, open questions, setup for next session). | End of session, before updating session_log.yaml. |
| 🌀 Scene Twist | Returns 3 twist options: Complication, Escalation, Reveal. Each grounded in existing aspects. | The scene has plateaued; you want to inject energy without railroading. |
| 📋 Session Prep | Generates a full prep document for the next session: opening scene, NPC agendas, compel setups, thread beats, stall escalations. | Prepping between sessions. |
| 🧠 GM Brain | Open-ended Q&A. Type any question about the current situation and get a targeted answer grounded in your campaign context. | "What am I forgetting?" / "What's the most interesting move right now?" / "Which PC needs a spotlight?" |
"What are the most interesting unused compel setups given recent events?"
"Musashi and Barnabus are about to conflict — what's at stake for each?"
"The party is stuck. What's the most natural escalation given the creature thread?"
All AI responses appear in the AI Response Panel (below the action bar). Click ✕ to dismiss it. The panel is not cleared when you make a new request — the new response replaces the old one.
Dice Roller
Click 🎲 Roll Fate in the header to roll 4 Fate dice (4dF). Each die shows −, □, or +. The total is displayed with color coding: positive (green), zero (grey), negative (red).
After a roll, 📖 Interpret appears. Click it to open the roll interpreter modal — enter the skill used and a brief description of what the character was attempting. The AI returns a 2–3 sentence narrative outcome at the correct Fate Condensed outcome level.
The dice result auto-hides after 8 seconds.
Session Log
The session log tracks events in chronological order. Events are automatically classified by type (dice roll, NPC speech, compel, narrative) and displayed with colored left-border indicators.
Adding Events
Click + Add Event or use the Command Palette (Cmd+K → "Add Event") to open the event input. Type what happened and press Enter or click Add. Events are immediately saved to localStorage.
How Events Feed AI Context
The last 5 recent events are automatically sent to every AI endpoint as recent context. This means the AI's suggestions are grounded in what just happened at the table. More events = better compel suggestions and twists.
Clearing the Log
Click 🗑 Clear to wipe all localStorage events, aspect tracking, and tension level. YAML history events (from session_log.yaml) are always shown regardless — they are never deleted.
Intel Panel (Right Sidebar)
NPCs
Each NPC card shows the character's name, role, and first two aspects. Click 💬 Dialogue on an NPC card to open the dialogue modal pre-filled with that NPC.
Story Threads
Threads are loaded from session_log.yaml. Each thread shows its name, status dot, and last development. Click any thread to ask the AI for advice on advancing it — the response appears in the AI panel with current state, best next development, and a ready compel opportunity.
Thread status colors: orange = active, gold = seeded, grey = hidden.
Story Pulse Dashboard
The Story Pulse section (top of right panel) gives a live session health overview:
| Element | Description |
|---|---|
| Tension meter | 5 clickable pips (1–5). Color shifts from green → gold → ember → dark red → blood red. Use it to track scene intensity. Persisted across refreshes. |
| Fate Economy | Total FP in play across all PCs, plus count of aspects invoked and compelled this session. |
| Arcs | Count of active / seeded / hidden threads. |
| Open Questions | Seeded questions from the last session summary in session_log.yaml. |
Command Palette
Press Cmd + K (Mac) or Ctrl + K (Windows/Linux) to open the command palette. Type to filter, use arrow keys to navigate, Enter to execute, Esc to close.
Player View
Click Player View in the header to open player.html — a read-only screen designed for a second monitor or projector facing the players.
The player view shows:
- Current scene name, aspects, and stakes
- Each PC's name, high concept, trouble, and aspects
It does not show fate points, stress, GM notes, or any AI tools. It auto-refreshes every 30 seconds, or you can click the ↺ Refresh button manually.
player.html in a separate browser window and drag it to the second screen. The auto-refresh keeps it in sync as you update the scene between encounters.
YAML Data Files
All campaign data lives in src/data/. Edit these files directly in a text editor between sessions.
| File | Contents | Edit when… |
|---|---|---|
pcs.yaml |
Player characters: name, high_concept, trouble, aspects, skills, stress boxes, fate_points, notes | A consequence is taken; a character advances; aspects change. |
npcs.yaml |
NPCs: name, role, personality, disposition, current_goal, aspects | An NPC's attitude shifts; a new NPC enters the story. |
scene.yaml |
Current scene: name, aspects, stakes, active_threats, gm_notes | The party moves to a new scene. |
session_log.yaml |
Sessions history (summaries, key moments, open questions), current threads, current session number | After each session: paste in the AI summary, update threads, increment the session number. |
AI Providers
The GM tool supports multiple AI backends. Claude is the default; others act as automatic fallbacks if Claude fails. You can also override which provider is used for the current browser session.
Provider Selection Panel
Click the status indicator (the dot + text in the top-right of the header) to open the provider panel. It shows every supported provider with its current status:
| Status | Meaning |
|---|---|
| ● Green dot | Provider is configured — an API key or URL is set in the Cloudflare Worker. |
| ● Grey dot | Provider is not configured — no key set; it will be skipped. |
| ✓ Checkmark | This provider is currently active for the session. |
Default badge | This is the worker's default primary (set by LLM_PROVIDER in ai.js). |
Setting a Session Override
Click any configured provider in the panel to use it as primary for the current session. The status indicator will update to show the active provider (e.g. Ready · gemini). Click the same provider again, or click Reset to default, to go back to the worker default.
The override is saved to localStorage and persists across page refreshes within the same session. It is not permanent — clearing browser storage resets it.
Fallback Chain
Even without a manual override, the worker tries providers in order if one fails:
- Claude (primary by default)
- Gemini 1.5 Flash (free tier — get key from
aistudio.google.com) - GPT-4o Mini (paid — get key from
platform.openai.com) - Ollama (local — requires a public tunnel URL)
Providers without a configured key are silently skipped. The panel will only show providers as clickable if their key is set in the Worker.
Configuring Providers
API keys are stored as Cloudflare Worker secrets — never in any file. Run each command and paste the key when prompted:
| Provider | Command | Cost |
|---|---|---|
| Claude | wrangler secret put ANTHROPIC_API_KEY | < $0.01/session |
| Gemini | wrangler secret put GEMINI_API_KEY | Free tier |
| OpenAI | wrangler secret put OPENAI_API_KEY | < $0.01/session |
| Ollama | wrangler secret put OLLAMA_URL | Free (local) |
After adding a new key, redeploy the worker: wrangler deploy. The provider will then show as configured (green) in the panel.
Deployment
See README.md for full setup and deployment instructions. In brief:
- The frontend (
src/) is a static site — serve it from Cloudflare Pages, GitHub Pages, or any static host - The AI backend (
workers/ai.js) deploys as a Cloudflare Worker viawrangler deploy - Set
CONFIG.workerUrlinapp.jsto your deployed Worker URL - Store your
ANTHROPIC_API_KEYas a Wrangler secret:wrangler secret put ANTHROPIC_API_KEY - For local dev: run
wrangler dev(Worker onlocalhost:8787) and opensrc/index.htmldirectly in a browser