# 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`