Seasons System
Titan implements Path of Exile-style seasons (leagues) with temporary and permanent leagues.
Season Types
Season Model
interface Season {
seasonId: string; // e.g., "standard", "season-1"
name: string; // Display name
description?: string;
status: SeasonStatus;
isPermanent: boolean;
targetSeasonId?: string; // Migration destination
startedAt?: string;
endsAt?: string;
}
Season Status
Status Values
| Status | Description |
|---|---|
Upcoming | Visible, no characters yet |
Active | Open for character creation |
Ending | Warning period, no new characters |
Ended | Finished, migration pending |
Migrating | Characters being moved |
Migrated | All characters moved |
Character Restrictions
When creating a character, players can choose restrictions:
| Restriction | Value | Effect |
|---|---|---|
| None | 0 | Normal gameplay |
| Hardcore | 1 | Death = migration to permanent |
| SoloSelfFound | 2 | Cannot trade with others |
Hardcore Characters
Solo Self-Found (SSF)
SSF characters:
- Cannot participate in trades (blocked by
SoloSelfFoundRule) - Cannot use shared stash tabs
- Play completely self-reliant
Season Migration
When a temporary season ends, characters migrate to the permanent league:
What Migrates
| Entity | Behavior |
|---|---|
| Characters | Moved to permanent league |
| Equipment | Stays on character |
| Bag Items | Moved to stash |
| Stash | Merged with permanent stash |
| Progress | Carried over |
Migration API
// Admin: End the season
await connection.invoke("EndSeason", "season-1");
// Admin: Start migration
await connection.invoke("StartMigration", "season-1");
// Check progress
const status = await connection.invoke("GetMigrationStatus", "season-1");
console.log(`${status.completed}/${status.total} characters migrated`);
Void League
For experimental mechanics, Void leagues prevent migration:
// Create void season
await connection.invoke("CreateSeason", {
seasonId: "void-experimental",
name: "Experimental Void",
isPermanent: true,
targetSeasonId: null // Items don't leave
});
Characters and items in Void leagues:
- Never migrate to permanent
- Are "stuck" in the void season
- Can still be played but isolated
Season Events
Subscribe to season updates:
connection.on("SeasonEvent", (event) => {
switch (event.eventType) {
case "SeasonCreated":
showNewSeason(event.season);
break;
case "SeasonStatusChanged":
updateSeasonStatus(event.season);
break;
case "MigrationStarted":
showMigrationBanner();
break;
case "MigrationCompleted":
refreshCharacterList();
break;
}
});
await connection.invoke("JoinAllSeasonsGroup");