fix(gameplay): use universe-generated AI companions
Some checks failed
CI / validate (pull_request) Waiting to run
CI / validate (push) Failing after 34m2s

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
2026-08-22 14:50:14 +05:00
parent 56bddafbe8
commit f6c0fbcfeb
12 changed files with 632 additions and 124 deletions

View File

@@ -112,6 +112,17 @@ const world = {
entity('faction', 'The Reclaimers', 'Salvagers who want the station stripped for parts.'),
entity('faction', 'The Seed Vault', 'An automated network protecting the last viable specimens.'),
],
companions: [1, 2, 3].map(index => ({
name: `Garden Companion ${index}`,
concept: `A universe-specific caretaker hero assigned to garden sector ${index}.`,
abilities: { str: 10, dex: 12, con: 11, int: 13, wis: 12, cha: 10 },
hp: 11,
maxHp: 11,
defense: 12,
proficiency: 2,
inventory: ['Garden survey kit'],
persona: { voice: 'Calm and observant.', motivation: 'Protect the living garden.', flaw: 'Trusts the station too much.', bond: 'Treats the party as new growth.' },
})),
hook: 'The airlock opens only after both visitors speak names the station already knows.',
hiddenThreat: 'The garden predicts visitors by growing imperfect biological copies of them.',
openingScene: 'The inner airlock opens on warm rain and rows of silver trees. A voice welcomes both salvagers by name, then asks why one of them has returned without the other.',
@@ -125,9 +136,9 @@ const { campaignId } = await appRequest('/api/v1/campaigns', owner.token, {
})
const starterParty = await appRequest(`/api/v1/campaigns/${campaignId}`, owner.token)
const ownerCharacter = starterParty.characters.find(character => character.user_id === owner.id && character.controller === 'human')
const automaticCompanion = starterParty.characters.find(character => character.controller === 'ai')
if (!ownerCharacter || !automaticCompanion || starterParty.round?.status !== 'open') {
throw new Error('[smoke] A new campaign did not start with an actionable owner hero, an AI companion, and an open round.')
const automaticCompanions = starterParty.characters.filter(character => character.controller === 'ai')
if (!ownerCharacter || automaticCompanions.length !== world.companions.length || automaticCompanions.some(character => character.name === 'Echo') || starterParty.round?.status !== 'open') {
throw new Error('[smoke] A new campaign did not start with its actionable owner hero, generated world companions, and an open round.')
}
console.log('[smoke] Joining the second player through an invite…')
@@ -158,7 +169,7 @@ if (!suggested?.character?.name || !suggested.character?.persona?.motivation) {
const initial = await appRequest(`/api/v1/campaigns/${campaignId}`, owner.token)
if (initial.members.length !== 2) throw new Error(`[smoke] Expected 2 members, received ${initial.members.length}.`)
if (initial.characters.length !== 3 || initial.round?.status !== 'open') throw new Error('[smoke] Multiplayer lobby did not expose two humans, one AI companion, and an open round.')
if (initial.characters.length !== 5 || initial.round?.status !== 'open') throw new Error('[smoke] Multiplayer lobby did not expose two humans, three generated AI companions, and an open round.')
const roundId = initial.round.id
console.log('[smoke] Verifying that the round waits for both humans…')