Rose is an intelligent virtual receptionist for Second Life that combines LSL scripts with a .NET Core backend and Claude AI to create natural, context-aware conversations.
┌─────────────────────────────────────────────────────────────┐
│ Second Life (LSL) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Sensor │ │ Chat │ │ Animations │ │
│ │ Script │──│ Script │──│ Script │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │ │
│ └─────────────────┼──────────────────┘ │
│ │ │
│ ┌──────┴───────┐ │
│ │ Main │ │
│ │ Script │ │
│ └──────┬───────┘ │
│ │ │
└───────────────────────────┼────────────────────────────────┘
│ HTTPS
│
┌───────────────────────────┼────────────────────────────────┐
│ Backend Server (.NET) │
│ │ │
│ ┌──────┴───────┐ │
│ │ API │ │
│ │ Controllers │ │
│ └──────┬───────┘ │
│ │ │
│ ┌──────────────────────┼──────────────────────┐ │
│ │ │ │ │
│ ┌──┴────┐ ┌─────┴─────┐ ┌────┴────┐ │
│ │Claude │ │ Personality│ │ Message │ │
│ │Service│ │ Service │ │ Queue │ │
│ └───┬───┘ └─────┬─────┘ └────┬────┘ │
│ │ │ │ │
│ └─────────────────────┼──────────────────────┘ │
│ │ │
│ ┌──────┴───────┐ │
│ │ Database │ │
│ │ (SQLite) │ │
│ └──────────────┘ │
└────────────────────────────────────────────────────────────┘
│
│ API Call
│
┌───────────────────────────┼────────────────────────────────┐
│ Anthropic Claude API │
│ (AI Conversation) │
└────────────────────────────────────────────────────────────┘
- Natural Conversations: Uses Claude AI for intelligent, context-aware responses
- Dual Personality System: Different behavior for office owners vs. visitors
- Message Queue: Store messages when recipients are offline
- Smart Wandering with Home Position: Natural movement with configurable home base
- Avatar Detection: Automatic greeting when visitors arrive
- Animation System: Contextual gestures and expressions
- Conversation Memory: Maintains context across multiple messages
- Access Control: Configurable roles (Owner, Visitor, Blocked)
- Chat Actions: Natural language commands trigger in-world actions (give items, navigate, etc.)
- Activity Context: AI is aware of Rose's current activity and available services
- Hierarchical Menus: Multi-level menu navigation ("beverage" → "coffee" → "mocha")
- .NET 8.0 SDK
- SQLite
- VPS or cloud hosting with public HTTPS endpoint
- Anthropic API key (https://console.anthropic.com/)
- Land with script permissions
- Avatar or NPC to host the scripts
- Build/modify permissions on the object
Rose uses a two-tier authentication system to support multiple paying subscribers:
For regular subscribers who use Rose in their Second Life locations.
For system administrators to manage subscriber accounts.
Contact your service provider to receive your unique subscriber API key.
- In Second Life, right-click your Rose object and select Edit
- Go to the Contents tab
- Find or create a notecard named RoseConfig
- Add your subscriber key:
SUBSCRIBER_KEY=your-subscriber-key-here - Save the notecard
- Reset the scripts (right-click object → More → Reset Scripts)
Your Rose is now ready to use!
| Level | Name | Monthly Credits | Best For |
|---|---|---|---|
| 1 | Basic | 1,000 | Small shops, personal offices |
| 2 | Pro | 5,000 | Busy stores, event venues |
| 3 | Enterprise | 50,000 | High-traffic locations, multiple sites |
- Each API request (greeting, chat message) consumes 1 credit
- When credits are exhausted, Rose will stop responding until the next billing cycle
- Check your credit usage: Touch your Rose object and say "credits"
- Upgrade your subscription at any time by contacting your provider
# API Configuration
SUBSCRIBER_KEY=your-subscriber-key-here
# Optional: Custom API endpoint
# API_ENDPOINT=https://rosercp.pantherplays.com/api
# Owner UUIDs (can have multiple)
OWNER_UUID=00000000-0000-0000-0000-000000000000
# Home Position (NEW)
HOME_WAYPOINT=0
HOME_DURATION_MINUTES=15
# Available Menu Items (NEW - comma-separated)
AVAILABLE_ACTIONS=Coffee, Tea, Water, Hot Chocolate, Espresso
# Advanced Settings
# GREETING_RANGE=10
New Features:
HOME_WAYPOINT: Waypoint number where Rose spends most of her time (set to -1 to disable)HOME_DURATION_MINUTES: How long Rose stays at home before starting her activity loopAVAILABLE_ACTIONS: Services/items Rose can provide via natural language chat
See docs/HOME_POSITION_AND_CHAT_ACTIONS.md for detailed documentation.
The master API key is stored only in the backend server configuration and grants access to all system administration endpoints.
Backend Setup (appsettings.json):
{
"ApiAuthentication": {
"MasterApiKey": "your-master-key-here"
},
"SubscriptionLevels": {
"1": {
"Name": "Basic",
"CreditLimit": 1000
},
"2": {
"Name": "Pro",
"CreditLimit": 5000
},
"3": {
"Name": "Enterprise",
"CreditLimit": 50000
}
}
}For Master Key (Linux/Mac):
openssl rand -base64 32PowerShell (Windows):
[Convert]::ToBase64String([System.Security.Cryptography.RandomNumberGenerator]::GetBytes(32))All endpoints require the master API key via X-API-Key header.
POST /api/system/subscribers/generate-key
Content-Type: application/json
X-API-Key: your-master-key
{
"subscriberId": "customer-123",
"subscriberName": "Jane's Boutique",
"subscriptionLevel": 2,
"notes": "Pro plan - annual billing",
"orderNumber": "ORD-2024-001",
"creditLimit": 5000,
"expiresAt": "2025-12-31T23:59:59Z"
}Response:
{
"id": "guid",
"apiKey": "generated-subscriber-key",
"subscriberId": "customer-123",
"subscriberName": "Jane's Boutique",
"subscriptionLevel": 2,
"createdAt": "2024-01-15T10:30:00Z",
"expiresAt": "2025-12-31T23:59:59Z",
"creditLimit": 5000
}PUT /api/system/subscribers/{id}/status
Content-Type: application/json
X-API-Key: your-master-key
{
"isActive": false
}GET /api/system/subscribers?activeOnly=true&level=2
X-API-Key: your-master-keyGET /api/system/subscribers/{id}
X-API-Key: your-master-keyPUT /api/system/subscribers/{id}/credits
Content-Type: application/json
X-API-Key: your-master-key
{
"creditLimit": 10000,
"resetUsage": true
}GET /api/system/status
X-API-Key: your-master-keyResponse:
{
"totalSubscribers": 25,
"activeSubscribers": 23,
"totalRequests": 45230,
"totalCreditsUsed": 38942,
"serverTime": "2024-01-15T10:30:00Z",
"subscribersByLevel": {
"1": 10,
"2": 12,
"3": 3
}
}GET /api/system/logs?count=50&subscriberName=Jane
X-API-Key: your-master-keyIf you configure your Rose with the master API key in the RoseConfig notecard, you can access system admin functions directly in Second Life:
- Set
SUBSCRIBER_KEYto your master key in RoseConfig - Touch your Rose object
- Select from the admin menu:
- New API Key: Generate a new subscriber key
- List Subs: View all subscribers
- Status: Check system statistics
- Logs: View recent activity logs
- Credits: Manage subscriber credits
- Never commit the master API key to version control
- Use environment variables or secure secret management in production
- Rotate keys periodically (at least annually)
- Monitor access logs for unauthorized attempts
- Keep subscriber keys separate from master key documentation
- Use HTTPS only for all API communications
- .NET 8.0 SDK
- SQLite
- VPS or cloud hosting with public HTTPS endpoint
- Anthropic API key (https://console.anthropic.com/)
- Land with script permissions
- Avatar or NPC to host the scripts
- Build/modify permissions on the object
-
Configure Settings Edit
RoseReceptionist.API/appsettings.jsonand add your Anthropic API key and owner UUIDs. -
Run Locally
cd RoseReceptionist.API dotnet restore dotnet build dotnet runNote: The database (
rose.db) is created automatically on first run with default settings. No manual database setup required! -
Deploy to Production Use Docker or systemd service (see detailed documentation below).
- Create an object in Second Life
- Add all 5 LSL scripts from
RoseReceptionist.LSL/folder - Edit RoseReceptionist_Main script and configure API credentials (see Security Setup above)
- Create a
RoseConfignotecard with owner UUIDs and other settings - Optionally add animations: wave, offer, think, flirt
Option A: Docker Deployment
docker build -t rose-receptionist .
docker run -d -p 5000:5000 -v /opt/rose-data:/app/data rose-receptionistOption B: systemd Service
dotnet publish -c Release -o /opt/rose-receptionist
sudo cp rose-receptionist.service /etc/systemd/system/
sudo systemctl enable rose-receptionist
sudo systemctl start rose-receptionistserver {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
}
}Add SSL: sudo certbot --nginx -d your-domain.com
Notify Rose of visitor arrival
{
"avatarKey": "uuid",
"avatarName": "John Doe",
"location": "Virtual Office"
}Send message to Rose
{
"avatarKey": "uuid",
"avatarName": "John Doe",
"message": "Hello Rose!",
"location": "Office",
"sessionId": "guid"
}Queue message for offline delivery
Retrieve pending messages
Manage access control list
{
"Anthropic": {
"ApiKey": "your-key-here",
"Model": "claude-3-haiku-20240307",
"MaxTokens": "150"
},
"Rose": {
"DefaultOwnerKeys": ["your-sl-uuid"],
"ConversationContextLimit": "10"
}
}# API credentials are configured in the script (secure)
OWNER_UUID_1=your-uuid-here
OWNER_UUID_2=your-uuid-here
WANDER_ENABLED=TRUE
WANDER_RADIUS=10
GREETING_RANGE=10
RECEPTIONIST_NAME=Rose
Rose now features an intelligent waypoint navigation system that allows her to patrol specific areas and perform activities at designated locations.
Instead of random wandering, Rose follows a path of numbered waypoint prims (Wander0, Wander1, Wander2, etc.) and performs actions defined in each prim's description. This creates realistic work routines like watering plants, checking equipment, or tidying the office.
-
Create Waypoint Prims
- Create prims in Second Life and name them sequentially:
Wander0,Wander1,Wander2, etc. - Rose will visit them in numerical order, looping back to the start after completing all waypoints.
- Create prims in Second Life and name them sequentially:
-
Configure Waypoint Actions Each waypoint prim's Description field should contain JSON defining what Rose does at that location:
{"type":"linger","name":"watering plants","orientation":180,"time":45,"animation":"watering","attachments":[{"item":"WateringCan","point":"RightHand"}]} -
Action Types
Transient - Pass through without stopping
{"type":"transient","name":"walking through hallway"}Linger - Stop, face direction, play animation, wait
{"type":"linger","name":"checking computer","orientation":90,"time":30,"animation":"typing"}Sit - Sit at the location with optional animation
{"type":"sit","name":"taking a break","time":60,"animation":"sit_relaxed"} -
JSON Field Reference
type(required): "transient", "linger", or "sit"name(required): Activity description (e.g., "watering plants")orientation(optional): Direction to face in degrees (0-360)time(optional): Duration in secondsanimation(optional): Animation name from inventoryattachments(optional): Array of items to attach (e.g., tools, props)
Here's a complete example of a 4-waypoint patrol route:
Wander0 - Reception Desk
{"type":"linger","name":"greeting visitors","orientation":0,"time":20}Wander1 - Break Room
{"type":"linger","name":"making coffee","orientation":270,"time":30,"animation":"pouring"}Wander2 - Office Plants
{"type":"linger","name":"watering plants","orientation":180,"time":45,"animation":"watering","attachments":[{"item":"WateringCan","point":"RightHand"}]}Wander3 - Hallway
{"type":"transient","name":"walking to next area"}Rose automatically tracks all activities and generates daily reports:
- Activity Logs: Every action is logged with timestamp, location, and duration
- Daily Reports: At the end of shift (configurable time), Rose generates a summary using Claude AI
- "What are you doing?": Rose can respond in chat with her current activity
Update RoseConfig.txt with these new settings:
# Wandering Configuration
WANDER_ENABLED=TRUE
WANDER_SENSOR_RANGE=50 # How far to scan for waypoints
WANDER_SCAN_INTERVAL=5 # How often to scan for new waypoints
# Shift and Reporting
SHIFT_START_TIME=09:00 # When Rose's workday begins
SHIFT_END_TIME=17:00 # When Rose's workday ends
DAILY_REPORT_TIME=17:05 # When to generate end-of-day report
The backend now includes these new endpoints:
POST /api/reports/activities- Log a new activityPUT /api/reports/activities/{id}/complete- Complete an activityGET /api/reports/activities/current- Get Rose's current activityGET /api/reports/activities/date/{date}- Get all activities for a specific datePOST /api/reports/daily- Generate daily report with Claude AI summary
- Spacing: Place waypoints 5-10 meters apart for natural walking
- Line of Sight: Ensure waypoints are within sensor range (50m default)
- Permissions: Verify pathfinding is enabled on your land
- Animations: Add custom animations to Rose's inventory for variety
- Activity Names: Use descriptive names for better daily reports
- 500 errors: Check logs in
logs/directory - Database errors: Verify write permissions
- Claude timeout: Check API key and rate limits
Cause: The script still has the default placeholder API key.
Solution:
- Edit the
RoseReceptionist_Mainscript - Update
API_KEYin the SECURITY CONFIGURATION section - Save the script
Cause: API key in script doesn't match the key in your backend configuration.
Solution:
- Check your backend
appsettings.json→ApiAuthentication:ApiKey - Compare with the
API_KEYvalue in your LSL script - Make sure they match exactly
- Restart both the backend service and reset LSL scripts
Important: Second Life does NOT allow setting the Content-Type header directly - it's automatically set to text/plain; charset=utf-8.
Solution:
- The LSL scripts in this repository use the
HTTP_MIMETYPEparameter to set the content type toapplication/json - No action needed if using the provided scripts
- If writing custom scripts, use:
HTTP_MIMETYPE, "application/json"in your HTTP parameters list
- No response: Verify API_ENDPOINT is configured correctly in the script
- No movement: Enable pathfinding and check permissions
- No animations: Add animations to inventory
- Claude API: ~$0.45/month (1000 messages/day)
- VPS Hosting: $10-20/month
- Total: ~$10-20/month
- Change default API key
- Use HTTPS only
- Enable rate limiting
- Restrict database permissions
- Rotate logs regularly
For issues or questions:
- GitHub Issues
- Second Life contact: [Your SL Name]
MIT License
Built with ❤️ for the Second Life community