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:

  1. Initialize the collection service at server startup
  2. Load player collections on character login
  3. Process item finds during gameplay
  4. Handle collection completion through UI interactions
  5. Save collections on logout or periodic intervals
  6. Clean up resources during server shutdown