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.guildMemberIdGuildMember.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