Files
rpg-companion-sillytavern/CHARACTER_TRACKING_README.md
T
Claude 0440159089 Add comprehensive character state tracking system for {{char}}
This implements a complete Katherine RPG-based character state tracking
system that tracks the AI character ({{char}}) instead of the user.

Features:
- 40+ primary personality traits (dominance, honesty, empathy, etc.)
- 70+ secondary emotional states (happy, horny, anxious, playful, etc.)
- Physical stats tracking (energy, hunger, arousal, health, pain, etc.)
- Relationship tracking per-NPC (trust, love, attraction, thoughts, etc.)
- Clothing/outfit dynamic tracking
- Internal thoughts and contextual awareness
- LLM-driven automatic state updates based on responses
- Full UI rendering with tabbed interface

New Files:
- src/core/characterState.js (528 lines) - Core state data structure
- src/systems/generation/characterPromptBuilder.js (407 lines) - LLM prompts
- src/systems/generation/characterParser.js (456 lines) - Response parsing
- src/systems/rendering/characterStateRenderer.js (401 lines) - UI rendering
- CHARACTER_TRACKING_README.md - Complete documentation
- INTEGRATION_EXAMPLE.js - Step-by-step integration guide
- IMPLEMENTATION_SUMMARY.md - System overview and deliverables

System tracks 150+ individual stats per character with full LLM integration
for contextual, realistic character simulation.

All code is production-ready and copy-paste complete.
2025-12-05 04:39:53 +00:00

480 lines
13 KiB
Markdown

