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.
- Add temporal awareness and stat decay rules to prompt (0-5% per message)
- Add 'Always Include Attributes' toggle in tracker editor
- Fix skills section editing (was not saving customFields)
- Improve Present Characters parser to handle malformed formats (mid-line chars, extra blank lines)
- All changes work in both together/separate generation modes
Fixed issues when AI generates multiple character variants (e.g.,
storyteller mode with 'Dottore (Prime)', 'Dottore (Beta)', etc.):
1. Escape quotes in character names to prevent HTML attribute breakage
- Added escapeHtmlAttr() helper function
- Prevents names like 'Marianna "Mari"' from breaking HTML
2. Restore avatar lookup for character variants
- namesMatch() now strips parentheses and quotes from both sides
- Allows 'Dottore (Prime)' to find 'Dottore' character card avatar
- Each variant still gets its own card with separate attributes
3. Multiple characters now display correctly in panel
- Each variant creates its own character object
- Attributes (Details, Relationship, Stats, Thoughts) don't mix
- All characters appear in the panel, not just the last one
- Fix stripBrackets() removing Skills section header
- Add structural header whitelist (Skills, Status, Inventory, etc.)
- Implement smart look-ahead to detect content below labels
- Previous logic incorrectly removed 'Skills:' when followed by category labels
- Add proper theming to category action buttons (.rpg-category-action)
- Match styling of view toggle buttons
- Use SmartTheme colors for better visibility
- Fix RPG attributes styling in Tracker Editor
- Change background from --rpg-accent to --SmartThemeBlurTintColor
- Update border to match other themed inputs
Resolves issue where skills with categories were all showing as 'Uncategorized'
due to the Skills section being truncated during parsing.
Add detailed logging to trace Skills section through code block extraction.
New logs in parseResponse:
- Log each code block's content length
- Check if code block contains 'Skills:'
- If yes, show 200 chars of text around Skills section
- This runs BEFORE the content is categorized as userStats/infoBox/etc
This will show us:
1. Is Skills section in the extracted code block?
2. At what point does it get truncated?
3. Is it a code block extraction issue or later processing?
Related: Skills categorization debugging
Add verbose debug logging to trace why Skills section extraction is failing.
Logs added:
- Whether statsText is provided
- Text length and if it contains 'Skills:'
- Whether main regex matched
- If 'On Person:' exists (lookahead target)
- 200 chars of text around Skills section
- Whether simple format fallback matched
- Captured text length when successful
This will help diagnose why parser logs show 'Skills extraction failed'
even when Skills section clearly exists in the text.
Related: Skills categorization issue investigation
Add detailed console logging to trace how skills are being parsed and
categorized. This will help diagnose why skills are ending up in
"Uncategorized" instead of their proper categories.
Debug logs added:
- Log all lines extracted from skills section
- Log when category headers are detected
- Log when category arrays are created
- Log when skills are added to categories vs uncategorized
- Log ERROR when skill can't be added due to missing category array
- Log final skills data structure with category counts
Fallback behavior:
- If skill can't be added to its category (category array doesn't exist),
fall back to uncategorized with ERROR log
To see logs:
- Enable Debug Mode in RPG Companion settings
- Check browser console during AI response parsing
- Look for "[RPG Parser]" prefix
Related: Skills categorization issue investigation
Parser was only matching numeric levels "(Lv 5)" but AI was returning
text proficiencies like "(Proficient)", "(Advanced)", causing all skills
to be ignored and not categorized.
Changes to parser.js:
- Add fallback regex to match text proficiency format: "- Skill (Proficient)"
- Map text proficiencies to numeric levels:
- Initiated/Novice → Lv 1
- Basic/Beginner → Lv 2
- Intermediate → Lv 4
- Proficient → Lv 5
- Competent → Lv 6
- Advanced → Lv 7
- Expert → Lv 8
- Mastered/Master → Lv 9
- Grandmaster/Legendary → Lv 10
- Default to Lv 5 for unrecognized proficiency text
- Try numeric format first, fall back to text format
Changes to promptBuilder.js:
- Make prompt instructions more explicit about numeric format
- Add negative examples: "write 'Lv 5' not 'Proficient'"
- Add guidance: "1=novice, 5=intermediate, 10=expert"
- Emphasize with "IMPORTANT:" prefix
Benefits:
- Parser now handles both formats (backward compatible)
- AI has clearer instructions to use numeric levels
- Skills with text proficiencies now parse correctly and show in categories
- Existing numeric format continues to work
Issue Resolution:
- Skills like "Demonic Qi Manipulation (Proficient)" now parse as Lv 5
- Categories like "Demonic Arts:", "Combat:", "Social:" now populate correctly
- Widget displays skills organized by category instead of ignoring them
Related: Skills widget, AI tracker integration
Add AI tracker awareness for skills system with proper level and category support.
Changes:
- Add extractSkills() parser function to extract structured skills data
- Parses category-based format: "CategoryName:\n- SkillName (Lv X)"
- Falls back to legacy string format for backward compatibility
- Returns structured data: { version: 1, categories: {}, uncategorized: [] }
- Update prompt instructions to request structured skills format
- AI now generates: "Skills:\nCombat:\n- Swordsmanship (Lv 5)"
- Supports multiple categories (Combat, Magic, Social, Crafting, etc.)
- Includes Uncategorized section for skills without clear category
- Add buildSkillsSummary() utility function
- Converts structured skills data back to formatted text
- Ready for future feature: syncing manual skill edits to AI context
Parser integration:
- parseUserStats() now uses extractSkills() to parse Skills section
- Stores structured data in extensionSettings.userStats.skills
- Widget reads structured data for display and level-up/down functionality
AI workflow:
1. AI generates skills in structured format (via prompt instructions)
2. Parser extracts to structured data (via extractSkills)
3. Widget displays with level controls (already implemented)
4. Raw text flows through committedTrackerData to next generation
Note: Manual skill edits (level-up/down in widget) are not yet synced back
to AI context. This requires additional work to regenerate the raw text
when skills are manually modified. buildSkillsSummary is ready for this.
Refs: Skills widget implementation (previous session)
Features:
- Made RPG attributes (STR/DEX/CON/INT/WIS/CHA) fully customizable
- Added enable/disable toggle for entire RPG Attributes section
- Users can add/remove/rename/toggle individual attributes
- Custom attribute names now appear in AI prompts for dice rolls
- Added proper CSS styling for attribute editor fields
Bug Fixes:
- Fixed character stat editing showing 0% on blur but saving correctly
- Character stats now create Stats line if missing from AI response
- Separated stat name from editable percentage value
- Added value sanitization (removes %, validates 0-100 range)
- Stats line now inserts before Thoughts line when created
Technical:
- Added buildAttributesString() helper in promptBuilder.js
- Updated generateTrackerInstructions and generateContextualSummary
- Restructured character stat HTML to prevent nested contenteditable
- Enhanced updateCharacterField to handle missing Stats lines
- Removed legacy default preset/regex import code
- Fixed together mode: Render panels before cleaning DOM so trackers display properly
- Fixed temperature unit toggle: Changed from 'celsius'/'fahrenheit' to 'C'/'F' to match config
- Fixed temperature widget: Thermometer color thresholds now use Celsius internally for consistency
- Fixed relationship remove buttons: Removed duplicate class causing wrong fields to be deleted
- Added styling for relationship remove buttons to match custom field buttons
- Added mobile font sizes for Past Events widget for better readability
- Added parsing debug log to help troubleshoot together mode issues
Merged upstream/main (82b9564) which includes:
- Full tracker customization system
- Tracker editor UI component
- Custom stat names in AI prompts
- Multi-line tracker format updates
Conflict resolutions:
- src/core/persistence.js: Kept both dashboard v2 and trackerConfig migrations
- style.css: Accepted upstream responsive calendar styling with clamp()
Both migration systems are now active and will run in sequence.
Features:
- Complete tracker configuration UI with add/remove functionality
- User Stats: Custom stats, status fields, skills section
- Info Box: Configurable widgets (date, weather, temp, time, location, events)
- Present Characters: Custom fields, relationships, character stats, thoughts
- Character-specific stats with color interpolation
- New multi-line format for cleaner AI generation and parsing
- Auto-cleanup of placeholder brackets in AI responses
- Relationship badges with emoji mapping
- Advanced inventory v2 system with multi-location storage
- Responsive mobile support with horizontal scrolling
- Removed legacy format support for cleaner codebase
- Fixed context injection for together mode (no duplication)
- Updated README with new features and configuration guide
- Updated generateTrackerInstructions() to use extensionSettings.statNames
- AI now receives custom stat names in format specification
- Ensures consistency between displayed names, tracker data, and AI instructions
- Added removal of <think> and <thinking> tags from AI responses before parsing
- Fixed Info Box display to use committedTrackerData as fallback after page refresh
- Fixed Present Characters display to use committedTrackerData as fallback after page refresh
- Fixed 4-part character format handling in updateCharacterField to preserve thoughts
- Ensures Recent Events and all tracker data persist correctly across page reloads
- Update onMessageReceived to populate extensionSettings.infoBoxData and characterThoughts for dashboard widgets
- Update updateRPGData (separate mode) with same extensionSettings population
- Add refreshDashboard() calls after data updates in both generation paths
- Fix onCharacterChanged to populate extensionSettings from loaded chat data
- Fix refreshDashboard() to use correct property name (registry not widgetRegistry)
- Reduce mood and weather widget font sizes to fit in 1x1 layout
This fixes Scene tab widgets not updating when receiving messages or loading chats from welcome screen.