Job/Class Unlock System
Relevant source files
The following files were used as context for generating this wiki page:The Job/Class Unlock System is a core progression mechanic in Souless. It allows players to unlock new playable character classes by performing specific in-game feats and subsequently defeating corresponding bosses. The system is designed as a two-step process: first, meeting a hidden condition to make a boss available, and second, defeating that boss to unlock the new class. The entire state of this progression is persisted within the player's save slot data.
This system is primarily managed by a set of interconnected classes: JobConditionTracker monitors player actions, JobUnlockManager handles the state logic of what is available and unlocked, BossEventHandler orchestrates the events following a boss defeat, and SaveSlotManager persists the data.
Architecture and Core Components
The system is composed of several key classes that collaborate to manage the unlock process. GameScene serves as the central hub where these components are instantiated and interact.
This diagram shows the relationships between the main components of the Job Unlock System.
Sources: src/scenes/GameScene.js, src/systems/characterType/JobConditionTracker.js, src/systems/characterType/BossEventHandler.js, src/systems/characterType/JobUnlockManager.js
Key Components
| Class | Description | Source File |
|---|---|---|
JobUnlockManager | A static utility class that manages the core logic of job unlocks. It maps jobs to bosses and manipulates the save data to track available and unlocked characters. | src/systems/characterType/JobUnlockManager.js |
JobConditionTracker | Tracks player performance against predefined conditions (e.g., survive without being hit). When a condition is met, it makes the corresponding boss available for challenge. | src/systems/characterType/JobConditionTracker.js |
BossEventHandler | Listens for the bossDefeated event from GameScene. It orchestrates the unlock sequence, including visual effects and transitioning to a new scene with the unlocked character. | src/systems/characterType/BossEventHandler.js |
SaveSlotManager | Manages all read/write operations for save game data, including the arrays that track job unlock progression. | src/utils/SaveSlotManager.js |
GameScene | The main game scene that instantiates and drives the JobConditionTracker and BossEventHandler. It is also responsible for spawning the appropriate boss based on the current unlock state. | src/scenes/GameScene.js |
Data Management
The state of the job unlock system is persisted in the save file for each slot, managed by SaveSlotManager. The following fields within the save data object are critical for this system.
This diagram illustrates the key fields in the save data object related to job progression.
| Field | Type | Description | Source File |
|---|---|---|---|
availableBoss | string[] | An array of job keys (e.g., 'assassin', 'monk') for which the unlock condition has been met, making the corresponding boss available to be challenged. | src/systems/characterType/JobConditionTracker.js:201-209 |
clearedBosses | string[] | An array of job keys for which the corresponding boss has been defeated. This is used to prevent re-challenging a defeated boss and to track progression. It is also synchronized with PortalConditionManager.defeatedBosses. | src/systems/characterType/JobUnlockManager.js:63-67 |
availableTypes | string[] | An array of all unlocked character class keys. When a job is unlocked, its key is added to this list. | src/systems/characterType/JobUnlockManager.js:55-57 |
Sources: src/utils/SaveSlotManager.js:40, src/systems/characterType/JobUnlockManager.js:49-67, src/systems/characterType/JobConditionTracker.js:201-209
Job Unlock Lifecycle
The process of unlocking a new job follows a distinct, multi-step flow, from meeting the initial condition to the final character unlock.
This diagram shows the end-to-end flow for unlocking a new job.
Sources: src/systems/characterType/JobConditionTracker.js:188-209, src/scenes/GameScene.js:581-590, src/systems/characterType/BossEventHandler.js:49-71
Detailed Breakdown
1. Condition Tracking
The first step to unlocking a job is to meet a specific gameplay condition. The JobConditionTracker class, instantiated in GameScene, runs in the background, monitoring player actions via events like player-hit and player-attack.
Each job has a unique condition. Once a condition is fulfilled, JobConditionTracker.completeCondition() is called. This function adds the job's key to the availableBoss array in the save data via JobUnlockManager.addAvailableBoss(), making the corresponding boss eligible to be spawned.
The conditions for each job are defined in the JobConditionTracker constructor.
| Job Key | Condition Type | Description | Source |
|---|---|---|---|
assassin | survive_no_hit | Survive for 15 seconds without taking damage from an enemy. | src/systems/characterType/JobConditionTracker.js:12-17 |
monk | survive_no_attack | Survive for 10 seconds without performing an attack. | src/systems/characterType/JobConditionTracker.js:18-23 |
bladekeeper | consecutive_hits | Land 5 consecutive hits on enemies within a 2-second combo window. | src/systems/characterType/JobConditionTracker.js:24-30 |
fire_knight | maintain_combat | Remain in combat for 10 seconds by attacking at least once every 1.5 seconds. | src/systems/characterType/JobConditionTracker.js:31-37 |
mauler | survive_low_hp | Survive for 15 seconds while player health is at or below 30% of max health. | src/systems/characterType/JobConditionTracker.js:38-43 |
princess | no_damage | Survive for 20 seconds without taking any damage. | src/systems/characterType/JobConditionTracker.js:44-49 |
Sources: src/systems/characterType/JobConditionTracker.js:8-50
2. Boss Spawning
Once a job key is present in the availableBoss array, the corresponding boss can be spawned in maps configured for manual boss spawns (e.g., spawnCondition: 'manual'). In GameScene, when the player initiates a boss fight (e.g., by pressing the 'B' key), the spawnBoss method checks the save data. It identifies the first boss in the availableBoss list that has not yet been cleared and spawns it.
The mapping from a job key to a boss entity type is defined in JobUnlockManager.JOB_BOSS_MAPPING.
Sources: src/scenes/GameScene.js:581-621, src/systems/characterType/JobUnlockManager.js:4-12
3. Character Unlock
When a player defeats a job-specific boss, GameScene emits a bossDefeated event with the boss type (e.g., 'assassin_boss'). The BossEventHandler listens for this event and triggers the final unlock sequence.
This diagram shows the sequence of events from defeating a boss to unlocking the new character.
The onBossDefeated method in BossEventHandler performs these key actions:
- Starts a slow-motion effect for cinematic impact.
- Determines the
jobKeyby reverse-mapping thebossTypeusingJobUnlockManager.getJobKeyFromBoss(). - Calls
JobUnlockManager.unlockCharacter(jobKey). This is the critical step that updates the save data:- The
jobKeyis added to theavailableTypesarray. - The
jobKeyis added to theclearedBossesarray. - The
jobKeyis removed from theavailableBossarray.
- The
- Shows a "JOB UNLOCKED" UI effect.
- Transitions to the
GameScene, automatically switching the player to the newly unlocked character.
Sources: src/systems/characterType/BossEventHandler.js:49-71, src/systems/characterType/JobUnlockManager.js:49-71