Rules System
The rules system provides configurable game parameters and settings for the EQ2 server. It has been fully converted from the original C++ EQ2EMu implementation to Go.
Overview
The rules system consists of:
- Rule Categories: Major groupings of rules (Player, Combat, World, etc.)
- Rule Types: Specific rule types within each category
- Rule Sets: Collections of rules that can be switched between
- Global/Zone Rules: Global rules apply server-wide, zone rules override for specific zones
Core Components
Files
constants.go
- Rule categories, types, and constantstypes.go
- Core data structures (Rule, RuleSet, RuleManagerStats)manager.go
- Main RuleManager implementation with default rulesdatabase.go
- Database operations for rule persistenceinterfaces.go
- Integration interfaces and adaptersrules_test.go
- Comprehensive test suite
Main Types
Rule
- Individual rule with category, type, value, and type conversion methodsRuleSet
- Collection of rules with ID and nameRuleManager
- Central management of all rules and rule setsDatabaseService
- Database operations for rule persistence
Rule Categories
The system supports 14 rule categories:
- Client - Client-related settings
- Faction - Faction system rules
- Guild - Guild system rules
- Player - Player-related rules (levels, stats, etc.)
- PVP - Player vs Player combat rules
- Combat - Combat system rules
- Spawn - NPC/spawn behavior rules
- UI - User interface rules
- World - Server-wide settings
- Zone - Zone-specific rules
- Loot - Loot system rules
- Spells - Spell system rules
- Expansion - Expansion flags
- Discord - Discord integration settings
Usage
Basic Usage
// Create rule manager
ruleManager := rules.NewRuleManager()
// Get a rule value
rule := ruleManager.GetGlobalRule(rules.CategoryPlayer, rules.PlayerMaxLevel)
maxLevel := rule.GetInt32() // Returns 50 (default)
// Get rule by name
rule2 := ruleManager.GetGlobalRuleByName("Player", "MaxLevel")
Database Integration
// Create database service
db, _ := database.Open("rules.db")
dbService := rules.NewDatabaseService(db)
// Create tables
dbService.CreateRulesTables()
// Load rules from database
dbService.LoadRuleSets(ruleManager, false)
Rule Adapters
// Create adapter for zone-specific rules
adapter := rules.NewRuleManagerAdapter(ruleManager, zoneID)
// Get rule with zone override
maxLevel := adapter.GetInt32(rules.CategoryPlayer, rules.PlayerMaxLevel)
Default Rules
The system includes comprehensive default rules matching the original C++ implementation:
- Player Max Level: 50
- Combat Max Range: 4.0
- Experience Multiplier: 1.0
- And 100+ other rules across all categories
Database Schema
The system uses three tables:
rulesets
- Rule set definitionsruleset_details
- Individual rule overrides per rule setvariables
- System variables including default rule set ID
Thread Safety
All operations are thread-safe using Go's sync.RWMutex for optimal read performance.
Performance
- Rule access: ~280ns per operation (benchmark)
- Rule manager creation: ~45μs per operation (benchmark)
- All operations are optimized for high-frequency access
Testing
Run the comprehensive test suite:
go test ./internal/rules/ -v
Migration from C++
This is a complete conversion from the original C++ implementation:
Rules.h
→constants.go
+types.go
Rules.cpp
→manager.go
RulesDB.cpp
→database.go
All functionality has been preserved with Go-native patterns and improvements:
- Better error handling
- Type safety
- Comprehensive interfaces
- Modern testing practices
- Performance optimizations