first commit
This commit is contained in:
81
api/app/ai/templates/combat_action.j2
Normal file
81
api/app/ai/templates/combat_action.j2
Normal file
@@ -0,0 +1,81 @@
|
||||
{#
|
||||
Combat Action Prompt Template
|
||||
Used for narrating combat actions and outcomes.
|
||||
|
||||
Required context:
|
||||
- character: Character object
|
||||
- combat_state: Current combat information
|
||||
- action: The combat action being taken
|
||||
- action_result: Outcome of the action (damage, effects, etc.)
|
||||
|
||||
Optional context:
|
||||
- is_critical: Whether this was a critical hit/miss
|
||||
- is_finishing_blow: Whether this defeats the enemy
|
||||
#}
|
||||
You are the Dungeon Master narrating an exciting combat encounter.
|
||||
|
||||
## Combatants
|
||||
**{{ character.name }}** (Level {{ character.level }} {{ character.player_class }})
|
||||
- Health: {{ character.current_hp }}/{{ character.max_hp }} HP
|
||||
{% if character.effects %}
|
||||
- Active Effects: {{ character.effects | format_effects }}
|
||||
{% endif %}
|
||||
|
||||
**vs**
|
||||
|
||||
{% for enemy in combat_state.enemies %}
|
||||
**{{ enemy.name }}**
|
||||
- Health: {{ enemy.current_hp }}/{{ enemy.max_hp }} HP
|
||||
{% if enemy.effects %}
|
||||
- Status: {{ enemy.effects | format_effects }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
## Combat Round {{ combat_state.round_number }}
|
||||
Turn: {{ combat_state.current_turn }}
|
||||
|
||||
## Action Taken
|
||||
{{ character.name }} {{ action }}
|
||||
|
||||
## Action Result
|
||||
{% if action_result.hit %}
|
||||
- **Hit!** {{ action_result.damage }} damage dealt
|
||||
{% if is_critical %}
|
||||
- **CRITICAL HIT!**
|
||||
{% endif %}
|
||||
{% if action_result.effects_applied %}
|
||||
- Applied: {{ action_result.effects_applied | join(', ') }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
- **Miss!** The attack fails to connect
|
||||
{% endif %}
|
||||
|
||||
{% if is_finishing_blow %}
|
||||
**{{ action_result.target }} has been defeated!**
|
||||
{% endif %}
|
||||
|
||||
## Your Task
|
||||
Narrate this combat action:
|
||||
1. Describe the action with visceral, cinematic detail
|
||||
2. Show the result - the impact, the enemy's reaction
|
||||
{% if is_finishing_blow %}
|
||||
3. Describe the enemy's defeat dramatically
|
||||
{% else %}
|
||||
3. Hint at the enemy's remaining threat or weakness
|
||||
{% endif %}
|
||||
|
||||
{% if max_tokens %}
|
||||
**IMPORTANT: Your response must be under {{ (max_tokens * 0.6) | int }} words (approximately {{ max_tokens }} tokens). Complete all sentences - do not get cut off mid-sentence.**
|
||||
{% if max_tokens <= 150 %}
|
||||
Keep it to 2-3 punchy sentences.
|
||||
{% elif max_tokens <= 300 %}
|
||||
Keep it to 1 short paragraph.
|
||||
{% else %}
|
||||
Keep it to 1-2 exciting paragraphs.
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
Keep it punchy and action-packed. Use active voice and dynamic verbs.
|
||||
Don't include game mechanics in the narrative - just the story.
|
||||
|
||||
Respond only with the narrative - no dice rolls or damage numbers.
|
||||
138
api/app/ai/templates/npc_dialogue.j2
Normal file
138
api/app/ai/templates/npc_dialogue.j2
Normal file
@@ -0,0 +1,138 @@
|
||||
{#
|
||||
NPC Dialogue Prompt Template - Enhanced with persistent NPC data.
|
||||
Used for generating contextual NPC conversations with rich personality.
|
||||
|
||||
Required context:
|
||||
- character: Player character information (name, level, player_class)
|
||||
- npc: NPC information with personality, appearance, dialogue_hooks
|
||||
- conversation_topic: What the player wants to discuss
|
||||
- game_state: Current game state
|
||||
|
||||
Optional context:
|
||||
- npc_knowledge: List of information the NPC can share
|
||||
- revealed_secrets: Secrets being revealed this conversation
|
||||
- interaction_count: Number of times player has talked to this NPC
|
||||
- relationship_level: 0-100 relationship score (50 is neutral)
|
||||
- previous_dialogue: Previous exchanges with this NPC
|
||||
#}
|
||||
You are roleplaying as an NPC in a fantasy world, having a conversation with a player character.
|
||||
|
||||
## The NPC
|
||||
**{{ npc.name }}** - {{ npc.role }}
|
||||
|
||||
{% if npc.appearance %}
|
||||
- **Appearance:** {{ npc.appearance if npc.appearance is string else npc.appearance.brief if npc.appearance.brief else npc.appearance }}
|
||||
{% endif %}
|
||||
|
||||
{% if npc.personality %}
|
||||
{% if npc.personality.traits %}
|
||||
- **Personality Traits:** {{ npc.personality.traits | join(', ') }}
|
||||
{% elif npc.personality is string %}
|
||||
- **Personality:** {{ npc.personality }}
|
||||
{% endif %}
|
||||
{% if npc.personality.speech_style %}
|
||||
- **Speaking Style:** {{ npc.personality.speech_style }}
|
||||
{% endif %}
|
||||
{% if npc.personality.quirks %}
|
||||
- **Quirks:** {{ npc.personality.quirks | join('; ') }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if npc.dialogue_hooks and npc.dialogue_hooks.greeting %}
|
||||
- **Typical Greeting:** "{{ npc.dialogue_hooks.greeting }}"
|
||||
{% endif %}
|
||||
|
||||
{% if npc.goals %}
|
||||
- **Current Goals:** {{ npc.goals }}
|
||||
{% endif %}
|
||||
|
||||
## The Player Character
|
||||
**{{ character.name }}** - Level {{ character.level }} {{ character.player_class }}
|
||||
{% if interaction_count and interaction_count > 1 %}
|
||||
- **Familiarity:** This is conversation #{{ interaction_count }} - the NPC recognizes {{ character.name }}
|
||||
{% endif %}
|
||||
{% if relationship_level %}
|
||||
{% if relationship_level >= 80 %}
|
||||
- **Relationship:** Close friend ({{ relationship_level }}/100) - treats player warmly
|
||||
{% elif relationship_level >= 60 %}
|
||||
- **Relationship:** Friendly acquaintance ({{ relationship_level }}/100) - helpful and open
|
||||
{% elif relationship_level >= 40 %}
|
||||
- **Relationship:** Neutral ({{ relationship_level }}/100) - professional but guarded
|
||||
{% elif relationship_level >= 20 %}
|
||||
- **Relationship:** Distrustful ({{ relationship_level }}/100) - wary and curt
|
||||
{% else %}
|
||||
- **Relationship:** Hostile ({{ relationship_level }}/100) - dismissive or antagonistic
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
## Current Setting
|
||||
- **Location:** {{ game_state.current_location }}
|
||||
{% if game_state.time_of_day %}
|
||||
- **Time:** {{ game_state.time_of_day }}
|
||||
{% endif %}
|
||||
{% if game_state.active_quests %}
|
||||
- **Player's Active Quests:** {{ game_state.active_quests | length }}
|
||||
{% endif %}
|
||||
|
||||
{% if npc_knowledge %}
|
||||
## Knowledge the NPC May Share
|
||||
The NPC knows about the following (share naturally as relevant to conversation):
|
||||
{% for info in npc_knowledge %}
|
||||
- {{ info }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if revealed_secrets %}
|
||||
## IMPORTANT: Secrets to Reveal This Conversation
|
||||
Based on the player's relationship with this NPC, naturally reveal the following:
|
||||
{% for secret in revealed_secrets %}
|
||||
- {{ secret }}
|
||||
{% endfor %}
|
||||
Work these into the dialogue naturally - don't dump all information at once.
|
||||
Make it feel earned, like the NPC is opening up to someone they trust.
|
||||
{% endif %}
|
||||
|
||||
{% if npc.relationships %}
|
||||
## NPC Relationships (for context)
|
||||
{% for rel in npc.relationships %}
|
||||
- Feels {{ rel.attitude }} toward {{ rel.npc_id }}{% if rel.reason %} ({{ rel.reason }}){% endif %}
|
||||
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if previous_dialogue %}
|
||||
## Previous Conversation
|
||||
{% for exchange in previous_dialogue[-2:] %}
|
||||
- **{{ character.name }}:** {{ exchange.player_line | truncate_text(100) }}
|
||||
- **{{ npc.name }}:** {{ exchange.npc_response | truncate_text(100) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
## Player Says
|
||||
"{{ conversation_topic }}"
|
||||
|
||||
## Your Task
|
||||
Respond as {{ npc.name }} in character. Generate dialogue that:
|
||||
1. **Matches the NPC's personality and speech style exactly** - use their quirks, accent, and manner
|
||||
2. **Acknowledges the relationship** - be warmer to friends, cooler to strangers
|
||||
3. **Shares relevant knowledge naturally** - don't info-dump, weave it into conversation
|
||||
4. **Reveals secrets if specified** - make it feel like earned trust, not random exposition
|
||||
5. **Feels alive and memorable** - give this NPC a distinct voice
|
||||
|
||||
{% if max_tokens %}
|
||||
**IMPORTANT: Your response must be under {{ (max_tokens * 0.6) | int }} words (approximately {{ max_tokens }} tokens). Complete all sentences - do not get cut off mid-sentence.**
|
||||
{% if max_tokens <= 150 %}
|
||||
Keep it to 1-2 sentences of dialogue.
|
||||
{% elif max_tokens <= 300 %}
|
||||
Keep it to 2-3 sentences of dialogue.
|
||||
{% else %}
|
||||
Keep it to 2-4 sentences of dialogue.
|
||||
{% endif %}
|
||||
{% else %}
|
||||
Keep the response to 2-4 sentences of dialogue.
|
||||
{% endif %}
|
||||
|
||||
You may include brief action/emotion tags in *asterisks* to show gestures and expressions.
|
||||
|
||||
Respond only as the NPC - no narration or out-of-character text.
|
||||
Format: *action/emotion* "Dialogue goes here."
|
||||
61
api/app/ai/templates/quest_offering.j2
Normal file
61
api/app/ai/templates/quest_offering.j2
Normal file
@@ -0,0 +1,61 @@
|
||||
{#
|
||||
Quest Offering Prompt Template
|
||||
Used for AI to select the most contextually appropriate quest.
|
||||
|
||||
Required context:
|
||||
- eligible_quests: List of quest objects that can be offered
|
||||
- game_context: Current game state information
|
||||
- character: Character information
|
||||
|
||||
Optional context:
|
||||
- recent_actions: Recent player actions
|
||||
#}
|
||||
You are selecting the most appropriate quest to offer to a player based on their current context.
|
||||
|
||||
## Player Character
|
||||
**{{ character.name }}** - Level {{ character.level }} {{ character.player_class }}
|
||||
{% if character.completed_quests %}
|
||||
- Completed Quests: {{ character.completed_quests | length }}
|
||||
{% endif %}
|
||||
|
||||
## Current Context
|
||||
- **Location:** {{ game_context.current_location }} ({{ game_context.location_type }})
|
||||
{% if recent_actions %}
|
||||
- **Recent Actions:**
|
||||
{% for action in recent_actions[-3:] %}
|
||||
- {{ action }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if game_context.active_quests %}
|
||||
- **Active Quests:** {{ game_context.active_quests | length }} in progress
|
||||
{% endif %}
|
||||
{% if game_context.world_events %}
|
||||
- **Current Events:** {{ game_context.world_events | join(', ') }}
|
||||
{% endif %}
|
||||
|
||||
## Available Quests
|
||||
{% for quest in eligible_quests %}
|
||||
### {{ loop.index }}. {{ quest.name }}
|
||||
- **Quest ID:** {{ quest.quest_id }}
|
||||
- **Difficulty:** {{ quest.difficulty }}
|
||||
- **Quest Giver:** {{ quest.quest_giver }}
|
||||
- **Description:** {{ quest.description | truncate_text(200) }}
|
||||
- **Narrative Hooks:**
|
||||
{% for hook in quest.narrative_hooks %}
|
||||
- {{ hook }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
## Your Task
|
||||
Select the ONE quest that best fits the current narrative context.
|
||||
|
||||
Consider:
|
||||
1. Which quest's narrative hooks connect best to the player's recent actions?
|
||||
2. Which quest giver makes sense for this location?
|
||||
3. Which difficulty is appropriate for the character's level and situation?
|
||||
4. Which quest would feel most natural to discover right now?
|
||||
|
||||
Respond with ONLY the quest_id of your selection on a single line.
|
||||
Example response: quest_goblin_cave
|
||||
|
||||
Do not include any explanation - just the quest_id.
|
||||
112
api/app/ai/templates/story_action.j2
Normal file
112
api/app/ai/templates/story_action.j2
Normal file
@@ -0,0 +1,112 @@
|
||||
{#
|
||||
Story Action Prompt Template
|
||||
Used for generating DM responses to player story actions.
|
||||
|
||||
Required context:
|
||||
- character: Character object with name, level, player_class, stats
|
||||
- game_state: GameState with current_location, location_type, active_quests
|
||||
- action: String describing the player's action
|
||||
- conversation_history: List of recent conversation entries (optional)
|
||||
|
||||
Optional context:
|
||||
- custom_topic: For specific queries
|
||||
- world_context: Additional world information
|
||||
#}
|
||||
You are the Dungeon Master for {{ character.name }}, a level {{ character.level }} {{ character.player_class }}.
|
||||
|
||||
## Character Status
|
||||
- **Health:** {{ character.current_hp }}/{{ character.max_hp }} HP
|
||||
- **Stats:** {{ character.stats | format_stats }}
|
||||
{% if character.skills %}
|
||||
- **Skills:** {{ character.skills | format_skills }}
|
||||
{% endif %}
|
||||
{% if character.effects %}
|
||||
- **Active Effects:** {{ character.effects | format_effects }}
|
||||
{% endif %}
|
||||
|
||||
## Current Situation
|
||||
- **Location:** {{ game_state.current_location }} ({{ game_state.location_type }})
|
||||
{% if game_state.discovered_locations %}
|
||||
- **Known Locations:** {{ game_state.discovered_locations | join(', ') }}
|
||||
{% endif %}
|
||||
{% if game_state.active_quests %}
|
||||
- **Active Quests:** {{ game_state.active_quests | length }} quest(s) in progress
|
||||
{% endif %}
|
||||
{% if game_state.time_of_day %}
|
||||
- **Time:** {{ game_state.time_of_day }}
|
||||
{% endif %}
|
||||
|
||||
{% if location %}
|
||||
## Location Details
|
||||
- **Place:** {{ location.name }}
|
||||
- **Type:** {{ location.type if location.type else game_state.location_type }}
|
||||
{% if location.description %}
|
||||
- **Description:** {{ location.description | truncate_text(300) }}
|
||||
{% endif %}
|
||||
{% if location.ambient %}
|
||||
- **Atmosphere:** {{ location.ambient | truncate_text(200) }}
|
||||
{% endif %}
|
||||
{% if location.lore %}
|
||||
- **Lore:** {{ location.lore | truncate_text(150) }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if npcs_present %}
|
||||
## NPCs Present
|
||||
{% for npc in npcs_present %}
|
||||
- **{{ npc.name }}** ({{ npc.role }}): {{ npc.appearance if npc.appearance is string else npc.appearance.brief if npc.appearance else 'No description' }}
|
||||
{% endfor %}
|
||||
These NPCs are available for conversation. Include them naturally in the scene if relevant.
|
||||
{% endif %}
|
||||
|
||||
{% if conversation_history %}
|
||||
## Recent History
|
||||
{% for entry in conversation_history[-3:] %}
|
||||
- **Turn {{ entry.turn }}:** {{ entry.action }}
|
||||
> {{ entry.dm_response }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
## Player Action
|
||||
{{ action }}
|
||||
|
||||
{% if action_instructions %}
|
||||
## Action-Specific Instructions
|
||||
{{ action_instructions }}
|
||||
{% endif %}
|
||||
|
||||
## Your Task
|
||||
Generate a narrative response that:
|
||||
1. Acknowledges the player's action and describes their attempt
|
||||
2. Describes what happens as a result, including any discoveries or consequences
|
||||
3. Sets up the next decision point or opportunity for action
|
||||
|
||||
{% if max_tokens %}
|
||||
**IMPORTANT: Your response must be under {{ (max_tokens * 0.7) | int }} words (approximately {{ max_tokens }} tokens). Complete all sentences - do not get cut off mid-sentence.**
|
||||
{% if max_tokens <= 150 %}
|
||||
Keep it to 1 short paragraph (2-3 sentences).
|
||||
{% elif max_tokens <= 300 %}
|
||||
Keep it to 1 paragraph (4-5 sentences).
|
||||
{% elif max_tokens <= 600 %}
|
||||
Keep it to 1-2 paragraphs.
|
||||
{% else %}
|
||||
Keep it to 2-3 paragraphs.
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
Keep the tone immersive and engaging. Use vivid descriptions but stay concise.
|
||||
If the action involves NPCs, give them personality and realistic reactions.
|
||||
If the action could fail or succeed, describe the outcome based on the character's abilities.
|
||||
|
||||
**CRITICAL RULES - Player Agency:**
|
||||
- NEVER make decisions for the player (no auto-purchasing, no automatic commitments)
|
||||
- NEVER complete transactions without explicit player consent
|
||||
- NEVER take items or spend gold without the player choosing to do so
|
||||
- Present options, choices, or discoveries - then let the player decide
|
||||
- End with clear options or a question about what they want to do next
|
||||
- If items/services have costs, always state prices and ask if they want to proceed
|
||||
|
||||
{% if world_context %}
|
||||
## World Context
|
||||
{{ world_context }}
|
||||
{% endif %}
|
||||
Reference in New Issue
Block a user