# Multi-Expansion Architecture Guide WoWee supports three World of Warcraft expansions in a unified codebase using an expansion profile system. This guide explains how the multi-expansion support works. ## Supported Expansions - **Vanilla (Classic) 1.12** - Original World of Warcraft - **The Burning Crusade (TBC) 2.4.3** - First expansion - **Wrath of the Lich King (WotLK) 3.3.5a** - Second expansion ## Architecture Overview The multi-expansion support is built on the **Expansion Profile** system: 1. **ExpansionProfile** (`include/game/expansion_profile.hpp`) - Metadata about each expansion - Defines protocol version, data paths, asset locations - Specifies which packet parsers to use 2. **Packet Parsers** - Expansion-specific message handling - `packet_parsers_classic.cpp` - Vanilla 1.12 message parsing - `packet_parsers_tbc.cpp` - TBC 2.4.3 message parsing - `packet_parsers_wotlk.cpp` (default) - WotLK 3.3.5a message parsing 3. **Update Fields** - Expansion-specific entity data layout - Loaded from `update_fields.json` in expansion data directory - Defines UNIT_END, OBJECT_END, field indices for stats/health/mana ## How to Use Different Expansions ### At Startup WoWee auto-detects the expansion based on: 1. Realm list response (protocol version) 2. Server build number 3. Update field count ### Manual Selection Set environment variable: ```bash WOWEE_EXPANSION=tbc ./wowee # Force TBC WOWEE_EXPANSION=classic ./wowee # Force Classic ``` ## Key Differences Between Expansions ### Packet Format Differences #### SMSG_SPELL_COOLDOWN - **Classic**: 12 bytes per entry (spellId + itemId + cooldown, no flags) - **TBC/WotLK**: 8 bytes per entry (spellId + cooldown) + flags byte #### SMSG_ACTION_BUTTONS - **Classic**: 120 slots, no mode byte - **TBC**: 132 slots, no mode byte - **WotLK**: 144 slots + uint8 mode byte #### SMSG_PARTY_MEMBER_STATS - **Classic/TBC**: Full uint64 for guid, uint16 health - **WotLK**: PackedGuid format, uint32 health ### Data Differences - **Talent trees**: Different spell IDs and tree structure per expansion - **Items**: Different ItemDisplayInfo entries - **Spells**: Different base stats, cooldowns - **Character textures**: Expansion-specific variants for races ## Adding Support for Another Expansion 1. Create new expansion profile entry in `expansion_profile.cpp` 2. Add packet parser file (`packet_parsers_*.cpp`) for message variants 3. Create update_fields.json with correct field layout 4. Test realm connection and character loading ## Code Patterns ### Checking Current Expansion ```cpp #include "game/expansion_profile.hpp" // Global helper bool isClassicLikeExpansion() { auto profile = ExpansionProfile::getActive(); return profile && (profile->name == "Classic" || profile->name == "Vanilla"); } // Specific check if (GameHandler::getInstance().isActiveExpansion("tbc")) { // TBC-specific code } ``` ### Expansion-Specific Packet Parsing ```cpp // In packet_parsers_*.cpp, implement expansion-specific logic bool parseXxxPacket(BitStream& data, ...) { // Custom logic for this expansion's packet format } ``` ## Common Issues ### "Update fields mismatch" Error - Ensure `update_fields.json` matches server's field layout - Check OBJECT_END and UNIT_END values - Verify field indices for your target expansion ### "Unknown packet" Warnings - Expansion-specific opcodes may not be registered - Check packet parser registration in `game_handler.cpp` - Verify expansion profile is active ### Packet Parsing Failures - Each expansion has different struct layouts - Always read data size first, then upfront validate - Use size capping (e.g., max 100 items in list) ## References - `include/game/expansion_profile.hpp` - Expansion metadata - `docs/status.md` - Current feature support by expansion - `src/game/packet_parsers_*.cpp` - Format-specific parsing logic - `docs/` directory - Additional protocol documentation