debug: add diagnostic logging to invention system

Every failure path was silent — LLM nulls, parse failures, validation
rejections, and promise errors were all swallowed. Adds per-attempt
logging at each gate plus a periodic summary of NPC/inventory/item state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-03-10 17:32:37 +00:00
parent 8e6a970ae4
commit 18f649d766

View File

@@ -26,6 +26,7 @@ export function createInventionSystem(
// Track in-flight requests to avoid duplicates
const pendingEntities = new Set<EntityId>();
const pendingItemIds = new Set<string>();
let lastDiagTick = 0;
return {
update(world: World, tick: number): void {
@@ -39,6 +40,18 @@ export function createInventionSystem(
const npcs = world.query('npcBrain');
// Periodic diagnostic summary (every 1000 ticks ≈ 10 invention checks)
if (tick - lastDiagTick >= 1000) {
lastDiagTick = tick;
let withInventory = 0;
let emptyInventory = 0;
for (const eid of npcs) {
const i = world.getComponent<Map<string, number>>(eid, 'inventory');
if (i && i.size > 0) withInventory++; else emptyInventory++;
}
console.log(`[Invention] tick=${tick} npcs=${npcs.length} withItems=${withInventory} emptyInv=${emptyInventory} pending=${pendingEntities.size} knownItems=${itemRegistry.getAll().length}`);
}
for (const entityId of npcs) {
if (pendingEntities.has(entityId)) continue;
@@ -85,6 +98,7 @@ export function createInventionSystem(
: '';
pendingEntities.add(entityId);
console.log(`[Invention] eureka! npc=${name} (${entityId}) INT=${intelligence} CUR=${curiosity} chance=${(chance * 100).toFixed(2)}% items=${inv.size}`);
llmService.generate('invention', {
npcName: name,
@@ -104,14 +118,28 @@ export function createInventionSystem(
}).then(response => {
pendingEntities.delete(entityId);
if (!response) {
console.log(`[Invention] LLM returned null for npc=${name} (${entityId})`);
return;
}
const parsed = parseInventionResponse(response);
if (!parsed) return;
if (!parsed) {
console.log(`[Invention] parse failed for npc=${name} (${entityId}), response=${response.substring(0, 200)}`);
return;
}
const validation = validateInvention(parsed, itemRegistry);
if (!validation.valid) return;
if (!validation.valid) {
console.log(`[Invention] validation failed for npc=${name} (${entityId}): ${validation.error} (suggested: "${parsed.name}" cat=${parsed.category} inputs=${JSON.stringify(parsed.inputs)})`);
return;
}
// Race guard: check if another NPC already claimed this itemId
if (pendingItemIds.has(validation.itemId!)) return;
if (pendingItemIds.has(validation.itemId!)) {
console.log(`[Invention] race guard blocked "${parsed.name}" for npc=${name} (${entityId}), itemId=${validation.itemId} already pending`);
return;
}
pendingItemIds.add(validation.itemId!);
// Compute current day
@@ -120,6 +148,8 @@ export function createInventionSystem(
const cycleTicks = Math.round(dayTicks + nightTicks);
const day = Math.floor(tick / cycleTicks) + 1;
console.log(`[Invention] SUCCESS npc=${name} (${entityId}) invented "${parsed.name}" (${validation.itemId}) cat=${parsed.category}`);
registerInvention({
raw: parsed,
itemId: validation.itemId!,
@@ -165,7 +195,8 @@ export function createInventionSystem(
});
pendingItemIds.delete(validation.itemId!);
}).catch(() => {
}).catch((err) => {
console.log(`[Invention] LLM error for npc=${name} (${entityId}): ${err?.message ?? err}`);
pendingEntities.delete(entityId);
});
}