-
Notifications
You must be signed in to change notification settings - Fork 38
Refactored GMCP system from monolithic to granular node architecture #424
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
The latest commit fixes the bug/issue I encountered while testing: ProblemThe GMCP module's plugin configuration system was overwriting user-defined settings. When users added custom values to their config-overrides.yaml file under the Modules.gmcp namespace, these values were being replaced by the plugin's default configuration on server startup. Root CauseThe plugin system used AddOverlayOverrides() which unconditionally overwrote configuration values, even when users had explicitly set different values in their override files. Additionally, the GMCP Mudlet module cached configuration values at startup, preventing runtime configuration changes from taking effect. SolutionConfiguration Preservation
Dynamic Configuration Reading
YAML Structure Preservation
Type System Improvements
How It Works Now
This architecture supports multiple GMCP sub-modules sharing configuration while respecting user customization. |
If the mob-equipment-template PR gets approved first, I will have to make a minor change to this one, to use the new UserInterface structure, as this one still uses the old TextFormats setup. Just FYI. |
Latest commit also addresses the WebClient to be able to use the moduler GMCP setup. I've also added a minor fix to enable the WebClient to be used across HTTPS. |
- Split monolithic GMCP updates into focused, event-driven modules - Added real-time combat tracking with individual update streams: - Combat status and cooldown timers (250ms updates) - Damage/healing event notifications - Enemy tracking with target priorities - Current target health monitoring - Added client-configurable GMCP subscriptions for selective data streaming - Extended event system with granular combat and game state events - Improved room GMCP with enhanced player/mob tracking - Added party member health and position updates - Enhanced game GMCP with server time and player count updates - Fixed combat cleanup when mobs are removed from rooms - Optimized GMCP updates to send only changed data New Events Added Event Constants: - CmdNoRoomGMCP - Skip GMCP room updates (prevents duplicate sends) Combat Events: - CombatStarted - Combat begins - CombatEnded - Combat ends (not death) - DamageDealt - Damage calculated and applied - HealingReceived - Health restored - TargetChanged - Primary target changes - AggroGained - Mob becomes hostile - AggroLost - Mob stops being hostile - MobVitalsChanged - Mob health/mana changes - MobStatusChanged - Mob status effects change - CombatActionStarted - Actions begin (casting, channeling) - CombatActionCompleted - Actions finish - CombatActionInterrupted - Actions interrupted - AttackAvoided - Attack fails to connect - CombatEffectTriggered - DoTs/bleeds/effects tick - CombatantFled - Flee attempt These events enable the granular GMCP combat tracking system. This refactoring enables clients to subscribe to specific GMCP modules and receive targeted updates instead of full state dumps, significantly reducing bandwidth and improving responsiveness during combat and exploration.
Added: - PlayerDespawn cleanup handlers to all combat modules - User validation with validateUserForGMCP helper function - ExitLockChanged event for exit state notifications - GMCP handler to send Room.Info.Exits updates on lock changes - Exit details map with type, state, name, hasKey, and hasPicked fields - Package documentation explaining design patterns for each module Fixed: - Memory leaks from uncleaned tracking maps - Function naming inconsistencies in Status and Events modules - Redundant "exits" wrapper in Room.Info.Exits output Changed: - Cooldown timer interval from 250ms to 200ms - Mutex usage to RLock for read-only operations - Exit state values to "locked" and "open" Removed: - Unused imports from gmcp.go and combat modules - Unused gmcp_batcher.go file - Rate limiting code from damage module
Added: - Centralized combat tracking system with shared combatUsers map - GetLowestRoomId() method to mapper for stable map identifiers - Map_id field to GMCP room data based on lowest connected room ID - Exit details for cross-map navigation (leads_to_map, leads_to_area) - ANSI code stripping for all GMCP text fields - CleanupUser() function for unified combat state cleanup - Support for non-compass direction exits in GMCP Fixed: - Race conditions in combat module cleanup by centralizing PlayerDespawn handling - Synchronous cooldown updates to prevent state inconsistencies - Combat round handlers to only process users currently in combat Changed: - Cooldown timer interval from 250ms to 200ms - NPC targeting from boolean to array of player names - Room.Info.Exits structure to remove redundant wrapper - GMCP module handling to always send all modules Removed: - Individual PlayerDespawn handlers from each combat module - GMCPUserCleanup event type and related infrastructure - Core.Supports.Set/Remove module tracking - Mob health tracking from Target module - Restriction on non-compass direction exits Breaking Changes: - Room.Info.Exits now exist as a primary node instead of Room.Info.Exits.exits - NPC targeting_you changed from boolean to targeting array
Added: - CharacterAlignmentChanged event for dedicated alignment change notifications - IsUserInCombat() centralized function for combat state detection - Proper PlayerDespawn cleanup calling CleanupUser() for all GMCP maps - CombatStarted events in attack commands for immediate GMCP updates - CombatEnded event when breaking combat - Immediate CharacterVitalsChanged events on all damage applications Fixed: - Cooldown timer only runs when player has aggro (actively fighting) - Combat status properly detects both attacking and being attacked states - Alignment changes now trigger GMCP Char.Info updates via dedicated event - Enemy list maintains consistency when being attacked without fighting back - Type mismatches in alignment event parameters (int8 to int conversion) Changed: - Consolidated duplicate combat detection logic into single source of truth - Replaced CharacterVitalsChanged with CharacterAlignmentChanged for alignment updates - Refactored combat event firing to use priority queue for immediate processing Removed: - Debug logging from GMCP and combat modules for production readiness - Unused imports from multiple files - Old backup files (.go.old, eventtypes.go.backup) - Incorrect code comments about CombatStarted events not firing - TODO comments and excessive documentation
Added: - AddOverlayDefaults function to preserve user configuration overrides - YAML v3 support for maintaining file structure when updating configs - Handler for Client.Map GMCP requests from Mudlet clients - Dynamic configuration reading for GMCP Mudlet settings Fixed: - SendClientMap GMCP command now properly responds with Client.Map structure - Plugin configuration now respects user overrides from config-overrides.yaml Changed: - Simplified config type inference with direct type names ("int", "string") - Converted GMCPMudletModule to GMCPMudletHandler pattern - Mudlet functionality consolidated into main GMCP module - Plugin overlays now use AddOverlayDefaults instead of AddOverlayOverrides Removed: - Empty load/save functions that were no longer needed - Duplicate plugin registration for Mudlet module
Added: - sendMudletMapperInstall function to handle mapper package installation via Client.GUI Changed: - Reordered GMCP messages to send Client.Map before Client.GUI for proper Mudlet client handling - Refactored sendMudletConfig to use dedicated functions instead of inline payload creation Removed: - Unnecessary user record fetch in sendMudletConfig function - Duplicate payload construction for mapper installation
Added: - Field mapping from new GMCP structure to expected flat format for Room data - Room.Info.Basic fields (id, coordinates, area) mapped to Info level - Room.Info.Exits converted to exitsv2 format with dx/dy/dz delta fields - Comments explaining why mapping is necessary for Room handler compatibility Changed: - Room.Info.Basic and Room.Info.Exits handlers to create flat data structure - Room handler triggers to check for mapped fields instead of nested objects - Vitals handler to use new field names directly (health, spell_points) - WebSocket connection to detect https protocol for wss://
Added: - Package documentation for GMCP module explaining protocol implementation Changed: - Removed redundant "Fire X event" comments from combat event handling - Removed obvious comments that restated code behavior - Removed visual noise comments (section dividers, unnecessary headers) - Added context for magic numbers and non-obvious algorithms - Focused comments on explaining WHY rather than WHAT Removed: - 18 redundant event firing comments in combat.go - Section divider comments throughout GMCP modules - Debug comments and commented-out code
288d1af
to
b300210
Compare
Updated all references from GetTextFormatsConfig() to GetUserInterfaceConfig().Formats to maintain compatibility with the UserInterface configuration structure introduced in mob-equipment-templates. Changed: - Config struct to use UserInterface instead of TextFormats - gmcp.Game.go to use c.UserInterface.Formats.Time - All usercommands and mobcommands to use GetUserInterfaceConfig().Formats - inbox.go DateString() to use UserInterface.Formats.Time - userrecord.prompt.go to use GetUserInterfaceConfig().Formats.Prompt
This PR transforms the GMCP system from monolithic structures that sent complete state updates to a granular architecture with individual "lowest level node" structures. Instead of sending entire Char, Room, or Party objects, the system now sends only the specific nodes that changed (e.g., Char.Vitals, Room.Info.Exits, Party.Vitals). This enables real-time updates without the overhead of transmitting complete state objects.
Added
Granular Node Structure:
GMCP Combat Modules:
GMCP Request Options:
Enhanced Room Features:
New Events for Tracking:
Other Improvements:
Removed
Breaking Changes (Only for the Mudlet UI - new UI fixed and ready to deploy)