398 lines
13 KiB
Markdown
398 lines
13 KiB
Markdown
|
|
# Mood System Analysis & Issues
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
After examining the Miku Discord bot's mood, mood rotation, and emoji nickname system, I've identified several critical issues that explain why they don't function correctly.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## System Architecture
|
||
|
|
|
||
|
|
### 1. **Dual Mood System**
|
||
|
|
The bot has TWO independent mood systems:
|
||
|
|
- **DM Mood**: Global mood for all direct messages (`globals.DM_MOOD`)
|
||
|
|
- **Server Mood**: Per-server mood tracked in `ServerConfig` objects
|
||
|
|
|
||
|
|
### 2. **Mood Rotation**
|
||
|
|
- **DM Mood**: Rotates every 2 hours (via `rotate_dm_mood()`)
|
||
|
|
- **Server Mood**: Rotates every 1 hour per server (via `rotate_server_mood()`)
|
||
|
|
|
||
|
|
### 3. **Nickname System**
|
||
|
|
Nicknames show mood emojis via the `MOOD_EMOJIS` dictionary in `utils/moods.py`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔴 CRITICAL ISSUES FOUND
|
||
|
|
|
||
|
|
### Issue #1: Nickname Update Logic Conflict
|
||
|
|
**Location**: `utils/moods.py` lines 143-163
|
||
|
|
|
||
|
|
**Problem**: The `update_all_server_nicknames()` function uses **DM mood** to update **all server** nicknames:
|
||
|
|
|
||
|
|
```python
|
||
|
|
async def update_all_server_nicknames():
|
||
|
|
"""Update nickname for all servers to show current DM mood"""
|
||
|
|
try:
|
||
|
|
mood = globals.DM_MOOD.lower() # ❌ Uses DM mood
|
||
|
|
print(f"🔍 DM mood is: {mood}")
|
||
|
|
emoji = MOOD_EMOJIS.get(mood, "")
|
||
|
|
|
||
|
|
nickname = f"Hatsune Miku{emoji}"
|
||
|
|
print(f"🔍 New nickname will be: {nickname}")
|
||
|
|
|
||
|
|
for guild in globals.client.guilds: # ❌ Updates ALL servers
|
||
|
|
me = guild.get_member(globals.BOT_USER.id)
|
||
|
|
if me is not None:
|
||
|
|
try:
|
||
|
|
await me.edit(nick=nickname)
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact**:
|
||
|
|
- Server nicknames show DM mood instead of their own server mood
|
||
|
|
- All servers get the same nickname despite having independent moods
|
||
|
|
- The per-server mood system is functionally broken for nicknames
|
||
|
|
|
||
|
|
**Expected Behavior**: Each server should display its own mood emoji based on `server_config.current_mood_name`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Issue #2: DM Mood Rotation Updates Server Nicknames
|
||
|
|
**Location**: `utils/moods.py` lines 121-142
|
||
|
|
|
||
|
|
**Problem**: The `rotate_dm_mood()` function is called by the DM mood scheduler but doesn't update any nicknames:
|
||
|
|
|
||
|
|
```python
|
||
|
|
async def rotate_dm_mood():
|
||
|
|
"""Rotate DM mood automatically (no keyword triggers)"""
|
||
|
|
try:
|
||
|
|
old_mood = globals.DM_MOOD
|
||
|
|
new_mood = old_mood
|
||
|
|
attempts = 0
|
||
|
|
|
||
|
|
while new_mood == old_mood and attempts < 5:
|
||
|
|
new_mood = random.choice(globals.AVAILABLE_MOODS)
|
||
|
|
attempts += 1
|
||
|
|
|
||
|
|
globals.DM_MOOD = new_mood
|
||
|
|
globals.DM_MOOD_DESCRIPTION = load_mood_description(new_mood)
|
||
|
|
|
||
|
|
print(f"🔄 DM mood rotated from {old_mood} to {new_mood}")
|
||
|
|
|
||
|
|
# Note: We don't update server nicknames here because servers have their own independent moods.
|
||
|
|
# DM mood only affects direct messages to users.
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact**:
|
||
|
|
- Comment says "servers have their own independent moods"
|
||
|
|
- But `update_all_server_nicknames()` uses DM mood anyway
|
||
|
|
- Inconsistent design philosophy
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Issue #3: Incorrect Nickname Function Called After Server Mood Rotation
|
||
|
|
**Location**: `server_manager.py` line 647
|
||
|
|
|
||
|
|
**Problem**: After rotating a server's mood, the system calls `update_server_nickname()` which is correct, BUT there's confusion in the codebase:
|
||
|
|
|
||
|
|
```python
|
||
|
|
async def rotate_server_mood(guild_id: int):
|
||
|
|
"""Rotate mood for a specific server"""
|
||
|
|
try:
|
||
|
|
# ... mood rotation logic ...
|
||
|
|
|
||
|
|
server_manager.set_server_mood(guild_id, new_mood_name, load_mood_description(new_mood_name))
|
||
|
|
|
||
|
|
# Update nickname for this specific server
|
||
|
|
await update_server_nickname(guild_id) # ✅ Correct function
|
||
|
|
|
||
|
|
print(f"🔄 Rotated mood for server {guild_id} from {old_mood_name} to {new_mood_name}")
|
||
|
|
```
|
||
|
|
|
||
|
|
**Analysis**: This part is actually correct, but...
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Issue #4: `nickname_mood_emoji()` Function Ambiguity
|
||
|
|
**Location**: `utils/moods.py` lines 165-171
|
||
|
|
|
||
|
|
**Problem**: This function can call either server-specific OR all-server update:
|
||
|
|
|
||
|
|
```python
|
||
|
|
async def nickname_mood_emoji(guild_id: int = None):
|
||
|
|
"""Update nickname with mood emoji for a specific server or all servers"""
|
||
|
|
if guild_id is not None:
|
||
|
|
# Update nickname for specific server
|
||
|
|
await update_server_nickname(guild_id)
|
||
|
|
else:
|
||
|
|
# Update nickname for all servers (using DM mood)
|
||
|
|
await update_all_server_nicknames()
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact**:
|
||
|
|
- If called without `guild_id`, it overwrites all server nicknames with DM mood
|
||
|
|
- Creates confusion about which mood system is active
|
||
|
|
- This function might be called incorrectly from various places
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Issue #5: Mood Detection in bot.py May Not Trigger Nickname Updates
|
||
|
|
**Location**: `bot.py` lines 469-512
|
||
|
|
|
||
|
|
**Problem**: When mood is auto-detected from keywords in messages, nickname updates are scheduled but may race with the rotation system:
|
||
|
|
|
||
|
|
```python
|
||
|
|
if detected and detected != server_config.current_mood_name:
|
||
|
|
print(f"🔄 Auto mood detection for server {message.guild.name}: {server_config.current_mood_name} -> {detected}")
|
||
|
|
|
||
|
|
# Block direct transitions to asleep unless from sleepy
|
||
|
|
if detected == "asleep" and server_config.current_mood_name != "sleepy":
|
||
|
|
print("❌ Ignoring asleep mood; server wasn't sleepy before.")
|
||
|
|
else:
|
||
|
|
# Update server mood
|
||
|
|
server_manager.set_server_mood(message.guild.id, detected)
|
||
|
|
|
||
|
|
# Update nickname for this server
|
||
|
|
from utils.moods import update_server_nickname
|
||
|
|
globals.client.loop.create_task(update_server_nickname(message.guild.id))
|
||
|
|
```
|
||
|
|
|
||
|
|
**Analysis**: This part looks correct, but creates a task that may conflict with hourly rotation.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Issue #6: No Emoji for "neutral" Mood
|
||
|
|
**Location**: `utils/moods.py` line 16
|
||
|
|
|
||
|
|
```python
|
||
|
|
MOOD_EMOJIS = {
|
||
|
|
"asleep": "💤",
|
||
|
|
"neutral": "", # ❌ Empty string
|
||
|
|
"bubbly": "🫧",
|
||
|
|
# ... etc
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact**: When bot is in neutral mood, nickname becomes just "Hatsune Miku" with no emoji, making it hard to tell if the system is working.
|
||
|
|
|
||
|
|
**Recommendation**: Add an emoji like "🎤" or "✨" for neutral mood.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔧 ROOT CAUSE ANALYSIS
|
||
|
|
|
||
|
|
The core problem is **architectural confusion** between two competing systems:
|
||
|
|
|
||
|
|
1. **Original Design Intent**: Servers should have independent moods with per-server nicknames
|
||
|
|
2. **Broken Implementation**: `update_all_server_nicknames()` uses global DM mood for all servers
|
||
|
|
3. **Mixed Signals**: Comments say servers are independent, but code says otherwise
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎯 RECOMMENDED FIXES
|
||
|
|
|
||
|
|
### Fix #1: Remove `update_all_server_nicknames()` Entirely
|
||
|
|
This function violates the per-server mood architecture. It should never be called.
|
||
|
|
|
||
|
|
**Action**:
|
||
|
|
- Delete or deprecate `update_all_server_nicknames()`
|
||
|
|
- Ensure all nickname updates go through `update_server_nickname(guild_id)`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Fix #2: Update `nickname_mood_emoji()` to Only Support Server-Specific Updates
|
||
|
|
|
||
|
|
**Current Code**:
|
||
|
|
```python
|
||
|
|
async def nickname_mood_emoji(guild_id: int = None):
|
||
|
|
if guild_id is not None:
|
||
|
|
await update_server_nickname(guild_id)
|
||
|
|
else:
|
||
|
|
await update_all_server_nicknames() # ❌ Remove this
|
||
|
|
```
|
||
|
|
|
||
|
|
**Fixed Code**:
|
||
|
|
```python
|
||
|
|
async def nickname_mood_emoji(guild_id: int):
|
||
|
|
"""Update nickname with mood emoji for a specific server"""
|
||
|
|
await update_server_nickname(guild_id)
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Fix #3: Add Neutral Mood Emoji
|
||
|
|
|
||
|
|
**Current**:
|
||
|
|
```python
|
||
|
|
"neutral": "",
|
||
|
|
```
|
||
|
|
|
||
|
|
**Fixed**:
|
||
|
|
```python
|
||
|
|
"neutral": "🎤", # Or ✨, 🎵, etc.
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Fix #4: Audit All Calls to Nickname Functions
|
||
|
|
|
||
|
|
Search for any calls to:
|
||
|
|
- `update_all_server_nicknames()` - should not exist
|
||
|
|
- `nickname_mood_emoji()` - must always pass guild_id
|
||
|
|
|
||
|
|
**FOUND ISSUES**:
|
||
|
|
|
||
|
|
#### ❌ `api.py` - THREE broken endpoints:
|
||
|
|
1. **Line 113-114**: `/mood` endpoint sets DM mood but updates ALL server nicknames
|
||
|
|
2. **Line 126-127**: `/mood/reset` endpoint sets DM mood but updates ALL server nicknames
|
||
|
|
3. **Line 139-140**: `/mood/calm` endpoint sets DM mood but updates ALL server nicknames
|
||
|
|
|
||
|
|
**Code**:
|
||
|
|
```python
|
||
|
|
@app.post("/mood")
|
||
|
|
async def set_mood_endpoint(data: MoodSetRequest):
|
||
|
|
# Update DM mood
|
||
|
|
globals.DM_MOOD = data.mood
|
||
|
|
globals.DM_MOOD_DESCRIPTION = load_mood_description(data.mood)
|
||
|
|
|
||
|
|
# ❌ WRONG: Updates ALL servers with DM mood
|
||
|
|
from utils.moods import update_all_server_nicknames
|
||
|
|
globals.client.loop.create_task(update_all_server_nicknames())
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact**:
|
||
|
|
- API endpoints that change DM mood incorrectly change ALL server nicknames
|
||
|
|
- This is the smoking gun! When you use the API/dashboard to change mood, it breaks server nicknames
|
||
|
|
- Confirms that DM mood and server moods should be completely independent
|
||
|
|
|
||
|
|
**Fix**:
|
||
|
|
- Remove nickname update calls from these endpoints
|
||
|
|
- DM mood should NOT affect server nicknames at all
|
||
|
|
- If you want to update server nicknames, use the per-server endpoints
|
||
|
|
|
||
|
|
#### ✅ `api.py` also has CORRECT per-server endpoints (line 145+):
|
||
|
|
- `/servers/{guild_id}/mood` - Gets server mood (correct)
|
||
|
|
- Likely has POST endpoints for setting server mood (need to verify)
|
||
|
|
|
||
|
|
**Locations checked**:
|
||
|
|
- ✅ `bot.py` - Uses `update_server_nickname(guild_id)` correctly
|
||
|
|
- ✅ `server_manager.py` - Rotation calls correct function
|
||
|
|
- ❌ `api.py` - DM mood endpoints incorrectly update all servers
|
||
|
|
- ⚠️ `command_router.py` - Imports `nickname_mood_emoji` but doesn't seem to use it
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Fix #5: Add Logging to Verify Mood/Nickname Sync
|
||
|
|
|
||
|
|
Add debug logging to `update_server_nickname()` to track:
|
||
|
|
- What mood the server thinks it has
|
||
|
|
- What emoji is being applied
|
||
|
|
- Whether the Discord API call succeeds
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Fix #6: Consider Removing DM Mood Entirely (Optional)
|
||
|
|
|
||
|
|
**Question**: Should DMs have their own mood system?
|
||
|
|
|
||
|
|
**Current Design**:
|
||
|
|
- DMs use `globals.DM_MOOD`
|
||
|
|
- DM mood rotates every 2 hours
|
||
|
|
- DM mood does NOT affect nicknames (correctly)
|
||
|
|
|
||
|
|
**Recommendation**: This is fine IF the nickname system stops using it. The current separation is logical.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📋 VERIFICATION CHECKLIST
|
||
|
|
|
||
|
|
After fixes, verify:
|
||
|
|
|
||
|
|
1. [ ] Each server maintains its own mood independently
|
||
|
|
2. [ ] Server nicknames update when server mood changes
|
||
|
|
3. [ ] Hourly mood rotation updates the correct server's nickname
|
||
|
|
4. [ ] Keyword mood detection updates the correct server's nickname
|
||
|
|
5. [ ] DM mood changes do NOT affect any server nicknames
|
||
|
|
6. [ ] Neutral mood shows an emoji (or document that empty is intentional)
|
||
|
|
7. [ ] No race conditions between rotation and manual mood changes
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🧪 TESTING PROCEDURE
|
||
|
|
|
||
|
|
1. **Test Server Mood Independence**:
|
||
|
|
- Join multiple servers
|
||
|
|
- Manually trigger mood change in one server
|
||
|
|
- Verify other servers maintain their moods
|
||
|
|
|
||
|
|
2. **Test Nickname Updates**:
|
||
|
|
- Trigger mood rotation
|
||
|
|
- Check nickname shows correct emoji
|
||
|
|
- Compare against `MOOD_EMOJIS` dictionary
|
||
|
|
|
||
|
|
3. **Test DM Mood Isolation**:
|
||
|
|
- Send DM to bot
|
||
|
|
- Wait for DM mood rotation
|
||
|
|
- Verify server nicknames don't change
|
||
|
|
|
||
|
|
4. **Test Mood Detection**:
|
||
|
|
- Send message with mood keywords
|
||
|
|
- Verify mood changes and nickname updates
|
||
|
|
- Check logs for correct mood detection
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📊 SUMMARY
|
||
|
|
|
||
|
|
| Component | Status | Issue |
|
||
|
|
|-----------|--------|-------|
|
||
|
|
| Server Mood System | ⚠️ **Partially Broken** | Nicknames use wrong mood when API called |
|
||
|
|
| DM Mood System | ✅ **Working** | Isolated correctly in bot logic |
|
||
|
|
| Mood Rotation | ✅ **Working** | Logic is correct |
|
||
|
|
| Nickname Updates | 🔴 **BROKEN** | API endpoints use DM mood for servers |
|
||
|
|
| Mood Detection | ✅ **Working** | Keywords trigger correctly |
|
||
|
|
| Emoji System | ⚠️ **Minor Issue** | Neutral has no emoji |
|
||
|
|
| Per-Server API | ✅ **Working** | `/servers/{guild_id}/mood` endpoints correct |
|
||
|
|
| Global DM API | 🔴 **BROKEN** | `/mood` endpoints incorrectly update servers |
|
||
|
|
|
||
|
|
**KEY FINDING**: The bug is primarily in the **API layer**, not the core bot logic!
|
||
|
|
|
||
|
|
When you (or a dashboard) calls:
|
||
|
|
- `/mood` endpoint → Changes DM mood → Updates ALL server nicknames ❌
|
||
|
|
- `/mood/reset` endpoint → Resets DM mood → Updates ALL server nicknames ❌
|
||
|
|
- `/mood/calm` endpoint → Calms DM mood → Updates ALL server nicknames ❌
|
||
|
|
|
||
|
|
This explains why it "doesn't seem like they function right" - the API is sabotaging the per-server system!
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🚀 PRIORITY FIX ORDER
|
||
|
|
|
||
|
|
1. **🔥 CRITICAL**: Fix API endpoints in `api.py` - Remove `update_all_server_nicknames()` calls from:
|
||
|
|
- `/mood` endpoint (line 113-114)
|
||
|
|
- `/mood/reset` endpoint (line 126-127)
|
||
|
|
- `/mood/calm` endpoint (line 139-140)
|
||
|
|
|
||
|
|
2. **HIGH**: Deprecate `update_all_server_nicknames()` function in `utils/moods.py`
|
||
|
|
- Add deprecation warning
|
||
|
|
- Eventually delete it entirely
|
||
|
|
|
||
|
|
3. **HIGH**: Fix `nickname_mood_emoji()` to require `guild_id`
|
||
|
|
- Remove the `guild_id=None` default
|
||
|
|
- Remove the DM mood branch
|
||
|
|
|
||
|
|
4. **MEDIUM**: Add neutral mood emoji - user experience
|
||
|
|
|
||
|
|
5. **LOW**: Add debug logging - future maintenance
|
||
|
|
|
||
|
|
**IMMEDIATE ACTION**: Fix the three API endpoints. This is the root cause of the visible bug.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📝 CODE LOCATIONS REFERENCE
|
||
|
|
|
||
|
|
- **Mood definitions**: `utils/moods.py`
|
||
|
|
- **Server config**: `server_manager.py`
|
||
|
|
- **Bot message handling**: `bot.py`
|
||
|
|
- **LLM mood usage**: `utils/llm.py`
|
||
|
|
- **Global DM mood**: `globals.py`
|
||
|
|
- **Mood files**: `moods/*.txt`
|