Compare commits
2 Commits
d5e4795fc4
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41975ecfe2 | ||
|
|
da30107f5b |
167
CHANGELOG.md
Normal file
167
CHANGELOG.md
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to the Storyteller RPG project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.2.0] - 2025-10-12
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- **Context-Aware Response Generator** 🧠
|
||||||
|
- Select multiple characters to include in AI-generated responses
|
||||||
|
- Two modes: Scene descriptions (broadcast) or Individual responses (private)
|
||||||
|
- Smart context building with character profiles, personalities, and conversation history
|
||||||
|
- Automatic parsing and distribution of individual responses
|
||||||
|
- Improved prompts with explicit `[CharacterName]` format for reliable parsing
|
||||||
|
|
||||||
|
- **Demo Session** 🎮
|
||||||
|
- Pre-configured "The Cursed Tavern" adventure
|
||||||
|
- Two characters: Bargin Ironforge (Dwarf Warrior) & Willow Moonwhisper (Elf Ranger)
|
||||||
|
- Auto-created on server startup
|
||||||
|
- Quick-access buttons on home page for instant testing
|
||||||
|
- Eliminates need to recreate test data during development
|
||||||
|
|
||||||
|
- **Session ID Copy Button** 📋
|
||||||
|
- One-click clipboard copy in storyteller dashboard
|
||||||
|
- Improved UX for session sharing
|
||||||
|
|
||||||
|
- **Comprehensive Documentation** 📚
|
||||||
|
- Feature guides for all major features
|
||||||
|
- Prompt engineering documentation
|
||||||
|
- Demo session usage guide
|
||||||
|
- Bug fixes summary
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- **Character Chat History** - Characters can now see full conversation with storyteller (not just most recent message)
|
||||||
|
- Fixed WebSocket message type handling (`storyteller_response` and `new_message`)
|
||||||
|
|
||||||
|
- **Pydantic Deprecation Warnings** - Replaced all `.dict()` calls with `.model_dump()` (9 instances)
|
||||||
|
- Code is now Pydantic V2 compliant
|
||||||
|
- No more deprecation warnings in console
|
||||||
|
|
||||||
|
- **WebSocket Manager Reference** - Fixed `character_connections` error in contextual response endpoint
|
||||||
|
- Now properly uses `manager.send_to_client()` with correct key format
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Improved LLM prompts for individual responses with explicit format instructions
|
||||||
|
- Simplified response parsing from 4 regex patterns to single reliable pattern
|
||||||
|
- Enhanced system prompts for better LLM compliance
|
||||||
|
- Reorganized documentation structure with dedicated features folder
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.1.0] - 2025-10-11
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- **Core Session Management**
|
||||||
|
- Create and join game sessions
|
||||||
|
- Session ID-based access control
|
||||||
|
- In-memory session storage
|
||||||
|
|
||||||
|
- **Character System**
|
||||||
|
- Character creation with name, description, and personality
|
||||||
|
- Character profiles visible to storyteller
|
||||||
|
- Per-character conversation history
|
||||||
|
|
||||||
|
- **Flexible Messaging System** 📨
|
||||||
|
- **Private Messages** - Character ↔ Storyteller only
|
||||||
|
- **Public Messages** - Visible to all players
|
||||||
|
- **Mixed Messages** - Public action + private thoughts
|
||||||
|
- Real-time message delivery via WebSockets
|
||||||
|
|
||||||
|
- **Scene Narration** 📜
|
||||||
|
- Storyteller can broadcast scene descriptions
|
||||||
|
- Scenes visible to all connected characters
|
||||||
|
- Scene history tracking
|
||||||
|
|
||||||
|
- **AI-Assisted Responses** ✨
|
||||||
|
- "AI Suggest" button for storytellers
|
||||||
|
- Generate response suggestions using character's LLM
|
||||||
|
- Editable before sending
|
||||||
|
|
||||||
|
- **Multi-LLM Support** 🤖
|
||||||
|
- Support for 100+ models via OpenRouter and OpenAI
|
||||||
|
- Per-character model selection
|
||||||
|
- Models: GPT-4o, GPT-4, GPT-3.5, Claude, Llama, Gemini, Mistral, etc.
|
||||||
|
- Each character can use a different model
|
||||||
|
|
||||||
|
- **Real-time Communication** ⚡
|
||||||
|
- WebSocket endpoints for characters and storyteller
|
||||||
|
- Instant message delivery
|
||||||
|
- Connection status indicators
|
||||||
|
- Pending response tracking
|
||||||
|
|
||||||
|
- **Modern UI** 🎨
|
||||||
|
- Clean, intuitive interface
|
||||||
|
- Gradient-themed design
|
||||||
|
- Responsive layout
|
||||||
|
- Character-specific color schemes
|
||||||
|
- Loading states and animations
|
||||||
|
|
||||||
|
### Technical
|
||||||
|
- FastAPI backend with WebSocket support
|
||||||
|
- React frontend with modern hooks
|
||||||
|
- ConnectionManager for WebSocket state
|
||||||
|
- Pydantic models for data validation
|
||||||
|
- CORS configuration for local development
|
||||||
|
- Environment-based API key management
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Planned Features
|
||||||
|
- Database persistence (PostgreSQL/MongoDB)
|
||||||
|
- User authentication system
|
||||||
|
- Character sheets with stats
|
||||||
|
- Dice rolling mechanics
|
||||||
|
- Combat system
|
||||||
|
- Image generation for scenes/characters
|
||||||
|
- Voice message support
|
||||||
|
- Session export functionality
|
||||||
|
- Mobile app versions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Version History
|
||||||
|
|
||||||
|
- **0.2.0** (2025-10-12) - Context-Aware AI, Demo Session, Bug Fixes
|
||||||
|
- **0.1.0** (2025-10-11) - Initial MVP Release
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Migration Notes
|
||||||
|
|
||||||
|
### 0.1.0 → 0.2.0
|
||||||
|
|
||||||
|
**No breaking changes.** All existing functionality preserved.
|
||||||
|
|
||||||
|
**New Features Available:**
|
||||||
|
- Click "▶ Show Generator" in storyteller dashboard for context-aware responses
|
||||||
|
- Demo session auto-created on startup (session ID: `demo-session-001`)
|
||||||
|
- Copy button next to session ID for easy sharing
|
||||||
|
|
||||||
|
**Bug Fixes Applied Automatically:**
|
||||||
|
- Full conversation history now visible
|
||||||
|
- No more Pydantic warnings
|
||||||
|
- WebSocket messages work correctly
|
||||||
|
|
||||||
|
**No Action Required:**
|
||||||
|
- In-memory sessions continue to work as before
|
||||||
|
- No database migrations needed
|
||||||
|
- Frontend automatically detects new features
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
See [docs/README.md](./docs/README.md) for documentation guidelines.
|
||||||
|
|
||||||
|
Report bugs or suggest features via GitHub issues.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Format inspired by [Keep a Changelog](https://keepachangelog.com/)*
|
||||||
@@ -1,308 +0,0 @@
|
|||||||
# 🎭 Storyteller RPG - Current Status
|
|
||||||
|
|
||||||
**Date:** October 11, 2025
|
|
||||||
**Session Duration:** ~1 hour
|
|
||||||
**Status:** ✅ Major MVP Features Implemented
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎉 What We Accomplished Today
|
|
||||||
|
|
||||||
### 1. ✨ AI-Assisted Storyteller Responses (Quick Win)
|
|
||||||
**New Feature:** Storytellers can now click "✨ AI Suggest" to generate response suggestions using the character's chosen LLM model.
|
|
||||||
|
|
||||||
**Implementation:**
|
|
||||||
- Added button in StorytellerView response section
|
|
||||||
- Shows loading state while generating
|
|
||||||
- Populates textarea with suggestion (editable before sending)
|
|
||||||
- Uses existing backend endpoint
|
|
||||||
|
|
||||||
**Files Modified:**
|
|
||||||
- `frontend/src/components/StorytellerView.js`
|
|
||||||
- `frontend/src/App.css` (added `.btn-secondary`, `.response-buttons`)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. 📢 Enhanced Message System (MVP Phase 1 - COMPLETE!)
|
|
||||||
|
|
||||||
This is the **core feature** that makes the app unique for RPG gameplay.
|
|
||||||
|
|
||||||
#### Message Types
|
|
||||||
1. **🔒 Private** - Only storyteller sees (default)
|
|
||||||
- Example: "I attempt to pickpocket the merchant"
|
|
||||||
|
|
||||||
2. **📢 Public** - All players see
|
|
||||||
- Example: "I shake hands with the merchant"
|
|
||||||
|
|
||||||
3. **🔀 Mixed** - Public action + secret motive
|
|
||||||
- Public: "I shake hands with the merchant"
|
|
||||||
- Private: "While shaking hands, I try to slip my hand into his pocket"
|
|
||||||
|
|
||||||
#### Backend Changes (`main.py`)
|
|
||||||
- **Message Model Updated:**
|
|
||||||
```python
|
|
||||||
class Message:
|
|
||||||
visibility: str = "private" # "public", "private", "mixed"
|
|
||||||
public_content: Optional[str] = None
|
|
||||||
private_content: Optional[str] = None
|
|
||||||
```
|
|
||||||
|
|
||||||
- **GameSession Model Updated:**
|
|
||||||
```python
|
|
||||||
class GameSession:
|
|
||||||
public_messages: List[Message] = [] # Shared feed
|
|
||||||
```
|
|
||||||
|
|
||||||
- **WebSocket Routing:**
|
|
||||||
- Private messages → Only to storyteller
|
|
||||||
- Public messages → Broadcast to all characters
|
|
||||||
- Mixed messages → Both feeds appropriately
|
|
||||||
|
|
||||||
#### Frontend Changes
|
|
||||||
|
|
||||||
**CharacterView.js:**
|
|
||||||
- Message type selector dropdown
|
|
||||||
- Public messages section (shows all player actions)
|
|
||||||
- Private conversation section (storyteller only)
|
|
||||||
- Mixed message composer with dual textareas
|
|
||||||
- Real-time updates for both feeds
|
|
||||||
|
|
||||||
**StorytellerView.js:**
|
|
||||||
- Public actions feed (last 5 actions)
|
|
||||||
- View all message types
|
|
||||||
- See both public and private content
|
|
||||||
|
|
||||||
**App.css:**
|
|
||||||
- New sections for public/private message display
|
|
||||||
- Mixed message composer styling
|
|
||||||
- Visual distinction between message types
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏗️ Architecture Improvements
|
|
||||||
|
|
||||||
### Message Flow
|
|
||||||
|
|
||||||
```
|
|
||||||
CHARACTER A STORYTELLER CHARACTER B
|
|
||||||
| | |
|
|
||||||
| "I pickpocket" (private) | |
|
|
||||||
|----------------------------->| |
|
|
||||||
| | |
|
|
||||||
| "I wave hello" (public) | |
|
|
||||||
|----------------------------->|----------------------------->|
|
|
||||||
| | |
|
|
||||||
| Sees both | Sees only public |
|
|
||||||
```
|
|
||||||
|
|
||||||
### Privacy Model
|
|
||||||
- ✅ Characters only see their own private messages
|
|
||||||
- ✅ Characters see ALL public messages
|
|
||||||
- ✅ Storyteller sees EVERYTHING
|
|
||||||
- ✅ Mixed messages split correctly
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎮 How to Use
|
|
||||||
|
|
||||||
### As a Character:
|
|
||||||
|
|
||||||
1. **Join a session** at http://localhost:3000
|
|
||||||
2. **Select message type** from dropdown:
|
|
||||||
- 🔒 Private (default) - Secret actions
|
|
||||||
- 📢 Public - Actions everyone sees
|
|
||||||
- 🔀 Mixed - Do something publicly while attempting something secret
|
|
||||||
3. **Send messages** - They route appropriately
|
|
||||||
4. **View public feed** - See what other players are doing
|
|
||||||
5. **Private conversation** - Your secret messages with storyteller
|
|
||||||
|
|
||||||
### As a Storyteller:
|
|
||||||
|
|
||||||
1. **Create session** and share ID
|
|
||||||
2. **View public feed** - See all public actions
|
|
||||||
3. **Select character** - View their private messages
|
|
||||||
4. **Click "✨ AI Suggest"** - Generate response ideas
|
|
||||||
5. **Respond privately** - Each character gets personalized replies
|
|
||||||
6. **Narrate scenes** - Broadcast to everyone
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📁 Files Modified
|
|
||||||
|
|
||||||
### Backend
|
|
||||||
- ✅ `main.py` - Message model, routing, public messages
|
|
||||||
|
|
||||||
### Frontend Components
|
|
||||||
- ✅ `frontend/src/components/CharacterView.js` - Message composer, public feed
|
|
||||||
- ✅ `frontend/src/components/StorytellerView.js` - AI suggest, public feed
|
|
||||||
|
|
||||||
### Styles
|
|
||||||
- ✅ `frontend/src/App.css` - New sections and components
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
- ✅ `docs/development/MVP_PROGRESS.md` - Detailed progress report
|
|
||||||
- ✅ `CURRENT_STATUS.md` - This file
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧪 Testing Status
|
|
||||||
|
|
||||||
### ✅ Verified
|
|
||||||
- Backend starts with new message model
|
|
||||||
- Frontend compiles successfully
|
|
||||||
- Both servers running (ports 3000 & 8000)
|
|
||||||
- API endpoints include `public_messages`
|
|
||||||
|
|
||||||
### ⏳ Manual Testing Needed
|
|
||||||
You should test these scenarios:
|
|
||||||
|
|
||||||
1. **Two Character Test:**
|
|
||||||
- Open two browser windows
|
|
||||||
- Create session as storyteller in window 1
|
|
||||||
- Join as Character A in window 2
|
|
||||||
- Join as Character B in window 3
|
|
||||||
- Send public message from Character A
|
|
||||||
- Verify Character B sees it
|
|
||||||
- Send private message from Character A
|
|
||||||
- Verify Character B does NOT see it
|
|
||||||
- Verify storyteller sees both
|
|
||||||
|
|
||||||
2. **Mixed Message Test:**
|
|
||||||
- Select "Mixed" message type
|
|
||||||
- Enter public action: "I examine the door"
|
|
||||||
- Enter private action: "I check for traps"
|
|
||||||
- Send and verify both parts appear correctly
|
|
||||||
|
|
||||||
3. **AI Suggest Test:**
|
|
||||||
- As storyteller, click "✨ AI Suggest"
|
|
||||||
- Verify suggestion generates
|
|
||||||
- Edit and send
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 What's Next
|
|
||||||
|
|
||||||
### Immediate Priorities
|
|
||||||
|
|
||||||
#### 1. Database Persistence (High Priority - 3-4 hours)
|
|
||||||
**Why:** Currently sessions only exist in memory. Server restart = data loss.
|
|
||||||
|
|
||||||
**What to add:**
|
|
||||||
```bash
|
|
||||||
# requirements.txt
|
|
||||||
sqlalchemy==2.0.23
|
|
||||||
aiosqlite==3.0.10
|
|
||||||
alembic==1.13.0
|
|
||||||
```
|
|
||||||
|
|
||||||
**Implementation:**
|
|
||||||
- Create `database.py` with SQLAlchemy models
|
|
||||||
- Replace in-memory `sessions` dict
|
|
||||||
- Add save/load endpoints
|
|
||||||
- Enable session persistence
|
|
||||||
|
|
||||||
#### 2. Character Profile System (MVP Phase 2 - 1-2 days)
|
|
||||||
Implement the race/class/personality system from MVP roadmap:
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- Character creation wizard
|
|
||||||
- Race selection (Human/Elf/Dwarf/Orc/Halfling)
|
|
||||||
- Class selection (Warrior/Wizard/Cleric/Archer/Rogue)
|
|
||||||
- Personality (Friendly/Serious/Doubtful/Measured)
|
|
||||||
- Profile-based LLM prompts
|
|
||||||
- Import/export (JSON & PNG)
|
|
||||||
|
|
||||||
#### 3. Show Character Names in Public Feed (Quick Fix - 30 mins)
|
|
||||||
Currently public messages don't clearly show WHO did the action.
|
|
||||||
|
|
||||||
**Update needed:**
|
|
||||||
- Include character name in public message broadcasts
|
|
||||||
- Display in public feed: "Gandalf the Wizard: I cast light"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 MVP Progress
|
|
||||||
|
|
||||||
**Phase 1:** ✅ 100% Complete (Enhanced Message System)
|
|
||||||
**Phase 2:** ⏳ 0% Complete (Character Profiles) - **NEXT**
|
|
||||||
**Phase 3:** ⏳ 0% Complete (User Mode Interfaces)
|
|
||||||
**Phase 4:** ⏳ 0% Complete (AI Automation)
|
|
||||||
**Phase 5:** ⏳ 0% Complete (Game Management & Database)
|
|
||||||
**Phase 6:** ⏳ 0% Complete (Polish & Testing)
|
|
||||||
|
|
||||||
**Overall MVP Progress:** ~8% (1/12 weeks)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Success Metrics
|
|
||||||
|
|
||||||
### ✅ Completed
|
|
||||||
- [x] Private character-storyteller communication
|
|
||||||
- [x] Public message broadcasting
|
|
||||||
- [x] Mixed message support
|
|
||||||
- [x] AI-assisted responses UI
|
|
||||||
- [x] Real-time WebSocket updates
|
|
||||||
- [x] Message type selection
|
|
||||||
- [x] Visual distinction between message types
|
|
||||||
|
|
||||||
### 🎲 Ready for Testing
|
|
||||||
- [ ] Multi-character public feed
|
|
||||||
- [ ] Mixed message splitting
|
|
||||||
- [ ] AI suggestion quality
|
|
||||||
- [ ] Message persistence across refresh (needs DB)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💡 Key Insights
|
|
||||||
|
|
||||||
1. **Message System is Core:** The public/private/mixed system is what makes this app special for RPG. Players can now create dramatic situations where they act one way publicly while secretly doing something else.
|
|
||||||
|
|
||||||
2. **Quick Wins Matter:** The AI Suggest button took 30 minutes but adds huge value for storytellers.
|
|
||||||
|
|
||||||
3. **Database is Critical:** Next session should start with SQLite implementation to prevent data loss and enable real features.
|
|
||||||
|
|
||||||
4. **Profile System is Next:** Character profiles with race/class/personality will make the LLM responses much more interesting and distinct.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Running the Application
|
|
||||||
|
|
||||||
The application is currently running:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Backend: http://localhost:8000
|
|
||||||
# Frontend: http://localhost:3000
|
|
||||||
|
|
||||||
# To restart both:
|
|
||||||
bash start.sh
|
|
||||||
|
|
||||||
# To stop:
|
|
||||||
# Ctrl+C in the terminal running start.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 Documentation
|
|
||||||
|
|
||||||
- **Setup:** `docs/setup/QUICKSTART.md`
|
|
||||||
- **MVP Roadmap:** `docs/planning/MVP_ROADMAP.md`
|
|
||||||
- **Progress Report:** `docs/development/MVP_PROGRESS.md`
|
|
||||||
- **Implementation Details:** `docs/development/IMPLEMENTATION_SUMMARY.md`
|
|
||||||
- **API Reference:** `docs/reference/LLM_GUIDE.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎉 Summary
|
|
||||||
|
|
||||||
**Excellent progress!** We've completed Phase 1 of the MVP roadmap (Enhanced Message System) and added a valuable quick win (AI Suggest). The application now supports:
|
|
||||||
|
|
||||||
- ✨ **AI-assisted storyteller responses**
|
|
||||||
- 🔒 **Private messages** (character ↔ storyteller only)
|
|
||||||
- 📢 **Public messages** (visible to all players)
|
|
||||||
- 🔀 **Mixed messages** (public action + secret motive)
|
|
||||||
- 🎭 **Real-time broadcasting** to appropriate audiences
|
|
||||||
- 🤖 **Multi-LLM support** (OpenAI + OpenRouter)
|
|
||||||
|
|
||||||
**The foundation is solid.** The message system works as designed, and the architecture supports the remaining MVP phases. Next session should focus on database persistence and character profiles to make the app truly shine.
|
|
||||||
|
|
||||||
**Great work finishing the MVP!** 🚀
|
|
||||||
71
README.md
71
README.md
@@ -4,13 +4,23 @@ A storyteller-centric roleplaying application where characters communicate **pri
|
|||||||
|
|
||||||
## ✨ Key Features
|
## ✨ Key Features
|
||||||
|
|
||||||
|
### Core Features
|
||||||
- **🔒 Private Character-Storyteller Communication**: Each character has a completely isolated conversation with the storyteller - no character can see what others are saying or receiving
|
- **🔒 Private Character-Storyteller Communication**: Each character has a completely isolated conversation with the storyteller - no character can see what others are saying or receiving
|
||||||
|
- **📢 Flexible Messaging System**: Private, public, or mixed messages for different roleplay scenarios
|
||||||
- **🎲 Storyteller-Centric Workflow**: The storyteller sees all character messages and responds to each individually
|
- **🎲 Storyteller-Centric Workflow**: The storyteller sees all character messages and responds to each individually
|
||||||
- **🤖 Multiple LLM Support**: Each character can use a different AI model (GPT-4, Claude, Llama, Gemini, Mistral, etc.) via OpenRouter or OpenAI
|
- **🧠 Context-Aware AI**: Generate responses considering multiple characters' actions simultaneously
|
||||||
- **📜 Scene Narration**: Storyteller can broadcast scene descriptions visible to all characters
|
- **🎮 Demo Session**: Pre-loaded "Cursed Tavern" adventure with two characters for instant testing
|
||||||
- **🧠 Isolated Memory Sessions**: Each character maintains their own separate conversation history with the storyteller
|
|
||||||
|
### AI & LLM Support
|
||||||
|
- **🤖 Multiple LLM Support**: GPT-4o, GPT-4, GPT-3.5, Claude, Llama, Gemini, Mistral (100+ models via OpenRouter)
|
||||||
|
- **✨ AI-Assisted Responses**: Get AI suggestions for storyteller responses
|
||||||
|
- **🎯 Smart Context Building**: AI considers character profiles, personalities, and conversation history
|
||||||
|
|
||||||
|
### Technical Features
|
||||||
- **⚡ Real-time WebSocket Communication**: Instant message delivery
|
- **⚡ Real-time WebSocket Communication**: Instant message delivery
|
||||||
|
- **🧠 Isolated Memory Sessions**: Each character maintains their own separate conversation history
|
||||||
- **🎨 Modern, Beautiful UI**: Clean, intuitive interface with gradient themes
|
- **🎨 Modern, Beautiful UI**: Clean, intuitive interface with gradient themes
|
||||||
|
- **📱 Responsive Design**: Works on desktop, tablet, and mobile
|
||||||
|
|
||||||
## 🎯 How It Works
|
## 🎯 How It Works
|
||||||
|
|
||||||
@@ -69,27 +79,51 @@ A storyteller-centric roleplaying application where characters communicate **pri
|
|||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
## Running the Application
|
## 🚀 Quick Start
|
||||||
|
|
||||||
### Start the Backend
|
### Easy Start (Recommended)
|
||||||
|
|
||||||
From the project root directory:
|
Use the startup script to launch both backend and frontend:
|
||||||
|
|
||||||
|
**Linux/Mac:**
|
||||||
|
```bash
|
||||||
|
bash start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
```bash
|
||||||
|
start.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
This will:
|
||||||
|
1. Start the FastAPI backend on `http://localhost:8000`
|
||||||
|
2. Start the React frontend on `http://localhost:3000`
|
||||||
|
3. Create a demo session automatically
|
||||||
|
4. Open your browser
|
||||||
|
|
||||||
|
### Demo Session 🎲
|
||||||
|
|
||||||
|
A pre-configured "Cursed Tavern" adventure is automatically created with:
|
||||||
|
- **Session ID:** `demo-session-001`
|
||||||
|
- **Characters:** Bargin (Dwarf Warrior) & Willow (Elf Ranger)
|
||||||
|
- **Quick-access buttons** on the home page
|
||||||
|
|
||||||
|
Just click a button and start playing!
|
||||||
|
|
||||||
|
### Manual Start
|
||||||
|
|
||||||
|
If you prefer to run services separately:
|
||||||
|
|
||||||
|
**Backend:**
|
||||||
```bash
|
```bash
|
||||||
uvicorn main:app --reload
|
uvicorn main:app --reload
|
||||||
```
|
```
|
||||||
|
|
||||||
The backend will be available at `http://localhost:8000`
|
**Frontend:**
|
||||||
|
|
||||||
### Start the Frontend
|
|
||||||
|
|
||||||
In a new terminal, navigate to the frontend directory and run:
|
|
||||||
```bash
|
```bash
|
||||||
cd frontend
|
cd frontend && npm start
|
||||||
npm start
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The frontend will open in your default browser at `http://localhost:3000`
|
|
||||||
|
|
||||||
## 🎮 How to Use
|
## 🎮 How to Use
|
||||||
|
|
||||||
### As the Storyteller
|
### As the Storyteller
|
||||||
@@ -184,10 +218,15 @@ Each character has a **completely isolated** conversation with the storyteller:
|
|||||||
|
|
||||||
All project documentation is organized in the [`docs/`](./docs/) folder:
|
All project documentation is organized in the [`docs/`](./docs/) folder:
|
||||||
|
|
||||||
|
### Quick Links
|
||||||
|
- **[Features Guide](./docs/features/)** - All features with examples and guides
|
||||||
|
- [Demo Session](./docs/features/DEMO_SESSION.md)
|
||||||
|
- [Context-Aware Responses](./docs/features/CONTEXTUAL_RESPONSE_FEATURE.md)
|
||||||
|
- [Bug Fixes Summary](./docs/features/FIXES_SUMMARY.md)
|
||||||
- **[Setup Guides](./docs/setup/)** - Quick start and installation
|
- **[Setup Guides](./docs/setup/)** - Quick start and installation
|
||||||
- **[Planning](./docs/planning/)** - Roadmaps and feature plans
|
- **[Planning](./docs/planning/)** - Roadmaps and feature plans
|
||||||
- **[Reference](./docs/reference/)** - Technical guides and file references
|
- **[Reference](./docs/reference/)** - Technical guides and file references
|
||||||
- **[Development](./docs/development/)** - Session notes and implementation details
|
- **[Development](./docs/development/)** - Testing and implementation details
|
||||||
|
|
||||||
See [docs/README.md](./docs/README.md) for the complete documentation index.
|
See [docs/README.md](./docs/README.md) for the complete documentation index.
|
||||||
|
|
||||||
|
|||||||
@@ -1,437 +0,0 @@
|
|||||||
# 🎉 Development Session Summary
|
|
||||||
|
|
||||||
**Date:** October 11, 2025
|
|
||||||
**Duration:** ~2 hours
|
|
||||||
**Branch:** mvp-phase-02
|
|
||||||
**Status:** ✅ Highly Productive - Phase 1 Complete + Tests Added
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Major Accomplishments
|
|
||||||
|
|
||||||
### 1. ✅ Phase 1 MVP Implementation (Complete!)
|
|
||||||
|
|
||||||
#### Enhanced Message System
|
|
||||||
Implemented the **core differentiating feature** of the application:
|
|
||||||
|
|
||||||
**Three Message Types:**
|
|
||||||
- **🔒 Private Messages** - Character ↔ Storyteller only
|
|
||||||
- **📢 Public Messages** - Visible to all players (action feed)
|
|
||||||
- **🔀 Mixed Messages** - Public action + secret motive
|
|
||||||
|
|
||||||
**Example Use Case:**
|
|
||||||
```
|
|
||||||
Player sends mixed message:
|
|
||||||
Public: "I shake hands with the merchant warmly"
|
|
||||||
Private: "While shaking, I try to pickpocket his coin purse"
|
|
||||||
|
|
||||||
Result:
|
|
||||||
- All players see: "I shake hands with the merchant"
|
|
||||||
- Only storyteller sees: "I try to pickpocket his coin purse"
|
|
||||||
```
|
|
||||||
|
|
||||||
**Implementation:**
|
|
||||||
- Updated backend `Message` model with visibility fields
|
|
||||||
- Added `public_messages` array to `GameSession`
|
|
||||||
- WebSocket routing for all message types
|
|
||||||
- Frontend message composer with type selector
|
|
||||||
- Separate public/private message displays
|
|
||||||
|
|
||||||
#### AI-Assisted Responses (Quick Win)
|
|
||||||
- Added "✨ AI Suggest" button in storyteller interface
|
|
||||||
- Generates contextual responses using character's LLM
|
|
||||||
- Editable before sending
|
|
||||||
- Visual loading state
|
|
||||||
|
|
||||||
### 2. ✅ Comprehensive Test Suite (88.9% Pass Rate)
|
|
||||||
|
|
||||||
Created 54 tests across 3 test files:
|
|
||||||
|
|
||||||
#### test_models.py (25 tests - ✅ 100% pass)
|
|
||||||
- Message creation and validation
|
|
||||||
- Character model testing
|
|
||||||
- GameSession functionality
|
|
||||||
- Message visibility logic
|
|
||||||
- Character isolation verification
|
|
||||||
|
|
||||||
#### test_api.py (23 tests - ✅ 100% pass)
|
|
||||||
- Session CRUD endpoints
|
|
||||||
- Character management
|
|
||||||
- Available models endpoint
|
|
||||||
- Error handling (404s)
|
|
||||||
- State persistence
|
|
||||||
|
|
||||||
#### test_websockets.py (23 tests - ⚠️ 74% pass)
|
|
||||||
- WebSocket connections ✅
|
|
||||||
- Message routing ⚠️ (6 async tests fail - TestClient limitation)
|
|
||||||
- Storyteller responses ⚠️
|
|
||||||
- Scene narration ⚠️
|
|
||||||
- Connection management ✅
|
|
||||||
|
|
||||||
**Coverage:** 78% (171/219 statements)
|
|
||||||
|
|
||||||
**Test Quality:**
|
|
||||||
- All critical paths tested
|
|
||||||
- Error handling validated
|
|
||||||
- Character isolation confirmed
|
|
||||||
- Message visibility verified
|
|
||||||
|
|
||||||
### 3. 📚 Documentation Created
|
|
||||||
|
|
||||||
Created comprehensive documentation:
|
|
||||||
|
|
||||||
1. **CURRENT_STATUS.md** - Complete feature overview
|
|
||||||
2. **MVP_PROGRESS.md** - Detailed progress tracking
|
|
||||||
3. **TESTING_GUIDE.md** - Manual test scenarios
|
|
||||||
4. **TEST_RESULTS.md** - Test suite analysis
|
|
||||||
5. **SESSION_SUMMARY.md** - This document
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Statistics
|
|
||||||
|
|
||||||
### Code Changes
|
|
||||||
- **Files Modified:** 7
|
|
||||||
- **Lines Added:** 1,398+
|
|
||||||
- **Backend Changes:** `main.py` (message system)
|
|
||||||
- **Frontend Changes:** `CharacterView.js`, `StorytellerView.js`
|
|
||||||
- **CSS Added:** Public/private message styling
|
|
||||||
- **Tests Added:** 54 comprehensive tests
|
|
||||||
|
|
||||||
### Test Results
|
|
||||||
- **Total Tests:** 54
|
|
||||||
- **Passed:** 48 (88.9%)
|
|
||||||
- **Failed:** 6 (WebSocket async - known limitation)
|
|
||||||
- **Coverage:** 78%
|
|
||||||
- **Status:** ✅ Production ready
|
|
||||||
|
|
||||||
### Features Completed
|
|
||||||
- ✅ Private messages
|
|
||||||
- ✅ Public messages
|
|
||||||
- ✅ Mixed messages
|
|
||||||
- ✅ AI-assisted responses
|
|
||||||
- ✅ Public action feed
|
|
||||||
- ✅ Message type selector
|
|
||||||
- ✅ Visual distinction between types
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛠️ Technical Highlights
|
|
||||||
|
|
||||||
### Backend Architecture
|
|
||||||
```python
|
|
||||||
class Message(BaseModel):
|
|
||||||
visibility: str = "private" # "public", "private", "mixed"
|
|
||||||
public_content: Optional[str] = None
|
|
||||||
private_content: Optional[str] = None
|
|
||||||
|
|
||||||
class GameSession(BaseModel):
|
|
||||||
public_messages: List[Message] = [] # Shared feed
|
|
||||||
```
|
|
||||||
|
|
||||||
### Message Routing Logic
|
|
||||||
```
|
|
||||||
Private → Character's private history only
|
|
||||||
Public → public_messages feed (broadcast to all)
|
|
||||||
Mixed → Both public_messages AND private history
|
|
||||||
```
|
|
||||||
|
|
||||||
### Frontend Components
|
|
||||||
- Message type selector (dropdown)
|
|
||||||
- Public messages section (highlighted feed)
|
|
||||||
- Private conversation section
|
|
||||||
- Mixed message composer (dual textareas)
|
|
||||||
- AI suggestion button (storyteller only)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 MVP Progress
|
|
||||||
|
|
||||||
### Phase 1: Enhanced Message System ✅ COMPLETE
|
|
||||||
- [x] Public/Private/Mixed message types
|
|
||||||
- [x] Message type selector UI
|
|
||||||
- [x] Message filtering logic
|
|
||||||
- [x] WebSocket handling
|
|
||||||
- [x] Public message broadcasting
|
|
||||||
|
|
||||||
### Phase 2: Character Profile System ⏳ NEXT
|
|
||||||
**Target:** 1-2 days
|
|
||||||
|
|
||||||
**Features to Implement:**
|
|
||||||
- Race selection (Human/Elf/Dwarf/Orc/Halfling)
|
|
||||||
- Class selection (Warrior/Wizard/Cleric/Archer/Rogue)
|
|
||||||
- Personality (Friendly/Serious/Doubtful/Measured)
|
|
||||||
- Profile-based LLM prompts
|
|
||||||
- Character import/export (JSON & PNG)
|
|
||||||
- Avatar upload
|
|
||||||
|
|
||||||
**Estimated Time:** 8-12 hours
|
|
||||||
|
|
||||||
### Overall MVP Status
|
|
||||||
- **Phase 1:** ✅ 100%
|
|
||||||
- **Phase 2:** ⏳ 0%
|
|
||||||
- **Phase 3:** ⏳ 0%
|
|
||||||
- **Phase 4:** ⏳ 0%
|
|
||||||
- **Phase 5:** ⏳ 0%
|
|
||||||
- **Phase 6:** ⏳ 0%
|
|
||||||
- **Overall:** ~8% (1/12 weeks)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🐛 Known Issues
|
|
||||||
|
|
||||||
### Minor Issues
|
|
||||||
1. **Pydantic Deprecation Warnings** (10 occurrences)
|
|
||||||
- Fix: Replace `.dict()` with `.model_dump()`
|
|
||||||
- Time: 5 minutes
|
|
||||||
- Priority: Medium
|
|
||||||
|
|
||||||
2. **Character Names in Public Feed**
|
|
||||||
- Public messages don't show which character sent them
|
|
||||||
- Time: 30 minutes
|
|
||||||
- Priority: Medium
|
|
||||||
|
|
||||||
3. **WebSocket Test Failures** (6 tests)
|
|
||||||
- TestClient limitation, not code issue
|
|
||||||
- Production functionality verified
|
|
||||||
- Priority: Low (accept as-is)
|
|
||||||
|
|
||||||
### Future Needs
|
|
||||||
- Database persistence (SQLite → PostgreSQL)
|
|
||||||
- Session authentication
|
|
||||||
- Character profiles (Phase 2)
|
|
||||||
- Game save/load
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 Files Changed
|
|
||||||
|
|
||||||
### Backend
|
|
||||||
- `main.py` - Message system, public_messages, routing
|
|
||||||
|
|
||||||
### Frontend
|
|
||||||
- `src/components/CharacterView.js` - Message composer, public feed
|
|
||||||
- `src/components/StorytellerView.js` - AI suggest, public feed
|
|
||||||
- `src/App.css` - Public/private message styling
|
|
||||||
|
|
||||||
### Tests
|
|
||||||
- `tests/test_models.py` - Model validation (25 tests)
|
|
||||||
- `tests/test_api.py` - API endpoints (23 tests)
|
|
||||||
- `tests/test_websockets.py` - WebSocket functionality (23 tests)
|
|
||||||
- `pytest.ini` - Test configuration
|
|
||||||
- `requirements.txt` - Added pytest dependencies
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
- `CURRENT_STATUS.md` - Feature overview
|
|
||||||
- `MVP_PROGRESS.md` - Progress tracking
|
|
||||||
- `TESTING_GUIDE.md` - Test scenarios
|
|
||||||
- `TEST_RESULTS.md` - Test analysis
|
|
||||||
- `SESSION_SUMMARY.md` - This file
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎓 What We Learned
|
|
||||||
|
|
||||||
### Technical Insights
|
|
||||||
1. **Message Visibility is Key** - The public/private/mixed system is what makes this RPG app unique
|
|
||||||
2. **WebSocket Testing is Hard** - TestClient has async limitations; integration tests needed
|
|
||||||
3. **Pydantic V2 Changes** - Need to update `.dict()` to `.model_dump()`
|
|
||||||
4. **Test-First Approach** - Having tests before Phase 2 will speed development
|
|
||||||
|
|
||||||
### Design Decisions
|
|
||||||
1. **Three Message Types** - Simple but powerful system
|
|
||||||
2. **Separate Feeds** - Public messages in their own feed vs private conversation
|
|
||||||
3. **Mixed Messages** - Most interesting feature for dramatic gameplay
|
|
||||||
4. **AI Suggestions** - Quick win that adds huge value
|
|
||||||
|
|
||||||
### Best Practices Applied
|
|
||||||
- Comprehensive unit tests
|
|
||||||
- Clear documentation
|
|
||||||
- Git commit messages
|
|
||||||
- Code coverage tracking
|
|
||||||
- Error handling validation
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Definition of Done
|
|
||||||
|
|
||||||
### Phase 1 Checklist
|
|
||||||
- [x] Message visibility fields added to models
|
|
||||||
- [x] Public messages feed implemented
|
|
||||||
- [x] WebSocket routing for all message types
|
|
||||||
- [x] Frontend message type selector
|
|
||||||
- [x] Public/private message displays
|
|
||||||
- [x] AI suggestion button
|
|
||||||
- [x] Visual distinction between types
|
|
||||||
- [x] Tests written (88.9% pass rate)
|
|
||||||
- [x] Documentation complete
|
|
||||||
- [x] Code committed to git
|
|
||||||
|
|
||||||
**Phase 1 Status:** ✅ **COMPLETE**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Next Session Priorities
|
|
||||||
|
|
||||||
### Immediate (Start of Next Session)
|
|
||||||
|
|
||||||
1. **Fix Pydantic Warnings** (5 minutes)
|
|
||||||
```python
|
|
||||||
# Replace in main.py
|
|
||||||
msg.dict() → msg.model_dump()
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Add Character Names to Public Feed** (30 minutes)
|
|
||||||
- Include character name in public message broadcasts
|
|
||||||
- Display: "Gandalf: I wave to the group"
|
|
||||||
|
|
||||||
### Phase 2 Implementation (Main Work)
|
|
||||||
|
|
||||||
3. **Character Profile Models** (2 hours)
|
|
||||||
- Add gender, race, class, personality fields
|
|
||||||
- Create profile prompt templates
|
|
||||||
- Update Character model
|
|
||||||
|
|
||||||
4. **Character Creation Wizard** (4 hours)
|
|
||||||
- Multi-step form UI
|
|
||||||
- Dropdown selectors
|
|
||||||
- Profile preview
|
|
||||||
- Custom prompts section
|
|
||||||
|
|
||||||
5. **Profile-Based LLM Prompts** (2 hours)
|
|
||||||
- Combine race + class + personality
|
|
||||||
- Inject into character LLM requests
|
|
||||||
- Test with different combinations
|
|
||||||
|
|
||||||
6. **Character Import/Export** (3 hours)
|
|
||||||
- JSON export/import
|
|
||||||
- PNG with metadata (stretch goal)
|
|
||||||
- Profile validation
|
|
||||||
|
|
||||||
7. **Phase 2 Tests** (2 hours)
|
|
||||||
- Test profile creation
|
|
||||||
- Test LLM prompt building
|
|
||||||
- Test import/export
|
|
||||||
- Aim for 80%+ coverage
|
|
||||||
|
|
||||||
**Total Estimated Time for Phase 2:** 12-15 hours (1.5-2 days)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💡 Recommendations
|
|
||||||
|
|
||||||
### Technical
|
|
||||||
1. ✅ **Tests First Approach** - We have good test coverage now
|
|
||||||
2. 🔄 **Incremental Commits** - Keep committing as features complete
|
|
||||||
3. 📝 **Update Documentation** - Keep docs in sync with code
|
|
||||||
4. 🎯 **One Feature at a Time** - Finish Phase 2 before Phase 3
|
|
||||||
|
|
||||||
### Process
|
|
||||||
1. **Manual Testing** - Test the enhanced message system manually
|
|
||||||
2. **Git Branches** - Stay on `mvp-phase-02` for Phase 2 work
|
|
||||||
3. **Coverage Goals** - Maintain 75%+ test coverage
|
|
||||||
4. **Documentation** - Update MVP_PROGRESS.md as you go
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📈 Success Metrics
|
|
||||||
|
|
||||||
### Achieved Today
|
|
||||||
- ✅ **Phase 1 Complete** - Core feature fully implemented
|
|
||||||
- ✅ **54 Tests Written** - Comprehensive test coverage
|
|
||||||
- ✅ **88.9% Pass Rate** - High quality tests
|
|
||||||
- ✅ **78% Code Coverage** - Excellent for MVP
|
|
||||||
- ✅ **5 Documentation Files** - Well-documented
|
|
||||||
- ✅ **All Committed to Git** - Clean version control
|
|
||||||
|
|
||||||
### Quality Indicators
|
|
||||||
- Zero critical bugs
|
|
||||||
- All core features working
|
|
||||||
- Tests passing for critical paths
|
|
||||||
- Documentation comprehensive
|
|
||||||
- Code reviewed and committed
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎉 Celebration Points!
|
|
||||||
|
|
||||||
**Huge Wins Today:**
|
|
||||||
1. 🎯 **Phase 1 MVP Feature Complete** - The message visibility system works beautifully
|
|
||||||
2. 🧪 **Test Suite Established** - 54 tests give us confidence
|
|
||||||
3. 📚 **Documentation Complete** - Easy to pick up next session
|
|
||||||
4. 🚀 **Production Ready** - Both servers running with new features
|
|
||||||
5. 💪 **Solid Foundation** - Ready for Phase 2 character profiles
|
|
||||||
|
|
||||||
**This is excellent progress!** The enhanced message system is the heart of what makes this RPG app unique. Players can now perform public actions while keeping secrets - exactly what you need for dramatic gameplay.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔮 Looking Ahead
|
|
||||||
|
|
||||||
### Next Session Goals
|
|
||||||
1. Implement Phase 2 (Character Profiles)
|
|
||||||
2. Add race/class/personality system
|
|
||||||
3. Build character creation wizard
|
|
||||||
4. Create profile-based LLM prompts
|
|
||||||
5. Add import/export functionality
|
|
||||||
|
|
||||||
### Future Phases
|
|
||||||
- **Phase 3:** User mode interfaces (Player/Storyteller/Gamemaster)
|
|
||||||
- **Phase 4:** AI automation (AI players & storytellers)
|
|
||||||
- **Phase 5:** Database & game management
|
|
||||||
- **Phase 6:** Polish & testing
|
|
||||||
|
|
||||||
**The MVP roadmap is solid, and we're executing well!**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Final Stats
|
|
||||||
|
|
||||||
| Metric | Value |
|
|
||||||
|--------|-------|
|
|
||||||
| **Session Duration** | ~2 hours |
|
|
||||||
| **Features Completed** | Phase 1 + AI Suggest + Tests |
|
|
||||||
| **Tests Written** | 54 |
|
|
||||||
| **Test Pass Rate** | 88.9% |
|
|
||||||
| **Code Coverage** | 78% |
|
|
||||||
| **Lines of Code Added** | 1,398+ |
|
|
||||||
| **Files Modified** | 7 |
|
|
||||||
| **Documentation Pages** | 5 |
|
|
||||||
| **Git Commits** | 1 major commit |
|
|
||||||
| **MVP Progress** | 8% → 16% (Phase 1 done!) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Session Complete!
|
|
||||||
|
|
||||||
**Status:** ✅ **Highly Successful**
|
|
||||||
|
|
||||||
We've completed Phase 1 of the MVP roadmap, added a comprehensive test suite with 88.9% pass rate, and created detailed documentation. The enhanced message system (private/public/mixed) is working perfectly - this is the core feature that makes your RPG app unique.
|
|
||||||
|
|
||||||
**Ready for Phase 2!** 🚀
|
|
||||||
|
|
||||||
The test suite gives us confidence to build character profiles knowing we won't break existing functionality. Great work!
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Commands to Remember:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run tests
|
|
||||||
.venv/bin/pytest -v
|
|
||||||
|
|
||||||
# Run specific test file
|
|
||||||
.venv/bin/pytest tests/test_models.py -v
|
|
||||||
|
|
||||||
# Run with coverage
|
|
||||||
.venv/bin/pytest --cov=main --cov-report=html
|
|
||||||
|
|
||||||
# Start application
|
|
||||||
bash start.sh
|
|
||||||
|
|
||||||
# Check servers
|
|
||||||
curl http://localhost:8000/docs # Backend API
|
|
||||||
curl http://localhost:3000 # Frontend
|
|
||||||
```
|
|
||||||
|
|
||||||
**Next Session:** Start with character profile system implementation! 🎭
|
|
||||||
155
TESTING_PHASE2.md
Normal file
155
TESTING_PHASE2.md
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
# Phase 2 Testing Guide
|
||||||
|
|
||||||
|
## 🎯 Quick Testing Steps
|
||||||
|
|
||||||
|
### 1. Start the Application
|
||||||
|
```bash
|
||||||
|
# Terminal 1 - Backend
|
||||||
|
cd /home/aodhan/projects/apps/storyteller
|
||||||
|
python -m uvicorn main:app --reload --port 8000
|
||||||
|
|
||||||
|
# Terminal 2 - Frontend
|
||||||
|
cd frontend
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Test Character Creation Wizard
|
||||||
|
|
||||||
|
1. **Open browser:** http://localhost:3000
|
||||||
|
2. **Enter Session ID:** Type any session ID (e.g., "test-session-123")
|
||||||
|
3. **Click "✨ Create Character (Wizard)"**
|
||||||
|
4. **Step through wizard:**
|
||||||
|
- Step 1: Enter name, select gender
|
||||||
|
- Step 2: Add description and background
|
||||||
|
- Step 3: Choose race and class (click cards)
|
||||||
|
- Step 4: Select personality type
|
||||||
|
- Step 5: Choose AI model
|
||||||
|
- Step 6: Review and create
|
||||||
|
|
||||||
|
### 3. Test Character Profile Display
|
||||||
|
|
||||||
|
1. After creating character, check:
|
||||||
|
- Profile badges appear (Race, Class, Personality)
|
||||||
|
- Character info shows all details
|
||||||
|
- Export button is visible
|
||||||
|
|
||||||
|
### 4. Test Export
|
||||||
|
|
||||||
|
1. Click "📥 Export" button in character view
|
||||||
|
2. JSON file should download
|
||||||
|
3. Open JSON to verify all profile data is present
|
||||||
|
|
||||||
|
### 5. Test Import
|
||||||
|
|
||||||
|
1. Create a new session or use existing
|
||||||
|
2. Click "✨ Create Character (Wizard)"
|
||||||
|
3. In Step 1, click "📥 Import from JSON"
|
||||||
|
4. Select previously exported character
|
||||||
|
5. Verify all fields are populated
|
||||||
|
6. Complete wizard to create
|
||||||
|
|
||||||
|
### 6. Test Profile-Based LLM Prompts
|
||||||
|
|
||||||
|
1. Send a message as the character
|
||||||
|
2. Check backend logs for generated system prompt
|
||||||
|
3. Should include race, class, and personality traits
|
||||||
|
|
||||||
|
### 7. Test Backward Compatibility
|
||||||
|
|
||||||
|
1. Click "↓ Quick Create" toggle
|
||||||
|
2. Fill in simple form (legacy mode)
|
||||||
|
3. Create character without profile
|
||||||
|
4. Character should work normally
|
||||||
|
|
||||||
|
## ✅ Expected Behavior
|
||||||
|
|
||||||
|
### Wizard
|
||||||
|
- [x] Smooth step navigation
|
||||||
|
- [x] Visual progress indicator
|
||||||
|
- [x] Selection cards highlight when clicked
|
||||||
|
- [x] Form validation (name required, description required)
|
||||||
|
- [x] Import populates all fields
|
||||||
|
- [x] Review shows complete summary
|
||||||
|
|
||||||
|
### Profile Display
|
||||||
|
- [x] Badges show race, class, personality
|
||||||
|
- [x] Character info section displays properly
|
||||||
|
- [x] Export button functional
|
||||||
|
|
||||||
|
### Export/Import
|
||||||
|
- [x] Export downloads valid JSON
|
||||||
|
- [x] JSON includes version, timestamp, character data
|
||||||
|
- [x] Import reads JSON correctly
|
||||||
|
- [x] Imported character gets new ID
|
||||||
|
|
||||||
|
### LLM Integration
|
||||||
|
- [x] System prompts include profile traits
|
||||||
|
- [x] Legacy characters still work
|
||||||
|
- [x] Profile-based prompts are coherent
|
||||||
|
|
||||||
|
## 🐛 Known Issues
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- ✅ Syntax error with escaped quotes in docstring (fixed)
|
||||||
|
|
||||||
|
### To Monitor
|
||||||
|
- Webpack deprecation warnings (harmless, won't affect functionality)
|
||||||
|
- Frontend hot reload may require manual refresh
|
||||||
|
|
||||||
|
## 🎮 Demo Session Test
|
||||||
|
|
||||||
|
Try the pre-configured demo:
|
||||||
|
1. Click "🏹 Play as Willow (Elf Ranger)"
|
||||||
|
2. Willow should have legacy profile (no structured profile)
|
||||||
|
3. Create new character with wizard
|
||||||
|
4. Compare the two in gameplay
|
||||||
|
|
||||||
|
## 📊 Profile Options to Test
|
||||||
|
|
||||||
|
### Races
|
||||||
|
- [ ] Human
|
||||||
|
- [ ] Elf
|
||||||
|
- [ ] Dwarf
|
||||||
|
- [ ] Orc
|
||||||
|
- [ ] Halfling
|
||||||
|
|
||||||
|
### Classes
|
||||||
|
- [ ] Warrior
|
||||||
|
- [ ] Wizard
|
||||||
|
- [ ] Cleric
|
||||||
|
- [ ] Archer
|
||||||
|
- [ ] Rogue
|
||||||
|
|
||||||
|
### Personalities
|
||||||
|
- [ ] Friendly
|
||||||
|
- [ ] Serious
|
||||||
|
- [ ] Doubtful
|
||||||
|
- [ ] Measured
|
||||||
|
|
||||||
|
### Combinations to Try
|
||||||
|
- Elf Wizard (Measured) - Classic magic user
|
||||||
|
- Dwarf Warrior (Serious) - Traditional tank
|
||||||
|
- Halfling Rogue (Friendly) - Lovable trickster
|
||||||
|
- Orc Cleric (Doubtful) - Interesting contrast
|
||||||
|
- Human Archer (Measured) - Balanced ranger
|
||||||
|
|
||||||
|
## 🔍 What to Check in Backend Logs
|
||||||
|
|
||||||
|
When character sends message, look for system prompt like:
|
||||||
|
```
|
||||||
|
You are [Name], a [gender] [race] [class]. [Description]
|
||||||
|
[Race traits] [Class traits] [Personality traits]
|
||||||
|
Background: [background if provided]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 Feedback to Provide
|
||||||
|
|
||||||
|
- UI/UX impressions
|
||||||
|
- Any bugs or errors
|
||||||
|
- Performance issues
|
||||||
|
- Suggested improvements
|
||||||
|
- Missing features
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Ready to test!** Start both servers and follow the steps above.
|
||||||
168
docs/README.md
168
docs/README.md
@@ -1,66 +1,152 @@
|
|||||||
# 📚 Storyteller RPG - Documentation
|
# 📚 Storyteller RPG Documentation
|
||||||
|
|
||||||
Welcome to the Storyteller RPG documentation. All project documentation is organized here by category.
|
Welcome to the Storyteller RPG documentation hub. All project documentation is organized here for easy navigation.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📁 Documentation Structure
|
## 📂 Documentation Structure
|
||||||
|
|
||||||
### 🚀 [setup/](./setup/)
|
### ✨ [Features](./features/)
|
||||||
**Getting started guides and quick references**
|
|
||||||
|
|
||||||
- **[QUICKSTART.md](./setup/QUICKSTART.md)** - 5-minute quick start guide
|
Comprehensive feature documentation with examples and guides.
|
||||||
- **[QUICK_REFERENCE.md](./setup/QUICK_REFERENCE.md)** - Quick reference for common tasks
|
|
||||||
|
|
||||||
### 📋 [planning/](./planning/)
|
- **[Features Overview](./features/README.md)** - Complete feature catalog
|
||||||
**Product roadmaps and feature planning**
|
- **[Demo Session Guide](./features/DEMO_SESSION.md)** - Using the pre-configured test session
|
||||||
|
- **[Context-Aware Responses](./features/CONTEXTUAL_RESPONSE_FEATURE.md)** - Multi-character AI generation
|
||||||
|
- **[Prompt Engineering](./features/PROMPT_IMPROVEMENTS.md)** - LLM prompt techniques
|
||||||
|
- **[Bug Fixes](./features/FIXES_SUMMARY.md)** - Recent fixes and improvements
|
||||||
|
|
||||||
- **[MVP_ROADMAP.md](./planning/MVP_ROADMAP.md)** - MVP feature requirements and roadmap
|
### 🚀 [Setup Guides](./setup/)
|
||||||
- **[NEXT_STEPS.md](./planning/NEXT_STEPS.md)** - Detailed future development roadmap
|
|
||||||
- **[PROJECT_PLAN.md](./planning/PROJECT_PLAN.md)** - Overall project planning and goals
|
|
||||||
|
|
||||||
### 📖 [reference/](./reference/)
|
Get started quickly with installation and configuration guides.
|
||||||
**Technical references and guides**
|
|
||||||
|
|
||||||
- **[LLM_GUIDE.md](./reference/LLM_GUIDE.md)** - Guide to available LLM models
|
- **[Quickstart Guide](./setup/QUICKSTART.md)** - Step-by-step setup instructions
|
||||||
- **[PROJECT_FILES_REFERENCE.md](./reference/PROJECT_FILES_REFERENCE.md)** - Complete file structure reference
|
- **[Quick Reference](./setup/QUICK_REFERENCE.md)** - Common commands and workflows
|
||||||
|
|
||||||
### 🔧 [development/](./development/)
|
### 📋 [Planning & Roadmap](./planning/)
|
||||||
**Development session notes and implementation details**
|
|
||||||
|
|
||||||
- **[SESSION_SUMMARY.md](./development/SESSION_SUMMARY.md)** - Complete development session summary
|
Project vision, milestones, and future plans.
|
||||||
- **[IMPLEMENTATION_SUMMARY.md](./development/IMPLEMENTATION_SUMMARY.md)** - Technical implementation details
|
|
||||||
|
- **[Project Plan](./planning/PROJECT_PLAN.md)** - Overall project structure and goals
|
||||||
|
- **[MVP Roadmap](./planning/MVP_ROADMAP.md)** - Minimum viable product phases
|
||||||
|
- **[Next Steps](./planning/NEXT_STEPS.md)** - Immediate priorities and tasks
|
||||||
|
|
||||||
|
### 🔧 [Development](./development/)
|
||||||
|
|
||||||
|
Technical implementation details and testing.
|
||||||
|
|
||||||
|
- **[MVP Progress](./development/MVP_PROGRESS.md)** - Current status and achievements
|
||||||
|
- **[Testing Guide](./development/TESTING_GUIDE.md)** - How to test the application
|
||||||
|
- **[Test Results](./development/TEST_RESULTS.md)** - Latest test results
|
||||||
|
|
||||||
|
### 📖 [Reference](./reference/)
|
||||||
|
|
||||||
|
Technical guides and comprehensive references.
|
||||||
|
|
||||||
|
- **[LLM Guide](./reference/LLM_GUIDE.md)** - Working with different AI models
|
||||||
|
- **[Project Files Reference](./reference/PROJECT_FILES_REFERENCE.md)** - Complete file structure
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🎯 Quick Navigation
|
## 🔗 Quick Links
|
||||||
|
|
||||||
**New to the project?**
|
### For New Users
|
||||||
1. Start with the main [README.md](../README.md) in the root directory
|
1. ⚡ Start with [Quickstart Guide](./setup/QUICKSTART.md)
|
||||||
2. Follow [setup/QUICKSTART.md](./setup/QUICKSTART.md) to get running
|
2. 🎮 Try the [Demo Session](./features/DEMO_SESSION.md) (pre-configured!)
|
||||||
3. Review [planning/MVP_ROADMAP.md](./planning/MVP_ROADMAP.md) to understand the vision
|
3. 📖 Review [Features Overview](./features/README.md) to see what's possible
|
||||||
|
4. 🤖 Check [LLM Guide](./reference/LLM_GUIDE.md) for model selection
|
||||||
|
|
||||||
**Want to contribute?**
|
### For Developers
|
||||||
1. Read [development/SESSION_SUMMARY.md](./development/SESSION_SUMMARY.md) for architecture
|
1. 🔧 Read [MVP Progress](./development/MVP_PROGRESS.md) for current state
|
||||||
2. Check [planning/NEXT_STEPS.md](./planning/NEXT_STEPS.md) for feature priorities
|
2. 🧪 Check [Testing Guide](./development/TESTING_GUIDE.md)
|
||||||
3. Refer to [reference/PROJECT_FILES_REFERENCE.md](./reference/PROJECT_FILES_REFERENCE.md) for code navigation
|
3. 📁 Review [Project Files Reference](./reference/PROJECT_FILES_REFERENCE.md)
|
||||||
|
4. 🚀 Follow [Next Steps](./planning/NEXT_STEPS.md) for contribution areas
|
||||||
|
|
||||||
**Looking for specific info?**
|
### For Storytellers
|
||||||
- **Setup/Installation** → [setup/](./setup/)
|
1. 🎭 See [Features Guide](./features/README.md) for all tools
|
||||||
- **Features & Roadmap** → [planning/](./planning/)
|
2. 🧠 Learn about [Context-Aware Responses](./features/CONTEXTUAL_RESPONSE_FEATURE.md)
|
||||||
- **API/Models/Files** → [reference/](./reference/)
|
3. 💡 Use [Quick Reference](./setup/QUICK_REFERENCE.md) for common tasks
|
||||||
- **Architecture** → [development/](./development/)
|
4. 🎲 Start with [Demo Session](./features/DEMO_SESSION.md) for practice
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📊 Documentation Overview
|
## 📊 Current Status (v0.2.0)
|
||||||
|
|
||||||
| Category | Files | Purpose |
|
### ✅ Completed Features
|
||||||
|----------|-------|---------|
|
- Private/public/mixed messaging system
|
||||||
| **Setup** | 2 | Getting started and quick references |
|
- Context-aware AI response generator
|
||||||
| **Planning** | 3 | Roadmaps, feature plans, project goals |
|
- Demo session with pre-configured characters
|
||||||
| **Reference** | 2 | Technical guides and file references |
|
- Real-time WebSocket communication
|
||||||
| **Development** | 2 | Session notes and implementation details |
|
- Multi-LLM support (GPT-4o, Claude, Llama, etc.)
|
||||||
|
- AI-assisted storyteller suggestions
|
||||||
|
- Session ID quick copy
|
||||||
|
- Full conversation history
|
||||||
|
|
||||||
|
### 🚧 Coming Soon
|
||||||
|
- Database persistence
|
||||||
|
- Character sheets & stats
|
||||||
|
- Dice rolling mechanics
|
||||||
|
- Combat system
|
||||||
|
- Image generation
|
||||||
|
- Voice messages
|
||||||
|
|
||||||
|
See [MVP Roadmap](./planning/MVP_ROADMAP.md) for the complete timeline.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Documentation Principles
|
||||||
|
|
||||||
|
This documentation follows these principles:
|
||||||
|
|
||||||
|
- **Progressive Disclosure**: Start simple, dive deeper as needed
|
||||||
|
- **Always Current**: Updated with each feature implementation
|
||||||
|
- **Example-Driven**: Real code examples and use cases
|
||||||
|
- **Clear Structure**: Logical organization for easy navigation
|
||||||
|
- **Feature-Focused**: Detailed guides for every feature
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Documentation Map
|
||||||
|
|
||||||
|
```
|
||||||
|
docs/
|
||||||
|
├── features/ ← Feature guides & examples
|
||||||
|
│ ├── README.md
|
||||||
|
│ ├── DEMO_SESSION.md
|
||||||
|
│ ├── CONTEXTUAL_RESPONSE_FEATURE.md
|
||||||
|
│ ├── PROMPT_IMPROVEMENTS.md
|
||||||
|
│ └── FIXES_SUMMARY.md
|
||||||
|
├── setup/ ← Installation & quick start
|
||||||
|
│ ├── QUICKSTART.md
|
||||||
|
│ └── QUICK_REFERENCE.md
|
||||||
|
├── planning/ ← Roadmap & future plans
|
||||||
|
│ ├── PROJECT_PLAN.md
|
||||||
|
│ ├── MVP_ROADMAP.md
|
||||||
|
│ └── NEXT_STEPS.md
|
||||||
|
├── development/ ← Technical & testing docs
|
||||||
|
│ ├── MVP_PROGRESS.md
|
||||||
|
│ ├── TESTING_GUIDE.md
|
||||||
|
│ └── TEST_RESULTS.md
|
||||||
|
└── reference/ ← Technical references
|
||||||
|
├── LLM_GUIDE.md
|
||||||
|
└── PROJECT_FILES_REFERENCE.md
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🤝 Contributing to Documentation
|
||||||
|
|
||||||
|
Found a typo or want to improve the docs? Contributions are welcome!
|
||||||
|
|
||||||
|
1. Documentation lives in the `docs/` folder
|
||||||
|
2. Use clear, concise language
|
||||||
|
3. Include examples where helpful
|
||||||
|
4. Keep formatting consistent
|
||||||
|
5. Update relevant indexes when adding new docs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Need help?** Start with the [Quickstart Guide](./setup/QUICKSTART.md) or check the main [README](../README.md).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,126 +0,0 @@
|
|||||||
# Implementation Summary
|
|
||||||
|
|
||||||
## ✅ Completed Features
|
|
||||||
|
|
||||||
### Backend (`main.py`)
|
|
||||||
- **Isolated Character Sessions**: Each character has a separate conversation history that only they and the storyteller can see
|
|
||||||
- **Private WebSocket Channels**:
|
|
||||||
- `/ws/character/{session_id}/{character_id}` - Character's private connection
|
|
||||||
- `/ws/storyteller/{session_id}` - Storyteller's master connection
|
|
||||||
- **Message Routing**: Messages flow privately between storyteller and individual characters
|
|
||||||
- **Scene Broadcasting**: Storyteller can narrate scenes visible to all characters
|
|
||||||
- **Real-time Updates**: WebSocket events for character joins, messages, and responses
|
|
||||||
- **Pending Response Tracking**: System tracks which characters are waiting for storyteller responses
|
|
||||||
- **AI Suggestions** (Optional): Endpoint for AI-assisted storyteller response generation
|
|
||||||
|
|
||||||
### Frontend Components
|
|
||||||
|
|
||||||
#### 1. **SessionSetup.js**
|
|
||||||
- Create new session (storyteller)
|
|
||||||
- Join existing session (character)
|
|
||||||
- Character creation with name, description, and personality
|
|
||||||
- Beautiful gradient UI with modern styling
|
|
||||||
|
|
||||||
#### 2. **CharacterView.js**
|
|
||||||
- Private chat interface with storyteller
|
|
||||||
- Real-time message delivery via WebSocket
|
|
||||||
- Scene narration display
|
|
||||||
- Conversation history preservation
|
|
||||||
- Connection status indicator
|
|
||||||
|
|
||||||
#### 3. **StorytellerView.js**
|
|
||||||
- Dashboard showing all characters
|
|
||||||
- Character list with pending response indicators
|
|
||||||
- Click character to view their private conversation
|
|
||||||
- Individual response system for each character
|
|
||||||
- Scene narration broadcast to all characters
|
|
||||||
- Visual indicators for pending messages
|
|
||||||
|
|
||||||
### Styling (`App.css`)
|
|
||||||
- Modern gradient theme (purple/blue)
|
|
||||||
- Responsive design
|
|
||||||
- Smooth animations and transitions
|
|
||||||
- Clear visual hierarchy
|
|
||||||
- Mobile-friendly layout
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
- **README.md**: Comprehensive guide with architecture, features, and API docs
|
|
||||||
- **QUICKSTART.md**: Fast setup and testing guide
|
|
||||||
- **.env.example**: Environment variable template
|
|
||||||
|
|
||||||
## 🔐 Privacy Implementation
|
|
||||||
|
|
||||||
The core requirement - **isolated character sessions** - is implemented through:
|
|
||||||
|
|
||||||
1. **Separate Data Structures**: Each character has `conversation_history: List[Message]`
|
|
||||||
2. **WebSocket Isolation**: Separate WebSocket connections per character
|
|
||||||
3. **Message Routing**: Messages only sent to intended recipient
|
|
||||||
4. **Storyteller View**: Only storyteller can see all conversations
|
|
||||||
5. **Scene Broadcast**: Shared narrations go to all, but conversations stay private
|
|
||||||
|
|
||||||
## 🎯 Workflow
|
|
||||||
|
|
||||||
```
|
|
||||||
Character A → Storyteller: "I search the room"
|
|
||||||
Character B → Storyteller: "I attack the guard"
|
|
||||||
↓
|
|
||||||
Storyteller sees both messages separately
|
|
||||||
↓
|
|
||||||
Storyteller → Character A: "You find a hidden key"
|
|
||||||
Storyteller → Character B: "You miss your swing"
|
|
||||||
↓
|
|
||||||
Character A only sees their conversation
|
|
||||||
Character B only sees their conversation
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📁 File Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
windsurf-project/
|
|
||||||
├── main.py # FastAPI backend with WebSocket support
|
|
||||||
├── requirements.txt # Python dependencies
|
|
||||||
├── .env.example # Environment template
|
|
||||||
├── README.md # Full documentation
|
|
||||||
├── QUICKSTART.md # Quick start guide
|
|
||||||
├── IMPLEMENTATION_SUMMARY.md # This file
|
|
||||||
└── frontend/
|
|
||||||
├── package.json
|
|
||||||
└── src/
|
|
||||||
├── App.js # Main app router
|
|
||||||
├── App.css # All styling
|
|
||||||
└── components/
|
|
||||||
├── SessionSetup.js # Session creation/join
|
|
||||||
├── CharacterView.js # Character interface
|
|
||||||
└── StorytellerView.js # Storyteller dashboard
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🚀 To Run
|
|
||||||
|
|
||||||
**Backend:**
|
|
||||||
```bash
|
|
||||||
python main.py
|
|
||||||
```
|
|
||||||
|
|
||||||
**Frontend:**
|
|
||||||
```bash
|
|
||||||
cd frontend && npm start
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🎨 Design Decisions
|
|
||||||
|
|
||||||
1. **WebSocket over REST**: Real-time bidirectional communication required for instant message delivery
|
|
||||||
2. **In-Memory Storage**: Simple session management; can be replaced with database for production
|
|
||||||
3. **Component-Based Frontend**: Separate views for different roles (setup, character, storyteller)
|
|
||||||
4. **Message Model**: Includes sender, content, timestamp for rich conversation history
|
|
||||||
5. **Pending Response Flag**: Helps storyteller track which characters need attention
|
|
||||||
|
|
||||||
## 🔮 Future Enhancements
|
|
||||||
|
|
||||||
- Database persistence (PostgreSQL/MongoDB)
|
|
||||||
- User authentication
|
|
||||||
- Character sheets with stats
|
|
||||||
- Dice rolling system
|
|
||||||
- Voice/audio support
|
|
||||||
- Mobile apps
|
|
||||||
- Multi-storyteller support
|
|
||||||
- Group chat rooms (for party discussions)
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
# 🎯 MVP Progress Report
|
# 🎯 MVP Progress Report
|
||||||
|
|
||||||
**Last Updated:** October 11, 2025
|
**Last Updated:** October 12, 2025
|
||||||
**Status:** Phase 1 Complete, Moving to Phase 2
|
**Status:** Phase 2 Complete, Moving to Phase 3
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -70,32 +70,48 @@
|
|||||||
- Public/private message flow ✅
|
- Public/private message flow ✅
|
||||||
- WebSocket handling for all types ✅
|
- WebSocket handling for all types ✅
|
||||||
|
|
||||||
### 🔄 Phase 2: Character Profile System (NEXT)
|
### ✅ Phase 2: Character Profile System (COMPLETE)
|
||||||
**Target:** Week 3-4
|
**Completed:** October 12, 2025
|
||||||
|
|
||||||
**Tasks:**
|
**Implemented:**
|
||||||
1. Extend `Character` model with profile fields
|
1. ✅ Extended `Character` model with profile fields
|
||||||
- Gender (Male/Female/Non-binary/Custom)
|
- Gender (Male/Female/Non-binary/Custom)
|
||||||
- Race (Human/Elf/Dwarf/Orc/Halfling)
|
- Race (Human/Elf/Dwarf/Orc/Halfling)
|
||||||
- Class (Warrior/Wizard/Cleric/Archer/Rogue)
|
- Class (Warrior/Wizard/Cleric/Archer/Rogue)
|
||||||
- Personality (Friendly/Serious/Doubtful/Measured)
|
- Personality (Friendly/Serious/Doubtful/Measured)
|
||||||
- Custom background text
|
- Custom background text
|
||||||
- Avatar upload/selection
|
- Avatar data field (base64)
|
||||||
|
|
||||||
2. Profile-based LLM prompts
|
2. ✅ Profile-based LLM prompts
|
||||||
- Combine race + class + personality traits
|
- Combined race + class + personality traits
|
||||||
- Inject into character's LLM requests
|
- Injected into character's LLM requests
|
||||||
- Create prompt template system
|
- Created comprehensive prompt template system
|
||||||
|
- `build_character_system_prompt()` function
|
||||||
|
|
||||||
3. Character creation wizard
|
3. ✅ Character creation wizard
|
||||||
- Multi-step form with dropdowns
|
- 6-step form with visual selection cards
|
||||||
- Profile preview
|
- Profile preview and review step
|
||||||
- Character customization
|
- Character customization with all options
|
||||||
|
- Import from JSON functionality
|
||||||
|
|
||||||
4. Import/Export system
|
4. ✅ Import/Export system
|
||||||
- Export to JSON
|
- Export to JSON (complete)
|
||||||
- Export to PNG with metadata
|
- Import from JSON (complete)
|
||||||
- Import from JSON/PNG
|
- Export button in CharacterView
|
||||||
|
- PNG with metadata (deferred to Phase 4)
|
||||||
|
|
||||||
|
**New Files:**
|
||||||
|
- `CharacterCreationWizard.js` (419 lines)
|
||||||
|
- `CharacterCreationWizard.css` (352 lines)
|
||||||
|
- `PHASE2_IMPLEMENTATION.md` (documentation)
|
||||||
|
|
||||||
|
**Modified Files:**
|
||||||
|
- `main.py` (+186 lines)
|
||||||
|
- `SessionSetup.js` (+25 lines)
|
||||||
|
- `CharacterView.js` (+30 lines)
|
||||||
|
- `App.css` (+45 lines)
|
||||||
|
|
||||||
|
**Total:** ~1,057 lines of code
|
||||||
|
|
||||||
### ⏳ Phase 3: User Mode Interfaces (Weeks 5-7)
|
### ⏳ Phase 3: User Mode Interfaces (Weeks 5-7)
|
||||||
- Player interface refinement
|
- Player interface refinement
|
||||||
|
|||||||
351
docs/development/PHASE2_IMPLEMENTATION.md
Normal file
351
docs/development/PHASE2_IMPLEMENTATION.md
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
# Phase 2 Implementation Summary
|
||||||
|
|
||||||
|
**Date:** October 12, 2025
|
||||||
|
**Status:** ✅ Complete
|
||||||
|
**Phase:** Character Profile System (MVP Phase 2)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Overview
|
||||||
|
|
||||||
|
Successfully implemented the Character Profile System as outlined in the MVP Roadmap. This phase adds structured character creation with race, class, gender, and personality traits, along with profile-based LLM prompts and import/export functionality.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Completed Features
|
||||||
|
|
||||||
|
### 1. Backend: Character Profile Model
|
||||||
|
|
||||||
|
**File:** `main.py`
|
||||||
|
|
||||||
|
Added `CharacterProfile` model with:
|
||||||
|
- **Gender:** Male, Female, Non-binary, Custom
|
||||||
|
- **Race:** Human, Elf, Dwarf, Orc, Halfling
|
||||||
|
- **Class:** Warrior, Wizard, Cleric, Archer, Rogue
|
||||||
|
- **Personality Type:** Friendly, Serious, Doubtful, Measured
|
||||||
|
- **Background:** Custom background story
|
||||||
|
- **Avatar Data:** Base64 encoded avatar (placeholder for future image support)
|
||||||
|
|
||||||
|
Extended `Character` model to include optional `profile` field for backward compatibility with legacy characters.
|
||||||
|
|
||||||
|
### 2. Backend: Prompt Template System
|
||||||
|
|
||||||
|
**File:** `main.py` (lines 76-129)
|
||||||
|
|
||||||
|
Created comprehensive prompt templates:
|
||||||
|
|
||||||
|
#### Race Templates
|
||||||
|
- **Human:** Versatile and adaptable
|
||||||
|
- **Elf:** Graceful, wise, with keen senses and magic affinity
|
||||||
|
- **Dwarf:** Stout, loyal, master craftsmen
|
||||||
|
- **Orc:** Powerful, direct, honorable warriors
|
||||||
|
- **Halfling:** Small, brave, lucky
|
||||||
|
|
||||||
|
#### Class Templates
|
||||||
|
- **Warrior:** Physical combat, tactics, protection
|
||||||
|
- **Wizard:** Arcane magic, knowledge, intellectual approach
|
||||||
|
- **Cleric:** Divine power, healing, compassion
|
||||||
|
- **Archer:** Ranged combat, precision, patience
|
||||||
|
- **Rogue:** Stealth, cunning, unconventional solutions
|
||||||
|
|
||||||
|
#### Personality Templates
|
||||||
|
- **Friendly:** Optimistic, cooperative, trusting
|
||||||
|
- **Serious:** Focused, pragmatic, efficient
|
||||||
|
- **Doubtful:** Cautious, skeptical, analytical
|
||||||
|
- **Measured:** Balanced, thoughtful, diplomatic
|
||||||
|
|
||||||
|
**Function:** `build_character_system_prompt(character: Character) -> str`
|
||||||
|
- Combines all profile traits into cohesive system prompt
|
||||||
|
- Maintains backward compatibility with legacy characters
|
||||||
|
- Injects profile context into LLM requests
|
||||||
|
|
||||||
|
### 3. Backend: API Endpoints
|
||||||
|
|
||||||
|
**New Endpoints:**
|
||||||
|
|
||||||
|
#### Character Creation (Updated)
|
||||||
|
```
|
||||||
|
POST /sessions/{session_id}/characters/
|
||||||
|
Body: CreateCharacterRequest (JSON with optional profile)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Legacy Character Creation (Backward Compatible)
|
||||||
|
```
|
||||||
|
POST /sessions/{session_id}/characters/legacy/
|
||||||
|
Query params: name, description, personality, llm_model
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Export Character
|
||||||
|
```
|
||||||
|
GET /sessions/{session_id}/characters/{character_id}/export
|
||||||
|
Returns: JSON with character data, version, timestamp
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Import Character
|
||||||
|
```
|
||||||
|
POST /sessions/{session_id}/characters/import
|
||||||
|
Body: { character_data: {...} }
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Profile Options
|
||||||
|
```
|
||||||
|
GET /profile/options
|
||||||
|
Returns: Available genders, races, classes, personalities with descriptions
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Frontend: Character Creation Wizard
|
||||||
|
|
||||||
|
**File:** `frontend/src/components/CharacterCreationWizard.js`
|
||||||
|
|
||||||
|
6-step wizard interface:
|
||||||
|
1. **Basic Info:** Name, gender, import option
|
||||||
|
2. **Description:** Character description and background
|
||||||
|
3. **Race & Class:** Visual selection cards with descriptions
|
||||||
|
4. **Personality:** Personality type selection
|
||||||
|
5. **AI Model:** LLM model selection with descriptions
|
||||||
|
6. **Review:** Complete character preview before creation
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Progressive disclosure design
|
||||||
|
- Visual progress indicator
|
||||||
|
- Selection cards with hover effects
|
||||||
|
- Import from JSON
|
||||||
|
- Form validation
|
||||||
|
- Responsive design
|
||||||
|
|
||||||
|
**File:** `frontend/src/components/CharacterCreationWizard.css`
|
||||||
|
- Modern dark theme matching application style
|
||||||
|
- Smooth animations and transitions
|
||||||
|
- Mobile-responsive grid layouts
|
||||||
|
- Visual feedback on selections
|
||||||
|
|
||||||
|
### 5. Frontend: SessionSetup Integration
|
||||||
|
|
||||||
|
**File:** `frontend/src/components/SessionSetup.js`
|
||||||
|
|
||||||
|
Updated to support both wizard and simple character creation:
|
||||||
|
- **Wizard Mode:** Full character creation with profile
|
||||||
|
- **Quick Create:** Toggle for simple legacy mode
|
||||||
|
- Import character JSON during wizard
|
||||||
|
- Session ID validation before opening wizard
|
||||||
|
|
||||||
|
### 6. Frontend: Character Export
|
||||||
|
|
||||||
|
**File:** `frontend/src/components/CharacterView.js`
|
||||||
|
|
||||||
|
Added export functionality:
|
||||||
|
- Export button in character header
|
||||||
|
- Downloads JSON file with character data
|
||||||
|
- Filename includes character name and date
|
||||||
|
- Profile badges display in character info
|
||||||
|
|
||||||
|
### 7. CSS Updates
|
||||||
|
|
||||||
|
**File:** `frontend/src/App.css`
|
||||||
|
|
||||||
|
Added styles for:
|
||||||
|
- Character profile badges
|
||||||
|
- Character actions container
|
||||||
|
- Export button styling
|
||||||
|
- Character creation options
|
||||||
|
- Wizard button styling
|
||||||
|
- Mobile responsive adjustments
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Technical Implementation Details
|
||||||
|
|
||||||
|
### Profile-Based LLM Prompts
|
||||||
|
|
||||||
|
The system now generates context-aware prompts by combining:
|
||||||
|
1. Character name and basic identity
|
||||||
|
2. Race traits (from RACE_PROMPTS)
|
||||||
|
3. Class abilities (from CLASS_PROMPTS)
|
||||||
|
4. Personality traits (from PERSONALITY_PROMPTS)
|
||||||
|
5. Custom background (if provided)
|
||||||
|
6. Legacy personality field (backward compatible)
|
||||||
|
|
||||||
|
**Example Generated Prompt:**
|
||||||
|
```
|
||||||
|
You are Thorin, a male Dwarf Warrior. A grizzled veteran seeking redemption.
|
||||||
|
You are a dwarf, stout and honorable with deep knowledge of stone and metal.
|
||||||
|
You are loyal, practical, and value tradition. You excel in physical combat
|
||||||
|
and tactics, preferring direct action and protecting your allies. You are
|
||||||
|
brave and decisive in battle. You are serious and focused, prioritizing
|
||||||
|
efficiency and practical solutions. You are disciplined and value getting
|
||||||
|
things done. Background: Former guardian of the Mountain Keep, exiled after
|
||||||
|
a tragic failure.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Import/Export Format
|
||||||
|
|
||||||
|
**Export Structure:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"version": "1.0",
|
||||||
|
"character": {
|
||||||
|
"id": "...",
|
||||||
|
"name": "Character Name",
|
||||||
|
"description": "...",
|
||||||
|
"profile": {
|
||||||
|
"gender": "Male",
|
||||||
|
"race": "Elf",
|
||||||
|
"character_class": "Wizard",
|
||||||
|
"personality_type": "Measured",
|
||||||
|
"background": "...",
|
||||||
|
"avatar_data": null
|
||||||
|
},
|
||||||
|
"llm_model": "gpt-4o",
|
||||||
|
"conversation_history": [],
|
||||||
|
"pending_response": false
|
||||||
|
},
|
||||||
|
"created_at": "2025-10-12T00:00:00",
|
||||||
|
"export_type": "storyteller_rpg_character"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Import Process:**
|
||||||
|
1. Validates JSON structure
|
||||||
|
2. Extracts character data
|
||||||
|
3. Generates new ID to avoid conflicts
|
||||||
|
4. Clears conversation history
|
||||||
|
5. Adds to session
|
||||||
|
6. Notifies storyteller via WebSocket
|
||||||
|
|
||||||
|
### Backward Compatibility
|
||||||
|
|
||||||
|
The system maintains full backward compatibility:
|
||||||
|
- Legacy characters without profiles still work
|
||||||
|
- `build_character_system_prompt()` handles both types
|
||||||
|
- Legacy endpoint available at `/characters/legacy/`
|
||||||
|
- Simple creation mode in SessionSetup
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Files Changed
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- `main.py`: +186 lines
|
||||||
|
- CharacterProfile model
|
||||||
|
- Prompt templates
|
||||||
|
- Profile building function
|
||||||
|
- Import/export endpoints
|
||||||
|
- Profile options endpoint
|
||||||
|
- Updated character creation
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
- `CharacterCreationWizard.js`: +419 lines (new)
|
||||||
|
- `CharacterCreationWizard.css`: +352 lines (new)
|
||||||
|
- `SessionSetup.js`: +25 lines modified
|
||||||
|
- `CharacterView.js`: +30 lines modified
|
||||||
|
- `App.css`: +45 lines modified
|
||||||
|
|
||||||
|
**Total:** ~1,057 lines added/modified
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Testing Checklist
|
||||||
|
|
||||||
|
- [ ] Create character with wizard (all steps)
|
||||||
|
- [ ] Export character to JSON
|
||||||
|
- [ ] Import character from JSON
|
||||||
|
- [ ] Verify profile displays in CharacterView
|
||||||
|
- [ ] Test legacy character creation (simple mode)
|
||||||
|
- [ ] Verify LLM prompts include profile data
|
||||||
|
- [ ] Test backward compatibility with existing characters
|
||||||
|
- [ ] Mobile responsive testing
|
||||||
|
- [ ] Profile options endpoint
|
||||||
|
- [ ] All race/class/personality combinations
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Next Steps (Phase 3)
|
||||||
|
|
||||||
|
According to MVP Roadmap:
|
||||||
|
|
||||||
|
### Phase 3: User Mode Interfaces (Weeks 5-7)
|
||||||
|
1. **Player Interface Refinement**
|
||||||
|
- Enhanced character sheet display
|
||||||
|
- Profile editing
|
||||||
|
- Inventory/stats (if applicable)
|
||||||
|
|
||||||
|
2. **Storyteller Dashboard**
|
||||||
|
- View all character profiles
|
||||||
|
- Profile-aware response generation
|
||||||
|
- AI player profile management
|
||||||
|
|
||||||
|
3. **Gamemaster Control Panel**
|
||||||
|
- Game creation wizard
|
||||||
|
- Player/role assignment
|
||||||
|
- Profile-based AI configuration
|
||||||
|
|
||||||
|
4. **Permission Enforcement**
|
||||||
|
- Backend decorators
|
||||||
|
- Frontend UI restrictions
|
||||||
|
- WebSocket filtering
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Known Limitations & Future Improvements
|
||||||
|
|
||||||
|
### Current Limitations
|
||||||
|
1. **Avatar Support:** Profile has `avatar_data` field but no UI for upload
|
||||||
|
2. **PNG Export:** JSON export works, PNG with metadata not yet implemented
|
||||||
|
3. **Profile Editing:** No UI to edit profile after creation
|
||||||
|
4. **Pre-made Templates:** No quick-start character templates
|
||||||
|
|
||||||
|
### Future Enhancements
|
||||||
|
1. **Avatar System:**
|
||||||
|
- Upload images
|
||||||
|
- AI-generated avatars (DALL-E/Stable Diffusion)
|
||||||
|
- Avatar gallery
|
||||||
|
|
||||||
|
2. **PNG Export/Import:**
|
||||||
|
- Embed profile in PNG metadata
|
||||||
|
- Visual character cards
|
||||||
|
|
||||||
|
3. **Profile Templates:**
|
||||||
|
- Pre-made character archetypes
|
||||||
|
- Quick-start templates (Fighter, Mage, Rogue, etc.)
|
||||||
|
- Community-shared templates
|
||||||
|
|
||||||
|
4. **Advanced Profiles:**
|
||||||
|
- Skills and abilities
|
||||||
|
- Equipment/inventory
|
||||||
|
- Stats (HP, MP, etc.)
|
||||||
|
- Character progression/leveling
|
||||||
|
|
||||||
|
5. **Profile Validation:**
|
||||||
|
- Character name uniqueness
|
||||||
|
- Profile completeness checks
|
||||||
|
- Custom validation rules
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Documentation Updates Needed
|
||||||
|
|
||||||
|
- [x] Phase 2 implementation summary (this document)
|
||||||
|
- [ ] Update MVP_PROGRESS.md with Phase 2 completion
|
||||||
|
- [ ] Update NEXT_STEPS.md with Phase 3 priorities
|
||||||
|
- [ ] User guide for character creation wizard
|
||||||
|
- [ ] API documentation for new endpoints
|
||||||
|
- [ ] Update CHANGELOG.md
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎉 Achievements
|
||||||
|
|
||||||
|
✅ **Profile System:** Comprehensive character profiles with 5 races, 5 classes, 4 personalities
|
||||||
|
✅ **Smart Prompts:** Context-aware LLM prompts based on character traits
|
||||||
|
✅ **Beautiful UI:** 6-step wizard with modern design
|
||||||
|
✅ **Import/Export:** Full character portability
|
||||||
|
✅ **Backward Compatible:** Legacy characters still work
|
||||||
|
✅ **Extensible:** Easy to add new races, classes, personalities
|
||||||
|
|
||||||
|
**Phase 2 Status:** ✅ COMPLETE
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Last Updated: October 12, 2025*
|
||||||
|
*Implementation Time: ~3 hours*
|
||||||
|
*Lines of Code: ~1,057*
|
||||||
@@ -1,502 +0,0 @@
|
|||||||
# 📝 Development Session Summary
|
|
||||||
|
|
||||||
**Date:** October 11, 2025
|
|
||||||
**Project:** Storyteller RPG Application
|
|
||||||
**Status:** ✅ Fully Functional MVP Complete
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Project Overview
|
|
||||||
|
|
||||||
Built a **storyteller-centric roleplaying application** where multiple AI character bots or human players interact with a storyteller through **completely isolated, private conversations**.
|
|
||||||
|
|
||||||
### Core Concept
|
|
||||||
- **Characters communicate ONLY with the storyteller** (never with each other by default)
|
|
||||||
- **Each character has separate memory/LLM sessions** - their responses are isolated
|
|
||||||
- **Storyteller sees all conversations** but responds to each character individually
|
|
||||||
- **Characters cannot see other characters' messages or responses**
|
|
||||||
- Characters can use **different AI models** (GPT-4, Claude, Llama, etc.) giving each unique personalities
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏗️ Architecture Built
|
|
||||||
|
|
||||||
### Backend: FastAPI + WebSockets
|
|
||||||
**File:** `/home/aodhan/projects/apps/storyteller/main.py` (398 lines)
|
|
||||||
|
|
||||||
**Key Components:**
|
|
||||||
1. **Data Models:**
|
|
||||||
- `GameSession` - Manages the game session and all characters
|
|
||||||
- `Character` - Stores character info, LLM model, and private conversation history
|
|
||||||
- `Message` - Individual message with sender, content, timestamp
|
|
||||||
- `ConnectionManager` - Handles WebSocket connections
|
|
||||||
|
|
||||||
2. **WebSocket Endpoints:**
|
|
||||||
- `/ws/character/{session_id}/{character_id}` - Private character connection
|
|
||||||
- `/ws/storyteller/{session_id}` - Storyteller dashboard connection
|
|
||||||
|
|
||||||
3. **REST Endpoints:**
|
|
||||||
- `POST /sessions/` - Create new game session
|
|
||||||
- `GET /sessions/{session_id}` - Get session details
|
|
||||||
- `POST /sessions/{session_id}/characters/` - Add character to session
|
|
||||||
- `GET /sessions/{session_id}/characters/{character_id}/conversation` - Get conversation history
|
|
||||||
- `POST /sessions/{session_id}/generate_suggestion` - AI-assisted storyteller responses
|
|
||||||
- `GET /models` - List available LLM models
|
|
||||||
|
|
||||||
4. **LLM Integration:**
|
|
||||||
- **OpenAI**: GPT-4o, GPT-4 Turbo, GPT-3.5 Turbo
|
|
||||||
- **OpenRouter**: Claude 3.5, Llama 3.1, Gemini Pro, Mistral, Cohere, 100+ models
|
|
||||||
- `call_llm()` function routes to appropriate provider based on model ID
|
|
||||||
- Each character can use a different model
|
|
||||||
|
|
||||||
5. **Message Flow:**
|
|
||||||
```
|
|
||||||
Character sends message → WebSocket → Stored in Character.conversation_history
|
|
||||||
↓
|
|
||||||
Forwarded to Storyteller
|
|
||||||
↓
|
|
||||||
Storyteller responds → WebSocket → Stored in Character.conversation_history
|
|
||||||
↓
|
|
||||||
Sent ONLY to that Character
|
|
||||||
```
|
|
||||||
|
|
||||||
### Frontend: React
|
|
||||||
**Files:**
|
|
||||||
- `frontend/src/App.js` - Main router component
|
|
||||||
- `frontend/src/components/SessionSetup.js` (180 lines) - Session creation/joining
|
|
||||||
- `frontend/src/components/CharacterView.js` (141 lines) - Character interface
|
|
||||||
- `frontend/src/components/StorytellerView.js` (243 lines) - Storyteller dashboard
|
|
||||||
- `frontend/src/App.css` (704 lines) - Complete styling
|
|
||||||
|
|
||||||
**Key Features:**
|
|
||||||
1. **SessionSetup Component:**
|
|
||||||
- Create new session (becomes storyteller)
|
|
||||||
- Join existing session (becomes character)
|
|
||||||
- Select LLM model for character
|
|
||||||
- Model selector fetches available models from backend
|
|
||||||
|
|
||||||
2. **CharacterView Component:**
|
|
||||||
- Private conversation with storyteller
|
|
||||||
- WebSocket connection for real-time updates
|
|
||||||
- See scene narrations from storyteller
|
|
||||||
- Character info display (name, description, personality)
|
|
||||||
- Connection status indicator
|
|
||||||
|
|
||||||
3. **StorytellerView Component:**
|
|
||||||
- Dashboard showing all characters
|
|
||||||
- Click character to view their private conversation
|
|
||||||
- Respond to characters individually
|
|
||||||
- Narrate scenes visible to all characters
|
|
||||||
- Pending response indicators (red badges)
|
|
||||||
- Character cards showing:
|
|
||||||
- Name, description, personality
|
|
||||||
- LLM model being used
|
|
||||||
- Message count
|
|
||||||
- Pending status
|
|
||||||
|
|
||||||
4. **UI/UX Design:**
|
|
||||||
- Beautiful gradient purple theme
|
|
||||||
- Responsive design
|
|
||||||
- Real-time message updates
|
|
||||||
- Auto-scroll to latest messages
|
|
||||||
- Clear visual distinction between sent/received messages
|
|
||||||
- Session ID prominently displayed for sharing
|
|
||||||
- Empty states with helpful instructions
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔑 Key Technical Decisions
|
|
||||||
|
|
||||||
### 1. **Isolated Conversations (Privacy-First)**
|
|
||||||
- Each `Character` object has its own `conversation_history: List[Message]`
|
|
||||||
- Messages are never broadcast to all clients
|
|
||||||
- WebSocket routing ensures messages only go to intended recipient
|
|
||||||
- Storyteller has separate WebSocket endpoint to see all
|
|
||||||
|
|
||||||
### 2. **Multi-LLM Support**
|
|
||||||
- Characters choose model at creation time
|
|
||||||
- Stored in `Character.llm_model` field
|
|
||||||
- Backend dynamically routes API calls based on model prefix:
|
|
||||||
- `gpt-*` → OpenAI API
|
|
||||||
- Everything else → OpenRouter API
|
|
||||||
- Enables creative gameplay with different AI personalities
|
|
||||||
|
|
||||||
### 3. **In-Memory Storage (Current)**
|
|
||||||
- `sessions: Dict[str, GameSession]` stores all active sessions
|
|
||||||
- Fast and simple for MVP
|
|
||||||
- **Limitation:** Data lost on server restart
|
|
||||||
- **Next step:** Add database persistence (see NEXT_STEPS.md)
|
|
||||||
|
|
||||||
### 4. **WebSocket-First Architecture**
|
|
||||||
- Real-time bidirectional communication
|
|
||||||
- Native WebSocket API (not socket.io)
|
|
||||||
- JSON message format with `type` field for routing
|
|
||||||
- Separate connections for characters and storyteller
|
|
||||||
|
|
||||||
### 5. **Scene Narration System**
|
|
||||||
- Storyteller can broadcast "scene" messages
|
|
||||||
- Sent to all connected characters simultaneously
|
|
||||||
- Stored in `GameSession.current_scene` and `scene_history`
|
|
||||||
- Different from private character-storyteller messages
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📁 Project Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
storyteller/
|
|
||||||
├── main.py # FastAPI backend (398 lines)
|
|
||||||
├── requirements.txt # Python dependencies
|
|
||||||
├── .env.example # API key template
|
|
||||||
├── .env # Your API keys (gitignored)
|
|
||||||
├── README.md # Comprehensive documentation
|
|
||||||
├── QUICKSTART.md # 5-minute setup guide
|
|
||||||
├── NEXT_STEPS.md # Future development roadmap
|
|
||||||
├── SESSION_SUMMARY.md # This file
|
|
||||||
├── start.sh # Auto-start script
|
|
||||||
├── dev.sh # Development mode script
|
|
||||||
└── frontend/
|
|
||||||
├── package.json # Node dependencies
|
|
||||||
├── public/
|
|
||||||
│ └── index.html # HTML template
|
|
||||||
└── src/
|
|
||||||
├── App.js # Main router
|
|
||||||
├── App.css # All styles (704 lines)
|
|
||||||
├── index.js # React entry point
|
|
||||||
└── components/
|
|
||||||
├── SessionSetup.js # Session creation/joining
|
|
||||||
├── CharacterView.js # Character interface
|
|
||||||
└── StorytellerView.js # Storyteller dashboard
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 How to Run
|
|
||||||
|
|
||||||
### Quick Start (Automated)
|
|
||||||
```bash
|
|
||||||
cd /home/aodhan/projects/apps/storyteller
|
|
||||||
chmod +x start.sh
|
|
||||||
./start.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### Manual Start
|
|
||||||
```bash
|
|
||||||
# Terminal 1 - Backend
|
|
||||||
cd /home/aodhan/projects/apps/storyteller
|
|
||||||
source .venv/bin/activate # or: source venv/bin/activate
|
|
||||||
python main.py
|
|
||||||
|
|
||||||
# Terminal 2 - Frontend
|
|
||||||
cd /home/aodhan/projects/apps/storyteller/frontend
|
|
||||||
npm start
|
|
||||||
```
|
|
||||||
|
|
||||||
### Environment Setup
|
|
||||||
```bash
|
|
||||||
# Copy example and add your API keys
|
|
||||||
cp .env.example .env
|
|
||||||
|
|
||||||
# Edit .env and add at least one:
|
|
||||||
# OPENAI_API_KEY=sk-... # For GPT models
|
|
||||||
# OPENROUTER_API_KEY=sk-... # For Claude, Llama, etc.
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔍 Important Implementation Details
|
|
||||||
|
|
||||||
### WebSocket Message Types
|
|
||||||
|
|
||||||
**Character → Storyteller:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "message",
|
|
||||||
"content": "I search the room for clues"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Storyteller → Character:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "storyteller_response",
|
|
||||||
"message": {
|
|
||||||
"id": "...",
|
|
||||||
"sender": "storyteller",
|
|
||||||
"content": "You find a hidden letter",
|
|
||||||
"timestamp": "2025-10-11T20:30:00"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Storyteller → All Characters:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "narrate_scene",
|
|
||||||
"content": "The room grows dark as thunder rumbles"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Storyteller receives character message:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "character_message",
|
|
||||||
"character_id": "uuid",
|
|
||||||
"character_name": "Aragorn",
|
|
||||||
"message": { ... }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Character joined notification:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "character_joined",
|
|
||||||
"character": {
|
|
||||||
"id": "uuid",
|
|
||||||
"name": "Legolas",
|
|
||||||
"description": "...",
|
|
||||||
"llm_model": "gpt-4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### LLM Integration
|
|
||||||
|
|
||||||
**Function:** `call_llm(model, messages, temperature, max_tokens)`
|
|
||||||
|
|
||||||
**Routing Logic:**
|
|
||||||
```python
|
|
||||||
if model.startswith("gpt-") or model.startswith("o1-"):
|
|
||||||
# Use OpenAI client
|
|
||||||
response = await client.chat.completions.create(...)
|
|
||||||
else:
|
|
||||||
# Use OpenRouter via httpx
|
|
||||||
response = await http_client.post("https://openrouter.ai/api/v1/chat/completions", ...)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Available Models (as of this session):**
|
|
||||||
- OpenAI: gpt-4o, gpt-4-turbo, gpt-4, gpt-3.5-turbo
|
|
||||||
- Anthropic (via OpenRouter): claude-3.5-sonnet, claude-3-opus, claude-3-haiku
|
|
||||||
- Meta: llama-3.1-70b, llama-3.1-8b
|
|
||||||
- Google: gemini-pro-1.5
|
|
||||||
- Mistral: mistral-large
|
|
||||||
- Cohere: command-r-plus
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎨 UI/UX Highlights
|
|
||||||
|
|
||||||
### Color Scheme
|
|
||||||
- Primary gradient: Purple (`#667eea` → `#764ba2`)
|
|
||||||
- Background: White cards on gradient
|
|
||||||
- Messages: Blue (sent) / Gray (received)
|
|
||||||
- Pending indicators: Red badges
|
|
||||||
- Status: Green (connected) / Gray (disconnected)
|
|
||||||
|
|
||||||
### Key UX Features
|
|
||||||
1. **Session ID prominently displayed** for easy sharing
|
|
||||||
2. **Pending response badges** show storyteller which characters are waiting
|
|
||||||
3. **Character cards** with all relevant info at a glance
|
|
||||||
4. **Empty states** guide users on what to do next
|
|
||||||
5. **Connection status** always visible
|
|
||||||
6. **Auto-scroll** to latest message
|
|
||||||
7. **Keyboard shortcuts** (Enter to send)
|
|
||||||
8. **Model selector** with descriptions helping users choose
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🐛 Known Limitations & TODO
|
|
||||||
|
|
||||||
### Current Limitations
|
|
||||||
1. **No persistence** - Sessions lost on server restart
|
|
||||||
2. **No authentication** - Anyone with session ID can join
|
|
||||||
3. **No message editing/deletion** - Messages are permanent
|
|
||||||
4. **No character limit** on messages (could be abused)
|
|
||||||
5. **No rate limiting** - API calls not throttled
|
|
||||||
6. **No offline support** - Requires active connection
|
|
||||||
7. **No mobile optimization** - Works but could be better
|
|
||||||
8. **No sound notifications** - Easy to miss new messages
|
|
||||||
|
|
||||||
### Security Considerations
|
|
||||||
- **CORS is wide open** (`allow_origins=["*"]`) - Restrict in production
|
|
||||||
- **No input validation** on message content - Add sanitization
|
|
||||||
- **API keys in environment** - Good, but consider secrets manager
|
|
||||||
- **No session expiration** - Sessions live forever in memory
|
|
||||||
- **WebSocket not authenticated** - Anyone with session ID can connect
|
|
||||||
|
|
||||||
### Performance Considerations
|
|
||||||
- **In-memory storage** - Won't scale to many sessions
|
|
||||||
- **No message pagination** - All history loaded at once
|
|
||||||
- **No connection pooling** - Each character = new WebSocket
|
|
||||||
- **No caching** - LLM calls always go to API
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💡 What Makes This Special
|
|
||||||
|
|
||||||
### Unique Features
|
|
||||||
1. **Each character uses a different AI model** - Creates emergent gameplay
|
|
||||||
2. **Completely private conversations** - True secret communication
|
|
||||||
3. **Storyteller-centric design** - Built for tabletop RPG flow
|
|
||||||
4. **Real-time updates** - Feels like a chat app
|
|
||||||
5. **Model flexibility** - 100+ LLMs via OpenRouter
|
|
||||||
6. **Zero configuration** - Works out of the box
|
|
||||||
|
|
||||||
### Design Philosophy
|
|
||||||
- **Storyteller is the hub** - All communication flows through them
|
|
||||||
- **Privacy first** - Characters truly can't see each other's messages
|
|
||||||
- **Flexibility** - Support for any LLM model
|
|
||||||
- **Simplicity** - Clean, intuitive interface
|
|
||||||
- **Real-time** - No page refreshes needed
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔄 Context for Continuing Development
|
|
||||||
|
|
||||||
### If Starting a New Chat Session
|
|
||||||
|
|
||||||
**What works:**
|
|
||||||
- ✅ Backend fully functional with all endpoints
|
|
||||||
- ✅ Frontend complete with all views
|
|
||||||
- ✅ WebSocket communication working
|
|
||||||
- ✅ Multi-LLM support implemented
|
|
||||||
- ✅ Scene narration working
|
|
||||||
- ✅ Private conversations isolated correctly
|
|
||||||
|
|
||||||
**Quick test to verify everything:**
|
|
||||||
```bash
|
|
||||||
# 1. Start servers
|
|
||||||
./start.sh
|
|
||||||
|
|
||||||
# 2. Create session as storyteller
|
|
||||||
# 3. Join session as character (new browser/incognito)
|
|
||||||
# 4. Send message from character
|
|
||||||
# 5. Verify storyteller sees it
|
|
||||||
# 6. Respond from storyteller
|
|
||||||
# 7. Verify character receives it
|
|
||||||
# 8. Test scene narration
|
|
||||||
```
|
|
||||||
|
|
||||||
**Common issues:**
|
|
||||||
- **Port 8000/3000 already in use** - `start.sh` kills existing processes
|
|
||||||
- **WebSocket won't connect** - Check backend is running, check browser console
|
|
||||||
- **LLM not responding** - Verify API keys in `.env`
|
|
||||||
- **npm/pip dependencies missing** - Run install commands
|
|
||||||
|
|
||||||
### Files to Modify for Common Tasks
|
|
||||||
|
|
||||||
**Add new WebSocket message type:**
|
|
||||||
1. Update message handler in `main.py` (character or storyteller endpoint)
|
|
||||||
2. Update frontend component to send/receive new type
|
|
||||||
|
|
||||||
**Add new REST endpoint:**
|
|
||||||
1. Add `@app.post()` or `@app.get()` in `main.py`
|
|
||||||
2. Add fetch call in appropriate frontend component
|
|
||||||
|
|
||||||
**Modify UI:**
|
|
||||||
1. Edit component in `frontend/src/components/`
|
|
||||||
2. Edit styles in `frontend/src/App.css`
|
|
||||||
|
|
||||||
**Add new LLM provider:**
|
|
||||||
1. Update `call_llm()` function in `main.py`
|
|
||||||
2. Update `get_available_models()` endpoint
|
|
||||||
3. Add model options in `SessionSetup.js`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Project Statistics
|
|
||||||
|
|
||||||
- **Total Lines of Code:** ~1,700
|
|
||||||
- **Backend:** ~400 lines (Python/FastAPI)
|
|
||||||
- **Frontend:** ~1,300 lines (React/JavaScript/CSS)
|
|
||||||
- **Time to MVP:** 1 session
|
|
||||||
- **Dependencies:** 8 Python packages, 5 npm packages (core)
|
|
||||||
- **API Endpoints:** 6 REST + 2 WebSocket
|
|
||||||
- **React Components:** 3 main + 1 router
|
|
||||||
- **Supported LLMs:** 15+ models across 6 providers
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎓 Learning Resources Used
|
|
||||||
|
|
||||||
### Technologies
|
|
||||||
- **FastAPI:** https://fastapi.tiangolo.com/
|
|
||||||
- **WebSockets:** https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
||||||
- **React:** https://react.dev/
|
|
||||||
- **OpenAI API:** https://platform.openai.com/docs
|
|
||||||
- **OpenRouter:** https://openrouter.ai/docs
|
|
||||||
|
|
||||||
### Key Concepts Implemented
|
|
||||||
- WebSocket bidirectional communication
|
|
||||||
- Async Python with FastAPI
|
|
||||||
- React state management with hooks
|
|
||||||
- Multi-provider LLM routing
|
|
||||||
- Real-time message delivery
|
|
||||||
- Isolated conversation contexts
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 Notes for Future You
|
|
||||||
|
|
||||||
### Why certain decisions were made:
|
|
||||||
- **WebSocket instead of polling:** Real-time updates without constant HTTP requests
|
|
||||||
- **Separate endpoints for character/storyteller:** Clean separation of concerns, different message types
|
|
||||||
- **In-memory storage first:** Fastest MVP, can migrate to DB later
|
|
||||||
- **Multi-LLM from start:** Makes the app unique and interesting
|
|
||||||
- **No socket.io:** Native WebSocket simpler for this use case
|
|
||||||
- **Private conversations:** Core feature that differentiates from group chat apps
|
|
||||||
|
|
||||||
### What went smoothly:
|
|
||||||
- FastAPI made WebSocket implementation easy
|
|
||||||
- React components stayed clean and modular
|
|
||||||
- OpenRouter integration was straightforward
|
|
||||||
- UI came together nicely with gradients
|
|
||||||
|
|
||||||
### What could be improved:
|
|
||||||
- Database persistence is the obvious next step
|
|
||||||
- Error handling could be more robust
|
|
||||||
- Mobile experience needs work
|
|
||||||
- Need proper authentication system
|
|
||||||
- Testing suite would be valuable
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Recommended Next Actions
|
|
||||||
|
|
||||||
**Immediate (Next Session):**
|
|
||||||
1. Test the app end-to-end to ensure everything works after IDE crash
|
|
||||||
2. Add AI suggestion button to storyteller UI (backend ready, just needs frontend)
|
|
||||||
3. Implement session persistence with SQLite
|
|
||||||
|
|
||||||
**Short Term (This Week):**
|
|
||||||
4. Add dice rolling system
|
|
||||||
5. Add typing indicators
|
|
||||||
6. Improve error messages
|
|
||||||
|
|
||||||
**Medium Term (This Month):**
|
|
||||||
7. Add authentication
|
|
||||||
8. Implement character sheets
|
|
||||||
9. Add image generation for scenes
|
|
||||||
|
|
||||||
See **NEXT_STEPS.md** for detailed roadmap with priorities and implementation notes.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 Session Handoff Checklist
|
|
||||||
|
|
||||||
- ✅ All files verified and up-to-date
|
|
||||||
- ✅ Architecture documented
|
|
||||||
- ✅ Key decisions explained
|
|
||||||
- ✅ Next steps outlined
|
|
||||||
- ✅ Common issues documented
|
|
||||||
- ✅ Code structure mapped
|
|
||||||
- ✅ API contracts specified
|
|
||||||
- ✅ Testing instructions provided
|
|
||||||
|
|
||||||
**You're ready to continue development!** 🎉
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Generated: October 11, 2025*
|
|
||||||
*Project Location: `/home/aodhan/projects/apps/storyteller`*
|
|
||||||
*Status: Production-ready MVP*
|
|
||||||
179
docs/features/README.md
Normal file
179
docs/features/README.md
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
# 🎭 Features Documentation
|
||||||
|
|
||||||
|
Detailed documentation for all Storyteller RPG features.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature Guides
|
||||||
|
|
||||||
|
### Core Features
|
||||||
|
|
||||||
|
#### [Demo Session](./DEMO_SESSION.md)
|
||||||
|
Pre-configured test session that auto-loads on startup. Includes two characters (Bargin & Willow) and "The Cursed Tavern" adventure. Perfect for development and testing.
|
||||||
|
|
||||||
|
**Quick Access:**
|
||||||
|
- Session ID: `demo-session-001`
|
||||||
|
- One-click buttons on home page
|
||||||
|
- No setup required
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### [Context-Aware Response Generator](./CONTEXTUAL_RESPONSE_FEATURE.md)
|
||||||
|
AI-powered tool for storytellers to generate responses considering multiple characters' actions simultaneously.
|
||||||
|
|
||||||
|
**Key Features:**
|
||||||
|
- Multi-character selection
|
||||||
|
- Scene descriptions (broadcast to all)
|
||||||
|
- Individual responses (private to each)
|
||||||
|
- Automatic parsing and distribution
|
||||||
|
- Smart context building
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Technical Documentation
|
||||||
|
|
||||||
|
#### [Prompt Engineering Improvements](./PROMPT_IMPROVEMENTS.md)
|
||||||
|
Details on how we improved the LLM prompts for reliable individual response parsing using the `[CharacterName]` format.
|
||||||
|
|
||||||
|
**Topics Covered:**
|
||||||
|
- Square bracket format rationale
|
||||||
|
- Regex parsing patterns
|
||||||
|
- System prompt enhancements
|
||||||
|
- Edge case handling
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### [Bug Fixes Summary](./FIXES_SUMMARY.md)
|
||||||
|
Comprehensive list of bugs fixed in the latest release.
|
||||||
|
|
||||||
|
**Fixed Issues:**
|
||||||
|
- Character chat history showing only recent messages
|
||||||
|
- Pydantic deprecation warnings (.dict → .model_dump)
|
||||||
|
- WebSocket manager reference errors
|
||||||
|
- Session ID copy functionality
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature Overview by Category
|
||||||
|
|
||||||
|
### For Storytellers 🎲
|
||||||
|
|
||||||
|
| Feature | Description | Status |
|
||||||
|
|---------|-------------|--------|
|
||||||
|
| **Session Management** | Create/join sessions, manage characters | ✅ Complete |
|
||||||
|
| **Scene Narration** | Broadcast scene descriptions to all players | ✅ Complete |
|
||||||
|
| **Private Responses** | Send individual messages to characters | ✅ Complete |
|
||||||
|
| **AI Suggestions** | Get AI-generated response suggestions | ✅ Complete |
|
||||||
|
| **Context-Aware Generator** | Generate responses considering multiple characters | ✅ Complete |
|
||||||
|
| **Pending Message Tracking** | See which characters need responses | ✅ Complete |
|
||||||
|
| **Demo Session** | Pre-loaded test scenario for quick start | ✅ Complete |
|
||||||
|
|
||||||
|
### For Players 🎭
|
||||||
|
|
||||||
|
| Feature | Description | Status |
|
||||||
|
|---------|-------------|--------|
|
||||||
|
| **Character Creation** | Define name, description, personality | ✅ Complete |
|
||||||
|
| **Private Messages** | Send private messages to storyteller | ✅ Complete |
|
||||||
|
| **Public Actions** | Broadcast actions visible to all players | ✅ Complete |
|
||||||
|
| **Mixed Messages** | Public action + private thoughts | ✅ Complete |
|
||||||
|
| **Scene Viewing** | See current scene description | ✅ Complete |
|
||||||
|
| **Public Feed** | View all players' public actions | ✅ Complete |
|
||||||
|
| **Conversation History** | Full chat log with storyteller | ✅ Complete |
|
||||||
|
|
||||||
|
### Message System 📨
|
||||||
|
|
||||||
|
| Feature | Description | Status |
|
||||||
|
|---------|-------------|--------|
|
||||||
|
| **Private Messages** | One-on-one conversation | ✅ Complete |
|
||||||
|
| **Public Messages** | Visible to all players | ✅ Complete |
|
||||||
|
| **Mixed Messages** | Public + private components | ✅ Complete |
|
||||||
|
| **Real-time Updates** | WebSocket-based live updates | ✅ Complete |
|
||||||
|
| **Message Persistence** | In-memory storage (session lifetime) | ✅ Complete |
|
||||||
|
|
||||||
|
### AI Integration 🤖
|
||||||
|
|
||||||
|
| Feature | Description | Status |
|
||||||
|
|---------|-------------|--------|
|
||||||
|
| **Multiple LLM Support** | GPT-4o, GPT-4, GPT-3.5, Claude, Llama | ✅ Complete |
|
||||||
|
| **AI Response Suggestions** | Quick response generation | ✅ Complete |
|
||||||
|
| **Context-Aware Generation** | Multi-character context building | ✅ Complete |
|
||||||
|
| **Structured Output Parsing** | [CharacterName] format parsing | ✅ Complete |
|
||||||
|
| **Temperature Control** | Creative vs. focused responses | ✅ Complete |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Coming Soon 🚀
|
||||||
|
|
||||||
|
### Planned Features
|
||||||
|
|
||||||
|
- **Database Persistence** - Save sessions and characters permanently
|
||||||
|
- **Character Sheets** - Stats, inventory, abilities
|
||||||
|
- **Dice Rolling** - Built-in dice mechanics
|
||||||
|
- **Combat System** - Turn-based combat management
|
||||||
|
- **Image Generation** - AI-generated scene/character images
|
||||||
|
- **Voice Messages** - Audio message support
|
||||||
|
- **Session Export** - Export conversation logs
|
||||||
|
- **User Authentication** - Account system with saved preferences
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature Request Process
|
||||||
|
|
||||||
|
Want to suggest a new feature?
|
||||||
|
|
||||||
|
1. **Check existing documentation** - Feature might already exist
|
||||||
|
2. **Review roadmap** - Check if it's already planned (see [MVP_ROADMAP.md](../planning/MVP_ROADMAP.md))
|
||||||
|
3. **Create an issue** - Describe the feature and use case
|
||||||
|
4. **Discuss implementation** - We'll evaluate feasibility and priority
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Version History
|
||||||
|
|
||||||
|
### v0.2.0 - Context-Aware Features (October 2025)
|
||||||
|
- ✅ Context-aware response generator
|
||||||
|
- ✅ Demo session with pre-configured characters
|
||||||
|
- ✅ Improved prompt engineering for parsing
|
||||||
|
- ✅ Bug fixes (chat history, Pydantic warnings)
|
||||||
|
- ✅ Session ID copy button
|
||||||
|
|
||||||
|
### v0.1.0 - MVP Phase 1 (October 2025)
|
||||||
|
- ✅ Basic session management
|
||||||
|
- ✅ Character creation and joining
|
||||||
|
- ✅ Private/public/mixed messaging
|
||||||
|
- ✅ Real-time WebSocket communication
|
||||||
|
- ✅ Scene narration
|
||||||
|
- ✅ AI-assisted responses
|
||||||
|
- ✅ Multiple LLM support
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Documentation Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
docs/
|
||||||
|
├── features/ ← You are here
|
||||||
|
│ ├── README.md
|
||||||
|
│ ├── DEMO_SESSION.md
|
||||||
|
│ ├── CONTEXTUAL_RESPONSE_FEATURE.md
|
||||||
|
│ ├── PROMPT_IMPROVEMENTS.md
|
||||||
|
│ └── FIXES_SUMMARY.md
|
||||||
|
├── development/
|
||||||
|
│ ├── MVP_PROGRESS.md
|
||||||
|
│ ├── TESTING_GUIDE.md
|
||||||
|
│ └── TEST_RESULTS.md
|
||||||
|
├── planning/
|
||||||
|
│ ├── MVP_ROADMAP.md
|
||||||
|
│ ├── PROJECT_PLAN.md
|
||||||
|
│ └── NEXT_STEPS.md
|
||||||
|
├── setup/
|
||||||
|
│ ├── QUICKSTART.md
|
||||||
|
│ └── QUICK_REFERENCE.md
|
||||||
|
└── reference/
|
||||||
|
├── PROJECT_FILES_REFERENCE.md
|
||||||
|
└── LLM_GUIDE.md
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Need help?** Check the [main README](../../README.md) or the [Quick Start Guide](../setup/QUICKSTART.md).
|
||||||
654
docs/reference/UI_DESIGN_PROMPTS.md
Normal file
654
docs/reference/UI_DESIGN_PROMPTS.md
Normal file
@@ -0,0 +1,654 @@
|
|||||||
|
# UI Design Prompts - Ready to Use
|
||||||
|
|
||||||
|
**Purpose:** Copy-paste prompts for UI design LLMs (v0.dev, Midjourney, etc.)
|
||||||
|
**Date:** October 12, 2025
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 Base Prompt Template
|
||||||
|
|
||||||
|
```
|
||||||
|
Design a modern dark-themed web application interface for a tabletop RPG storytelling platform.
|
||||||
|
|
||||||
|
Visual Style:
|
||||||
|
- Dark theme with purple gradient accents (#667eea to #764ba2)
|
||||||
|
- Card-based layout with rounded corners (8-12px radius)
|
||||||
|
- Smooth shadows for depth and elevation
|
||||||
|
- Clean, modern sans-serif typography
|
||||||
|
- RPG fantasy aesthetic with subtle magical elements
|
||||||
|
|
||||||
|
Color Palette:
|
||||||
|
- Background: Deep dark blue (#1a1a2e, #16213e)
|
||||||
|
- Surface: Dark slate (#2d3748)
|
||||||
|
- Primary: Purple gradient (#667eea to #764ba2)
|
||||||
|
- Text: White/light gray (#ffffff, #e2e8f0)
|
||||||
|
- Accent: Bright purple (#667eea)
|
||||||
|
|
||||||
|
Design Principles:
|
||||||
|
- Clear visual hierarchy
|
||||||
|
- Generous white space
|
||||||
|
- Accessible contrast ratios
|
||||||
|
- Smooth animations and transitions
|
||||||
|
- Mobile-responsive design
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Prompt 1: Session Setup / Landing Page
|
||||||
|
|
||||||
|
```
|
||||||
|
Create a modern dark-themed landing page for an RPG storytelling web app called "Storyteller RPG"
|
||||||
|
|
||||||
|
Page Components:
|
||||||
|
1. Header Section:
|
||||||
|
- Large app title with dice emoji (🎭 Storyteller RPG)
|
||||||
|
- Subtitle: "Private character-storyteller interactions"
|
||||||
|
- Centered layout
|
||||||
|
|
||||||
|
2. Demo Session Card:
|
||||||
|
- Title: "🎲 Demo Session - The Cursed Tavern"
|
||||||
|
- Short description text
|
||||||
|
- Three horizontally arranged buttons:
|
||||||
|
* "🎲 Join as Storyteller" (primary gradient button)
|
||||||
|
* "⚔️ Play as Bargin (Dwarf Warrior)" (character button)
|
||||||
|
* "🏹 Play as Willow (Elf Ranger)" (character button)
|
||||||
|
- Gradient background (gold #ffd89b to teal #19547b)
|
||||||
|
- Rounded corners with padding
|
||||||
|
|
||||||
|
3. Divider:
|
||||||
|
- Horizontal line with centered text "OR CREATE YOUR OWN"
|
||||||
|
|
||||||
|
4. Create Session Section:
|
||||||
|
- White card with shadow
|
||||||
|
- Title: "Create New Session"
|
||||||
|
- Description: "Start a new game as the storyteller"
|
||||||
|
- Text input field for session name
|
||||||
|
- Full-width primary button: "Create Session"
|
||||||
|
|
||||||
|
5. Divider:
|
||||||
|
- Horizontal line with "OR"
|
||||||
|
|
||||||
|
6. Join Session Section:
|
||||||
|
- White card with shadow
|
||||||
|
- Title: "Join Existing Session"
|
||||||
|
- Form with inputs:
|
||||||
|
* Session ID field
|
||||||
|
* Character name field
|
||||||
|
* Character description textarea
|
||||||
|
* Personality textarea (optional)
|
||||||
|
* Model selector dropdown
|
||||||
|
- Large gradient button: "✨ Create Character (Wizard)"
|
||||||
|
- Secondary toggle: "↓ Quick Create"
|
||||||
|
|
||||||
|
Visual Style:
|
||||||
|
- Purple gradient background for page
|
||||||
|
- White content cards with soft shadows
|
||||||
|
- Centered layout, max-width 600px
|
||||||
|
- Generous padding and spacing
|
||||||
|
- Modern, clean, inviting design
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Prompt 2: Character View (Player Interface)
|
||||||
|
|
||||||
|
```
|
||||||
|
Design a dark-themed character view interface for a player in an RPG session
|
||||||
|
|
||||||
|
Layout Structure:
|
||||||
|
- Full-height application with header, scrollable content, and fixed message composer
|
||||||
|
|
||||||
|
Components:
|
||||||
|
|
||||||
|
1. Character Header (Dark gradient #2d3748):
|
||||||
|
- Left side:
|
||||||
|
* Character name (large, white)
|
||||||
|
* Character description (gray text)
|
||||||
|
* Personality trait with emoji (🎭)
|
||||||
|
* Three profile badges: Race | Class | Personality
|
||||||
|
(Pills with purple accent color)
|
||||||
|
- Right side:
|
||||||
|
* Export button (📥 Export) with subtle purple background
|
||||||
|
* Connection status indicator:
|
||||||
|
- Green dot "● Connected" when active
|
||||||
|
- Gray dot "○ Disconnected" when offline
|
||||||
|
|
||||||
|
2. Current Scene Card (if active):
|
||||||
|
- Highlighted card with scene icon (📜)
|
||||||
|
- Title: "Current Scene"
|
||||||
|
- Scene description text
|
||||||
|
- Distinct background color from messages
|
||||||
|
|
||||||
|
3. Two-Column Content Area:
|
||||||
|
|
||||||
|
Left Column - Public Messages Feed:
|
||||||
|
- Title: "📢 Public Actions (All Players See)"
|
||||||
|
- Message cards with:
|
||||||
|
* Sender name/icon
|
||||||
|
* Message content
|
||||||
|
* Timestamp
|
||||||
|
* Light background with left purple border accent
|
||||||
|
|
||||||
|
Right Column - Private Conversation:
|
||||||
|
- Title: "💬 Private Conversation with Storyteller"
|
||||||
|
- Chat-style message bubbles:
|
||||||
|
* Character messages: Right-aligned, purple gradient
|
||||||
|
* Storyteller messages: Left-aligned, darker color
|
||||||
|
* Timestamps below each message
|
||||||
|
- Auto-scroll to bottom
|
||||||
|
|
||||||
|
4. Message Composer (Fixed Bottom):
|
||||||
|
- Visibility dropdown selector (Private | Public | Mixed)
|
||||||
|
- For "Mixed" mode:
|
||||||
|
* Two textareas stacked:
|
||||||
|
- "Public action (all players see)..."
|
||||||
|
- "Private action (only storyteller sees)..."
|
||||||
|
* "Send Mixed Message" button
|
||||||
|
- For simple mode:
|
||||||
|
* Single input field (placeholder changes by visibility)
|
||||||
|
* "Send" button
|
||||||
|
- Elevated shadow, dark background
|
||||||
|
|
||||||
|
Visual Style:
|
||||||
|
- Dark theme throughout
|
||||||
|
- Purple accent colors for character messages
|
||||||
|
- Clear visual separation between public and private
|
||||||
|
- Smooth scrolling
|
||||||
|
- Professional messaging interface aesthetic
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Prompt 3: Character Creation Wizard
|
||||||
|
|
||||||
|
```
|
||||||
|
Design a beautiful multi-step character creation wizard modal for an RPG application
|
||||||
|
|
||||||
|
Modal Structure:
|
||||||
|
- Full-screen dark overlay (semi-transparent)
|
||||||
|
- Centered wizard container (max 800px wide)
|
||||||
|
- Dark gradient background (#1a1a2e to #16213e)
|
||||||
|
- Rounded corners with border
|
||||||
|
|
||||||
|
Components:
|
||||||
|
|
||||||
|
1. Wizard Header:
|
||||||
|
- Large title: "Create Your Character"
|
||||||
|
- Progress indicator: 6 step pills arranged horizontally
|
||||||
|
* "1. Basic Info" | "2. Description" | "3. Race & Class" | "4. Personality" | "5. AI Model" | "6. Review"
|
||||||
|
* Active step: Purple gradient background, white text
|
||||||
|
* Inactive steps: Muted gray background, gray text
|
||||||
|
* Completed steps: Dimmed purple
|
||||||
|
- Steps wrap on mobile
|
||||||
|
|
||||||
|
2. Content Area (Changes per step):
|
||||||
|
|
||||||
|
Step 1 - Basic Info:
|
||||||
|
- Text input: "Character Name" (with autofocus glow)
|
||||||
|
- Dropdown: "Gender" (Male, Female, Non-binary, Custom)
|
||||||
|
- Import section:
|
||||||
|
* Light text: "💡 Have an existing character?"
|
||||||
|
* Button: "📥 Import from JSON" (outlined style)
|
||||||
|
|
||||||
|
Step 3 - Race & Class (example):
|
||||||
|
- Grid of 5 selection cards (2-3 columns responsive)
|
||||||
|
- Each card:
|
||||||
|
* Race/Class name (bold white)
|
||||||
|
* Short description (gray)
|
||||||
|
* Unselected: Dark background, light border
|
||||||
|
* Selected: Purple gradient background, bright border, slight shadow
|
||||||
|
* Hover: Lift effect with shadow
|
||||||
|
- Two sections: Race cards, then Class cards
|
||||||
|
|
||||||
|
Step 6 - Review:
|
||||||
|
- Preview card with sections:
|
||||||
|
* Basic Information (list of key-value pairs)
|
||||||
|
* Description (paragraph)
|
||||||
|
* Background (if provided)
|
||||||
|
* AI Model
|
||||||
|
- Summary box at bottom:
|
||||||
|
* Purple gradient background
|
||||||
|
* "Character Summary" heading
|
||||||
|
* Natural language sentence about the character
|
||||||
|
|
||||||
|
3. Wizard Footer:
|
||||||
|
- Left: "Cancel" button (secondary)
|
||||||
|
- Right: Navigation buttons
|
||||||
|
* "← Back" (secondary, only shows steps 2-6)
|
||||||
|
* "Next →" (primary purple gradient, steps 1-5)
|
||||||
|
* "✨ Create Character" (primary gradient, step 6)
|
||||||
|
|
||||||
|
Animations:
|
||||||
|
- Step content fades in with slight upward movement
|
||||||
|
- Card selection: Scale transform + glow
|
||||||
|
- Progress indicator: Smooth transitions
|
||||||
|
- Button hovers: Elevation effect
|
||||||
|
|
||||||
|
Visual Style:
|
||||||
|
- Dark, immersive wizard experience
|
||||||
|
- Purple accent throughout
|
||||||
|
- Clear visual hierarchy
|
||||||
|
- Smooth, modern interactions
|
||||||
|
- Feels guided and professional
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Prompt 4: Storyteller View Dashboard
|
||||||
|
|
||||||
|
```
|
||||||
|
Design a comprehensive storyteller dashboard for managing an RPG game session
|
||||||
|
|
||||||
|
Layout:
|
||||||
|
- Sidebar + main content area (grid layout)
|
||||||
|
- Dark theme with purple accents
|
||||||
|
|
||||||
|
Components:
|
||||||
|
|
||||||
|
1. Header Bar:
|
||||||
|
- Session name (large white text)
|
||||||
|
- Session ID with copy button
|
||||||
|
- "Generate Contextual Response" button (purple gradient)
|
||||||
|
- Connection status indicator
|
||||||
|
|
||||||
|
2. Left Sidebar - Character List:
|
||||||
|
- Title: "Characters in Session"
|
||||||
|
- Scrollable character cards (one per character):
|
||||||
|
* Character name (white)
|
||||||
|
* Small profile badges (Race | Class | Personality)
|
||||||
|
* "Needs Response" red indicator (if pending)
|
||||||
|
* Hover: Light background
|
||||||
|
* Selected: Purple left border + highlighted background
|
||||||
|
- Empty state: "No characters yet" with muted text
|
||||||
|
|
||||||
|
3. Main Content Area - Tabs:
|
||||||
|
|
||||||
|
Tab 1 - Public Actions Feed:
|
||||||
|
- Title: "📢 Recent Public Actions"
|
||||||
|
- Timeline/feed of public messages:
|
||||||
|
* Character avatar/icon
|
||||||
|
* Character name
|
||||||
|
* Action text
|
||||||
|
* Timestamp
|
||||||
|
* Compact card style with left accent
|
||||||
|
|
||||||
|
Tab 2 - Character Conversation (selected character):
|
||||||
|
- Character header showing their profile
|
||||||
|
- Message thread (scrollable):
|
||||||
|
* Character messages (left-aligned)
|
||||||
|
* Storyteller responses (right-aligned, purple)
|
||||||
|
* Timestamps
|
||||||
|
- Response composer section:
|
||||||
|
* Large textarea "Write your response..."
|
||||||
|
* "✨ AI Suggest" button (secondary)
|
||||||
|
* "Send Private Response" button (primary)
|
||||||
|
|
||||||
|
Tab 3 - Scene Narration:
|
||||||
|
- Title: "📜 Broadcast Scene to All Players"
|
||||||
|
- Large textarea for scene description
|
||||||
|
- Context options:
|
||||||
|
* Character selection checkboxes
|
||||||
|
* Additional context input
|
||||||
|
- "Generate with AI" button (secondary)
|
||||||
|
- "Broadcast Scene" button (primary, large)
|
||||||
|
|
||||||
|
4. AI Suggestion Panel (conditional):
|
||||||
|
- Appears when "AI Suggest" clicked
|
||||||
|
- Green accent background
|
||||||
|
- Title: "AI-Generated Suggestion"
|
||||||
|
- Editable textarea with generated response
|
||||||
|
- Model indicator (small text)
|
||||||
|
- Action buttons:
|
||||||
|
* "Use This Response" (success green)
|
||||||
|
* "Regenerate" (secondary)
|
||||||
|
* "Cancel" (text button)
|
||||||
|
|
||||||
|
Visual Style:
|
||||||
|
- Dark command center aesthetic
|
||||||
|
- Clear information hierarchy
|
||||||
|
- Easy to scan character list
|
||||||
|
- Comfortable reading for long text
|
||||||
|
- Purple highlights for storyteller actions
|
||||||
|
- Green highlights for AI features
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Prompt 5: Gamemaster Control Panel
|
||||||
|
|
||||||
|
```
|
||||||
|
Design a powerful gamemaster control panel for managing RPG game sessions
|
||||||
|
|
||||||
|
Layout:
|
||||||
|
- Command center dashboard style
|
||||||
|
- Sidebar navigation + main content panels
|
||||||
|
- Dark theme with multiple accent colors
|
||||||
|
|
||||||
|
Components:
|
||||||
|
|
||||||
|
1. Header:
|
||||||
|
- Title: "Gamemaster Control Panel"
|
||||||
|
- Current game indicator (pill badge)
|
||||||
|
- Quick action buttons:
|
||||||
|
* "Create New Game" (purple gradient)
|
||||||
|
* "Load Game" (secondary)
|
||||||
|
* "Save Game" (secondary)
|
||||||
|
|
||||||
|
2. Left Navigation:
|
||||||
|
- Vertical menu with icons:
|
||||||
|
* Dashboard (overview icon)
|
||||||
|
* Games (list icon)
|
||||||
|
* Players (users icon)
|
||||||
|
* Settings (gear icon)
|
||||||
|
- Active item: Purple left border + highlight
|
||||||
|
|
||||||
|
3. Main Content - Game Creation Wizard:
|
||||||
|
|
||||||
|
Step 2 - Player Slots:
|
||||||
|
- Grid of player slot cards (2-3 columns):
|
||||||
|
* Slot number badge (top-right)
|
||||||
|
* Type toggle: Human | AI (switch component)
|
||||||
|
* If Human:
|
||||||
|
- User selector dropdown
|
||||||
|
- Character assignment
|
||||||
|
* If AI:
|
||||||
|
- AI model dropdown
|
||||||
|
- Personality/behavior settings
|
||||||
|
* Drag handle (for reordering)
|
||||||
|
- "Add Slot" button at end
|
||||||
|
|
||||||
|
Each slot card:
|
||||||
|
- Dark background with border
|
||||||
|
- Assigned: Green accent border
|
||||||
|
- Empty: Dashed border
|
||||||
|
- Hover: Lift effect
|
||||||
|
|
||||||
|
4. Main Content - Game Overview Dashboard:
|
||||||
|
- Metric cards row (4 cards):
|
||||||
|
* Active Players (number + icon)
|
||||||
|
* Total Messages (number + icon)
|
||||||
|
* Session Duration (time + icon)
|
||||||
|
* AI Usage Cost ($ + icon)
|
||||||
|
- Current scene card (large, highlighted)
|
||||||
|
- Recent activity feed
|
||||||
|
- Quick actions panel
|
||||||
|
|
||||||
|
5. Role Assignment Interface:
|
||||||
|
- Drag-and-drop layout:
|
||||||
|
* Left: Available players list (cards)
|
||||||
|
* Right: Game slots (drop zones)
|
||||||
|
* Visual feedback during drag
|
||||||
|
- Each player card:
|
||||||
|
* Avatar/icon
|
||||||
|
* Username
|
||||||
|
* Online status
|
||||||
|
* Drag handle
|
||||||
|
|
||||||
|
Visual Style:
|
||||||
|
- Professional dashboard aesthetic
|
||||||
|
- Multiple status colors (green=good, red=alert, yellow=warning)
|
||||||
|
- Clear data visualization
|
||||||
|
- Interactive drag-and-drop
|
||||||
|
- Elevated cards with shadows
|
||||||
|
- Purple primary, green success, red danger
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Prompt 6: Admin Dashboard
|
||||||
|
|
||||||
|
```
|
||||||
|
Design a comprehensive system administration dashboard for monitoring and management
|
||||||
|
|
||||||
|
Layout:
|
||||||
|
- Full-width dashboard with sidebar navigation
|
||||||
|
- Dark theme with data visualization focus
|
||||||
|
|
||||||
|
Components:
|
||||||
|
|
||||||
|
1. Top Header:
|
||||||
|
- Title: "System Administration"
|
||||||
|
- System status indicators (colored dots):
|
||||||
|
* API Status (green/red)
|
||||||
|
* Database (green/red)
|
||||||
|
* WebSocket (green/red)
|
||||||
|
- Global stats (small numbers):
|
||||||
|
* Active Games: 12
|
||||||
|
* Active Users: 48
|
||||||
|
* API Calls Today: 1,234
|
||||||
|
|
||||||
|
2. Sidebar Navigation:
|
||||||
|
- Vertical menu items:
|
||||||
|
* Dashboard (home icon)
|
||||||
|
* Games (controller icon)
|
||||||
|
* Users (people icon)
|
||||||
|
* LLM Config (brain icon)
|
||||||
|
* Analytics (chart icon)
|
||||||
|
* Costs (dollar icon)
|
||||||
|
* Logs (terminal icon)
|
||||||
|
- Active: Purple background + white icon
|
||||||
|
|
||||||
|
3. Dashboard Overview:
|
||||||
|
- 4 metric cards (top row):
|
||||||
|
* Total Games (number, trend arrow, sparkline)
|
||||||
|
* Total Users (number, trend arrow, sparkline)
|
||||||
|
* Today's Cost ($, trend arrow)
|
||||||
|
* System Health (percentage, circular progress)
|
||||||
|
|
||||||
|
- Charts section:
|
||||||
|
* Line chart: "Games Created Over Time" (7 days)
|
||||||
|
* Bar chart: "Model Usage Distribution"
|
||||||
|
* Pie chart: "Cost Breakdown by Model"
|
||||||
|
|
||||||
|
- Recent Activity Feed:
|
||||||
|
* Timeline of recent events
|
||||||
|
* Color-coded by type (create, error, warning)
|
||||||
|
* Timestamps
|
||||||
|
* Quick action buttons
|
||||||
|
|
||||||
|
4. Games Management Table:
|
||||||
|
- Data table with columns:
|
||||||
|
* ID | Name | GM | Players | Status | Created | Actions
|
||||||
|
- Features:
|
||||||
|
* Sort arrows in headers
|
||||||
|
* Search bar (top-right)
|
||||||
|
* Filter chips (by status)
|
||||||
|
* Pagination controls (bottom)
|
||||||
|
- Row actions:
|
||||||
|
* View (eye icon)
|
||||||
|
* Edit (pencil icon)
|
||||||
|
* Delete (trash icon)
|
||||||
|
- Status badges (colored):
|
||||||
|
* Active (green)
|
||||||
|
* Paused (yellow)
|
||||||
|
* Completed (gray)
|
||||||
|
|
||||||
|
5. Cost Analytics View:
|
||||||
|
- Summary cards (top):
|
||||||
|
* This Month ($)
|
||||||
|
* Per Game Average ($)
|
||||||
|
* Most Expensive Model (name + $)
|
||||||
|
- Cost breakdown table:
|
||||||
|
* Model | Calls | Total Cost | Avg Per Call
|
||||||
|
* Sortable columns
|
||||||
|
- Date range picker (top-right)
|
||||||
|
- Export CSV button
|
||||||
|
|
||||||
|
Visual Style:
|
||||||
|
- Professional admin interface
|
||||||
|
- Data-focused with clear metrics
|
||||||
|
- Color-coded status indicators
|
||||||
|
- Clean tables with good readability
|
||||||
|
- Charts with tooltips
|
||||||
|
- Responsive grid layouts
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Specialized Component Prompts
|
||||||
|
|
||||||
|
### Prompt: Message Bubble Component
|
||||||
|
|
||||||
|
```
|
||||||
|
Design a modern chat message bubble component for a dark-themed RPG interface
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
- Two variants: Character (sent) and Storyteller (received)
|
||||||
|
- Character messages:
|
||||||
|
* Right-aligned
|
||||||
|
* Purple gradient background (#667eea to #764ba2)
|
||||||
|
* White text
|
||||||
|
* Rounded corners (more rounded on left side)
|
||||||
|
* Small shadow
|
||||||
|
- Storyteller messages:
|
||||||
|
* Left-aligned
|
||||||
|
* Dark gray background (#374151)
|
||||||
|
* Light gray text
|
||||||
|
* Rounded corners (more rounded on right side)
|
||||||
|
* Subtle border
|
||||||
|
- Both include:
|
||||||
|
* Message content (wrapped text)
|
||||||
|
* Timestamp (small, muted, below bubble)
|
||||||
|
* Sender name (optional, above bubble)
|
||||||
|
- Smooth entry animation (fade + slide)
|
||||||
|
- Hover: Slight shadow increase
|
||||||
|
```
|
||||||
|
|
||||||
|
### Prompt: Selection Card Component
|
||||||
|
|
||||||
|
```
|
||||||
|
Design an interactive selection card for character race/class/personality selection
|
||||||
|
|
||||||
|
States:
|
||||||
|
1. Default:
|
||||||
|
- Dark background (#2d3748)
|
||||||
|
- Light border (rgba(255,255,255,0.1))
|
||||||
|
- Rounded corners (10px)
|
||||||
|
- Padding: 20px
|
||||||
|
- Content:
|
||||||
|
* Title (bold, white, 16px)
|
||||||
|
* Description (gray, 13px)
|
||||||
|
|
||||||
|
2. Hover:
|
||||||
|
- Background: Slightly lighter
|
||||||
|
- Border: Purple tint
|
||||||
|
- Transform: translateY(-2px)
|
||||||
|
- Shadow: Elevated
|
||||||
|
|
||||||
|
3. Selected:
|
||||||
|
- Background: Purple gradient (subtle)
|
||||||
|
- Border: Bright purple (#667eea)
|
||||||
|
- Shadow: Purple glow
|
||||||
|
- Checkmark icon (top-right corner)
|
||||||
|
|
||||||
|
Animation:
|
||||||
|
- Smooth transition on all state changes
|
||||||
|
- Scale slightly on click
|
||||||
|
- Ripple effect on selection
|
||||||
|
|
||||||
|
Size:
|
||||||
|
- Min width: 200px
|
||||||
|
- Flexible height based on content
|
||||||
|
- Grid-friendly
|
||||||
|
```
|
||||||
|
|
||||||
|
### Prompt: Progress Indicator Component
|
||||||
|
|
||||||
|
```
|
||||||
|
Design a multi-step progress indicator for a wizard interface
|
||||||
|
|
||||||
|
Components:
|
||||||
|
- 6 steps arranged horizontally
|
||||||
|
- Each step:
|
||||||
|
* Number or icon
|
||||||
|
* Label text below
|
||||||
|
* Connecting line to next step
|
||||||
|
|
||||||
|
States per step:
|
||||||
|
1. Completed:
|
||||||
|
- Checkmark icon (white)
|
||||||
|
- Purple filled circle
|
||||||
|
- Purple line to next
|
||||||
|
- Label: Purple, smaller
|
||||||
|
|
||||||
|
2. Active/Current:
|
||||||
|
- Number in white
|
||||||
|
- Purple gradient circle (larger)
|
||||||
|
- Pulsing glow animation
|
||||||
|
- Label: White, bold
|
||||||
|
|
||||||
|
3. Upcoming:
|
||||||
|
- Number in gray
|
||||||
|
- Gray outlined circle
|
||||||
|
- Gray dashed line to next
|
||||||
|
- Label: Gray, normal
|
||||||
|
|
||||||
|
Responsive:
|
||||||
|
- Desktop: Horizontal line
|
||||||
|
- Mobile: Vertical or wrapped
|
||||||
|
|
||||||
|
Visual Style:
|
||||||
|
- Modern, clean
|
||||||
|
- Clear current position
|
||||||
|
- Motivating progress visualization
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📱 Mobile-Specific Prompts
|
||||||
|
|
||||||
|
### Prompt: Mobile Navigation
|
||||||
|
|
||||||
|
```
|
||||||
|
Design a mobile-friendly bottom navigation bar for the RPG app
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
- Fixed to bottom of screen
|
||||||
|
- Dark background with slight transparency
|
||||||
|
- 4-5 navigation items:
|
||||||
|
* Home/Session (house icon)
|
||||||
|
* Character (person icon)
|
||||||
|
* Messages (chat icon)
|
||||||
|
* More (dots icon)
|
||||||
|
- Active item:
|
||||||
|
* Purple icon color
|
||||||
|
* Label text (white)
|
||||||
|
* Indicator line on top
|
||||||
|
- Inactive items:
|
||||||
|
* Gray icon
|
||||||
|
* Small label (optional)
|
||||||
|
- Badge notifications (red dot on icons)
|
||||||
|
- Safe area insets for iOS
|
||||||
|
- Subtle shadow on top edge
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 Using These Prompts
|
||||||
|
|
||||||
|
### With v0.dev (Vercel):
|
||||||
|
```
|
||||||
|
Copy base template + specific page prompt
|
||||||
|
Add: "Generate React/Next.js components with Tailwind CSS"
|
||||||
|
Review generated code and iterate
|
||||||
|
```
|
||||||
|
|
||||||
|
### With Midjourney/DALL-E:
|
||||||
|
```
|
||||||
|
Copy prompt
|
||||||
|
Add: "UI mockup, high fidelity, Figma style"
|
||||||
|
Generate multiple variations
|
||||||
|
Use as design reference
|
||||||
|
```
|
||||||
|
|
||||||
|
### With Claude/GPT:
|
||||||
|
```
|
||||||
|
Copy prompt
|
||||||
|
Add: "Generate HTML/CSS code for this design"
|
||||||
|
or "Create a React component for this"
|
||||||
|
Iterate on the implementation
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**All prompts are ready to copy and use!** Customize colors, spacing, or specific elements as needed.
|
||||||
890
docs/reference/UI_ELEMENTS_INVENTORY.md
Normal file
890
docs/reference/UI_ELEMENTS_INVENTORY.md
Normal file
@@ -0,0 +1,890 @@
|
|||||||
|
# UI Elements Inventory - Storyteller RPG
|
||||||
|
|
||||||
|
**Purpose:** Comprehensive list of UI elements organized by page for design template generation
|
||||||
|
**Date:** October 12, 2025
|
||||||
|
**Status:** Phase 2 Complete, Planning Phase 3
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 Design System Overview
|
||||||
|
|
||||||
|
### Color Palette
|
||||||
|
- **Primary Gradient:** #667eea to #764ba2 (purple gradient)
|
||||||
|
- **Secondary Gradient:** #ffd89b to #19547b (gold to teal)
|
||||||
|
- **Background Dark:** #1a1a2e, #16213e
|
||||||
|
- **Surface Dark:** #2d3748
|
||||||
|
- **Text Light:** #ffffff, #e2e8f0
|
||||||
|
- **Text Muted:** #a0aec0, #718096
|
||||||
|
- **Accent:** #667eea (purple)
|
||||||
|
- **Success:** #10b981, #34d399
|
||||||
|
- **Warning:** #f59e0b
|
||||||
|
- **Error:** #ef4444
|
||||||
|
|
||||||
|
### Typography
|
||||||
|
- **Font Family:** -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif
|
||||||
|
- **H1:** 2.5rem, bold
|
||||||
|
- **H2:** 2rem, bold
|
||||||
|
- **H3:** 1.5rem, semibold
|
||||||
|
- **Body:** 1rem
|
||||||
|
- **Small:** 0.875rem
|
||||||
|
|
||||||
|
### Spacing Scale
|
||||||
|
- **xs:** 0.25rem (4px)
|
||||||
|
- **sm:** 0.5rem (8px)
|
||||||
|
- **md:** 1rem (16px)
|
||||||
|
- **lg:** 1.5rem (24px)
|
||||||
|
- **xl:** 2rem (32px)
|
||||||
|
- **2xl:** 3rem (48px)
|
||||||
|
|
||||||
|
### Border Radius
|
||||||
|
- **Small:** 6px
|
||||||
|
- **Medium:** 8px
|
||||||
|
- **Large:** 12px
|
||||||
|
- **XLarge:** 20px
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Page 1: Session Setup / Landing Page
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Entry point for creating or joining game sessions
|
||||||
|
|
||||||
|
### Layout Structure
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────┐
|
||||||
|
│ Header (Logo + Title) │
|
||||||
|
├─────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ Demo Session Cards │
|
||||||
|
│ │
|
||||||
|
├─────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ Create New Session Section │
|
||||||
|
│ │
|
||||||
|
├─────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ Join Existing Session Section │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### UI Elements
|
||||||
|
|
||||||
|
#### **Header Section**
|
||||||
|
- **App Title:** Large heading with emoji (🎭 Storyteller RPG)
|
||||||
|
- **Subtitle:** Descriptive tagline
|
||||||
|
- **Logo/Icon:** Optional app icon
|
||||||
|
|
||||||
|
#### **Demo Section**
|
||||||
|
- **Section Title:** "🎲 Demo Session - The Cursed Tavern"
|
||||||
|
- **Description Text:** Short description paragraph
|
||||||
|
- **Button Group (3 buttons):**
|
||||||
|
- Storyteller button (🎲 icon, primary style)
|
||||||
|
- Character 1 button (⚔️ icon, character style)
|
||||||
|
- Character 2 button (🏹 icon, character style)
|
||||||
|
- **Visual Style:** Gradient background, rounded corners
|
||||||
|
|
||||||
|
#### **Divider Elements**
|
||||||
|
- **Text Divider:** "OR CREATE YOUR OWN" / "OR"
|
||||||
|
- **Horizontal line with text overlay**
|
||||||
|
|
||||||
|
#### **Create Session Section**
|
||||||
|
- **Section Title:** "Create New Session"
|
||||||
|
- **Section Description:** "Start a new game as the storyteller"
|
||||||
|
- **Input Field:** Text input for session name
|
||||||
|
- **Primary Button:** "Create Session" (full width)
|
||||||
|
- **Visual Style:** White card with shadow
|
||||||
|
|
||||||
|
#### **Join Session Section**
|
||||||
|
- **Section Title:** "Join Existing Session"
|
||||||
|
- **Section Description:** "Play as a character in an ongoing game"
|
||||||
|
- **Form Elements:**
|
||||||
|
- Session ID input field
|
||||||
|
- Character name input field
|
||||||
|
- Character description textarea
|
||||||
|
- Personality traits textarea (optional)
|
||||||
|
- Model selector dropdown (grouped options)
|
||||||
|
- Model hint text
|
||||||
|
- **Action Buttons:**
|
||||||
|
- "✨ Create Character (Wizard)" - Primary gradient button
|
||||||
|
- "↓ Quick Create" toggle - Secondary button
|
||||||
|
- "Join Session (Simple)" - Conditional primary button
|
||||||
|
- **Visual Style:** White card with shadow
|
||||||
|
|
||||||
|
### Responsive Behavior
|
||||||
|
- **Desktop:** Single column, max-width 600px, centered
|
||||||
|
- **Mobile:** Full width, stacked elements
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Page 2: Character View (Player Interface)
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Interface for players to interact with storyteller and view game state
|
||||||
|
|
||||||
|
### Layout Structure
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────┐
|
||||||
|
│ Character Header (Info + Status) │
|
||||||
|
├─────────────────────────────────────────────────┤
|
||||||
|
│ Current Scene Card (if active) │
|
||||||
|
├─────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────┬─────────────────────────┐ │
|
||||||
|
│ │ Public Messages │ Private Conversation │ │
|
||||||
|
│ │ Feed │ with Storyteller │ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ └─────────────────┴─────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
├─────────────────────────────────────────────────┤
|
||||||
|
│ Message Composer (Bottom) │
|
||||||
|
└─────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### UI Elements
|
||||||
|
|
||||||
|
#### **Character Header**
|
||||||
|
- **Character Name:** Large heading
|
||||||
|
- **Character Description:** Paragraph text
|
||||||
|
- **Personality Trait:** Small text with emoji (🎭)
|
||||||
|
- **Profile Badges:** 3 pill-shaped badges
|
||||||
|
- Race badge
|
||||||
|
- Class badge
|
||||||
|
- Personality type badge
|
||||||
|
- **Action Buttons:**
|
||||||
|
- Export button (📥 Export)
|
||||||
|
- **Status Indicator:** Connection status dot
|
||||||
|
- Connected: Green dot + "● Connected"
|
||||||
|
- Disconnected: Gray dot + "○ Disconnected"
|
||||||
|
- **Visual Style:** Dark gradient background, rounded top corners
|
||||||
|
|
||||||
|
#### **Current Scene Card** (Conditional)
|
||||||
|
- **Section Title:** "📜 Current Scene"
|
||||||
|
- **Scene Text:** Paragraph with scene description
|
||||||
|
- **Visual Style:** Highlighted card, distinct from messages
|
||||||
|
|
||||||
|
#### **Public Messages Section**
|
||||||
|
- **Section Title:** "📢 Public Actions (All Players See)"
|
||||||
|
- **Message List:**
|
||||||
|
- Message bubble/card per public action
|
||||||
|
- Sender indicator (🎭 Public Action / 🎲 Scene)
|
||||||
|
- Message content
|
||||||
|
- Timestamp (small, muted)
|
||||||
|
- **Visual Style:** Light background, left border accent
|
||||||
|
|
||||||
|
#### **Private Conversation Section**
|
||||||
|
- **Section Title:** "💬 Private Conversation with Storyteller"
|
||||||
|
- **Message List:**
|
||||||
|
- Message bubbles alternating left/right
|
||||||
|
- Character messages (right aligned, purple)
|
||||||
|
- Storyteller messages (left aligned, different color)
|
||||||
|
- Timestamps
|
||||||
|
- **Scroll Behavior:** Auto-scroll to bottom on new message
|
||||||
|
|
||||||
|
#### **Message Composer** (Bottom Section)
|
||||||
|
- **Visibility Selector:** Dropdown
|
||||||
|
- Options: Private, Public, Mixed
|
||||||
|
- **Mixed Mode Form:**
|
||||||
|
- Public textarea: "Public action (all players see)..."
|
||||||
|
- Private textarea: "Private action (only storyteller sees)..."
|
||||||
|
- Send button: "Send Mixed Message"
|
||||||
|
- **Simple Mode Form:**
|
||||||
|
- Single input field (changes placeholder by visibility)
|
||||||
|
- Send button
|
||||||
|
- **Visual Style:** Fixed to bottom, elevated shadow
|
||||||
|
|
||||||
|
### Component States
|
||||||
|
- **Connected State:** Full functionality enabled
|
||||||
|
- **Disconnected State:** Inputs disabled, gray overlay
|
||||||
|
- **Loading State:** Skeleton screens
|
||||||
|
- **Empty State:** "No messages yet" placeholder
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Page 3: Character Creation Wizard
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Multi-step guided character creation with profile system
|
||||||
|
|
||||||
|
### Layout Structure
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ Wizard Header (Title + Progress) │
|
||||||
|
├─────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ Step Content Area │
|
||||||
|
│ (Changes per step) │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
├─────────────────────────────────────────┤
|
||||||
|
│ Footer (Cancel | Back | Next/Create) │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### UI Elements
|
||||||
|
|
||||||
|
#### **Wizard Overlay**
|
||||||
|
- **Full-screen modal:** Dark semi-transparent background
|
||||||
|
- **Centered container:** Max 800px width
|
||||||
|
- **Visual Style:** Dark gradient card with border
|
||||||
|
|
||||||
|
#### **Wizard Header**
|
||||||
|
- **Title:** "Create Your Character" (large heading)
|
||||||
|
- **Progress Indicator:** 6 steps
|
||||||
|
- Step pills showing: "1. Basic Info", "2. Description", etc.
|
||||||
|
- Active step highlighted
|
||||||
|
- Completed steps dimmed
|
||||||
|
- Responsive: Wraps on mobile
|
||||||
|
|
||||||
|
#### **Step 1: Basic Info**
|
||||||
|
- **Step Title:** "Basic Information"
|
||||||
|
- **Input Fields:**
|
||||||
|
- Character name (text input, required, autofocus)
|
||||||
|
- Gender dropdown (4 options)
|
||||||
|
- **Import Section:**
|
||||||
|
- Import hint text: "💡 Have an existing character?"
|
||||||
|
- File upload button: "📥 Import from JSON"
|
||||||
|
- Hidden file input (accepts .json)
|
||||||
|
- **Visual Style:** Form inputs with dark theme
|
||||||
|
|
||||||
|
#### **Step 2: Description**
|
||||||
|
- **Step Title:** "Character Description"
|
||||||
|
- **Input Fields:**
|
||||||
|
- Description textarea (required, 4 rows)
|
||||||
|
- Background textarea (optional, 3 rows)
|
||||||
|
- **Visual Style:** Larger text areas, clear labels
|
||||||
|
|
||||||
|
#### **Step 3: Race & Class**
|
||||||
|
- **Step Title:** "Race & Class"
|
||||||
|
- **Race Selection:**
|
||||||
|
- Label: "Race"
|
||||||
|
- Selection grid (responsive, min 200px cards)
|
||||||
|
- 5 clickable cards:
|
||||||
|
- Race name (bold)
|
||||||
|
- Race description (smaller text)
|
||||||
|
- Selected state: gradient background + border
|
||||||
|
- Hover state: slight elevation
|
||||||
|
- **Class Selection:**
|
||||||
|
- Same layout as Race
|
||||||
|
- 5 class cards
|
||||||
|
- **Visual Style:** Grid layout, interactive cards
|
||||||
|
|
||||||
|
#### **Step 4: Personality**
|
||||||
|
- **Step Title:** "Personality Type"
|
||||||
|
- **Selection Grid:**
|
||||||
|
- 4 personality type cards
|
||||||
|
- Same card style as race/class
|
||||||
|
- **Additional Input:**
|
||||||
|
- "Additional Personality Traits" textarea (optional, 3 rows)
|
||||||
|
- **Visual Style:** Consistent with Step 3
|
||||||
|
|
||||||
|
#### **Step 5: AI Model**
|
||||||
|
- **Step Title:** "AI Model Selection"
|
||||||
|
- **Model Dropdown:**
|
||||||
|
- Large dropdown (bigger padding/font)
|
||||||
|
- Grouped options (OpenAI / OpenRouter)
|
||||||
|
- Shows provider in parentheses
|
||||||
|
- **Help Text:**
|
||||||
|
- "💡 Different models give different personalities!"
|
||||||
|
- Multi-line hint text
|
||||||
|
- **Visual Style:** Prominent dropdown, informative hint
|
||||||
|
|
||||||
|
#### **Step 6: Review**
|
||||||
|
- **Step Title:** "Review Your Character"
|
||||||
|
- **Preview Card:**
|
||||||
|
- Multiple sections with borders between:
|
||||||
|
- Basic Information (name, gender, race, class, personality)
|
||||||
|
- Description
|
||||||
|
- Background (if provided)
|
||||||
|
- Additional Traits (if provided)
|
||||||
|
- AI Model
|
||||||
|
- Summary box at bottom:
|
||||||
|
- Highlighted background
|
||||||
|
- "Character Summary" heading
|
||||||
|
- Natural language summary sentence
|
||||||
|
- **Visual Style:** Clean, organized, easy to scan
|
||||||
|
|
||||||
|
#### **Wizard Footer**
|
||||||
|
- **Button Layout:**
|
||||||
|
- Cancel (left, secondary)
|
||||||
|
- Navigation (right):
|
||||||
|
- Back button (steps 2-6, secondary)
|
||||||
|
- Next button (steps 1-5, primary)
|
||||||
|
- Create button (step 6, primary with sparkles)
|
||||||
|
- **Visual Style:** Fixed footer, clear hierarchy
|
||||||
|
|
||||||
|
### Animation & Transitions
|
||||||
|
- **Step Changes:** Fade in with slight upward movement
|
||||||
|
- **Card Selection:** Transform scale + shadow on selection
|
||||||
|
- **Button Hovers:** Slight elevation, color shift
|
||||||
|
- **Progress Indicator:** Smooth transitions between steps
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Page 4: Storyteller View
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Interface for storyteller to manage game, view all character actions, and respond
|
||||||
|
|
||||||
|
### Layout Structure
|
||||||
|
```
|
||||||
|
┌──────────────────────────────────────────────────┐
|
||||||
|
│ Header (Session Info + Controls) │
|
||||||
|
├──────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌───────────────┬────────────────────────────┐ │
|
||||||
|
│ │ Character │ Main Content Area: │ │
|
||||||
|
│ │ List │ │ │
|
||||||
|
│ │ (Sidebar) │ - Public Actions Feed │ │
|
||||||
|
│ │ │ - Selected Character View │ │
|
||||||
|
│ │ │ - Scene Narration │ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ └───────────────┴────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
└──────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### UI Elements
|
||||||
|
|
||||||
|
#### **Storyteller Header**
|
||||||
|
- **Session Name:** Large heading
|
||||||
|
- **Session ID:** Copy button with ID
|
||||||
|
- **Control Buttons:**
|
||||||
|
- Generate contextual response button
|
||||||
|
- Other session controls
|
||||||
|
- **Visual Style:** Dark header, elevated
|
||||||
|
|
||||||
|
#### **Character List Sidebar**
|
||||||
|
- **Section Title:** "Characters in Session"
|
||||||
|
- **Character Cards:** (One per character)
|
||||||
|
- Character name
|
||||||
|
- Race/Class/Personality badges
|
||||||
|
- "Needs Response" indicator (conditional)
|
||||||
|
- Click to select
|
||||||
|
- Active state highlighting
|
||||||
|
- **Empty State:** "No characters yet" message
|
||||||
|
- **Visual Style:** Scrollable sidebar, clear selection state
|
||||||
|
|
||||||
|
#### **Public Actions Feed**
|
||||||
|
- **Section Title:** "📢 Recent Public Actions"
|
||||||
|
- **Feed Items:**
|
||||||
|
- Character name/avatar
|
||||||
|
- Public action text
|
||||||
|
- Timestamp
|
||||||
|
- Compact card style
|
||||||
|
- **Visual Style:** Timeline/feed layout
|
||||||
|
|
||||||
|
#### **Character Conversation View**
|
||||||
|
- **Character Header:**
|
||||||
|
- Selected character name
|
||||||
|
- Profile info
|
||||||
|
- **Conversation Thread:**
|
||||||
|
- Message list (character + storyteller messages)
|
||||||
|
- Clear visual distinction between senders
|
||||||
|
- Timestamps
|
||||||
|
- **Response Composer:**
|
||||||
|
- Textarea for response
|
||||||
|
- "✨ AI Suggest" button
|
||||||
|
- "Send Private Response" button
|
||||||
|
- **Visual Style:** Similar to character view but reversed perspective
|
||||||
|
|
||||||
|
#### **AI Suggestion Modal/Section**
|
||||||
|
- **Generated Response Display:**
|
||||||
|
- Title: "AI-Generated Suggestion"
|
||||||
|
- Response content (editable)
|
||||||
|
- Model used indicator
|
||||||
|
- **Action Buttons:**
|
||||||
|
- "Use This Response"
|
||||||
|
- "Regenerate"
|
||||||
|
- "Cancel"
|
||||||
|
- **Visual Style:** Highlighted section, easy to edit
|
||||||
|
|
||||||
|
#### **Scene Narration Section**
|
||||||
|
- **Section Title:** "Broadcast Scene to All Players"
|
||||||
|
- **Input Field:**
|
||||||
|
- Large textarea for scene description
|
||||||
|
- Character count/hint
|
||||||
|
- **Contextual Generation:**
|
||||||
|
- "Generate with AI" button
|
||||||
|
- Character selection checkboxes
|
||||||
|
- Additional context input
|
||||||
|
- **Send Button:** "📜 Broadcast Scene"
|
||||||
|
- **Visual Style:** Prominent, distinct from private responses
|
||||||
|
|
||||||
|
### Responsive Behavior
|
||||||
|
- **Desktop:** Sidebar + main content (grid layout)
|
||||||
|
- **Tablet:** Collapsible sidebar
|
||||||
|
- **Mobile:** Stack vertically, tab navigation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Page 5: Gamemaster Control Panel (Phase 3)
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Admin interface to create games, assign roles, and manage session
|
||||||
|
|
||||||
|
### Layout Structure
|
||||||
|
```
|
||||||
|
┌────────────────────────────────────────────┐
|
||||||
|
│ GM Header (Game Info + Quick Actions) │
|
||||||
|
├────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌──────────────┬──────────────────────┐ │
|
||||||
|
│ │ Game │ Main Panel: │ │
|
||||||
|
│ │ Sessions │ │ │
|
||||||
|
│ │ List │ - Game Setup Wizard │ │
|
||||||
|
│ │ │ - Role Assignment │ │
|
||||||
|
│ │ │ - Player Management │ │
|
||||||
|
│ │ │ - Game State View │ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ └──────────────┴──────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
└────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### UI Elements
|
||||||
|
|
||||||
|
#### **GM Dashboard Header**
|
||||||
|
- **Title:** "Gamemaster Control Panel"
|
||||||
|
- **Active Game Indicator:** Current game name
|
||||||
|
- **Quick Actions:**
|
||||||
|
- "Create New Game" button
|
||||||
|
- "Load Game" button
|
||||||
|
- "Save Game" button
|
||||||
|
- **Visual Style:** Command center aesthetic
|
||||||
|
|
||||||
|
#### **Game Sessions List**
|
||||||
|
- **List Items:** (Per game)
|
||||||
|
- Game name
|
||||||
|
- Status badge (not started, active, paused, completed)
|
||||||
|
- Player count
|
||||||
|
- Created date
|
||||||
|
- Actions: View, Edit, Delete
|
||||||
|
- **Visual Style:** Card list, status colors
|
||||||
|
|
||||||
|
#### **Game Creation Wizard**
|
||||||
|
- **Step 1: Game Info**
|
||||||
|
- Game name input
|
||||||
|
- Scenario/setting textarea
|
||||||
|
- Genre/theme selector
|
||||||
|
- **Step 2: Player Slots**
|
||||||
|
- Slot configuration (number input)
|
||||||
|
- Slot cards:
|
||||||
|
- Slot type (Human/AI toggle)
|
||||||
|
- Player assignment (if human)
|
||||||
|
- AI configuration (if AI)
|
||||||
|
- **Step 3: Storyteller Assignment**
|
||||||
|
- Radio buttons: Human / AI
|
||||||
|
- User selector (if human)
|
||||||
|
- AI model selector (if AI)
|
||||||
|
- Storytelling style dropdown
|
||||||
|
- **Step 4: Game Settings**
|
||||||
|
- Turn-based toggle
|
||||||
|
- Auto-save interval
|
||||||
|
- Other game rules
|
||||||
|
- **Visual Style:** Multi-step wizard like character creation
|
||||||
|
|
||||||
|
#### **Role Assignment Interface**
|
||||||
|
- **Player Slots Grid:**
|
||||||
|
- Drag-and-drop cards
|
||||||
|
- Each slot shows:
|
||||||
|
- Slot number
|
||||||
|
- Assigned player/AI
|
||||||
|
- Character info (if selected)
|
||||||
|
- Edit button
|
||||||
|
- **Available Players Panel:**
|
||||||
|
- List of users
|
||||||
|
- Drag to assign
|
||||||
|
- **Visual Style:** Interactive, clear assignment state
|
||||||
|
|
||||||
|
#### **Game State Overview**
|
||||||
|
- **Tabs:**
|
||||||
|
- Overview
|
||||||
|
- Characters
|
||||||
|
- Messages
|
||||||
|
- Timeline
|
||||||
|
- **Overview Tab:**
|
||||||
|
- Game status
|
||||||
|
- Current scene
|
||||||
|
- Active players
|
||||||
|
- Statistics (messages, actions, etc.)
|
||||||
|
- **Characters Tab:**
|
||||||
|
- All character profiles
|
||||||
|
- Stats/inventory (if applicable)
|
||||||
|
- **Messages Tab:**
|
||||||
|
- All messages (public + private)
|
||||||
|
- Filter controls
|
||||||
|
- **Visual Style:** Dashboard with data cards
|
||||||
|
|
||||||
|
#### **AI Storyteller Command Interface**
|
||||||
|
- **Command Input:**
|
||||||
|
- Special input for GM → AI storyteller
|
||||||
|
- Examples: "Introduce a plot twist", "Increase difficulty"
|
||||||
|
- **AI Status:**
|
||||||
|
- Active/paused toggle
|
||||||
|
- Last action timestamp
|
||||||
|
- Response queue
|
||||||
|
- **Override Controls:**
|
||||||
|
- Edit AI responses
|
||||||
|
- Take manual control
|
||||||
|
- **Visual Style:** Distinct command interface
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Page 6: Admin Dashboard (Development/Future)
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
System-wide administration, monitoring, and configuration
|
||||||
|
|
||||||
|
### Layout Structure
|
||||||
|
```
|
||||||
|
┌────────────────────────────────────────┐
|
||||||
|
│ Admin Header (System Status) │
|
||||||
|
├────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌──────────┬──────────────────────┐ │
|
||||||
|
│ │ Nav Menu │ Content Panel │ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ │ - Games │ (Changes per menu) │ │
|
||||||
|
│ │ - Users │ │ │
|
||||||
|
│ │ - Models │ │ │
|
||||||
|
│ │ - Costs │ │ │
|
||||||
|
│ │ - Logs │ │ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ └──────────┴──────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
└────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### UI Elements
|
||||||
|
|
||||||
|
#### **Admin Header**
|
||||||
|
- **Title:** "System Administration"
|
||||||
|
- **System Status Indicators:**
|
||||||
|
- API status (green/red dot)
|
||||||
|
- Active games count
|
||||||
|
- Active users count
|
||||||
|
- **Visual Style:** Dark header, status indicators
|
||||||
|
|
||||||
|
#### **Navigation Menu**
|
||||||
|
- **Menu Items:**
|
||||||
|
- Dashboard (overview)
|
||||||
|
- Games Management
|
||||||
|
- User Management
|
||||||
|
- LLM Configuration
|
||||||
|
- Cost Analytics
|
||||||
|
- System Logs
|
||||||
|
- Settings
|
||||||
|
- **Visual Style:** Vertical menu, active state highlighting
|
||||||
|
|
||||||
|
#### **Dashboard Overview**
|
||||||
|
- **Metric Cards:**
|
||||||
|
- Total games (number + trend)
|
||||||
|
- Total users (number + trend)
|
||||||
|
- API calls today (number + cost)
|
||||||
|
- System health (percentage)
|
||||||
|
- **Recent Activity Feed:**
|
||||||
|
- Latest games created
|
||||||
|
- Recent errors
|
||||||
|
- High-cost requests
|
||||||
|
- **Charts:**
|
||||||
|
- Games over time
|
||||||
|
- Cost over time
|
||||||
|
- Model usage distribution
|
||||||
|
- **Visual Style:** Grid of cards, charts with tooltips
|
||||||
|
|
||||||
|
#### **Games Management**
|
||||||
|
- **Games Table:**
|
||||||
|
- Columns: ID, Name, GM, Players, Status, Created, Actions
|
||||||
|
- Sort controls
|
||||||
|
- Filter controls
|
||||||
|
- Pagination
|
||||||
|
- **Actions:**
|
||||||
|
- View details
|
||||||
|
- Force end
|
||||||
|
- Delete
|
||||||
|
- **Visual Style:** Data table with actions
|
||||||
|
|
||||||
|
#### **User Management**
|
||||||
|
- **Users Table:**
|
||||||
|
- Columns: Username, Email, Role, Games, Joined, Status, Actions
|
||||||
|
- Search bar
|
||||||
|
- Role filter
|
||||||
|
- **Actions:**
|
||||||
|
- Edit role
|
||||||
|
- Suspend/activate
|
||||||
|
- View activity
|
||||||
|
- **Visual Style:** Data table with user cards
|
||||||
|
|
||||||
|
#### **LLM Configuration**
|
||||||
|
- **Model Cards:** (Per model)
|
||||||
|
- Model name
|
||||||
|
- Provider
|
||||||
|
- Status (enabled/disabled toggle)
|
||||||
|
- Usage stats
|
||||||
|
- Cost per token
|
||||||
|
- Edit button
|
||||||
|
- **Add Model Form:**
|
||||||
|
- Model ID input
|
||||||
|
- API key input
|
||||||
|
- Configuration options
|
||||||
|
- **Visual Style:** Grid of model cards
|
||||||
|
|
||||||
|
#### **Cost Analytics**
|
||||||
|
- **Summary Cards:**
|
||||||
|
- Total cost this month
|
||||||
|
- Average per game
|
||||||
|
- Most expensive model
|
||||||
|
- **Cost Breakdown:**
|
||||||
|
- Per model chart
|
||||||
|
- Per game table
|
||||||
|
- Per user table
|
||||||
|
- **Date Range Selector:**
|
||||||
|
- Preset ranges (Today, Week, Month)
|
||||||
|
- Custom range picker
|
||||||
|
- **Export Button:** Download CSV
|
||||||
|
- **Visual Style:** Charts and tables
|
||||||
|
|
||||||
|
#### **System Logs**
|
||||||
|
- **Log Viewer:**
|
||||||
|
- Real-time log stream
|
||||||
|
- Log level filter (Info, Warning, Error)
|
||||||
|
- Search/filter input
|
||||||
|
- Timestamp
|
||||||
|
- Auto-scroll toggle
|
||||||
|
- **Visual Style:** Terminal/console aesthetic
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Common UI Components (Used Across Pages)
|
||||||
|
|
||||||
|
### Buttons
|
||||||
|
- **Primary Button:**
|
||||||
|
- Gradient background (#667eea to #764ba2)
|
||||||
|
- White text, rounded corners
|
||||||
|
- Hover: Slight lift, darker gradient
|
||||||
|
- Sizes: Small, Medium, Large
|
||||||
|
- **Secondary Button:**
|
||||||
|
- Transparent/outlined style
|
||||||
|
- Border color matches theme
|
||||||
|
- Hover: Background color change
|
||||||
|
- **Icon Buttons:**
|
||||||
|
- Circular or square
|
||||||
|
- Icon only, tooltip on hover
|
||||||
|
- **Danger Button:**
|
||||||
|
- Red color scheme
|
||||||
|
- Used for delete/destructive actions
|
||||||
|
|
||||||
|
### Input Fields
|
||||||
|
- **Text Input:**
|
||||||
|
- Dark background with light border
|
||||||
|
- Focus: Border color change, glow effect
|
||||||
|
- Error state: Red border + error message below
|
||||||
|
- Success state: Green border
|
||||||
|
- **Textarea:**
|
||||||
|
- Same as text input but multi-line
|
||||||
|
- Resize handle
|
||||||
|
- **Dropdown/Select:**
|
||||||
|
- Custom styled select
|
||||||
|
- Grouped options support
|
||||||
|
- Search/filter (for long lists)
|
||||||
|
- **Checkbox:**
|
||||||
|
- Custom checkbox with checkmark animation
|
||||||
|
- Label click support
|
||||||
|
- **Radio Buttons:**
|
||||||
|
- Custom styled radio
|
||||||
|
- Clear selected state
|
||||||
|
- **File Upload:**
|
||||||
|
- Drag-and-drop zone
|
||||||
|
- File type indicator
|
||||||
|
- Upload progress
|
||||||
|
|
||||||
|
### Cards
|
||||||
|
- **Base Card:**
|
||||||
|
- Rounded corners (8-12px)
|
||||||
|
- Shadow for elevation
|
||||||
|
- Padding: 1-2rem
|
||||||
|
- Background: White or dark surface
|
||||||
|
- **Interactive Card:**
|
||||||
|
- Hover state: Lift effect
|
||||||
|
- Click state: Scale slightly
|
||||||
|
- Selection state: Border highlight
|
||||||
|
- **Info Card:**
|
||||||
|
- Icon + title + content
|
||||||
|
- Color-coded by type
|
||||||
|
|
||||||
|
### Badges/Pills
|
||||||
|
- **Status Badge:**
|
||||||
|
- Small, rounded pill
|
||||||
|
- Color-coded (green=active, red=error, yellow=warning)
|
||||||
|
- Sizes: XS, SM, MD
|
||||||
|
- **Count Badge:**
|
||||||
|
- Circular badge with number
|
||||||
|
- Often overlays buttons/icons
|
||||||
|
|
||||||
|
### Modals/Overlays
|
||||||
|
- **Modal:**
|
||||||
|
- Full-screen semi-transparent overlay
|
||||||
|
- Centered content container
|
||||||
|
- Close button (X) in top-right
|
||||||
|
- Click outside to close (optional)
|
||||||
|
- **Toast/Notification:**
|
||||||
|
- Slide in from top-right
|
||||||
|
- Auto-dismiss after timeout
|
||||||
|
- Close button
|
||||||
|
- Type: Success, Error, Warning, Info
|
||||||
|
|
||||||
|
### Navigation
|
||||||
|
- **Tabs:**
|
||||||
|
- Horizontal tabs with active state
|
||||||
|
- Underline or background highlight
|
||||||
|
- **Breadcrumbs:**
|
||||||
|
- Path navigation
|
||||||
|
- Separator (/ or >)
|
||||||
|
- Click to navigate
|
||||||
|
- **Pagination:**
|
||||||
|
- Previous/Next buttons
|
||||||
|
- Page numbers
|
||||||
|
- Jump to page input
|
||||||
|
|
||||||
|
### Loading States
|
||||||
|
- **Spinner:**
|
||||||
|
- Circular spinner (small, medium, large)
|
||||||
|
- Themed color
|
||||||
|
- **Skeleton Screen:**
|
||||||
|
- Gray placeholder boxes
|
||||||
|
- Shimmer animation
|
||||||
|
- **Progress Bar:**
|
||||||
|
- Linear progress indicator
|
||||||
|
- Percentage display (optional)
|
||||||
|
|
||||||
|
### Empty States
|
||||||
|
- **No Data:**
|
||||||
|
- Icon + message
|
||||||
|
- Call-to-action button
|
||||||
|
- Helpful hint text
|
||||||
|
- **Error State:**
|
||||||
|
- Error icon + message
|
||||||
|
- Retry button
|
||||||
|
- Support link
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📱 Responsive Breakpoints
|
||||||
|
|
||||||
|
### Desktop (1024px+)
|
||||||
|
- Multi-column layouts
|
||||||
|
- Sidebars visible
|
||||||
|
- Full navigation
|
||||||
|
|
||||||
|
### Tablet (768px - 1023px)
|
||||||
|
- Collapsible sidebars
|
||||||
|
- Stacked cards
|
||||||
|
- Simplified navigation
|
||||||
|
|
||||||
|
### Mobile (<768px)
|
||||||
|
- Single column
|
||||||
|
- Bottom navigation
|
||||||
|
- Hamburger menu
|
||||||
|
- Full-screen modals
|
||||||
|
- Larger tap targets
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ♿ Accessibility Requirements
|
||||||
|
|
||||||
|
### Keyboard Navigation
|
||||||
|
- All interactive elements focusable
|
||||||
|
- Logical tab order
|
||||||
|
- Focus indicators (outline)
|
||||||
|
- Keyboard shortcuts (optional)
|
||||||
|
|
||||||
|
### Screen Reader Support
|
||||||
|
- Semantic HTML
|
||||||
|
- ARIA labels where needed
|
||||||
|
- Alt text for images
|
||||||
|
- Form labels associated
|
||||||
|
|
||||||
|
### Color Contrast
|
||||||
|
- WCAG AA minimum (4.5:1 for text)
|
||||||
|
- Color not sole indicator
|
||||||
|
- High contrast mode support
|
||||||
|
|
||||||
|
### Interaction
|
||||||
|
- Minimum touch target: 44x44px
|
||||||
|
- No timing-critical interactions
|
||||||
|
- Error prevention and recovery
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 Animation Guidelines
|
||||||
|
|
||||||
|
### Durations
|
||||||
|
- **Micro:** 100-200ms (hover, focus)
|
||||||
|
- **Short:** 200-300ms (buttons, tooltips)
|
||||||
|
- **Medium:** 300-500ms (modals, page transitions)
|
||||||
|
- **Long:** 500-800ms (complex animations)
|
||||||
|
|
||||||
|
### Easing
|
||||||
|
- **Ease-out:** UI appearing (modal open)
|
||||||
|
- **Ease-in:** UI disappearing (modal close)
|
||||||
|
- **Ease-in-out:** Smooth transitions
|
||||||
|
|
||||||
|
### Motion Preferences
|
||||||
|
- Respect `prefers-reduced-motion`
|
||||||
|
- Disable decorative animations
|
||||||
|
- Keep functional animations
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📐 Layout Patterns
|
||||||
|
|
||||||
|
### Container Widths
|
||||||
|
- **Max Width:** 1200px (main content)
|
||||||
|
- **Narrow:** 600px (forms, wizards)
|
||||||
|
- **Wide:** 1400px (dashboards)
|
||||||
|
|
||||||
|
### Grid Systems
|
||||||
|
- **12-column grid** for complex layouts
|
||||||
|
- **Flexbox** for simple layouts
|
||||||
|
- **CSS Grid** for card grids
|
||||||
|
|
||||||
|
### Spacing Rhythm
|
||||||
|
- Consistent vertical rhythm (8px base unit)
|
||||||
|
- Component spacing: 16px, 24px, 32px
|
||||||
|
- Section spacing: 48px, 64px
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Priority Elements for UI Design Templates
|
||||||
|
|
||||||
|
### High Priority (MVP Essential)
|
||||||
|
1. Session Setup page
|
||||||
|
2. Character View
|
||||||
|
3. Character Creation Wizard
|
||||||
|
4. Storyteller View
|
||||||
|
5. Primary buttons and inputs
|
||||||
|
|
||||||
|
### Medium Priority (Phase 3)
|
||||||
|
6. Gamemaster Control Panel
|
||||||
|
7. Role assignment interface
|
||||||
|
8. Game state dashboard
|
||||||
|
|
||||||
|
### Low Priority (Future)
|
||||||
|
9. Admin Dashboard
|
||||||
|
10. Analytics views
|
||||||
|
11. Advanced settings
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Use this document to prompt UI design tools with specific page requirements!**
|
||||||
|
|
||||||
|
Example prompt structure:
|
||||||
|
```
|
||||||
|
Create a modern dark-themed UI design for [PAGE NAME] with the following elements:
|
||||||
|
[List specific elements from above]
|
||||||
|
Color scheme: Purple gradient (#667eea to #764ba2)
|
||||||
|
Style: Modern, RPG-themed, clean
|
||||||
|
```
|
||||||
401
docs/reference/UI_ELEMENTS_REFERENCE.md
Normal file
401
docs/reference/UI_ELEMENTS_REFERENCE.md
Normal file
@@ -0,0 +1,401 @@
|
|||||||
|
# UI Elements Reference - Storyteller RPG
|
||||||
|
|
||||||
|
**Purpose:** Complete catalog of UI elements for design system templates
|
||||||
|
**Date:** October 12, 2025
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 Design System Overview
|
||||||
|
|
||||||
|
### Color Palette
|
||||||
|
- **Primary:** Purple gradient (#667eea to #764ba2)
|
||||||
|
- **Background:** Dark theme (#1a1a2e, #16213e)
|
||||||
|
- **Success:** Green (#10b981, #86efac)
|
||||||
|
- **Text:** White (#fff), Light gray (#aaa, #ccc)
|
||||||
|
- **Borders:** Subtle white rgba (0.1 opacity)
|
||||||
|
|
||||||
|
### Typography
|
||||||
|
- **Headings:** 24-32px, bold
|
||||||
|
- **Body:** 14-16px, normal
|
||||||
|
- **Small:** 12-13px, secondary info
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Page 1: Session Setup / Landing Page
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Entry point for creating/joining sessions and characters
|
||||||
|
|
||||||
|
### Key Sections
|
||||||
|
|
||||||
|
#### 1. Header Area
|
||||||
|
- **App Title:** "🎭 Storyteller RPG"
|
||||||
|
- **Subtitle:** Brief tagline
|
||||||
|
- **Logo placeholder** (future)
|
||||||
|
|
||||||
|
#### 2. Demo Session Quick Access
|
||||||
|
- **Section Title:** "🎲 Demo Session - 'The Cursed Tavern'"
|
||||||
|
- **Description text:** Brief explanation
|
||||||
|
- **Three action buttons:**
|
||||||
|
- Join as Storyteller (gold gradient)
|
||||||
|
- Play as Bargin (character 1)
|
||||||
|
- Play as Willow (character 2)
|
||||||
|
- **Button styling:** Large, prominent, with icons
|
||||||
|
|
||||||
|
#### 3. Session Creation Section
|
||||||
|
- **Section Title:** "Create New Session"
|
||||||
|
- **Description:** "Start a new game as the storyteller"
|
||||||
|
- **Input field:** Session name (text)
|
||||||
|
- **Primary button:** "Create Session"
|
||||||
|
|
||||||
|
#### 4. Session Join Section
|
||||||
|
- **Section Title:** "Join Existing Session"
|
||||||
|
- **Description:** "Play as a character in an ongoing game"
|
||||||
|
- **Form elements:**
|
||||||
|
- Session ID input (text)
|
||||||
|
- Character name input (text, required)
|
||||||
|
- Description textarea (3 rows)
|
||||||
|
- Personality textarea (2 rows, optional)
|
||||||
|
- Model selector (dropdown with optgroups)
|
||||||
|
- Model hint text (small, gray)
|
||||||
|
- **Character creation options:**
|
||||||
|
- Primary button: "✨ Create Character (Wizard)"
|
||||||
|
- Divider: "or"
|
||||||
|
- Toggle button: "Quick Create" (shows simple form)
|
||||||
|
- **Submit button:** "Join Session (Simple)" (conditional)
|
||||||
|
|
||||||
|
#### 5. Dividers
|
||||||
|
- Horizontal rule with centered text ("OR")
|
||||||
|
- Visual separation between sections
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Page 2: Character View (Player Perspective)
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Player's interface for interacting with storyteller
|
||||||
|
|
||||||
|
### Layout Structure
|
||||||
|
Three-column layout: Info | Messages | Public Feed
|
||||||
|
|
||||||
|
### Key Sections
|
||||||
|
|
||||||
|
#### 1. Character Header
|
||||||
|
- **Character name** (h2, white, bold)
|
||||||
|
- **Description text** (gray, italic)
|
||||||
|
- **Personality traits** (with emoji prefix)
|
||||||
|
- **Profile badges** (if profile exists):
|
||||||
|
- Race badge
|
||||||
|
- Class badge
|
||||||
|
- Personality type badge
|
||||||
|
- **Action buttons:**
|
||||||
|
- Export button (📥)
|
||||||
|
- Connection status indicator (● Connected / ○ Disconnected)
|
||||||
|
|
||||||
|
#### 2. Current Scene Panel (if active)
|
||||||
|
- **Section title:** "📜 Current Scene"
|
||||||
|
- **Scene text** (large, prominent)
|
||||||
|
- **Background:** Highlighted panel
|
||||||
|
|
||||||
|
#### 3. Public Messages Section
|
||||||
|
- **Section title:** "📢 Public Actions (All Players See)"
|
||||||
|
- **Message list:**
|
||||||
|
- Message sender label
|
||||||
|
- Timestamp
|
||||||
|
- Message content
|
||||||
|
- Visual distinction from private messages
|
||||||
|
|
||||||
|
#### 4. Private Conversation Area
|
||||||
|
- **Section title:** "💬 Private Conversation with Storyteller"
|
||||||
|
- **Message thread:**
|
||||||
|
- Character messages (right-aligned, colored)
|
||||||
|
- Storyteller messages (left-aligned, different color)
|
||||||
|
- Timestamps
|
||||||
|
- Message bubbles
|
||||||
|
- **Auto-scroll to latest**
|
||||||
|
|
||||||
|
#### 5. Message Composer
|
||||||
|
- **Message visibility selector** (dropdown):
|
||||||
|
- Private
|
||||||
|
- Public
|
||||||
|
- Mixed
|
||||||
|
- **Input area (varies by type):**
|
||||||
|
- Private/Public: Single text input
|
||||||
|
- Mixed: Two textareas (public + private)
|
||||||
|
- **Send button** (primary, disabled when disconnected)
|
||||||
|
|
||||||
|
#### 6. AI Generation Section (future)
|
||||||
|
- Generate suggestion button
|
||||||
|
- Prompt customization
|
||||||
|
- Regenerate option
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Page 3: Storyteller View (GM Perspective)
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Game master interface to manage all players and narrate story
|
||||||
|
|
||||||
|
### Layout Structure
|
||||||
|
Two-column: Character list sidebar | Main content area
|
||||||
|
|
||||||
|
### Key Sections
|
||||||
|
|
||||||
|
#### 1. Session Header
|
||||||
|
- **Session name** (h2)
|
||||||
|
- **Session ID display** with copy button
|
||||||
|
- **Quick copy feedback** (tooltip/toast)
|
||||||
|
|
||||||
|
#### 2. Character List Sidebar
|
||||||
|
- **Section title:** "Active Characters"
|
||||||
|
- **Character cards:**
|
||||||
|
- Character name
|
||||||
|
- "💬 View" button (per character)
|
||||||
|
- Highlight active selection
|
||||||
|
- Pending response indicator (red dot)
|
||||||
|
- **Scrollable list**
|
||||||
|
|
||||||
|
#### 3. Scene Narration Panel
|
||||||
|
- **Section title:** "📜 Scene Narration"
|
||||||
|
- **Textarea:** Large input for scene description
|
||||||
|
- **Buttons:**
|
||||||
|
- "Broadcast Scene" (primary)
|
||||||
|
- "✨ AI Suggest" (secondary, generates scene)
|
||||||
|
|
||||||
|
#### 4. Public Actions Feed
|
||||||
|
- **Section title:** "📢 Recent Public Actions"
|
||||||
|
- **Message list:**
|
||||||
|
- Character name
|
||||||
|
- Action content
|
||||||
|
- Timestamp
|
||||||
|
- **Latest 5 messages shown**
|
||||||
|
|
||||||
|
#### 5. Character Conversation View
|
||||||
|
- **Header:** Selected character name
|
||||||
|
- **Conversation thread:**
|
||||||
|
- Character messages
|
||||||
|
- Your responses
|
||||||
|
- Timestamps
|
||||||
|
- **Response composer:**
|
||||||
|
- Large textarea
|
||||||
|
- Button group:
|
||||||
|
- "✨ AI Suggest"
|
||||||
|
- "Send Private Response"
|
||||||
|
|
||||||
|
#### 6. Multi-Character Response (future)
|
||||||
|
- Select multiple characters
|
||||||
|
- Generate context-aware response
|
||||||
|
- Broadcast to selected players
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Page 4: Character Creation Wizard
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
6-step guided character creation with profiles
|
||||||
|
|
||||||
|
### Layout Structure
|
||||||
|
Modal overlay with centered card
|
||||||
|
|
||||||
|
### Key Sections
|
||||||
|
|
||||||
|
#### 1. Wizard Header
|
||||||
|
- **Title:** "Create Your Character"
|
||||||
|
- **Progress indicator:**
|
||||||
|
- 6 steps shown
|
||||||
|
- Active step highlighted
|
||||||
|
- Step labels visible
|
||||||
|
|
||||||
|
#### 2. Step Navigation
|
||||||
|
- **Footer buttons:**
|
||||||
|
- Cancel (left)
|
||||||
|
- Back (if not step 1)
|
||||||
|
- Next (steps 1-5)
|
||||||
|
- Create Character (step 6)
|
||||||
|
|
||||||
|
### Step-by-Step UI Elements
|
||||||
|
|
||||||
|
#### Step 1: Basic Info
|
||||||
|
- **Form elements:**
|
||||||
|
- Name input (required)
|
||||||
|
- Gender selector (dropdown)
|
||||||
|
- **Import section:**
|
||||||
|
- Hint text
|
||||||
|
- Import from JSON button (file picker)
|
||||||
|
|
||||||
|
#### Step 2: Description
|
||||||
|
- **Form elements:**
|
||||||
|
- Description textarea (4 rows, required)
|
||||||
|
- Background textarea (3 rows, optional)
|
||||||
|
|
||||||
|
#### Step 3: Race & Class
|
||||||
|
- **Selection grids:** (2x3 or responsive)
|
||||||
|
- Race cards (clickable)
|
||||||
|
- Class cards (clickable)
|
||||||
|
- **Card elements:**
|
||||||
|
- Name (bold)
|
||||||
|
- Description (gray)
|
||||||
|
- Selected state (highlighted border, gradient background)
|
||||||
|
- Hover effects
|
||||||
|
|
||||||
|
#### Step 4: Personality
|
||||||
|
- **Selection grid:** 2x2
|
||||||
|
- Personality type cards
|
||||||
|
- Same card styling as Step 3
|
||||||
|
- **Additional traits textarea** (optional)
|
||||||
|
|
||||||
|
#### Step 5: AI Model
|
||||||
|
- **Model selector:** Large dropdown
|
||||||
|
- Optgroups (OpenAI, OpenRouter)
|
||||||
|
- Model names with providers
|
||||||
|
- **Hint text:** Model personality differences
|
||||||
|
|
||||||
|
#### Step 6: Review
|
||||||
|
- **Preview panels:**
|
||||||
|
- Basic Information
|
||||||
|
- Description
|
||||||
|
- Background (if provided)
|
||||||
|
- Additional Traits (if provided)
|
||||||
|
- AI Model
|
||||||
|
- **Summary card:**
|
||||||
|
- Character identity statement
|
||||||
|
- Highlighted/special styling
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Future Pages (Phase 3+)
|
||||||
|
|
||||||
|
### Gamemaster Dashboard
|
||||||
|
- **Game creation wizard**
|
||||||
|
- **Player slot assignment**
|
||||||
|
- **Role management grid**
|
||||||
|
- **Game state overview**
|
||||||
|
- **AI control panel**
|
||||||
|
|
||||||
|
### Admin Panel
|
||||||
|
- **System overview**
|
||||||
|
- **User management**
|
||||||
|
- **LLM configuration**
|
||||||
|
- **Cost tracking dashboard**
|
||||||
|
- **Analytics charts**
|
||||||
|
|
||||||
|
### Character Sheet (Enhanced)
|
||||||
|
- **Stats display**
|
||||||
|
- **Inventory grid**
|
||||||
|
- **Skills list**
|
||||||
|
- **Equipment slots**
|
||||||
|
- **Character progression**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 Common UI Components
|
||||||
|
|
||||||
|
### Buttons
|
||||||
|
1. **Primary button:** Purple gradient, white text
|
||||||
|
2. **Secondary button:** Transparent, border, hover effect
|
||||||
|
3. **Wizard button:** Extra gradient styling
|
||||||
|
4. **Export/Action buttons:** Subtle rgba background
|
||||||
|
5. **Icon buttons:** Small, inline
|
||||||
|
|
||||||
|
### Form Elements
|
||||||
|
1. **Text inputs:** Dark background, subtle border, focus glow
|
||||||
|
2. **Textareas:** Resizable, same styling as inputs
|
||||||
|
3. **Dropdowns:** Custom styling, optgroups
|
||||||
|
4. **File pickers:** Hidden, triggered by styled button
|
||||||
|
|
||||||
|
### Cards
|
||||||
|
1. **Selection cards:** Clickable, hover lift, selected state
|
||||||
|
2. **Character cards:** Compact, button included
|
||||||
|
3. **Message cards:** Bubbles, aligned left/right
|
||||||
|
4. **Preview panels:** Bordered sections with headers
|
||||||
|
|
||||||
|
### Indicators
|
||||||
|
1. **Status dots:** Colored circles (● ○)
|
||||||
|
2. **Badges:** Rounded rectangles, colored background
|
||||||
|
3. **Progress bars:** Step indicators
|
||||||
|
4. **Loading states:** Spinners, skeleton screens
|
||||||
|
|
||||||
|
### Feedback
|
||||||
|
1. **Toasts/Alerts:** Success/error messages
|
||||||
|
2. **Tooltips:** Hover information
|
||||||
|
3. **Validation messages:** Inline form errors
|
||||||
|
4. **Empty states:** No data placeholders
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📐 Layout Patterns
|
||||||
|
|
||||||
|
### Responsive Breakpoints
|
||||||
|
- **Desktop:** > 768px (multi-column)
|
||||||
|
- **Mobile:** ≤ 768px (single column, stacked)
|
||||||
|
|
||||||
|
### Grid Systems
|
||||||
|
- **2-column:** Sidebar + main content
|
||||||
|
- **3-column:** Info + center + sidebar
|
||||||
|
- **Selection grids:** Auto-fit, min 200px
|
||||||
|
|
||||||
|
### Spacing
|
||||||
|
- **Sections:** 2-3rem padding
|
||||||
|
- **Elements:** 1-1.5rem gaps
|
||||||
|
- **Inline:** 0.5-1rem margins
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Design Prompt Template
|
||||||
|
|
||||||
|
**For UI Design LLM:**
|
||||||
|
|
||||||
|
```
|
||||||
|
Create a modern, dark-themed UI design for [PAGE NAME] with these elements:
|
||||||
|
|
||||||
|
**Color Scheme:**
|
||||||
|
- Primary: Purple gradient (#667eea to #764ba2)
|
||||||
|
- Background: Dark navy (#1a1a2e, #16213e)
|
||||||
|
- Accents: White with 10% opacity borders
|
||||||
|
- Text: White and light gray
|
||||||
|
|
||||||
|
**Layout:**
|
||||||
|
[Describe specific layout]
|
||||||
|
|
||||||
|
**Components Needed:**
|
||||||
|
[List specific elements for that page]
|
||||||
|
|
||||||
|
**Style:**
|
||||||
|
- Modern, clean, RPG-themed
|
||||||
|
- Smooth gradients and shadows
|
||||||
|
- Glassmorphism effects
|
||||||
|
- Smooth hover animations
|
||||||
|
- Mobile responsive
|
||||||
|
|
||||||
|
**Inspiration:**
|
||||||
|
Discord's UI, modern game interfaces, fantasy themes
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Component Priority
|
||||||
|
|
||||||
|
### Essential (Implement First)
|
||||||
|
1. Session setup forms
|
||||||
|
2. Message display/composer
|
||||||
|
3. Character header/info
|
||||||
|
4. Navigation/buttons
|
||||||
|
|
||||||
|
### Important (Phase 2-3)
|
||||||
|
1. Character creation wizard
|
||||||
|
2. Storyteller dashboard
|
||||||
|
3. Profile displays
|
||||||
|
4. Export/import UI
|
||||||
|
|
||||||
|
### Nice-to-Have (Phase 4+)
|
||||||
|
1. Character sheets with stats
|
||||||
|
2. Inventory management
|
||||||
|
3. Dice roller UI
|
||||||
|
4. Image generation panels
|
||||||
|
5. Analytics dashboards
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Total UI Elements Cataloged:** 100+
|
||||||
|
**Pages Documented:** 4 (+ 3 future)
|
||||||
|
**Ready for design system creation** ✅
|
||||||
343
docs/reference/UI_QUICK_REFERENCE.md
Normal file
343
docs/reference/UI_QUICK_REFERENCE.md
Normal file
@@ -0,0 +1,343 @@
|
|||||||
|
# UI Design Quick Reference
|
||||||
|
|
||||||
|
**TL;DR guide for getting UI designs quickly**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Priority Order
|
||||||
|
|
||||||
|
### Phase 2 (Current - Already Built)
|
||||||
|
✅ Session Setup Page
|
||||||
|
✅ Character View
|
||||||
|
✅ Character Creation Wizard
|
||||||
|
✅ Storyteller View
|
||||||
|
|
||||||
|
### Phase 3 (Next - Need Designs)
|
||||||
|
🎨 Gamemaster Control Panel
|
||||||
|
🎨 Game Creation Wizard
|
||||||
|
🎨 Role Assignment Interface
|
||||||
|
|
||||||
|
### Phase 4+ (Future)
|
||||||
|
⏳ Admin Dashboard
|
||||||
|
⏳ Analytics Views
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 6 Core Pages Summary
|
||||||
|
|
||||||
|
| Page | Purpose | Complexity | Priority |
|
||||||
|
|------|---------|------------|----------|
|
||||||
|
| **Session Setup** | Landing, join/create | Low | ✅ Built |
|
||||||
|
| **Character View** | Player interface | Medium | ✅ Built |
|
||||||
|
| **Character Wizard** | Character creation | Medium | ✅ Built |
|
||||||
|
| **Storyteller View** | GM interface | High | ✅ Built |
|
||||||
|
| **Gamemaster Panel** | Game management | High | 🎨 Next |
|
||||||
|
| **Admin Dashboard** | System admin | High | ⏳ Future |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 Design Files Location
|
||||||
|
|
||||||
|
All design documentation in `/docs/reference/`:
|
||||||
|
- **UI_ELEMENTS_INVENTORY.md** - Complete element list by page (15,000+ words)
|
||||||
|
- **UI_DESIGN_PROMPTS.md** - Copy-paste prompts for LLMs
|
||||||
|
- **UI_QUICK_REFERENCE.md** - This file
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚡ Quick Start
|
||||||
|
|
||||||
|
### To Get Designs Fast:
|
||||||
|
|
||||||
|
1. **Read the prompts file:**
|
||||||
|
- `/docs/reference/UI_DESIGN_PROMPTS.md`
|
||||||
|
- Find the page you need
|
||||||
|
- Copy the full prompt
|
||||||
|
|
||||||
|
2. **Choose your tool:**
|
||||||
|
- **v0.dev** (Vercel) - Best for React/Tailwind code
|
||||||
|
- **Midjourney/DALL-E** - Best for visual mockups
|
||||||
|
- **Claude/GPT-4** - Best for HTML/CSS implementation
|
||||||
|
|
||||||
|
3. **Generate:**
|
||||||
|
- Paste prompt
|
||||||
|
- Add tool-specific instructions
|
||||||
|
- Generate multiple variations
|
||||||
|
- Iterate and refine
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 Current Design System (Already Implemented)
|
||||||
|
|
||||||
|
### Colors
|
||||||
|
```css
|
||||||
|
--primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
--bg-dark: #1a1a2e;
|
||||||
|
--surface-dark: #2d3748;
|
||||||
|
--text-light: #ffffff;
|
||||||
|
--accent-purple: #667eea;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Components We Have
|
||||||
|
- ✅ Buttons (primary, secondary, icon)
|
||||||
|
- ✅ Input fields (text, textarea, dropdown)
|
||||||
|
- ✅ Cards (base, interactive, info)
|
||||||
|
- ✅ Badges/Pills
|
||||||
|
- ✅ Message bubbles
|
||||||
|
- ✅ Selection cards (wizard)
|
||||||
|
- ✅ Progress indicator
|
||||||
|
- ✅ Form layouts
|
||||||
|
- ✅ Modal overlays
|
||||||
|
|
||||||
|
### Components We Need
|
||||||
|
- 🎨 Data tables
|
||||||
|
- 🎨 Drag-and-drop cards
|
||||||
|
- 🎨 Charts (line, bar, pie)
|
||||||
|
- 🎨 Timeline/activity feed
|
||||||
|
- 🎨 Tabs component
|
||||||
|
- 🎨 Metric cards with trends
|
||||||
|
- 🎨 Role assignment slots
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Example: Getting Gamemaster Panel Design
|
||||||
|
|
||||||
|
### Option 1: v0.dev (Code + Design)
|
||||||
|
```
|
||||||
|
Prompt: [Copy from UI_DESIGN_PROMPTS.md - Prompt 5]
|
||||||
|
Add: "Generate as Next.js components with Tailwind CSS and shadcn/ui"
|
||||||
|
Output: Working React code + visual preview
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 2: Midjourney (Mockup)
|
||||||
|
```
|
||||||
|
Prompt: [Copy from UI_DESIGN_PROMPTS.md - Prompt 5]
|
||||||
|
Add: "UI mockup, high fidelity, Figma style, dark theme, 4k"
|
||||||
|
Output: Visual design to reference
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 3: Manual Implementation
|
||||||
|
```
|
||||||
|
1. Read element list in UI_ELEMENTS_INVENTORY.md
|
||||||
|
2. Sketch/wireframe layout
|
||||||
|
3. Build components one by one
|
||||||
|
4. Match existing design system colors/spacing
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Common Customizations
|
||||||
|
|
||||||
|
### To Match Different Styles:
|
||||||
|
|
||||||
|
**Sci-Fi Theme:**
|
||||||
|
```
|
||||||
|
Change gradient to: #00d9ff to #0099ff (cyan)
|
||||||
|
Add: Glowing borders, neon accents
|
||||||
|
Fonts: Orbitron or Exo 2
|
||||||
|
```
|
||||||
|
|
||||||
|
**Fantasy Theme:**
|
||||||
|
```
|
||||||
|
Keep purple gradient
|
||||||
|
Add: Texture overlays, paper-like cards
|
||||||
|
Fonts: Cinzel or IM Fell
|
||||||
|
Decorative borders
|
||||||
|
```
|
||||||
|
|
||||||
|
**Minimal Theme:**
|
||||||
|
```
|
||||||
|
Change to monochrome: #000000 to #ffffff
|
||||||
|
Remove: Gradients, decorative elements
|
||||||
|
Fonts: Inter or System UI
|
||||||
|
Flat design
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📐 Layout Templates
|
||||||
|
|
||||||
|
### Dashboard Layout (Gamemaster/Admin)
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────┐
|
||||||
|
│ Header (Global Actions) │
|
||||||
|
├──────┬──────────────────────────┤
|
||||||
|
│ Nav │ Main Content Area │
|
||||||
|
│ Bar │ │
|
||||||
|
│ │ ┌────────┬────────┐ │
|
||||||
|
│ │ │ Card │ Card │ │
|
||||||
|
│ │ └────────┴────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ │ [Tables/Charts/Forms] │
|
||||||
|
└──────┴──────────────────────────┘
|
||||||
|
|
||||||
|
Sidebar: 240px
|
||||||
|
Content: flex-1
|
||||||
|
Gap: 24px
|
||||||
|
```
|
||||||
|
|
||||||
|
### Chat Layout (Character/Storyteller)
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────┐
|
||||||
|
│ Header (Info + Actions) │
|
||||||
|
├─────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ Scrollable Message Area │
|
||||||
|
│ (Messages stacked vertically) │
|
||||||
|
│ │
|
||||||
|
├─────────────────────────────────┤
|
||||||
|
│ Fixed Composer (Bottom) │
|
||||||
|
└─────────────────────────────────┘
|
||||||
|
|
||||||
|
Header: Auto height
|
||||||
|
Messages: flex-1, overflow-auto
|
||||||
|
Composer: Auto height, fixed position
|
||||||
|
```
|
||||||
|
|
||||||
|
### Wizard Layout
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────┐
|
||||||
|
│ Wizard Header + Progress │
|
||||||
|
├─────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ Step Content (Centered) │
|
||||||
|
│ Max Width: 600px │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
├─────────────────────────────────┤
|
||||||
|
│ Footer (Cancel | Back | Next) │
|
||||||
|
└─────────────────────────────────┘
|
||||||
|
|
||||||
|
Modal: Max 800px width, centered
|
||||||
|
Content: Vertical padding 48px
|
||||||
|
Footer: Sticky bottom
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Phase 3 Design Priorities
|
||||||
|
|
||||||
|
### Must Have First:
|
||||||
|
1. **Gamemaster Dashboard** - Overview/home screen
|
||||||
|
2. **Game Creation Form** - Simple version
|
||||||
|
3. **Player Slot Cards** - Assignment interface
|
||||||
|
|
||||||
|
### Can Wait:
|
||||||
|
4. Role drag-and-drop (use simple assignment first)
|
||||||
|
5. Advanced analytics
|
||||||
|
6. Detailed configuration screens
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Tips for Design Consistency
|
||||||
|
|
||||||
|
### When Designing New Pages:
|
||||||
|
|
||||||
|
1. **Reuse existing components**
|
||||||
|
- Check what's already built
|
||||||
|
- Extend rather than recreate
|
||||||
|
|
||||||
|
2. **Match spacing**
|
||||||
|
- Use 8px grid system
|
||||||
|
- Common gaps: 16px, 24px, 32px
|
||||||
|
|
||||||
|
3. **Follow color usage**
|
||||||
|
- Purple for primary actions
|
||||||
|
- Dark backgrounds (#2d3748)
|
||||||
|
- White/light text
|
||||||
|
|
||||||
|
4. **Keep hierarchy clear**
|
||||||
|
- Largest: Page titles (2rem)
|
||||||
|
- Medium: Section titles (1.5rem)
|
||||||
|
- Normal: Body text (1rem)
|
||||||
|
|
||||||
|
5. **Maintain card style**
|
||||||
|
- Rounded 8-12px
|
||||||
|
- Subtle shadows
|
||||||
|
- Padding 1-2rem
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📱 Responsive Breakpoints
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* Mobile First */
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tablet - 768px */
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.container {
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
.grid {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Desktop - 1024px */
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.grid {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Workflow Recommendation
|
||||||
|
|
||||||
|
### For Phase 3 Implementation:
|
||||||
|
|
||||||
|
**Week 1:** Design Phase
|
||||||
|
- Day 1: Generate Gamemaster dashboard mockups
|
||||||
|
- Day 2: Review and refine designs
|
||||||
|
- Day 3: Generate component mockups
|
||||||
|
- Day 4: Finalize design system updates
|
||||||
|
- Day 5: Create component specifications
|
||||||
|
|
||||||
|
**Week 2-3:** Implementation
|
||||||
|
- Build reusable components
|
||||||
|
- Implement layouts
|
||||||
|
- Connect to backend
|
||||||
|
- Test responsive behavior
|
||||||
|
- Polish animations
|
||||||
|
|
||||||
|
**Week 4:** Polish
|
||||||
|
- Fix edge cases
|
||||||
|
- Accessibility improvements
|
||||||
|
- Performance optimization
|
||||||
|
- User testing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Resources
|
||||||
|
|
||||||
|
### Design Tools
|
||||||
|
- **v0.dev** - https://v0.dev (AI code generation)
|
||||||
|
- **Figma** - https://figma.com (Design/prototype)
|
||||||
|
- **Tailwind UI** - https://tailwindui.com (Component library)
|
||||||
|
- **shadcn/ui** - https://ui.shadcn.com (React components)
|
||||||
|
|
||||||
|
### Inspiration
|
||||||
|
- **Dribbble** - Search "RPG dashboard dark theme"
|
||||||
|
- **Behance** - Search "game master interface"
|
||||||
|
- **Awwwards** - Dark themed web apps
|
||||||
|
|
||||||
|
### Color Tools
|
||||||
|
- **Coolors** - Generate palette variations
|
||||||
|
- **Color Hunt** - Find complementary palettes
|
||||||
|
- **Contrast Checker** - Ensure accessibility
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Everything you need to get UI designs for Phase 3 is ready!** 🎨✨
|
||||||
|
|
||||||
|
Start with the Gamemaster Control Panel - that's the biggest design challenge for Phase 3.
|
||||||
@@ -954,6 +954,16 @@ body {
|
|||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.public-message-character-header {
|
||||||
|
background: #2d3748;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.public-msg-content {
|
.public-msg-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
color: #2d3748;
|
color: #2d3748;
|
||||||
@@ -1223,6 +1233,75 @@ body {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Character Profile Display */
|
||||||
|
.character-profile-summary {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-badge {
|
||||||
|
background: rgba(102, 126, 234, 0.2);
|
||||||
|
color: #667eea;
|
||||||
|
padding: 0.25rem 0.75rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 500;
|
||||||
|
border: 1px solid rgba(102, 126, 234, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-actions {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.75rem;
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-export {
|
||||||
|
background: rgba(102, 126, 234, 0.2);
|
||||||
|
color: #fff;
|
||||||
|
border: 1px solid rgba(102, 126, 234, 0.5);
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-export:hover {
|
||||||
|
background: rgba(102, 126, 234, 0.3);
|
||||||
|
border-color: #667eea;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Character Creation Options */
|
||||||
|
.character-creation-options {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-wizard {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
border: none;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-wizard:hover {
|
||||||
|
background: linear-gradient(135deg, #5568d3 0%, #65408b 100%);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-divider {
|
||||||
|
color: #718096;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.storyteller-content {
|
.storyteller-content {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
@@ -1235,4 +1314,12 @@ body {
|
|||||||
.message {
|
.message {
|
||||||
max-width: 85%;
|
max-width: 85%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.character-creation-options {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-divider {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
321
frontend/src/components/CharacterCreationWizard.css
Normal file
321
frontend/src/components/CharacterCreationWizard.css
Normal file
@@ -0,0 +1,321 @@
|
|||||||
|
.wizard-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.8);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 1000;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-container {
|
||||||
|
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
|
||||||
|
border-radius: 15px;
|
||||||
|
max-width: 800px;
|
||||||
|
width: 100%;
|
||||||
|
max-height: 90vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-header {
|
||||||
|
padding: 30px;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-header h2 {
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 28px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-progress {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 10px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-step {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 100px;
|
||||||
|
padding: 10px;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #888;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-step.active {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-content {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-step {
|
||||||
|
animation: fadeIn 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from { opacity: 0; transform: translateY(10px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-step h3 {
|
||||||
|
margin: 0 0 25px 0;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: #aaa;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input[type="text"],
|
||||||
|
.form-group textarea,
|
||||||
|
.form-group select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
border-radius: 8px;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: inherit;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input[type="text"]:focus,
|
||||||
|
.form-group textarea:focus,
|
||||||
|
.form-group select:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #667eea;
|
||||||
|
background: rgba(102, 126, 234, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group textarea {
|
||||||
|
resize: vertical;
|
||||||
|
min-height: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 15px;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-card {
|
||||||
|
padding: 20px;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
border: 2px solid rgba(255, 255, 255, 0.1);
|
||||||
|
border-radius: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-card:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
border-color: rgba(102, 126, 234, 0.5);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-card.selected {
|
||||||
|
background: linear-gradient(135deg, rgba(102, 126, 234, 0.2) 0%, rgba(118, 75, 162, 0.2) 100%);
|
||||||
|
border-color: #667eea;
|
||||||
|
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #fff;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-desc {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #aaa;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.import-section {
|
||||||
|
margin-top: 30px;
|
||||||
|
padding: 20px;
|
||||||
|
background: rgba(102, 126, 234, 0.1);
|
||||||
|
border: 1px dashed rgba(102, 126, 234, 0.3);
|
||||||
|
border-radius: 10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.import-hint {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
color: #aaa;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-import {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 10px 20px;
|
||||||
|
background: rgba(102, 126, 234, 0.2);
|
||||||
|
border: 1px solid #667eea;
|
||||||
|
border-radius: 8px;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-import:hover {
|
||||||
|
background: rgba(102, 126, 234, 0.3);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-select-large {
|
||||||
|
padding: 15px !important;
|
||||||
|
font-size: 15px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-hint {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #aaa;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-preview {
|
||||||
|
background: rgba(255, 255, 255, 0.03);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-section {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-section:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-section h4 {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
color: #667eea;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-section p {
|
||||||
|
margin: 5px 0;
|
||||||
|
color: #ccc;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-section strong {
|
||||||
|
color: #fff;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-summary {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 20px;
|
||||||
|
background: linear-gradient(135deg, rgba(102, 126, 234, 0.2) 0%, rgba(118, 75, 162, 0.2) 100%);
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid rgba(102, 126, 234, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-summary h4 {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-text {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-footer {
|
||||||
|
padding: 20px 30px;
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-navigation {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-loading {
|
||||||
|
padding: 50px;
|
||||||
|
text-align: center;
|
||||||
|
color: #aaa;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.wizard-container {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100vh;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-progress {
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-step {
|
||||||
|
min-width: 60px;
|
||||||
|
padding: 8px 5px;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-content {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-header {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard-header h2 {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
389
frontend/src/components/CharacterCreationWizard.js
Normal file
389
frontend/src/components/CharacterCreationWizard.js
Normal file
@@ -0,0 +1,389 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import './CharacterCreationWizard.css';
|
||||||
|
|
||||||
|
const API_URL = 'http://localhost:8000';
|
||||||
|
|
||||||
|
function CharacterCreationWizard({ sessionId, onCharacterCreated, onCancel }) {
|
||||||
|
const [step, setStep] = useState(1);
|
||||||
|
const [profileOptions, setProfileOptions] = useState(null);
|
||||||
|
const [availableModels, setAvailableModels] = useState({ openai: [], openrouter: [] });
|
||||||
|
|
||||||
|
// Character data
|
||||||
|
const [characterData, setCharacterData] = useState({
|
||||||
|
name: '',
|
||||||
|
description: '',
|
||||||
|
personality: '',
|
||||||
|
llm_model: 'gpt-3.5-turbo',
|
||||||
|
profile: {
|
||||||
|
gender: 'Male',
|
||||||
|
race: 'Human',
|
||||||
|
character_class: 'Warrior',
|
||||||
|
personality_type: 'Friendly',
|
||||||
|
background: '',
|
||||||
|
avatar_data: null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Fetch profile options
|
||||||
|
fetch(`${API_URL}/profile/options`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => setProfileOptions(data))
|
||||||
|
.catch(err => console.error('Error fetching profile options:', err));
|
||||||
|
|
||||||
|
// Fetch available models
|
||||||
|
fetch(`${API_URL}/models`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
setAvailableModels(data);
|
||||||
|
if (data.openai.length > 0) {
|
||||||
|
updateCharacterData('llm_model', data.openai[0].id);
|
||||||
|
} else if (data.openrouter.length > 0) {
|
||||||
|
updateCharacterData('llm_model', data.openrouter[0].id);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => console.error('Error fetching models:', err));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const updateCharacterData = (field, value) => {
|
||||||
|
setCharacterData(prev => ({ ...prev, [field]: value }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateProfile = (field, value) => {
|
||||||
|
setCharacterData(prev => ({
|
||||||
|
...prev,
|
||||||
|
profile: { ...prev.profile, [field]: value }
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNext = () => {
|
||||||
|
if (step === 1 && !characterData.name.trim()) {
|
||||||
|
alert('Please enter a character name');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (step === 2 && !characterData.description.trim()) {
|
||||||
|
alert('Please enter a character description');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setStep(step + 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBack = () => {
|
||||||
|
setStep(step - 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCreate = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${API_URL}/sessions/${sessionId}/characters/`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(characterData),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to create character');
|
||||||
|
}
|
||||||
|
|
||||||
|
const character = await response.json();
|
||||||
|
onCharacterCreated(character);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error creating character:', error);
|
||||||
|
alert('Failed to create character: ' + error.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleImport = async (event) => {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const text = await file.text();
|
||||||
|
const importedData = JSON.parse(text);
|
||||||
|
|
||||||
|
// Extract character data
|
||||||
|
const charData = importedData.character || importedData;
|
||||||
|
|
||||||
|
// Update form with imported data
|
||||||
|
setCharacterData({
|
||||||
|
name: charData.name || '',
|
||||||
|
description: charData.description || '',
|
||||||
|
personality: charData.personality || '',
|
||||||
|
llm_model: charData.llm_model || 'gpt-3.5-turbo',
|
||||||
|
profile: charData.profile || characterData.profile
|
||||||
|
});
|
||||||
|
|
||||||
|
setStep(1); // Go to first step to review
|
||||||
|
alert('Character imported! Review and modify as needed.');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error importing character:', error);
|
||||||
|
alert('Failed to import character. Please check the file format.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!profileOptions) {
|
||||||
|
return <div className="wizard-loading">Loading character creation wizard...</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="wizard-overlay">
|
||||||
|
<div className="wizard-container">
|
||||||
|
<div className="wizard-header">
|
||||||
|
<h2>Create Your Character</h2>
|
||||||
|
<div className="wizard-progress">
|
||||||
|
<div className={`progress-step ${step >= 1 ? 'active' : ''}`}>1. Basic Info</div>
|
||||||
|
<div className={`progress-step ${step >= 2 ? 'active' : ''}`}>2. Description</div>
|
||||||
|
<div className={`progress-step ${step >= 3 ? 'active' : ''}`}>3. Race & Class</div>
|
||||||
|
<div className={`progress-step ${step >= 4 ? 'active' : ''}`}>4. Personality</div>
|
||||||
|
<div className={`progress-step ${step >= 5 ? 'active' : ''}`}>5. AI Model</div>
|
||||||
|
<div className={`progress-step ${step >= 6 ? 'active' : ''}`}>6. Review</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="wizard-content">
|
||||||
|
{/* Step 1: Basic Info */}
|
||||||
|
{step === 1 && (
|
||||||
|
<div className="wizard-step">
|
||||||
|
<h3>Basic Information</h3>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Character Name *</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={characterData.name}
|
||||||
|
onChange={(e) => updateCharacterData('name', e.target.value)}
|
||||||
|
placeholder="Enter your character's name"
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Gender</label>
|
||||||
|
<select
|
||||||
|
value={characterData.profile.gender}
|
||||||
|
onChange={(e) => updateProfile('gender', e.target.value)}
|
||||||
|
>
|
||||||
|
{profileOptions.genders.map(gender => (
|
||||||
|
<option key={gender} value={gender}>{gender}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="import-section">
|
||||||
|
<p className="import-hint">💡 Have an existing character?</p>
|
||||||
|
<label className="btn-import">
|
||||||
|
📥 Import from JSON
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
accept=".json"
|
||||||
|
onChange={handleImport}
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Step 2: Description */}
|
||||||
|
{step === 2 && (
|
||||||
|
<div className="wizard-step">
|
||||||
|
<h3>Character Description</h3>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Description *</label>
|
||||||
|
<textarea
|
||||||
|
value={characterData.description}
|
||||||
|
onChange={(e) => updateCharacterData('description', e.target.value)}
|
||||||
|
placeholder="Describe your character (e.g., A brave knight seeking redemption)"
|
||||||
|
rows="4"
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Background Story (Optional)</label>
|
||||||
|
<textarea
|
||||||
|
value={characterData.profile.background}
|
||||||
|
onChange={(e) => updateProfile('background', e.target.value)}
|
||||||
|
placeholder="Additional background or backstory"
|
||||||
|
rows="3"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Step 3: Race & Class */}
|
||||||
|
{step === 3 && (
|
||||||
|
<div className="wizard-step">
|
||||||
|
<h3>Race & Class</h3>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Race</label>
|
||||||
|
<div className="selection-grid">
|
||||||
|
{profileOptions.races.map(race => (
|
||||||
|
<div
|
||||||
|
key={race}
|
||||||
|
className={`selection-card ${characterData.profile.race === race ? 'selected' : ''}`}
|
||||||
|
onClick={() => updateProfile('race', race)}
|
||||||
|
>
|
||||||
|
<div className="selection-name">{race}</div>
|
||||||
|
<div className="selection-desc">{profileOptions.race_descriptions[race]}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Class</label>
|
||||||
|
<div className="selection-grid">
|
||||||
|
{profileOptions.classes.map(cls => (
|
||||||
|
<div
|
||||||
|
key={cls}
|
||||||
|
className={`selection-card ${characterData.profile.character_class === cls ? 'selected' : ''}`}
|
||||||
|
onClick={() => updateProfile('character_class', cls)}
|
||||||
|
>
|
||||||
|
<div className="selection-name">{cls}</div>
|
||||||
|
<div className="selection-desc">{profileOptions.class_descriptions[cls]}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Step 4: Personality */}
|
||||||
|
{step === 4 && (
|
||||||
|
<div className="wizard-step">
|
||||||
|
<h3>Personality Type</h3>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Choose a personality that defines your character's behavior</label>
|
||||||
|
<div className="selection-grid">
|
||||||
|
{profileOptions.personality_types.map(personality => (
|
||||||
|
<div
|
||||||
|
key={personality}
|
||||||
|
className={`selection-card ${characterData.profile.personality_type === personality ? 'selected' : ''}`}
|
||||||
|
onClick={() => updateProfile('personality_type', personality)}
|
||||||
|
>
|
||||||
|
<div className="selection-name">{personality}</div>
|
||||||
|
<div className="selection-desc">{profileOptions.personality_descriptions[personality]}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Additional Personality Traits (Optional)</label>
|
||||||
|
<textarea
|
||||||
|
value={characterData.personality}
|
||||||
|
onChange={(e) => updateCharacterData('personality', e.target.value)}
|
||||||
|
placeholder="Any additional personality traits or quirks"
|
||||||
|
rows="3"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Step 5: AI Model */}
|
||||||
|
{step === 5 && (
|
||||||
|
<div className="wizard-step">
|
||||||
|
<h3>AI Model Selection</h3>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Choose the AI model for this character</label>
|
||||||
|
<select
|
||||||
|
value={characterData.llm_model}
|
||||||
|
onChange={(e) => updateCharacterData('llm_model', e.target.value)}
|
||||||
|
className="model-select-large"
|
||||||
|
>
|
||||||
|
{availableModels.openai.length > 0 && (
|
||||||
|
<optgroup label="OpenAI Models">
|
||||||
|
{availableModels.openai.map(model => (
|
||||||
|
<option key={model.id} value={model.id}>
|
||||||
|
{model.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</optgroup>
|
||||||
|
)}
|
||||||
|
{availableModels.openrouter.length > 0 && (
|
||||||
|
<optgroup label="OpenRouter Models">
|
||||||
|
{availableModels.openrouter.map(model => (
|
||||||
|
<option key={model.id} value={model.id}>
|
||||||
|
{model.name} ({model.provider})
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</optgroup>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
<p className="model-hint">
|
||||||
|
💡 Different models give different personalities! Try Claude for creative responses,
|
||||||
|
GPT-4 for detailed reasoning, or Llama for faster interactions.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Step 6: Review */}
|
||||||
|
{step === 6 && (
|
||||||
|
<div className="wizard-step">
|
||||||
|
<h3>Review Your Character</h3>
|
||||||
|
<div className="character-preview">
|
||||||
|
<div className="preview-section">
|
||||||
|
<h4>Basic Information</h4>
|
||||||
|
<p><strong>Name:</strong> {characterData.name}</p>
|
||||||
|
<p><strong>Gender:</strong> {characterData.profile.gender}</p>
|
||||||
|
<p><strong>Race:</strong> {characterData.profile.race}</p>
|
||||||
|
<p><strong>Class:</strong> {characterData.profile.character_class}</p>
|
||||||
|
<p><strong>Personality:</strong> {characterData.profile.personality_type}</p>
|
||||||
|
</div>
|
||||||
|
<div className="preview-section">
|
||||||
|
<h4>Description</h4>
|
||||||
|
<p>{characterData.description}</p>
|
||||||
|
</div>
|
||||||
|
{characterData.profile.background && (
|
||||||
|
<div className="preview-section">
|
||||||
|
<h4>Background</h4>
|
||||||
|
<p>{characterData.profile.background}</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{characterData.personality && (
|
||||||
|
<div className="preview-section">
|
||||||
|
<h4>Additional Traits</h4>
|
||||||
|
<p>{characterData.personality}</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="preview-section">
|
||||||
|
<h4>AI Model</h4>
|
||||||
|
<p>{characterData.llm_model}</p>
|
||||||
|
</div>
|
||||||
|
<div className="preview-summary">
|
||||||
|
<h4>Character Summary</h4>
|
||||||
|
<p className="summary-text">
|
||||||
|
{characterData.name} is a {characterData.profile.gender.toLowerCase()} {characterData.profile.race} {characterData.profile.character_class} with a {characterData.profile.personality_type.toLowerCase()} personality.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="wizard-footer">
|
||||||
|
<div className="wizard-actions">
|
||||||
|
<button className="btn-secondary" onClick={onCancel}>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<div className="wizard-navigation">
|
||||||
|
{step > 1 && (
|
||||||
|
<button className="btn-secondary" onClick={handleBack}>
|
||||||
|
← Back
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{step < 6 ? (
|
||||||
|
<button className="btn-primary" onClick={handleNext}>
|
||||||
|
Next →
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button className="btn-primary" onClick={handleCreate}>
|
||||||
|
✨ Create Character
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CharacterCreationWizard;
|
||||||
@@ -16,6 +16,30 @@ function CharacterView({ sessionId, characterId }) {
|
|||||||
const wsRef = useRef(null);
|
const wsRef = useRef(null);
|
||||||
const messagesEndRef = useRef(null);
|
const messagesEndRef = useRef(null);
|
||||||
|
|
||||||
|
const handleExportCharacter = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${API_URL}/sessions/${sessionId}/characters/${characterId}/export`);
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
// Create download link
|
||||||
|
const dataStr = JSON.stringify(data, null, 2);
|
||||||
|
const dataBlob = new Blob([dataStr], { type: 'application/json' });
|
||||||
|
const url = URL.createObjectURL(dataBlob);
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
link.download = `${characterInfo?.name || 'character'}_${new Date().toISOString().split('T')[0]}.json`;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
|
||||||
|
alert('Character exported successfully!');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error exporting character:', error);
|
||||||
|
alert('Failed to export character');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Fetch character info
|
// Fetch character info
|
||||||
fetch(`${API_URL}/sessions/${sessionId}/characters/${characterId}/conversation`)
|
fetch(`${API_URL}/sessions/${sessionId}/characters/${characterId}/conversation`)
|
||||||
@@ -109,8 +133,18 @@ function CharacterView({ sessionId, characterId }) {
|
|||||||
{characterInfo?.personality && (
|
{characterInfo?.personality && (
|
||||||
<p className="character-personality">🎭 {characterInfo.personality}</p>
|
<p className="character-personality">🎭 {characterInfo.personality}</p>
|
||||||
)}
|
)}
|
||||||
|
{characterInfo?.profile && (
|
||||||
|
<div className="character-profile-summary">
|
||||||
|
<span className="profile-badge">{characterInfo.profile.race}</span>
|
||||||
|
<span className="profile-badge">{characterInfo.profile.character_class}</span>
|
||||||
|
<span className="profile-badge">{characterInfo.profile.personality_type}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="connection-status">
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="character-actions">
|
||||||
|
<button className="btn-export" onClick={handleExportCharacter} title="Export character">
|
||||||
|
📥 Export
|
||||||
|
</button>
|
||||||
<span className={`status-indicator ${isConnected ? 'connected' : 'disconnected'}`}>
|
<span className={`status-indicator ${isConnected ? 'connected' : 'disconnected'}`}>
|
||||||
{isConnected ? '● Connected' : '○ Disconnected'}
|
{isConnected ? '● Connected' : '○ Disconnected'}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import CharacterCreationWizard from './CharacterCreationWizard';
|
||||||
|
|
||||||
const API_URL = 'http://localhost:8000';
|
const API_URL = 'http://localhost:8000';
|
||||||
|
|
||||||
@@ -10,6 +11,8 @@ function SessionSetup({ onCreateSession, onJoinSession }) {
|
|||||||
const [characterPersonality, setCharacterPersonality] = useState('');
|
const [characterPersonality, setCharacterPersonality] = useState('');
|
||||||
const [selectedModel, setSelectedModel] = useState('gpt-3.5-turbo');
|
const [selectedModel, setSelectedModel] = useState('gpt-3.5-turbo');
|
||||||
const [availableModels, setAvailableModels] = useState({ openai: [], openrouter: [] });
|
const [availableModels, setAvailableModels] = useState({ openai: [], openrouter: [] });
|
||||||
|
const [showWizard, setShowWizard] = useState(false);
|
||||||
|
const [useSimpleMode, setUseSimpleMode] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Fetch available models
|
// Fetch available models
|
||||||
@@ -66,7 +69,7 @@ function SessionSetup({ onCreateSession, onJoinSession }) {
|
|||||||
llm_model: selectedModel,
|
llm_model: selectedModel,
|
||||||
});
|
});
|
||||||
|
|
||||||
const charResponse = await fetch(`${API_URL}/sessions/${joinSessionId}/characters/?${params}`, {
|
const charResponse = await fetch(`${API_URL}/sessions/${joinSessionId}/characters/legacy/?${params}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -78,6 +81,19 @@ function SessionSetup({ onCreateSession, onJoinSession }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCharacterCreated = (character) => {
|
||||||
|
setShowWizard(false);
|
||||||
|
onJoinSession(joinSessionId, character.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const openWizard = () => {
|
||||||
|
if (!joinSessionId.trim()) {
|
||||||
|
alert('Please enter a Session ID first');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setShowWizard(true);
|
||||||
|
};
|
||||||
|
|
||||||
// Quick join demo session functions
|
// Quick join demo session functions
|
||||||
const joinDemoStoryteller = () => {
|
const joinDemoStoryteller = () => {
|
||||||
onCreateSession("demo-session-001");
|
onCreateSession("demo-session-001");
|
||||||
@@ -144,6 +160,15 @@ function SessionSetup({ onCreateSession, onJoinSession }) {
|
|||||||
<div className="setup-section">
|
<div className="setup-section">
|
||||||
<h2>Join Existing Session</h2>
|
<h2>Join Existing Session</h2>
|
||||||
<p className="section-description">Play as a character in an ongoing game</p>
|
<p className="section-description">Play as a character in an ongoing game</p>
|
||||||
|
|
||||||
|
{showWizard && (
|
||||||
|
<CharacterCreationWizard
|
||||||
|
sessionId={joinSessionId}
|
||||||
|
onCharacterCreated={handleCharacterCreated}
|
||||||
|
onCancel={() => setShowWizard(false)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="input-group">
|
<div className="input-group">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -202,9 +227,21 @@ function SessionSetup({ onCreateSession, onJoinSession }) {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button className="btn-primary" onClick={joinSession}>
|
<div className="character-creation-options">
|
||||||
Join Session
|
<button className="btn-primary btn-wizard" onClick={openWizard}>
|
||||||
|
✨ Create Character (Wizard)
|
||||||
</button>
|
</button>
|
||||||
|
<span className="option-divider">or</span>
|
||||||
|
<button className="btn-secondary" onClick={() => setUseSimpleMode(!useSimpleMode)}>
|
||||||
|
{useSimpleMode ? '↑ Hide' : '↓ Quick Create'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{useSimpleMode && (
|
||||||
|
<button className="btn-primary" onClick={joinSession}>
|
||||||
|
Join Session (Simple)
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
214
main.py
214
main.py
@@ -42,11 +42,21 @@ class Message(BaseModel):
|
|||||||
public_content: Optional[str] = None # For mixed messages - visible to all
|
public_content: Optional[str] = None # For mixed messages - visible to all
|
||||||
private_content: Optional[str] = None # For mixed messages - only storyteller sees
|
private_content: Optional[str] = None # For mixed messages - only storyteller sees
|
||||||
|
|
||||||
|
class CharacterProfile(BaseModel):
|
||||||
|
"""Character profile with race, class, gender, and personality traits"""
|
||||||
|
gender: str = "Male" # Male, Female, Non-binary, Custom
|
||||||
|
race: str = "Human" # Human, Elf, Dwarf, Orc, Halfling
|
||||||
|
character_class: str = "Warrior" # Warrior, Wizard, Cleric, Archer, Rogue
|
||||||
|
personality_type: str = "Friendly" # Friendly, Serious, Doubtful, Measured
|
||||||
|
background: str = "" # Custom background story
|
||||||
|
avatar_data: Optional[str] = None # base64 encoded avatar image
|
||||||
|
|
||||||
class Character(BaseModel):
|
class Character(BaseModel):
|
||||||
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
|
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
|
||||||
name: str
|
name: str
|
||||||
description: str
|
description: str
|
||||||
personality: str = "" # Additional personality traits
|
personality: str = "" # Additional personality traits (legacy field)
|
||||||
|
profile: Optional[CharacterProfile] = None # Structured profile
|
||||||
llm_model: str = "gpt-3.5-turbo" # LLM model for this character
|
llm_model: str = "gpt-3.5-turbo" # LLM model for this character
|
||||||
conversation_history: List[Message] = [] # Private conversation with storyteller
|
conversation_history: List[Message] = [] # Private conversation with storyteller
|
||||||
pending_response: bool = False # Waiting for storyteller response
|
pending_response: bool = False # Waiting for storyteller response
|
||||||
@@ -63,6 +73,61 @@ class GameSession(BaseModel):
|
|||||||
scene_history: List[str] = [] # All scenes narrated
|
scene_history: List[str] = [] # All scenes narrated
|
||||||
public_messages: List[Message] = [] # Public messages visible to all characters
|
public_messages: List[Message] = [] # Public messages visible to all characters
|
||||||
|
|
||||||
|
# Character Profile Prompt Templates
|
||||||
|
RACE_PROMPTS = {
|
||||||
|
"Human": "You are a human character, versatile and adaptable to any situation. You have a balanced approach to problem-solving.",
|
||||||
|
"Elf": "You are an elf, graceful and wise with centuries of experience. You have keen senses and a deep connection to nature and magic.",
|
||||||
|
"Dwarf": "You are a dwarf, stout and honorable with deep knowledge of stone and metal. You are loyal, practical, and value tradition.",
|
||||||
|
"Orc": "You are an orc, powerful and direct with a strong sense of honor and combat prowess. You value strength and straightforward action.",
|
||||||
|
"Halfling": "You are a halfling, small but brave with natural luck and a cheerful disposition. You are resourceful and enjoy the simple pleasures of life."
|
||||||
|
}
|
||||||
|
|
||||||
|
CLASS_PROMPTS = {
|
||||||
|
"Warrior": "You excel in physical combat and tactics, preferring direct action and protecting your allies. You are brave and decisive in battle.",
|
||||||
|
"Wizard": "You are a master of arcane arts, solving problems with magic and knowledge. You are intellectual, curious, and often seek understanding before action.",
|
||||||
|
"Cleric": "You channel divine power to heal and protect, guided by faith and compassion. You support your allies and seek to help those in need.",
|
||||||
|
"Archer": "You are a skilled marksman, preferring distance and precision in combat. You are patient, observant, and value accuracy over brute force.",
|
||||||
|
"Rogue": "You rely on stealth and cunning, using tricks and skills to overcome obstacles. You are clever, adaptable, and often find unconventional solutions."
|
||||||
|
}
|
||||||
|
|
||||||
|
PERSONALITY_PROMPTS = {
|
||||||
|
"Friendly": "You are friendly and approachable, always looking for the good in others. You prefer cooperation and building positive relationships.",
|
||||||
|
"Serious": "You are serious and focused, prioritizing efficiency and practical solutions. You are disciplined and value getting things done.",
|
||||||
|
"Doubtful": "You are cautious and skeptical, questioning motives and analyzing situations carefully. You prefer to be prepared for potential threats.",
|
||||||
|
"Measured": "You are measured and thoughtful, weighing options carefully before acting. You seek balance and consider multiple perspectives."
|
||||||
|
}
|
||||||
|
|
||||||
|
def build_character_system_prompt(character: Character) -> str:
|
||||||
|
"""Build system prompt from character profile"""
|
||||||
|
if not character.profile:
|
||||||
|
# Legacy character without profile
|
||||||
|
base_prompt = f"You are {character.name}. {character.description}"
|
||||||
|
if character.personality:
|
||||||
|
base_prompt += f" {character.personality}"
|
||||||
|
return base_prompt
|
||||||
|
|
||||||
|
# Build prompt from profile
|
||||||
|
profile = character.profile
|
||||||
|
race_trait = RACE_PROMPTS.get(profile.race, "")
|
||||||
|
class_trait = CLASS_PROMPTS.get(profile.character_class, "")
|
||||||
|
personality_trait = PERSONALITY_PROMPTS.get(profile.personality_type, "")
|
||||||
|
|
||||||
|
prompt_parts = [
|
||||||
|
f"You are {character.name}, a {profile.gender.lower()} {profile.race} {profile.character_class}.",
|
||||||
|
character.description,
|
||||||
|
race_trait,
|
||||||
|
class_trait,
|
||||||
|
personality_trait,
|
||||||
|
]
|
||||||
|
|
||||||
|
if profile.background:
|
||||||
|
prompt_parts.append(f"Background: {profile.background}")
|
||||||
|
|
||||||
|
if character.personality: # Legacy personality field
|
||||||
|
prompt_parts.append(character.personality)
|
||||||
|
|
||||||
|
return " ".join(filter(None, prompt_parts))
|
||||||
|
|
||||||
# In-memory storage (replace with database in production)
|
# In-memory storage (replace with database in production)
|
||||||
sessions: Dict[str, GameSession] = {}
|
sessions: Dict[str, GameSession] = {}
|
||||||
|
|
||||||
@@ -98,22 +163,27 @@ async def get_session(session_id: str):
|
|||||||
raise HTTPException(status_code=404, detail="Session not found")
|
raise HTTPException(status_code=404, detail="Session not found")
|
||||||
return sessions[session_id]
|
return sessions[session_id]
|
||||||
|
|
||||||
|
class CreateCharacterRequest(BaseModel):
|
||||||
|
name: str
|
||||||
|
description: str
|
||||||
|
personality: str = "" # Legacy field
|
||||||
|
llm_model: str = "gpt-3.5-turbo"
|
||||||
|
profile: Optional[CharacterProfile] = None
|
||||||
|
|
||||||
@app.post("/sessions/{session_id}/characters/")
|
@app.post("/sessions/{session_id}/characters/")
|
||||||
async def add_character(
|
async def add_character(
|
||||||
session_id: str,
|
session_id: str,
|
||||||
name: str,
|
request: CreateCharacterRequest
|
||||||
description: str,
|
|
||||||
personality: str = "",
|
|
||||||
llm_model: str = "gpt-3.5-turbo"
|
|
||||||
):
|
):
|
||||||
if session_id not in sessions:
|
if session_id not in sessions:
|
||||||
raise HTTPException(status_code=404, detail="Session not found")
|
raise HTTPException(status_code=404, detail="Session not found")
|
||||||
|
|
||||||
character = Character(
|
character = Character(
|
||||||
name=name,
|
name=request.name,
|
||||||
description=description,
|
description=request.description,
|
||||||
personality=personality,
|
personality=request.personality,
|
||||||
llm_model=llm_model
|
profile=request.profile,
|
||||||
|
llm_model=request.llm_model
|
||||||
)
|
)
|
||||||
session = sessions[session_id]
|
session = sessions[session_id]
|
||||||
session.characters[character.id] = character
|
session.characters[character.id] = character
|
||||||
@@ -127,12 +197,128 @@ async def add_character(
|
|||||||
"id": character.id,
|
"id": character.id,
|
||||||
"name": character.name,
|
"name": character.name,
|
||||||
"description": character.description,
|
"description": character.description,
|
||||||
"llm_model": character.llm_model
|
"llm_model": character.llm_model,
|
||||||
|
"profile": character.profile.dict() if character.profile else None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return character
|
return character
|
||||||
|
|
||||||
|
# Legacy endpoint for backward compatibility
|
||||||
|
@app.post("/sessions/{session_id}/characters/legacy/")
|
||||||
|
async def add_character_legacy(
|
||||||
|
session_id: str,
|
||||||
|
name: str,
|
||||||
|
description: str,
|
||||||
|
personality: str = "",
|
||||||
|
llm_model: str = "gpt-3.5-turbo"
|
||||||
|
):
|
||||||
|
request = CreateCharacterRequest(
|
||||||
|
name=name,
|
||||||
|
description=description,
|
||||||
|
personality=personality,
|
||||||
|
llm_model=llm_model
|
||||||
|
)
|
||||||
|
return await add_character(session_id, request)
|
||||||
|
|
||||||
|
# Export character to JSON
|
||||||
|
@app.get("/sessions/{session_id}/characters/{character_id}/export")
|
||||||
|
async def export_character(session_id: str, character_id: str):
|
||||||
|
"""Export character profile to JSON"""
|
||||||
|
if session_id not in sessions:
|
||||||
|
raise HTTPException(status_code=404, detail="Session not found")
|
||||||
|
|
||||||
|
session = sessions[session_id]
|
||||||
|
if character_id not in session.characters:
|
||||||
|
raise HTTPException(status_code=404, detail="Character not found")
|
||||||
|
|
||||||
|
character = session.characters[character_id]
|
||||||
|
|
||||||
|
export_data = {
|
||||||
|
"version": "1.0",
|
||||||
|
"character": character.model_dump(),
|
||||||
|
"created_at": datetime.now().isoformat(),
|
||||||
|
"export_type": "storyteller_rpg_character"
|
||||||
|
}
|
||||||
|
|
||||||
|
return export_data
|
||||||
|
|
||||||
|
# Import character from JSON
|
||||||
|
class ImportCharacterRequest(BaseModel):
|
||||||
|
character_data: dict
|
||||||
|
|
||||||
|
@app.post("/sessions/{session_id}/characters/import")
|
||||||
|
async def import_character(session_id: str, request: ImportCharacterRequest):
|
||||||
|
"""Import character from exported JSON"""
|
||||||
|
if session_id not in sessions:
|
||||||
|
raise HTTPException(status_code=404, detail="Session not found")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Validate and extract character data
|
||||||
|
char_data = request.character_data
|
||||||
|
if "character" in char_data:
|
||||||
|
char_data = char_data["character"]
|
||||||
|
|
||||||
|
# Create character from imported data
|
||||||
|
character = Character(**char_data)
|
||||||
|
# Generate new ID to avoid conflicts
|
||||||
|
character.id = str(uuid.uuid4())
|
||||||
|
# Clear conversation history
|
||||||
|
character.conversation_history = []
|
||||||
|
character.pending_response = False
|
||||||
|
|
||||||
|
session = sessions[session_id]
|
||||||
|
session.characters[character.id] = character
|
||||||
|
|
||||||
|
# Notify storyteller
|
||||||
|
storyteller_key = f"{session_id}_storyteller"
|
||||||
|
if storyteller_key in manager.active_connections:
|
||||||
|
await manager.send_to_client(storyteller_key, {
|
||||||
|
"type": "character_joined",
|
||||||
|
"character": {
|
||||||
|
"id": character.id,
|
||||||
|
"name": character.name,
|
||||||
|
"description": character.description,
|
||||||
|
"llm_model": character.llm_model,
|
||||||
|
"profile": character.profile.dict() if character.profile else None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return character
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(status_code=400, detail=f"Invalid character data: {str(e)}")
|
||||||
|
|
||||||
|
# Get profile options
|
||||||
|
@app.get("/profile/options")
|
||||||
|
async def get_profile_options():
|
||||||
|
"""Get available profile options for character creation"""
|
||||||
|
return {
|
||||||
|
"genders": ["Male", "Female", "Non-binary", "Custom"],
|
||||||
|
"races": list(RACE_PROMPTS.keys()),
|
||||||
|
"classes": list(CLASS_PROMPTS.keys()),
|
||||||
|
"personality_types": list(PERSONALITY_PROMPTS.keys()),
|
||||||
|
"race_descriptions": {
|
||||||
|
"Human": "Versatile and adaptable",
|
||||||
|
"Elf": "Graceful, wise, with keen senses",
|
||||||
|
"Dwarf": "Stout, loyal, master craftsmen",
|
||||||
|
"Orc": "Powerful, direct, honorable",
|
||||||
|
"Halfling": "Small, brave, lucky"
|
||||||
|
},
|
||||||
|
"class_descriptions": {
|
||||||
|
"Warrior": "Physical combat and tactics",
|
||||||
|
"Wizard": "Arcane magic and knowledge",
|
||||||
|
"Cleric": "Divine power and healing",
|
||||||
|
"Archer": "Ranged combat and precision",
|
||||||
|
"Rogue": "Stealth, cunning, and skills"
|
||||||
|
},
|
||||||
|
"personality_descriptions": {
|
||||||
|
"Friendly": "Optimistic and cooperative",
|
||||||
|
"Serious": "Focused and pragmatic",
|
||||||
|
"Doubtful": "Cautious and analytical",
|
||||||
|
"Measured": "Balanced and thoughtful"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# WebSocket endpoint for character interactions (character view)
|
# WebSocket endpoint for character interactions (character view)
|
||||||
@app.websocket("/ws/character/{session_id}/{character_id}")
|
@app.websocket("/ws/character/{session_id}/{character_id}")
|
||||||
async def character_websocket(websocket: WebSocket, session_id: str, character_id: str):
|
async def character_websocket(websocket: WebSocket, session_id: str, character_id: str):
|
||||||
@@ -338,11 +524,15 @@ async def generate_suggestion(session_id: str, character_id: str, context: str =
|
|||||||
|
|
||||||
character = session.characters[character_id]
|
character = session.characters[character_id]
|
||||||
|
|
||||||
# Prepare context for AI suggestion
|
# Prepare context for AI suggestion using character profile
|
||||||
|
system_prompt = build_character_system_prompt(character)
|
||||||
|
if session.current_scene:
|
||||||
|
system_prompt += f" Current scene: {session.current_scene}"
|
||||||
|
|
||||||
messages = [
|
messages = [
|
||||||
{
|
{
|
||||||
"role": "system",
|
"role": "system",
|
||||||
"content": f"You are {character.name} in an RPG. Respond in character. Character description: {character.description}. Personality: {character.personality}. Current scene: {session.current_scene}"
|
"content": system_prompt
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user