Dungeon **bosses** are special **custom mobs** placed in boss rooms. They use the `isDungeonBoss` flag, separate loot rules from normal enemies, and drive **portals**, **progression**, and some **aspect** effects. --- ## Which bosses exist? Each dungeon type rolls **three** boss archetypes (with replacement) from the same pool: | Boss | Entity | Notes (base stats in code) | |------|--------|-----------------------------| | **Arachne** | `CustomEntities.ARACHNE` | 200 HP, 0.3 move speed, 0.8 knockback resist | | **Bonecrusher** | `CustomEntities.BONECRUSHER` | 200 HP, 0.25 move speed, 0.8 knockback resist | | **Elf Duelist** | `CustomEntities.ELF_DUELIST` | 100 HP, 0.33 move speed, 0 knockback resist | Stats come from `*BossStats` objects (`EntityTypeStats`). Bosses do **not** use the random dungeon gear system (`canHaveWeapons` / `canHaveArmor` are false for these types); they are authored as full boss entities. --- ## How many bosses per run? - **Default:** each `DungeonType` defines **`bossCount = 3`** (`DungeonType.STRONGHOLD` and `DungeonType.NETHER`). - **Aspect of Dominion:** each stack of this aspect **adds one extra boss** to the layout (`DungeonGenerateCommand.bossCount += count`). The in-game line is: “Dungeon contains an additional Boss” per stack. The layout generator receives the final `bossCount` after aspects are applied, and `BossGenerationService` spawns that many bosses at the layout’s boss spawn positions. --- ## Spawn behaviour 1. Bosses are spawned with **random scale** (`DungeonBossSettings.getRandomScale`, same style as minor variance on normal mobs). 2. **`isAiDisabled = true`** until the boss is **activated** (below). 3. They are marked as **dungeon enemies** and **dungeon bosses**, and their **original spawn pose** is stored (`setDungeonBossSpawnPosition`) for portals. 4. The dungeon world stores **`totalBossCount`** equal to the number of bosses spawned. **Nether dungeons:** the type’s `applyMisc` hook gives **Fire Resistance** to spawned enemies; that list includes **bosses** for NETHER, not for STRONGHOLD. --- ## Activation and scaling (“enhance boss”) When a **dungeon boss** takes damage: - If its AI is still disabled and the **attacker is a player** who is **not** in Creative or Spectator, the boss **activates**: AI turns on, **`enhanceBoss`** runs, and the boss **targets** that player. **`enhanceBoss`** reads how many bosses were **already killed** in this dungeon world (`getBossesKilled()`). If that number is **greater than zero**, the boss gains **custom attributes** from `DungeonBossSettings.getAttributePerKilledBoss(killedBosses)`: | Effect (per prior boss killed) | Approximate meaning | |--------------------------------|---------------------| | **+0.25** on “drop more loot” | Stronger loot multiplier on that boss | | **−0.15** on “more damage taken” | Takes less damage (negative roll on the “more damage taken” attribute type) | | **+0.1** on “more damage” | Deals more damage | So the **first** boss you fight (`killedBosses == 0` at activation) gets **no** extra scaling. Later bosses in the same run are tougher if you have already killed one or more bosses **before** they activate. --- ## Death: loot, portals, and events ### Crystals (normal boss death loot) Bosses **do not** use the regular dungeon enemy equipment-drop path (`LootService` skips bosses there). Instead, on **`DungeonBossDeathEvent`**, the game drops **crystals**: - Base count: **`dungeonLevel / 7 +` random uniform **`[0, dungeonLevel / 5)`** (`LootSettings.getBossBaseCrystalCount`). - Count is multiplied by the boss’s **custom-attribute loot multiplier** (same idea as other loot scaling). - Crystal **types** are drawn from `LootSettings.CRYSTALS` with level restrictions (calibration, permutation, reforge, corruption, sacrificial, etc.). ### Portal On each **`DungeonBossDeathEvent`**, a **leave portal** is spawned at that boss’s **stored spawn position** (so each boss room can get its own exit portal when cleared). ### Boss kill counter and “final” boss The world increments **`bossesKilled`**. When **`bossesKilled >= totalBossCount`**, a **`DungeonFinalBossDeathEvent`** is published (last boss of the run). - **Aspect of Ghosts:** if that aspect is in the dungeon’s aspect map, the **final** boss also drops a rolled **Geistergaloschen** armor piece (`AspectOfGhostsService` on `DungeonFinalBossDeathEvent`). ### Progression and “dungeon completed” On the **first** boss death in a dungeon, `DungeonCompletionService` marks the world as **dungeon completed** (if not already) and fires **`DungeonCompletedEvent`**. That event is what: - Clears the opener’s **dungeon seed** (`DungeonSeedService`), - Applies **dungeon level progress** to players in the world (`DungeonLevelService`). So **dungeon level / seed progression** is tied to that **first** boss kill in the run, not necessarily the last. Subsequent boss kills still drop crystals and portals; **`DungeonFinalBossDeathEvent`** is separate and used for effects like Ghosts’ final-boss drop. --- ## Comparison with other modifiers - **[Elite enemies](Elite-Enemies.md)** are a flag on **regular** spawns (Raid Omen, aspect drop, etc.). Bosses are a different pipeline. - **[Loot Goblins](Loot-Goblins.md)** apply to normal dungeon enemies, not to the boss equipment rules above. --- ## Summary | Topic | Behaviour | |--------|-----------| | Roster | **Arachne**, **Bonecrusher**, **Elf Duelist** — 3 picks with replacement by default | | Count | **3** base; **+1 per stack** of **Aspect of Dominion** | | Fight start | **Dormant** until a survival-mode **player** damages the boss; then AI + scaling + aggro | | Scaling | Later bosses get **more loot / less damage taken / more damage** based on **bosses already killed** when they activate | | Drops | **Crystals** (level-based formula + loot multiplier), not normal enemy gear | | Exits | **Portal** at each boss’s spawn on death | | Last boss | **`DungeonFinalBossDeathEvent`**; **Aspect of Ghosts** adds **Geistergaloschen** on the final kill | | Progress | **`DungeonCompletedEvent`** (seed + level progress) on **first** boss death | For implementation details, see `BossGenerationService`, `DungeonBossService`, `DungeonBossSettings`, `LootService` (boss branch), and `DungeonPortalService` (boss death).