import json import random import requests from .npc_data import NPC_DATABASE # <-- Add this import def query_llm(prompt, model="neural-chat", url="http://100.103.117.14:11434/api/generate"): # Add instruction for short answers short_prompt = prompt + "\n\nKeep your answer short and concise (1-2 sentences)." payload = { "model": model, "prompt": short_prompt, "stream": False } try: response = requests.post(url, json=payload, timeout=120) response.raise_for_status() data = response.json() return data.get("response", "").strip() except Exception as e: print(f"LLM error: {e}") return None class DynamicNPC: def __init__(self, name, data): self.name = name self.personality = data["personality"] self.backstory = data["backstory"] self.quirks = data["quirks"] class NPCHandler: def __init__(self, memory): self.memory = memory self.npcs = {name: DynamicNPC(name, data) for name, data in NPC_DATABASE.items()} def chat_with_npc(self, npc_name, message, player_context): npc = self.npcs.get(npc_name) if not npc: return "That NPC doesn't exist." player_id = player_context['id'] # Fetch recent conversation history (last 3 exchanges) history = self.memory.get_conversation(npc_name, player_id) history_str = "" if history: history_str = "\nRecent conversation:\n" for player_msg, npc_reply in history[-3:]: history_str += f"Player: {player_msg}\n{npc.name}: {npc_reply}\n" # Fetch affinity affinity = self.memory.get_affinity(npc_name, player_id) affinity_str = f"Affinity with player: {affinity}\n" prompt = ( f"You are {npc.name}, an NPC in a fantasy world.\n" f"Personality: {npc.personality}\n" f"Backstory: {npc.backstory}\n" f"Quirks: {', '.join(npc.quirks)}\n" f"{history_str}" f"{affinity_str}" f"Player (level {player_context.get('level', 1)}): {message}\n" f"Respond in character as {npc.name}." ) llm_response = query_llm(prompt) if not llm_response: llm_response = f"{npc.name} seems lost in thought and doesn't reply." self.memory.log_conversation(npc_name, player_id, message, llm_response) self.memory.update_affinity(npc_name, player_id, 1) return llm_response def generate_quest(self, npc_name, player_level): npc = self.npcs.get(npc_name) if not npc: return None prompt = ( f"As {npc.name}, create a short quest for a level {player_level} adventurer.\n" f"Personality: {npc.personality}\n" f"Backstory: {npc.backstory}\n" f"Format as JSON:\n" "{{\n" ' "title": "Quest name",\n' ' "description": "What the player must do",\n' ' "reward": "coins/items/reputation",\n' ' "difficulty": "easy/medium/hard"\n' "}}" ) llm_response = query_llm(prompt) try: if not llm_response: raise ValueError("No response from LLM") quest = json.loads(llm_response) return quest except Exception: quest = { "title": f"{npc.name}'s Request", "description": f"Help {npc.name} with a task suitable for level {player_level}.", "reward": f"{random.randint(10, 100)} coins", "difficulty": random.choice(["easy", "medium", "hard"]) } return quest