Files
Dungeons-Ground/apps/web/composables/useDemo.ts
pavel444-byte 9dd856ff8c
Some checks failed
CI / validate (push) Successful in 1h3m54s
CI / validate (pull_request) Failing after 14m14s
fix(gameplay): use AI-generated world companions
Co-authored-by: multica-agent <github@multica.ai>
2026-08-21 20:38:12 +05:00

51 lines
5.5 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { Character, WorldStarter } from '@dng/shared'
const defaultWorld: WorldStarter = {
title: 'Signal at Black Meridian',
genre: 'Solar gothic science fiction',
tone: 'Tense, mysterious, hopeful under pressure',
premise: 'At the edge of charted space, a dead relay begins broadcasting tomorrows distress calls. The crew of the courier Orison is the only ship close enough to answer.',
contentBoundaries: ['13+ adventure', 'No explicit sexual content', 'No graphic gore'],
startingLocation: { id: 'loc_meridian', kind: 'location', name: 'Black Meridian Relay', summary: 'A lightless communications cathedral orbiting a cold blue star.', tags: ['station', 'derelict'], secrets: ['The distress calls are being sent by the crew themselves, three days in the future.'] },
npcs: [
{ id: 'npc_lyra', kind: 'npc', name: 'Lyra Venn', summary: 'A calm signal analyst who hears patterns as music.', tags: ['analyst'], secrets: ['She recognizes the voice in the transmission.'] },
{ id: 'npc_cassian', kind: 'npc', name: 'Cassian Holt', summary: 'A company marshal with a sealed retrieval order.', tags: ['marshal'], secrets: ['His orders prioritize the relay core over the crew.'] },
{ id: 'npc_moth', kind: 'npc', name: 'Moth', summary: 'A maintenance intelligence speaking through antique service drones.', tags: ['ai'], secrets: ['Moth has been awake for eighty-seven years.'] },
],
factions: [
{ id: 'fac_heliograph', kind: 'faction', name: 'Heliograph Compact', summary: 'A mercantile coalition that owns the relay network.', tags: ['corporate'], secrets: [] },
{ id: 'fac_quiet', kind: 'faction', name: 'The Quiet Choir', summary: 'Pilgrims who believe signals can remember the dead.', tags: ['mystic'], secrets: [] },
],
companions: [
{ name: 'Rook-7', concept: 'A security intelligence in a weathered rescue frame.', abilities: { str: 16, dex: 11, con: 15, int: 10, wis: 12, cha: 8 }, hp: 15, maxHp: 15, defense: 15, proficiency: 2, inventory: ['Arc baton', 'Emergency beacon'], persona: { voice: 'Direct and protective.', motivation: 'Keep the crew alive long enough to learn the truth.', flaw: 'Treats uncertainty as a threat.', bond: 'The Orison crew gave Rook a second purpose.' } },
{ name: 'Sable Thread', concept: 'A probabilistic navigator who reads possible futures as tangled routes.', abilities: { str: 8, dex: 14, con: 10, int: 16, wis: 13, cha: 11 }, hp: 10, maxHp: 10, defense: 13, proficiency: 2, inventory: ['Route prism', 'Vacuum line'], persona: { voice: 'Careful, elliptical, and precise.', motivation: 'Find the future in which everyone returns.', flaw: 'Can hesitate when too many paths look viable.', bond: 'Trusts the party to choose what prediction cannot.' } },
{ name: 'Morrow Coil', concept: 'A former relay technician rebuilt around experimental signal hardware.', abilities: { str: 11, dex: 12, con: 13, int: 14, wis: 10, cha: 13 }, hp: 12, maxHp: 12, defense: 12, proficiency: 2, inventory: ['Signal probe', 'Insulated field coat'], persona: { voice: 'Warm humor under technical jargon.', motivation: 'Prove the relay can be understood instead of destroyed.', flaw: 'Cannot leave a broken machine alone.', bond: 'Believes this party is the last honest crew in the sector.' } },
],
hook: 'Dock with the silent relay, locate the source of the impossible distress call, and decide whether its warning should be believed.',
hiddenThreat: 'A causality fracture is teaching the relay to choose which future becomes real.',
openingScene: 'The Orison drifts beneath the relays vast black vanes. Every console shows the same countdown: 00:17:42. Then your own voice breaks through the static: “Do not open the central archive.”',
}
const defaultCharacters: Character[] = [
{ id: 'char_mara', name: 'Mara Vale', concept: 'Human salvage pilot with an instinct for impossible routes', controller: 'human', userId: 'demo', abilities: { str: 10, dex: 16, con: 13, int: 12, wis: 14, cha: 11 }, hp: 11, maxHp: 11, defense: 14, proficiency: 2, inventory: ['Pulse cutter', 'Vacuum cloak'], statuses: [] },
{ id: 'char_rook', name: 'Rook-7', concept: 'AI companion inhabiting a weathered security frame', controller: 'ai', userId: null, abilities: { str: 16, dex: 11, con: 15, int: 10, wis: 12, cha: 8 }, hp: 15, maxHp: 15, defense: 15, proficiency: 2, inventory: ['Arc baton', 'Emergency beacon'], statuses: [] },
]
export function useDemo() {
const signedIn = useState('signed-in', () => false)
const worlds = useState<WorldStarter[]>('worlds', () => [defaultWorld])
const activeWorld = useState<WorldStarter>('active-world', () => defaultWorld)
const characters = useState<Character[]>('characters', () => defaultCharacters)
const roundNumber = useState('round-number', () => 3)
const scene = useState('scene', () => defaultWorld.openingScene)
const history = useState<Array<{ type: 'narration' | 'action' | 'roll'; author: string; body: string; meta?: string }>>('history', () => [
{ type: 'narration', author: 'GROUNDKEEPER', body: defaultWorld.openingScene, meta: 'ROUND 03 · NOW' },
{ type: 'action', author: 'MARA VALE', body: 'I ask the Orison to isolate the transmission and compare the voiceprint to mine.', meta: 'READY' },
{ type: 'roll', author: 'SYSTEM CHECK', body: 'Intelligence check · 1d20 + 3 = 17', meta: 'SUCCESS · DC 14' },
])
const currentAction = useState('current-action', () => '')
const ready = useState('ready', () => false)
return { signedIn, worlds, activeWorld, characters, roundNumber, scene, history, currentAction, ready }
}