diff --git a/server/src/llm/backstoryGenerator.ts b/server/src/llm/backstoryGenerator.ts new file mode 100644 index 0000000..5897f40 --- /dev/null +++ b/server/src/llm/backstoryGenerator.ts @@ -0,0 +1,38 @@ +import type { Stats } from '@dflike/shared'; +import type { World } from '../ecs/World.js'; +import type { LlmService } from './llmService.js'; + +const STAT_KEYS: (keyof Stats)[] = [ + 'strength', 'dexterity', 'constitution', 'intelligence', 'perception', + 'sociability', 'courage', 'curiosity', 'empathy', 'temperament', +]; + +const STAT_ABBREVS: Record = { + strength: 'STR', dexterity: 'DEX', constitution: 'CON', + intelligence: 'INT', perception: 'PER', + sociability: 'SOC', courage: 'COU', curiosity: 'CUR', + empathy: 'EMP', temperament: 'TMP', +}; + +export function formatStatsForPrompt(stats: Stats): string { + return STAT_KEYS.map(k => `${STAT_ABBREVS[k]}:${Math.floor(stats[k])}`).join(', '); +} + +export async function generateBackstory( + world: World, + entityId: number, + llmService: LlmService, +): Promise { + const name = world.getComponent(entityId, 'name'); + const stats = world.getComponent(entityId, 'stats'); + if (!name || !stats) return; + + const result = await llmService.generate('backstory', { + npcName: name, + stats: formatStatsForPrompt(stats), + }); + + if (result) { + world.addComponent(entityId, 'backstory', result); + } +} diff --git a/server/src/systems/narrationEmitter.ts b/server/src/systems/narrationEmitter.ts index 11a5c54..8904f3e 100644 --- a/server/src/systems/narrationEmitter.ts +++ b/server/src/systems/narrationEmitter.ts @@ -3,19 +3,9 @@ import type { } from '@dflike/shared'; import type { World } from '../ecs/World.js'; import type { NarrationService } from '../llm/narrationService.js'; +import { formatStatsForPrompt } from '../llm/backstoryGenerator.js'; import { classify } from './relationshipHelpers.js'; -function formatStatsForPrompt(stats: Stats): string { - const personality = [ - `sociability:${stats.sociability}`, - `courage:${stats.courage}`, - `curiosity:${stats.curiosity}`, - `empathy:${stats.empathy}`, - `temperament:${stats.temperament}`, - ]; - return personality.join(', '); -} - export function narrationEmitter( world: World, narrationService: NarrationService,