feat: session auto-capture + NPC→Initiative push + lore grounding everywhere
- SessionLogger listens for a new LogEntry bus event; dice rolls, initiative turns/rounds, generated encounters and calendar day advances land in the active session as timestamped entries — the raw material the AI summary actually needs. Mute toggle in the toolbar (persisted, default on). - NPC Generator: '⚔ to initiative' button pushes the generated stat block (HP) into the tracker via the existing AddCombatants bus event. - ragQuery now set on Encounter, Quest and Session summary too (NPC/Item/World already had it) — every generator is world-grounded.
This commit is contained in:
@@ -205,6 +205,7 @@ IMPORTANT: Return ONLY a raw JSON object. NO markdown fences, NO code blocks, NO
|
||||
system: "You are a D&D encounter designer. You MUST respond with ONLY valid JSON. No markdown fences, no code blocks, no explanation. Just the JSON object.",
|
||||
temperature: 0.9,
|
||||
max_tokens: 400,
|
||||
ragQuery: `${terrain} monsters encounter`,
|
||||
},
|
||||
});
|
||||
const parsed = parseLlmJson<Encounter>(result);
|
||||
@@ -219,6 +220,11 @@ IMPORTANT: Return ONLY a raw JSON object. NO markdown fences, NO code blocks, NO
|
||||
`Encounter: ${parsed.difficulty || "?"} in ${terrain}`,
|
||||
`Encounter (party of ${partySize} level-${partyLevel}) in ${terrain}. ${monsters}\nTerrain: ${flattenValue(parsed.terrain)}\nDifficulty: ${flattenValue(parsed.difficulty)}\nLoot: ${flattenValue(parsed.loot)}`,
|
||||
);
|
||||
// ponytail: the fight starts — tell the session log.
|
||||
bus.emit(Events.LogEntry, {
|
||||
text: `⚔ Encounter: ${title} (${flattenValue(parsed.difficulty) || "?"}) — ${monsters}`,
|
||||
tag: "#combat",
|
||||
});
|
||||
} else {
|
||||
addToast("LLM returned an unparseable response", "error");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user