Skip to main content

Multi-Game Support

Overview​

The platform supports guilds and characters from multiple games through a template system. While the initial focus is World of Warcraft, the architecture allows for easy expansion to other MMOs and games.

Game Templates​

Character Templates​

Available character templates define which games are supported:

enum CharacterTemplate {
WOW_RETAIL = 'WOW_RETAIL',
WOW_CLASSIC = 'WOW_CLASSIC',
WOW_CATACLYSM = 'WOW_CATACLYSM',
FFXIV = 'FFXIV',
GUILD_WARS_2 = 'GUILD_WARS_2',
CUSTOM = 'CUSTOM',
}

Guild Templates​

Guild templates determine which game a guild is associated with:

// Currently focused on WoW, expandable in future
const GUILD_TEMPLATES = [
{
game: 'WOW_RETAIL',
name: 'World of Warcraft (Retail)',
factions: ['ALLIANCE', 'HORDE'],
},
{
game: 'WOW_CLASSIC',
name: 'World of Warcraft (Classic)',
factions: ['ALLIANCE', 'HORDE'],
},
];

Sync Sources​

Characters and guilds can be created from different sources:

GuildSyncSource​

enum GuildSyncSource {
BLIZZARD = 'blizzard', // Auto-synced from Battle.net API
STANDALONE = 'standalone', // Manually managed (no API sync)
}

Blizzard Guilds:

  • Roster synced daily from Battle.net API
  • Roles/ranks auto-updated from WoW
  • Requires at least one member with linked Battle.net account

Standalone Guilds:

  • Manually managed by guild leaders
  • No external API dependency
  • Good for non-WoW games or private guilds

CharacterSyncSource​

enum CharacterSyncSource {
BLIZZARD = 'blizzard', // From Battle.net OAuth sync
MANUAL = 'manual', // Manually created by user
}

Blizzard Characters:

  • Full data from Battle.net API (level, class, race, gear, etc.)
  • Avatar URLs auto-fetched
  • Auto-updates on user sync
  • Auto-claims matching GuildMember records

Manual Characters:

  • User-provided data (for non-WoW games)
  • No avatar auto-fetch
  • Template validation ensures valid fields

Creating Manual Characters​

Users can create characters for any supported game:

API Endpoint​

POST /api/v1/characters
Authorization: Bearer <jwt-token>
Content-Type: application/json

{
"name": "Yshtola",
"realm": "Hyperion",
"level": 100,
"characterClass": "SCHOLAR",
"race": "MIQOTE",
"faction": "EORZEA",
"syncSource": "manual",
"characterTemplate": "FFXIV"
}

Template Validation​

Each template has specific validation rules:

WoW Retail:

  • Max level: 80
  • Valid classes: WARRIOR, PALADIN, HUNTER, etc.
  • Valid factions: ALLIANCE, HORDE

FFXIV:

  • Max level: 100
  • Valid classes: SCHOLAR, PALADIN, DARK_KNIGHT, etc.
  • Custom faction handling

Custom:

  • Minimal validation
  • User defines all fields
  • Good for niche games or custom use cases

Guild Setup​

Creating a Standalone Guild​

For non-WoW guilds or manually-managed WoW guilds:

POST /api/v1/guilds
Authorization: Bearer <jwt-token>
Content-Type: application/json

{
"name": "Eorzea Knights",
"realm": "Hyperion",
"faction": "EORZEA",
"syncSource": "standalone"
}

Standalone guild features:

  • Manual membership management
  • Custom role creation
  • No roster auto-sync
  • Full control over permissions

Creating a Blizzard Guild​

For WoW guilds with Battle.net sync:

POST /api/v1/guilds
Authorization: Bearer <jwt-token>
Content-Type: application/json

{
"name": "Example Guild",
"realm": "Area 52",
"faction": "HORDE",
"syncSource": "blizzard"
}

Blizzard guild features:

  • Automatic roster sync (daily at 3 AM)
  • Roles/ranks mirror WoW structure
  • Officer promotions sync automatically
  • Requires Battle.net-linked members

Database Schema​

Character Model​

model Character {
id String @id @default(uuid())
userId String
name String
realm String
level Int?
characterClass String?
race String?
faction String?

// Multi-game support
syncSource CharacterSyncSource @default(blizzard)
characterTemplate CharacterTemplate?

// Battle.net specific
avatarUrl String?
lastSyncedAt DateTime?

// Relations
user User @relation(fields: [userId], references: [id])
memberships Membership[]
guildMember GuildMember?
}

