Collections System
The collections system provides comprehensive achievement-based item collection functionality for EverQuest II server emulation, converted from the original C++ EQ2EMu implementation.
Overview
The collections system allows players to find specific items scattered throughout the game world and combine them into collections for rewards. When players complete a collection by finding all required items, they receive rewards such as experience, coins, items, or a choice of selectable items.
Architecture
Core Components
Collection - Individual collection with required items, rewards, and completion tracking
MasterCollectionList - Registry of all available collections in the game
PlayerCollectionList - Per-player collection progress and completion tracking
CollectionManager - High-level collection system coordinator
CollectionService - Service layer for game integration and client communication
Key Features
- Item-Based Collections: Players find specific items to complete collections
- Multiple Reward Types: Coins, experience points, fixed items, and selectable items
- Progress Tracking: Real-time tracking of collection completion progress
- Category Organization: Collections organized by categories for easy browsing
- Level Restrictions: Collections appropriate for different player levels
- Thread Safety: All operations use proper Go concurrency patterns
- Database Persistence: Player progress saved automatically
Collection Structure
Collection Data
- ID: Unique collection identifier
- Name: Display name for the collection
- Category: Organizational category (e.g., "Artifacts", "Shinies")
- Level: Recommended level for the collection
- Items: List of required items with index positions
- Rewards: Coins, XP, items, and selectable items
Item States
- Not Found (0): Player hasn't found this item yet
- Found (1): Player has found and added this item to the collection
Collection States
- Incomplete: Not all required items have been found
- Ready to Turn In: All items found but not yet completed
- Completed: Collection has been turned in and rewards claimed
Database Schema
Collections Table
CREATE TABLE collections (
id INTEGER PRIMARY KEY,
collection_name TEXT NOT NULL,
collection_category TEXT NOT NULL DEFAULT '',
level INTEGER NOT NULL DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
Collection Details Table
CREATE TABLE collection_details (
collection_id INTEGER NOT NULL,
item_id INTEGER NOT NULL,
item_index INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (collection_id, item_id),
FOREIGN KEY (collection_id) REFERENCES collections(id) ON DELETE CASCADE
);
Collection Rewards Table
CREATE TABLE collection_rewards (
id INTEGER PRIMARY KEY AUTOINCREMENT,
collection_id INTEGER NOT NULL,
reward_type TEXT NOT NULL, -- 'Item', 'Selectable', 'Coin', 'XP'
reward_value TEXT NOT NULL,
reward_quantity INTEGER NOT NULL DEFAULT 1,
FOREIGN KEY (collection_id) REFERENCES collections(id) ON DELETE CASCADE
);
Player Collections Table
CREATE TABLE character_collections (
char_id INTEGER NOT NULL,
collection_id INTEGER NOT NULL,
completed INTEGER NOT NULL DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (char_id, collection_id),
FOREIGN KEY (collection_id) REFERENCES collections(id) ON DELETE CASCADE
);
Player Collection Items Table
CREATE TABLE character_collection_items (
char_id INTEGER NOT NULL,
collection_id INTEGER NOT NULL,
collection_item_id INTEGER NOT NULL,
found_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (char_id, collection_id, collection_item_id),
FOREIGN KEY (char_id, collection_id) REFERENCES character_collections(char_id, collection_id) ON DELETE CASCADE
);
Usage Examples
System Initialization
// Initialize collection service
database := NewDatabaseCollectionManager(db)
itemLookup := NewItemLookupService()
clientManager := NewClientManager()
service := NewCollectionService(database, itemLookup, clientManager)
err := service.Initialize(ctx)
Player Operations
// Load player collections when they log in
err := service.LoadPlayerCollections(ctx, characterID)
// Process when player finds an item
err := service.ProcessItemFound(characterID, itemID)
// Complete a collection
rewardProvider := NewRewardProvider()
err := service.CompleteCollection(characterID, collectionID, rewardProvider)
// Get player's collection progress
progress, err := service.GetPlayerCollectionProgress(characterID)
// Unload when player logs out
err := service.UnloadPlayerCollections(ctx, characterID)
Collection Management
// Get all collections in a category
collections := manager.GetCollectionsByCategory("Artifacts")
// Search collections by name
collections := manager.SearchCollections("Ancient")
// Get collections appropriate for player level
collections := manager.GetAvailableCollections(playerLevel)
// Check if item is needed by any collection
needed := masterList.NeedsItem(itemID)
Reward System
Reward Types
Coin Rewards
collection.SetRewardCoin(50000) // 5 gold
Experience Rewards
collection.SetRewardXP(10000) // 10,000 XP
Item Rewards (automatically given)
collection.AddRewardItem(CollectionRewardItem{
ItemID: 12345,
Quantity: 1,
})
Selectable Rewards (player chooses one)
collection.AddSelectableRewardItem(CollectionRewardItem{
ItemID: 12346,
Quantity: 1,
})
Integration Interfaces
ItemLookup
Provides item information and validation for collections.
ClientManager
Handles client communication for collection updates and lists.
RewardProvider
Manages distribution of collection rewards to players.
CollectionEventHandler
Handles collection-related events for logging and notifications.
Thread Safety
All operations are thread-safe using:
sync.RWMutex
for collection and list operations- Atomic updates for collection progress
- Database transactions for consistency
- Proper locking hierarchies to prevent deadlocks
Performance Features
- Efficient Lookups: Hash-based collection and item lookups
- Lazy Loading: Player collections loaded only when needed
- Batch Operations: Multiple items and collections processed together
- Connection Pooling: Efficient database connection management
- Caching: Master collections cached in memory
Event System
The collections system provides comprehensive event handling:
// Item found event
OnItemFound(characterID, collectionID, itemID int32)
// Collection completed event
OnCollectionCompleted(characterID, collectionID int32)
// Rewards claimed event
OnRewardClaimed(characterID, collectionID int32, rewards []CollectionRewardItem, coin, xp int64)
Statistics and Monitoring
System Statistics
- Total collections available
- Collections per category
- Total items across all collections
- Reward distribution statistics
Player Statistics
- Collections completed
- Collections in progress
- Items found
- Progress percentages
Error Handling
Comprehensive error handling covers:
- Database connection failures
- Invalid collection or item IDs
- Reward distribution failures
- Concurrent access issues
- Data validation errors
Future Enhancements
Areas marked for future implementation:
- Collection discovery mechanics
- Rare item collection bonuses
- Collection sharing and trading
- Achievement integration
- Collection leaderboards
- Seasonal collections
File Structure
internal/collections/
├── README.md # This documentation
├── constants.go # Collection constants and limits
├── types.go # Core data structures
├── interfaces.go # Integration interfaces
├── collections.go # Collection implementation
├── master_list.go # Master collection registry
├── player_list.go # Player collection tracking
├── database.go # Database operations
└── manager.go # High-level collection services
Dependencies
eq2emu/internal/database
- Database wrapper- Standard library:
context
,sync
,fmt
,strings
,time
Testing
The collections system is designed for comprehensive testing:
- Mock interfaces for all dependencies
- Unit tests for collection logic
- Integration tests with database
- Concurrent operation testing
- Performance benchmarking
Migration from C++
Key changes from the C++ implementation:
- Go interfaces for better modularity
- Context-based operations for cancellation
- Proper error handling with wrapped errors
- Thread-safe operations using sync primitives
- Database connection pooling
- Event-driven architecture for notifications
Integration Notes
When integrating with the game server:
- Initialize the collection service at server startup
- Load player collections on character login
- Process item finds during gameplay
- Handle collection completion through UI interactions
- Save collections on logout or periodic intervals
- Clean up resources during server shutdown