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
- User syncs characters via Battle.net OAuth
- For each synced character:
- Check if a
GuildMemberexists with matching name + realm - If found and unclaimed:
- Link
Character.guildMemberId→GuildMember.id - Set
GuildMember.claimedAttimestamp - Create
Membershiprecord linking character to guild
- Link
- Check if a
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:
- Template-First: Define CharacterTemplate and validation rules
- API-Optional: Support both API-synced and manual entry
- Minimal Abstraction: Don't over-engineer for hypothetical games
- WoW-Compatible: New features shouldn't break existing WoW guilds
Configuration
Adding a New Template
- Add enum value to
CharacterTemplate:
// apps/api/src/domains/character/entities/character.entity.ts
export enum CharacterTemplate {
// ... existing templates
NEW_GAME = 'NEW_GAME',
}
- Update validation in
CreateManualCharacterDto:
@IsEnum(CharacterTemplate)
characterTemplate: CharacterTemplate;
@ValidateIf(o => o.characterTemplate === CharacterTemplate.NEW_GAME)
@Max(100) // Max level for new game
level: number;
- Update template response endpoint:
// character.controller.ts
@Get('templates')
getTemplates() {
return {
templates: [
// ... existing templates
{
value: CharacterTemplate.NEW_GAME,
label: 'New Game Name',
maxLevel: 100
}
]
};
}
- 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