Guild Model​

model Guild {
id String @id @default(uuid())
name String
realm String
faction String

// Multi-game support
syncSource GuildSyncSource @default(standalone)

// Battle.net specific
lastRosterSync DateTime?

// Relations
roles Role[]
memberships Membership[]
events Event[]
guildMembers GuildMember[]
}

Auto-Claiming for Blizzard Characters​

When a user syncs characters from Battle.net, they automatically claim matching GuildMember records:

How It Works​

  1. User syncs characters via Battle.net OAuth
  2. For each synced character:
    • Check if a GuildMember exists with matching name + realm
    • If found and unclaimed:
      • Link Character.guildMemberId → GuildMember.id
      • Set GuildMember.claimedAt timestamp
      • Create Membership record linking character to guild

Benefits​

  • Seamless onboarding (no manual "claim" step)
  • Guild rosters populated immediately
  • Character data stays fresh via user syncs

See Guild Roster System for full details.

Future Game Support​

Planned​

Final Fantasy XIV:

  • Lodestone API integration (if/when available)
  • Free Company roster sync
  • Job/class validation

Guild Wars 2:

  • Guild API integration
  • World vs World tracking
  • Profession validation

Elder Scrolls Online:

  • Guild roster (if API available)
  • Alliance tracking
  • Class/role system

Custom Games:

  • User-defined templates
  • Flexible field mapping
  • Community-submitted templates

Design Principles​

When adding new game support:

  1. Template-First: Define CharacterTemplate and validation rules
  2. API-Optional: Support both API-synced and manual entry
  3. Minimal Abstraction: Don't over-engineer for hypothetical games
  4. WoW-Compatible: New features shouldn't break existing WoW guilds

Configuration​

Adding a New Template​

  1. Add enum value to CharacterTemplate:
// apps/api/src/domains/character/entities/character.entity.ts
export enum CharacterTemplate {
// ... existing templates
NEW_GAME = 'NEW_GAME',
}
  1. Update validation in CreateManualCharacterDto:
@IsEnum(CharacterTemplate)
characterTemplate: CharacterTemplate;

@ValidateIf(o => o.characterTemplate === CharacterTemplate.NEW_GAME)
@Max(100) // Max level for new game
level: number;
  1. Update template response endpoint:
// character.controller.ts
@Get('templates')
getTemplates() {
return {
templates: [
// ... existing templates
{
value: CharacterTemplate.NEW_GAME,
label: 'New Game Name',
maxLevel: 100
}
]
};
}
  1. Update frontend form/validation accordingly

Template API Endpoints​

GET /characters/templates​

Get available character templates:

{
"templates": [
{
"value": "WOW_RETAIL",
"label": "World of Warcraft (Retail)",
"maxLevel": 80
},
{
"value": "FFXIV",
"label": "Final Fantasy XIV",
"maxLevel": 100
},
{
"value": "CUSTOM",
"label": "Custom/Other Game",
"maxLevel": null
}
]
}

GET /guilds/templates​

Get available guild templates:

{
"templates": [
{
"game": "WOW_RETAIL",
"name": "World of Warcraft (Retail)",
"factions": ["ALLIANCE", "HORDE"],
"supportsSync": true
},
{
"game": "FFXIV",
"name": "Final Fantasy XIV",
"factions": ["CUSTOM"],
"supportsSync": false
}
]
}

Limitations​

Current​

  • No API sync for non-WoW games (manual entry only)
  • Avatar fetching only works for Battle.net characters
  • FFXIV/GW2 templates are placeholders (no validation)

By Design​

  • Not trying to be a universal gaming platform
  • Focus on guild management, not game-specific features
  • API integrations only when stable/official

Use Cases​

WoW Guild (Primary)​

  • Full Battle.net sync
  • Automatic roster updates
  • Officer permission sync
  • Character gear tracking (future)

Multi-Game Guild​

  • Mix of WoW and FFXIV characters
  • Manual management for FFXIV members
  • Custom roles per game
  • Unified event scheduling

Classic WoW Guild​

  • Separate from Retail guild
  • Uses WoW Classic template
  • Level cap 60
  • Vanilla class restrictions

Private/Casual Guild​

  • Standalone mode (no API sync)
  • Manual membership management
  • Custom roles and permissions
  • No external dependencies