Kelsidavis-WoWee/EXPANSION_GUIDE.md
Kelsi c103743c3a docs: fix stale keybindings, paths, and API examples
GETTING_STARTED.md:
- Fix keybinding table: T→N for talents, Q→L for quest log, W→M for
  world map, add missing keys (C, I, O, J, Y, K), remove nonexistent
  minimap toggle
- Fix extract_assets.ps1 example param (-WowDirectory → positional)
- Fix Data/ directory tree to match actual manifest layout
- Fix log path: ~/.wowee/logs/ → logs/wowee.log (local directory)

EXPANSION_GUIDE.md:
- Add Turtle WoW 1.17 to supported expansions
- Update code examples to use game_utils.hpp helpers
  (isActiveExpansion/isClassicLikeExpansion/isPreWotlk) instead of
  removed ExpansionProfile::getActive() and GameHandler::getInstance()
- Update packet parser references (WotLK is default in domain handlers,
  not a separate packet_parsers_wotlk.cpp file)
- Update references section with game_utils.hpp
2026-03-30 18:26:47 -07:00

4 KiB

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
  • Turtle WoW 1.17 - Custom Vanilla-based server with extended content

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 / Turtle WoW message parsing
    • packet_parsers_tbc.cpp - TBC 2.4.3 message parsing
    • Default (WotLK 3.3.5a) parsers in game_handler.cpp and domain handlers
  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:

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

#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)
}

Expansion-Specific Packet Parsing

// In packet_parsers_*.cpp, implement expansion-specific logic
bool TbcPacketParsers::parseXxx(network::Packet& packet, XxxData& 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
  • include/game/game_utils.hpp - isActiveExpansion(), isClassicLikeExpansion(), isPreWotlk()
  • src/game/packet_parsers_classic.cpp / packet_parsers_tbc.cpp - Expansion-specific parsing
  • docs/status.md - Current feature support
  • docs/ directory - Additional protocol documentation