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.
- 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
- Turtle WoW 1.17 - Custom Vanilla-based server with extended content
The multi-expansion support is built on the Expansion Profile system:
-
ExpansionProfile (
include/game/expansion_profile.hpp) - Metadata about each expansion- Defines protocol version, data paths, asset locations
- Specifies which packet parsers to use
-
Packet Parsers - Expansion-specific message handling
packet_parsers_classic.cpp- Vanilla 1.12 / Turtle WoW message parsingpacket_parsers_tbc.cpp- TBC 2.4.3 message parsing- Default (WotLK 3.3.5a) parsers in
game_handler.cppand domain handlers
-
Update Fields - Expansion-specific entity data layout
- Loaded from
update_fields.jsonin expansion data directory - Defines UNIT_END, OBJECT_END, field indices for stats/health/mana
- Loaded from
WoWee auto-detects the expansion based on:
- Realm list response (protocol version)
- Server build number
- Update field count
Set environment variable:
WOWEE_EXPANSION=tbc ./wowee # Force TBC
WOWEE_EXPANSION=classic ./wowee # Force Classic- Classic: 12 bytes per entry (spellId + itemId + cooldown, no flags)
- TBC/WotLK: 8 bytes per entry (spellId + cooldown) + flags byte
- Classic: 120 slots, no mode byte
- TBC: 132 slots, no mode byte
- WotLK: 144 slots + uint8 mode byte
- Classic/TBC: Full uint64 for guid, uint16 health
- WotLK: PackedGuid format, uint32 health
- 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
- Create new expansion profile entry in
expansion_profile.cpp - Add packet parser file (
packet_parsers_*.cpp) for message variants - Create update_fields.json with correct field layout
- Test realm connection and character loading
#include "game/game_utils.hpp"
// Shared helpers (defined in game_utils.hpp)
if (isActiveExpansion("tbc")) {
// TBC-specific code
}
if (isClassicLikeExpansion()) {
// Classic or Turtle WoW
}
if (isPreWotlk()) {
// Classic, Turtle, or TBC (not WotLK)
}// In packet_parsers_*.cpp, implement expansion-specific logic
bool TbcPacketParsers::parseXxx(network::Packet& packet, XxxData& data) {
// Custom logic for this expansion's packet format
}- Ensure
update_fields.jsonmatches server's field layout - Check OBJECT_END and UNIT_END values
- Verify field indices for your target expansion
- Expansion-specific opcodes may not be registered
- Check packet parser registration in
game_handler.cpp - Verify expansion profile is active
- Each expansion has different struct layouts
- Always read data size first, then upfront validate
- Use size capping (e.g., max 100 items in list)
include/game/expansion_profile.hpp- Expansion metadatainclude/game/game_utils.hpp-isActiveExpansion(),isClassicLikeExpansion(),isPreWotlk()src/game/packet_parsers_classic.cpp/packet_parsers_tbc.cpp- Expansion-specific parsingdocs/status.md- Current feature supportdocs/directory - Additional protocol documentation