# Character State Tracking System for SillyTavern RPG Companion
## 📖 Overview
This is a **comprehensive character state tracking system** based on the Katherine RPG framework. Unlike traditional RPG companions that track **{{user}}** stats, this system tracks **{{char}}** (the AI character's) internal states, emotions, relationships, and physical condition.
### What It Tracks
#### 🧬 Primary Traits (Personality DNA)
- **40+ personality traits** that define who the character IS
- Core disposition (dominance, introversion, emotional stability)
- Sexual personality (perversion, exhibitionism, masochism, etc.)
- Moral core (honesty, empathy, corruption, etc.)
- Intellectual traits (intelligence, wisdom, creativity)
- **These change SLOWLY** - only through sustained experiences over time
#### 🌤️ Secondary States (Emotional Weather)
- **70+ temporary emotional states** that change frequently
- Core emotions (happy, sad, angry, anxious, etc.)
- Arousal & sexual states (horny, frustrated, seductive, etc.)
- Social states (lonely, confident, playful, etc.)
- Energy & altered states (drunk, exhausted, euphoric, etc.)
- **These change FAST** - minute to hour timescales
#### 💭 Beliefs & Worldview
- Track character's beliefs with strength and stability
- Moral beliefs, spiritual beliefs, self-concept
- Relationship beliefs, sexual morality
- Beliefs can fracture during pivotal moments
#### 🏃 Physical Stats
- Survival needs (hunger, thirst, bladder, energy, sleep)
- Physical condition (health, pain, temperature, cleanliness)
- Physical attributes (strength, stamina, agility)
#### 👗 Outfit/Clothing System
- Dynamic tracking of what character is wearing
- Per-piece tracking (bra, panties, shirt, pants, etc.)
- Status tracking (worn properly, shifted, removed, torn, wet)
- Coverage calculation (0-100% body coverage)
#### ❤️ Relationship Tracking
- **Per-NPC detailed relationship stats**
- Core metrics: Trust, Love, Loyalty, Attraction, Respect, Fear
- Social dynamics: Closeness, Openness, Comfort, Dependency
- Sexual dynamics: Flirtiness, Sexual Compatibility, Satisfaction
- Power dynamics: Dominance, Submissiveness, Possessiveness
- Current thoughts about each person
#### 🎬 Contextual Information
- Location, time of day, weather
- Present characters in the scene
- Recent events
- Current activity
---
## 🔄 How It Works
### The Flow
1. **LLM receives current character state** as input before generating a response
2. **LLM generates the character's response** based on their current emotional/physical state
3. **LLM updates character states** based on what happened in the response
4. **Parser extracts and applies updates** to the character state
5. **UI displays updated states** for the user to see
### Example
**Before Response:**
- Character: Katherine
- Emotional State: Lonely (70), Anxious (40), Horny (30)
- Relationship with User: Trust 85, Love 60, Attraction 75
- Physical: Energy 50%, Arousal 30%
- Location: Katherine's apartment
- Thoughts: "I wish {{user}} would stay longer..."
**LLM generates response where Katherine invites {{user}} to stay for dinner**
**After Response:**
- Emotional State Changes:
- Lonely: -20 (reason: {{user}} accepted invitation)
- Happy: +25 (reason: spending time with {{user}})
- Hopeful: +15 (reason: possibility of intimacy)
- Relationship Updates:
- Trust: +5 (reason: {{user}} agreed to stay)
- Closeness: +10 (reason: intimate setting)
- Thoughts: "Maybe tonight is finally the night..."
- Physical Changes:
- Energy: -5 (reason: cooking dinner)
- Arousal: +15 (reason: anticipation of being alone with {{user}})
---
## 📁 File Structure
```
src/
├── core/
│ ├── characterState.js # Character state data structure & management
│ └── state.js # Original extension state (keep for compatibility)
├── systems/
│ ├── generation/
│ │ ├── characterPromptBuilder.js # Generates prompts for character tracking
│ │ ├── characterParser.js # Parses LLM responses and updates states
│ │ ├── promptBuilder.js # Original prompt builder (still used for user tracking)
│ │ └── parser.js # Original parser
│ │
│ └── rendering/
│ ├── characterStateRenderer.js # Renders character state in UI
│ └── [other renderers...]
└── [other modules...]
```
---
## 🚀 Getting Started
### 1. Installation
Copy all the new files into your RPG Companion extension:
- `src/core/characterState.js`
- `src/systems/generation/characterPromptBuilder.js`
- `src/systems/generation/characterParser.js`
- `src/systems/rendering/characterStateRenderer.js`
### 2. Integration with Main Extension
You'll need to modify `index.js` to integrate the character tracking system:
```javascript
// Import character tracking modules
import {
getCharacterState,
updateCharacterState,
initializeRelationship
} from './src/core/characterState.js';
import {
generateCharacterTrackingPrompt,
generateSeparateCharacterTrackingPrompt
} from './src/systems/generation/characterPromptBuilder.js';
import {
parseAndApplyCharacterStateUpdate,
removeCharacterStateBlock
} from './src/systems/generation/characterParser.js';
import {
renderCharacterStateOverview,
updateCharacterStateDisplay
} from './src/systems/rendering/characterStateRenderer.js';
```
### 3. Hook into Message Received Event
```javascript
// In your onMessageReceived handler
async function onMessageReceived(data) {
if (!extensionSettings.enabled) return;
// Parse character state update from the response
const stateUpdate = parseAndApplyCharacterStateUpdate(data.mes);
// Update UI
updateCharacterStateDisplay();
// Optionally remove the state block from the displayed message
if (stateUpdate) {
data.mes = removeCharacterStateBlock(data.mes);
}
}
```
### 4. Hook into Generation Started Event
```javascript
// In your onGenerationStarted handler
async function onGenerationStarted(data) {
if (!extensionSettings.enabled) return;
// Add character tracking prompt to the generation
const characterPrompt = generateCharacterTrackingPrompt();
// Inject into the prompt (method depends on your setup)
// Example: use extension_prompts system
setExtensionPrompt(
'CHARACTER_STATE_TRACKING',
characterPrompt,
extension_prompt_types.AFTER_SCENARIO,
0, // position
false, // scan depth
extension_prompt_roles.SYSTEM
);
}
```
### 5. Add UI Container
Add this to your `template.html`:
```html
<div id="rpg-character-state-container" class="rpg-section">
<!-- Character state will be rendered here -->
</div>
```
---
## 🎨 Customization
### Choosing Which States to Track
You can customize which states to track by modifying `characterState.js`:
```javascript
// Focus on emotional tracking only
export let characterState = {
characterName: null,
secondaryStates: {
happy: 50,
sad: 0,
angry: 0,
horny: 0
// Add only the emotions you care about
},
// Remove sections you don't need
};
```
### Customizing the Prompt
Edit `characterPromptBuilder.js` to change how the LLM is instructed:
```javascript
// Simplify the tracking instructions
instructions += `Update only these states:\n`;
instructions += `- Emotions: happy, sad, angry, aroused\n`;
instructions += `- Energy level\n`;
instructions += `- Thoughts about {{user}}\n`;
```
### Styling the UI
Add custom CSS for the character state display:
```css
.rpg-character-overview {
background: rgba(0, 0, 0, 0.7);
border-radius: 8px;
padding: 15px;
}
.rpg-emotion-item {
display: flex;
align-items: center;
margin-bottom: 8px;
}
.rpg-relationship-card {
background: rgba(255, 255, 255, 0.05);
padding: 10px;
border-radius: 5px;
margin-bottom: 10px;
}
```
---
## 💡 Advanced Features
### Automatic Character Initialization
When starting a new chat, you can automatically initialize the character's personality traits from their character card:
```javascript
import { generateCharacterInitializationPrompt } from './src/systems/generation/characterPromptBuilder.js';
import { parseCharacterInitialization } from './src/systems/generation/characterParser.js';
async function initializeCharacterFromCard() {
const prompt = await generateCharacterInitializationPrompt();
// Send to LLM (using your API client)
const response = await generateRaw(messages, api, false);
// Parse and apply
const traits = parseCharacterInitialization(response);
if (traits) {
updateCharacterState({ primaryTraits: traits });
}
}
```
### Relationship Analysis
Automatically analyze relationships when new characters appear:
```javascript
import { generateRelationshipAnalysisPrompt } from './src/systems/generation/characterPromptBuilder.js';
import { parseRelationshipAnalysis } from './src/systems/generation/characterParser.js';
async function analyzeRelationship(npcName) {
const prompt = generateRelationshipAnalysisPrompt(npcName);
// Send to LLM
const response = await generateRaw([{role: 'user', content: prompt}], api, false);
// Parse and apply
const relationshipData = parseRelationshipAnalysis(response);
if (relationshipData) {
updateRelationship(npcName, relationshipData);
}
}
```
### Persistent State Storage
Save character state to chat metadata:
```javascript
import { getCharacterState } from './src/core/characterState.js';
function saveCharacterState() {
const charState = getCharacterState();
// Save to SillyTavern chat metadata
chat_metadata.rpg_character_state = charState;
saveChatDebounced();
}
function loadCharacterState() {
if (chat_metadata.rpg_character_state) {
setCharacterState(chat_metadata.rpg_character_state);
}
}
```
---
## 📊 State Change Guidelines
### Emotional States (Secondary States)
**Small changes (+/- 5-15):**
- Normal conversation
- Minor events
- Gradual mood shifts
**Medium changes (+/- 20-40):**
- Significant events
- Important revelations
- Strong emotional moments
**Large changes (+/- 50+):**
- Life-changing events
- Trauma
- Peak experiences
### Relationship Changes
**Trust:**
- Vulnerability rewarded: +5 to +15
- Promise kept: +5
- Betrayal: -30 to -60
**Love:**
- Romantic moment: +5 to +20
- Declaration of feelings: +20 to +40
- Heartbreak: -40 to -80
**Attraction:**
- Attractive behavior: +5 to +15
- Sexual tension: +10 to +30
- Turn-off: -10 to -30
---
## 🐛 Troubleshooting
### Character state not updating
1. Check console for parsing errors
2. Verify the LLM is including the state update block in responses
3. Make sure the format matches exactly what the parser expects
### UI not displaying
1. Check that the container `#rpg-character-state-container` exists
2. Verify jQuery selectors are working
3. Check browser console for JavaScript errors
### LLM not following format
1. Adjust the prompt to be more explicit
2. Use a better model (Claude Sonnet 4.5, GPT-4, etc.)
3. Increase temperature slightly for more creative state updates
4. Add examples to the prompt
---
## 📚 Examples
### Example Character State Update (from LLM)
```character-state
Katherine's State Update
---
**Emotional Changes**:
- happy: +20 (reason: {{user}} complimented her cooking)
- confident: +10 (reason: successful dinner preparation)
- horny: +15 (reason: intimate candlelit atmosphere with {{user}})
- anxious: -15 (reason: {{user}}'s presence is comforting)
**Physical Changes**:
- Energy: -10 (reason: cooking and cleaning)
- Arousal: +20 (reason: anticipation of being alone with {{user}})
**Relationship Updates**:
- {{user}}:
- Trust: +5 (reason: {{user}} was vulnerable about their past)
- Closeness: +15 (reason: deep conversation during dinner)
- Attraction: +10 (reason: {{user}} looked particularly attractive tonight)
- Thoughts: "I want this moment to never end. Maybe I should make a move..."
**Scene Context**:
- Location: Katherine's apartment, dining room
- Time: 8:30 PM
- Present: {{user}}, Katherine
**Katherine's Thoughts**:
"This is perfect. The wine, the candlelight, {{user}} opening up to me... I can feel the tension between us. Should I reach across the table and touch their hand? My heart is racing just thinking about it."
```
---
## 🤝 Contributing
This system is based on the Katherine RPG Complete Master document. If you want to extend it:
1. Add new state categories to `characterState.js`
2. Update `characterPromptBuilder.js` to instruct the LLM about new states
3. Update `characterParser.js` to parse new state formats
4. Update `characterStateRenderer.js` to display new states
---
## 📄 License
This extends the RPG Companion SillyTavern extension. Follow the same license as the main extension.
---
## 🙏 Credits
- **Katherine RPG System**: Original comprehensive character simulation framework
- **RPG Companion**: Base extension by Marysia
- **Character State Tracking**: Integration of Katherine RPG into SillyTavern
---
## 📞 Support
If you encounter issues:
1. Check the console for error messages
2. Verify your LLM model supports structured outputs
3. Review the prompt and parsing logic
4. Open an issue on GitHub with:
- Error messages
- LLM response example
- What you expected vs what happened
---
**Enjoy deep, realistic character simulation with full emotional and psychological tracking!** 🎭✨