Final Boss(sprint2 version) - UQcsse3200/2026-studio-4 GitHub Wiki

Historical Sprint 2 implementation: retained for design history and its original evidence. Stage 2 charge attacks and other old tuning below are not the current encounter. Start with Final Boss: Grandpa and Stage 2 Remake and Stage 3 Improvements.

Overview

Grandpa is the game's three-stage Final Boss. The encounter combines shielded summon waves, timed opportunities to damage the boss, movement penalties, ice attacks and a statue-based finale. The player must respond to changing attack patterns and visible warnings. The encounter ends with Grandpa returning alive in his peaceful form.

Feature ticket: Final Boss (Grandpa) #93.

Feature Responsibilities

According to the feature ticket:

  • Eden (@edenyzh): shared Final Boss framework, Stage 1 and Stage 3.
  • Chananyu (@MaidOfFire67): Stage 2.

The stages share one Grandpa entity, health pool and phase controller. Gameplay changes between stages without replacing the boss entity.

Encounter Progression

Health percentages refer to Grandpa's maximum health, which defaults to 100 HP.

Phase Boss damage rules Progression condition
Stage 1, Wave 1 Shielded at full health Remove all eight summons.
Stage 1 break Receives 25% of normal incoming damage; health cannot fall below 90% The full seven-second break expires.
Stage 1, Wave 2 Shielded Remove all sixteen summons; health is then set to 80%.
Stage 2 Vulnerable after the protected handover Reach 60% health to trigger Stage 3.
Stage 3, Wave 1 Vulnerable, including during recovery Reach 20% health to trigger the charge.
Stage 3 charge Shielded at the 20% health floor Three seconds elapse.
Stage 3, Wave 2 Grandpa is hidden; each statue has its own hit counter Defeat all five statues.
Peaceful ending Grandpa remains alive and invulnerable Complete the return transformation and show the ending dialogue.

A three-second protected handover separates Stage 1 from Stage 2 and Stage 2 from Stage 3. Health floors prevent a powerful hit from skipping the intended combat phases.

Gameplay

Stage 1: Summons and Temporary Vulnerability

Grandpa appears peacefully, transforms into the Wizard and casts before the summon waves.

During Wave 1, eight explosive summons approach the player at the slower movement speed. A proximity-triggered explosion has a one-second warning, giving the player time to leave its area. A ranged hit can trigger earlier detonation. Grandpa moves towards the player in steps with pauses while avoiding summons.

Remaining within 1.5 world units of Grandpa causes five damage every second, subject to normal combat protections. Actual player health loss produces a brief red flash. Grandpa stays shielded while the summons remain.

When all eight summons are removed, Grandpa stops for a seven-second break and takes only 25% of normal incoming damage. Reaching the 90% health floor restores his shield immediately; the remaining break time still runs.

During Wave 2, sixteen faster summons appear and detonate without the first wave's warning delay. Grandpa retreats using the edge-movement mode, stays shielded and no longer applies Wave 1 proximity damage. Petrification adds a separate warning-and-dodge mechanic.

Stage 1: Petrification Timing

Petrification is a temporary movement slowdown. Its red targeting circle records the player's position once and remains fixed.

  1. The red circle flashes for 0.5 seconds. This warning applies no petrification penalty.
  2. When the warning ends, the player's current position is checked against the 1.2-world-unit radius.
  3. Remaining inside or on the boundary applies a 0.5 movement-speed multiplier for two seconds. Leaving before the check avoids that cast; returning after it has resolved does not cause a hit.
  4. The actual penalty displays red blinking and a status indicator. This effect is separate from the brief flash caused by ordinary health loss.
  5. A 2.5-second cooldown starts after resolution. The next warning also waits for any previous petrification penalty to end.

The shared status-effect system applies and expires the slowdown. Repeated requests refresh its duration instead of compounding the reduction. Removing the effect preserves unrelated effects and any changes made to base movement speed.

Clearing Wave 2 removes the Boss-owned petrification effect, sets Grandpa to 80% maximum health and completes Stage 1.

Stage 2: Charge Attacks and Recovery

Stage 2 uses charge movement and periodic close-range damage. The configured attack and stationary recovery periods are 20 and seven seconds respectively. Contact damage is disabled during recovery.

At 60% maximum health, Stage 2 charge behaviour is cancelled and the protected handover to Stage 3 begins.

Stage 3, Wave 1: Ice Volleys and Freeze

Grandpa maintains distance while firing ice fans containing three projectiles: one in the centre and two at ±30 degrees. Static walls block the projectiles.

Two volleys are separated by 1.6 seconds. After the second volley, Grandpa stops for a three-second recovery, including one repositioning teleport after 0.25 seconds. Existing projectiles remain active, and the boss remains vulnerable. The next volley cycle begins when recovery ends.

An ice hit triggers the following sequence:

  1. Lock new player movement, dash and attack actions and interrupt the current volley cycle.
  2. Grandpa moves for one second, then teleports beside the player.
  3. After 0.25 seconds, attempt one strike.
  4. An in-range strike applies ten damage through the normal combat rules, releases the Boss-owned freeze and is followed by a retreat teleport.
  5. A missed strike does not repeat. The freeze ends after its three-second maximum duration.

This freeze uses a control lock rather than modifying movement-speed buffs. Stage transitions, player defeat and disposal release the Boss-owned lock.

Stage 3, Wave 2: Statues and Jumping

At 20% maximum health, Grandpa becomes shielded and charges for three seconds. Ice projectiles and freeze are cleared. Grandpa and his health display disappear, his collision body is disabled, and five statues appear.

SPACE temporarily performs a jump instead of a dash. An on-screen hint explains the change. The player can move and attack while airborne.

Statues alternate movement and pauses and take turns attacking through a shared scheduler. Each slam has a 0.6-second warning and a 0.9-second jump before landing creates an expanding ring-shaped shockwave.

A sufficiently timed player jump avoids the moving ring edge. Each ring resolves player contact once, including a successful jump over it, so landing inside an already-passed ring is safe.

Each statue requires ten distinct accepted positive weapon hits, independent of weapon damage. Hits 3, 6 and 9 request an evasive teleport without resetting the hit count. A successful evade cancels that statue's current slam and restarts recovery; blocked destinations are retried.

As statues break, survivors gradually gather into a tighter formation and attack more frequently:

Living statues Target interval between warning starts across the encounter
5 3.0 seconds
4 2.7 seconds
3 2.4 seconds
2 2.1 seconds
1 1.8 seconds

These are encounter-wide intervals. Active warnings and jumps retain their full durations; an individual attack can be delayed by recovery or an evade. Movement routes and teleport destinations use wall and actor-clearance checks.

Tornadoes

Each of the first four defeated statues leaves one tornado, with a maximum of four visible or pending tornadoes. An obstructed spawn waits for a clear position.

Tornadoes wander slowly, pursue a nearby visible player and resume wandering when the player moves away. Movement uses camera bounds, wall checks and clearance from other tornadoes, statues and reserved statue routes.

Sprint 2 tornadoes do not cause contact damage, knockback or additional status effects.

The final statue spawns no fifth tornado. Existing tornadoes stop and dissolve with grey-white effects, pending spawns are cancelled, and remaining shockwaves and camera shake are cleared. Normal SPACE dash behaviour returns.

A 1.2-second transformation brings peaceful Grandpa back near the player's current position, using camera and obstacle checks. He remains alive and invulnerable. The ending dialogue and encounter-completion event follow the transformation. Continue or Enter advances the dialogue and releases its control lock when finished.

Implementation Architecture

The Final Boss uses the engine's entity-component architecture. One boss entity holds the shared health, protection, movement and stage components. Each stage checks the shared phase and manages its own behaviour.

Class or group Responsibility
FinalBossFactory Validates configurations and assembles the boss and Stage 1 summons.
FinalBossPhaseControllerComponent Controls ordered stage progression and the protected handover between stages.
CombatStatsComponent and FinalBossDamageControllerComponent Hold health and enforce shields, damage multipliers and health floors.
FinalBossStageOneComponent, FinalBossStageTwoComponent, FinalBossStageThreeComponent Manage their respective combat sequences, timers and completion conditions.
FinalBossMovementComponent Provides shared movement modes, charge control and access to the room camera.
FinalBossPetrificationComponent and PlayerPetrificationComponent Separate Boss targeting and warning resolution from application of the player's timed status effect.
Visual components and FinalBossEndingDialogueComponent Draw the encounter's feedback and present the jump hint and ending dialogue.
FinalBossTornadoController Manages tornado spawning, movement and dissolution as a helper owned by Stage 3.

The three stage configuration classes hold gameplay values and validate them before use. The factory currently creates their default configurations directly. See the [factory assembly][fb-factory] and [Stage 3 controller][fb-stage-three].

Phase and State Management

The shared phase controller and individual stages use enums, timers and guarded transitions to implement finite-state machines. completeStage(completedPhase) accepts completion only for the current phase. A successful transition advances the phase, applies the handover protection when appropriate, and publishes PHASE_CHANGED.

Stage 1 and Stage 2 request completion through STAGE_COMPLETED. Stage 3 calls the same controller's completeStage(STAGE_THREE) method after the return transformation. Its local state becomes PEACEFUL, while the shared phase becomes DEFEATED. Here, DEFEATED represents encounter completion; Grandpa remains alive. See the [phase controller][fb-phases] and [ending implementation][fb-stage-three].

Design Patterns Applied

Factory Pattern: Centralised Entity Construction

FinalBossFactory.createFinalBoss(target, summonSpawner) applies the factory approach discussed in Week 5, App 05 - Design Patterns, pages 5-6. It creates the base NPC, validates the stage configurations and adds the required components before returning the entity.

The room manager supplies the player and a spawn callback. This keeps the component assembly in one place, so room code can create a complete Final Boss through one entry point. createExplosiveSummon(...) similarly centralises the shared construction of Stage 1 summons while accepting movement speed and warning duration for each wave.

This is a static factory arrangement. Adding a required Boss component still requires updating the factory, but callers can retain the same creation API. See [FinalBossFactory][fb-factory] and its [room integration][fb-room-manager].

Observer Pattern: Event-Based Component Communication

The Final Boss reuses the engine's EventHandler, applying the Observer pattern discussed in Week 5, pages 9 and 14-15:

  • addListener(...) registers a listener for a named event, corresponding to attachment.
  • trigger(...) notifies the registered listeners and passes the event arguments.
  • Registered callbacks, such as PlayerPetrificationComponent.apply(...), perform the receiving component's response.

For example, the Boss publishes a petrification request on the player's event handler. The player component receives it and creates a PetrificationEffect through the shared status-effect controller. Similarly, Stage 3 publishes state changes that the ending dialogue component observes to show the jump hint or peaceful dialogue.

This separates the notification sender from the receiving behaviour. Event names, argument types and the entity carrying the event remain shared contracts, so integration tests must check them. See the existing [event framework][fb-events-engine], [player adapter][fb-player-petrification] and [dialogue listener][fb-dialogue].

Petrification Interaction Diagram

The sequence below shows a normal request for a living player with an active status-effect controller. REQUESTED and CLEAR_REQUESTED abbreviate the corresponding FinalBossEvents constants. The participant labels abbreviate FinalBossPetrificationComponent, the player's EventHandler, PlayerPetrificationComponent and StatusEffectsControllerComponent.

sequenceDiagram
    participant B as Boss petrification
    participant E as Player events
    participant P as Player petrification
    participant S as Status effects

    P->>E: addListener(REQUESTED, apply)
    P->>E: addListener(CLEAR_REQUESTED, clear)

    Note over B,P: Warning ends. Check current player position.
    alt Player remains inside the circle
        B->>E: trigger(REQUESTED, multiplier, seconds)
        E->>P: apply(multiplier, seconds)
        P->>S: removeStatusEffect(previous)
        P->>P: Create timed PetrificationEffect
        P->>S: addStatusEffect(next)
    else Player escaped
        Note over B,E: No player effect request
    end

    Note over B,S: When Stage 1 Wave 2 ends
    B->>E: trigger(CLEAR_REQUESTED)
    E->>P: clear()
    P->>S: removeStatusEffect(previous)
Loading

Removing the previous Boss-owned effect before adding another refreshes the duration without stacking this penalty. The shared controller manages expiry; the adapter's removal callback notifies effective-stat listeners. Unrelated effects and base movement-speed changes are preserved. The diagram omits rendering and stat-notification calls to focus on the event contract. See the [Boss sender][fb-boss-petrification] and [player receiver][fb-player-petrification].

Integration Contracts

Cross-Team Interfaces

Team Integration boundary
Status Effects — Team 2 Petrification uses the shared controller, timed effects and effective movement-speed values.
Weapons — Team 3 Shielding, health floors, summon detonation and statue hit counting use the combat interfaces; new heavy attacks respect player control locks.
Rooms and shared UI — Team 4 The room manager supplies spawning and camera context and handles encounter completion. Shared health data/events remain available for UI integration.

These interfaces follow the feature ticket; the concrete APIs are listed below.

Creating and Registering the Boss

FinalBossFactory.createFinalBoss(Entity target, Consumer<Entity> summonSpawner) requires non-null arguments and returns an unregistered entity. The caller must arrange registration through the normal game-area lifecycle.

EnemyManagerComponent already handles the FINAL_BOSS spawn type. It passes this::spawnEntity for spawned summons and statues, supplies the room camera to the movement component when available, and tracks the main boss for room completion. Spawned Boss actors use the supplied callback rather than becoming separate entries in the room's activeEnemies set; their progression is managed by the Boss controllers. See [EnemyManagerComponent][fb-room-manager].

Events and Payloads

Event Event handler Payload and contract
FinalBossEvents.STAGE_COMPLETED Boss FinalBossPhase: the stage requesting completion. The phase controller validates the request.
FinalBossEvents.PHASE_CHANGED Boss FinalBossPhase: the new phase. A change to Stage 2 or Stage 3 begins a protected handover before normal combat resumes.
FinalBossEvents.PETRIFICATION_EFFECT_REQUESTED Player Float multiplier, then Float durationSeconds. Values must be finite; multiplier must be in [0, 1] and duration non-negative. The adapter handles application and replacement.
FinalBossEvents.PETRIFICATION_EFFECT_CLEAR_REQUESTED Player No arguments. Removes only the effect tracked by PlayerPetrificationComponent.
FinalBossStageThreeComponent.STATE_CHANGED Boss FinalBossStageThreeState. The dialogue component responds to the statue wave and peaceful ending.
"finalBossEncounterCompleted" Boss No arguments. Emitted after Grandpa's return transformation. The room manager removes the boss from its active-enemy tracking and clears the room if no tracked enemies remain.

Use the correct entity's event handler and preserve argument order. The player factory already adds PlayerPetrificationComponent alongside CombatStatsComponent and StatusEffectsControllerComponent. See [event constants][fb-event-names], [PlayerFactory][fb-player-factory] and [room completion handling][fb-room-manager].

Player Controls and Physics Cleanup

PlayerActions.setControlsLocked(owner, locked) tracks each owner's lock separately. Stage 3 freeze and the ending dialogue therefore release their own locks without cancelling another owner's lock. setJumpEnabled(owner, enabled) uses the same ownership approach for replacing dash with jump during the statue wave. See [PlayerActions][fb-player-actions].

Statue removal can be triggered from a physics contact callback. That path schedules entity disposal so body destruction occurs after the physics world unlocks. Future changes must preserve this ordering; [FinalBossStatueCollisionTest][fb-collision-test] exercises a real weapon contact and checks deferred removal.

Design Decisions and Changes

The decisions below are supported by the implementation, regression tests and recorded development notes. Gameplay balance and readability still require the recorded manual evaluation described in the test plan.

Testing Strategy

Testing combines automated component tests, integration tests using real game components and Box2D, and the manual gameplay plan below.

Mocking and Repeatable Test Conditions

JUnit tests use Mockito to control dependencies while exercising the behaviour under test:

  • Controlled time: mocked GameTime supplies specific timestamps and frame durations. Tests can check warning expiry, cooldowns and transitions without waiting for real time.
  • Controlled collaborators: phase and movement mocks select the required stage or isolate movement commands. Stage 1 entrance tests also use a scoped static factory mock to create simple summon entities while testing the real stage controller.
  • Interaction verification: verify(..., times(1)) checks that completion is submitted once. ArgumentCaptor checks the movement impulses requested during petrification and after recovery; this verifies the commands sent to physics.
  • Real physics with observation: spy(new PhysicsEngine()) retains real Box2D behaviour while allowing checks that a collision callback schedules removal and that body destruction occurs after the world unlocks.

The petrification integration tests retain the real Boss petrification component, player adapter, combat stats and shared status-effect controller. Separate collision and movement tests run actual physics steps. See the [petrification tests][test-petrification], [Stage 1 entrance tests][test-entrance] and [statue collision test][test-collision].

Test Design

The suite includes:

  • Boundary cases: updates immediately before and after timing thresholds; health just above a phase threshold and an oversized hit that reaches its floor.
  • Negative and repeated inputs: zero or negative statue damage, repeated contacts from the same attack source, and repeated completion or cleanup requests.
  • Lifecycle cases: player defeat, disposal, stage changes, interrupted attacks and preservation of effects or control locks owned by another component.
  • Spatial cases: camera edges, walls, crossing routes, blocked destinations and long frames. Statue movement tests use fixed seeds, including 7, 31 and 2026, and check movement and separation over multiple physics updates.

For example, [FinalBossHealthProgressionTest][test-health] uses 1,000 maximum HP to check percentage-based progression: Stage 2 remains active at 601 HP, an oversized hit stops at 600, and the later Stage 3 hit stops at 200. This checks that progression scales with maximum health.

Automated Regression Tests

The following groups identify the behaviour checked by existing test code. The CI result is recorded separately below.

Area Behaviour checked Test evidence
Shared progression Ordered phases, rejection of stale completion, protected transitions and health floors under oversized damage [Phase controller][test-phase]; [health progression][test-health]
Stage 1 sequence and protection Entrance before spawning, wave counts, full break duration, 80% handover, shield behaviour and capped vulnerability [Entrance][test-entrance]; [damage controller][test-damage]
Explosive summons Warning delay, explosion radius, ranged-triggered detonation, removal once and interactions with invisibility [Explosive summons][test-summons]
Petrification Harmless warning period, position at expiry, slowdown and recovery, refresh without stacking, preservation of other effects and cleanup [Status integration][test-petrification]
Player feedback Petrification blinking follows the effect lifetime; ordinary damage flashing responds to actual health loss [Petrification flash][test-petrification-flash]; [damage flash][test-damage-flash]
Stage 3 ice and freeze Three-projectile fans, two-volley recovery, interrupted sequences, one strike, thaw and control-lock ownership [Volley tests][test-volley]; [Stage 3 tests][test-stage-three]; [player actions][test-player-actions]
Statue hits and evasion Ten accepted hits, duplicate-source rejection, evasion on every third hit, interrupted slams and safe deferred physics changes [Stage 3 tests][test-stage-three]; [evade tests][test-evade]; [collision test][test-collision]
Slams and jumping Shared attack cadence, one ring contact, long-frame crossing, correctly timed jumps, recovery and restoration of dash [Slam tests][test-slam]; [player jump tests][test-jump]
Actor movement and spacing Actual statue movement, wall and route checks, camera containment, and moving statues and tornadoes together [Statue spacing][test-spacing]; [combined spacing][test-cross-spacing]
Tornado lifecycle Four-remnant cap including queued spawns, pursuit and release, blocked-spawn retries, final dissolution and cleanup [Tornado controller][test-tornado]; [Stage 3 integration][test-tornado-integration]
Peaceful return Return near the player's latest position, camera and obstacle handling, living invulnerable Grandpa and one completion notification [Grandpa return][test-return]; [Stage 3 tests][test-stage-three]
Assets Texture loading, frame slicing within sheet bounds and selective tornado-background transparency [Asset tests][test-assets]

Regression Evidence Informing a Revision

The [petrification implementation note][test-petrification-notes] records that the overlap regression failed against the earlier implementation and passed after the warning-timing fix. The corrected behaviour waits for the previous penalty to expire before starting another warning.

previousPenaltyShouldExpireBeforeNextWarningStarts() preserves this case with a deliberately shortened cooldown. This protects the design requirement that the player can respond to a new warning without an earlier petrification penalty still active.

Other regression cases protect the related integration decisions: effect removal preserves unrelated buffs, releasing freeze preserves other control locks, and physics callbacks defer unsafe body changes.

Verified CI Evidence

The Game Unit Tests run completed successfully on 16 September 2026 for 521e21b69cd6ea1b5d7b6432a7711308fdfa3ad8. Its Run Unit Tests step passed using JDK 21 and ./gradlew test from the source directory. See the [workflow definition][test-workflow].

This is automated-suite evidence for the merged revision. Visual readability, difficulty and complete gameplay interaction are evaluated through the manual plan below. Numerical coverage should be reported from an identified JaCoCo report for the same revision.

Reproducing Automated Tests

Use JDK 21 and run these commands from the repository's source directory.

Run the full suite, as in CI:

./gradlew test

For focused work on the Final Boss and affected player behaviour:

./gradlew :core:test \
  --tests '*FinalBoss*' \
  --tests '*PlayerPetrificationFlashTest' \
  --tests '*PlayerDamageFlashComponentTest' \
  --tests '*PlayerJumpTest' \
  --tests '*PlayerActionsTest'

Gameplay Cases

ID Steps Expected result Recorded result / evidence
M1 — Stage 1 progression Observe the entrance, clear the first wave, attack during the break, then clear the second wave. Transformation and casting precede combat; waves contain 8 and 16 summons. The break lasts seven seconds, damage is reduced and health stays at or above 90%. Wave 2 completion sets health to 80% and starts the protected handover. Awaiting record.
M2 — Escape the warning In Wave 2, leave the flashing red circle before it ends. Return to the old location after resolution. The circle stays at its captured position. No petrification penalty occurs during the warning or after this successful escape. Awaiting record.
M3 — Receive and recover from petrification Remain inside a warning until expiry, then move while observing the player and stat display. Wait for recovery and the next warning. The warning itself causes no slowdown. On resolution, movement is halved for two seconds and the player blinks red. Speed and feedback recover; the next warning does not overlap the previous penalty. Awaiting record.
M4 — Stage 2 handover Observe charge and recovery behaviour, then continue attacking until the 60% threshold. Stage 2 has attack and stationary recovery periods. At 60%, its charge is cancelled; the protected handover precedes Stage 3 ice combat. Awaiting record.
M5 — Ice sequence Observe two volleys and recovery. In a separate cycle, allow an ice projectile to hit and attempt movement and new attacks. Each fan contains three projectiles. Recovery follows two volleys. Freeze blocks new actions; the teleport sequence attempts one strike, releases freeze on an in-range strike and retreats. Awaiting record.
M6 — Statue hit counting Reach 20% Boss health. After the charge, use separated weapon attacks on one statue and record accepted hits. Five statues appear. Accepted hits 3, 6 and 9 request evasion; hit 10 breaks the statue. Evasion preserves its remaining hit count. Awaiting record.
M7 — Jump and shockwaves During the statue wave, compare standing on the ground when a ring reaches the player with jumping early enough to clear its edge. Continue moving and attacking while airborne. SPACE performs a jump. A grounded ring contact applies damage once; a sufficiently high jump avoids it. Landing inside an already-passed ring does not cause a delayed hit. Awaiting record.
M8 — Tornadoes and escalation Break the first four statues one at a time. Observe survivors, then approach and move away from a tornado. Move near camera edges and other actors. Up to four tornadoes appear, subject to clear spawn space. Survivors gather gradually and attack more frequently. Tornadoes wander, pursue nearby players and release distant targets; they apply no contact damage in Sprint 2. Movement remains readable and avoids obstacles where space permits. Awaiting record.
M9 — Peaceful ending Break the last statue near a camera edge, observe the return, then advance all dialogue using Continue or Enter. No fifth tornado appears. Existing tornadoes stop and dissolve; rings and shake clear. Grandpa returns nearby, visible, alive and invulnerable. Dialogue completes and controls become usable; SPACE returns to dash. Awaiting record.
M10 — Defeat and restart During the statue wave with tornadoes present, allow player defeat, then restart and begin a new encounter. Old hazards, jump mode, feedback and Boss-owned control locks do not carry into the new encounter. The new Boss starts its normal entrance sequence. Awaiting record.
M11 — Room completion integration During a complete encounter, inspect the room manager at its roomCleared trigger using the debugger. Completion is reached after the peaceful transformation through finalBossEncounterCompleted. The boss is removed from activeEnemies; the default boss-only room is cleared while Grandpa remains alive. Awaiting record.

Current Sprint Scope and Future Work

The merged implementation includes all three stages, shared status-effect integration, the statue and tornado finale, player feedback and ending dialogue functionality.

Tornado damage and further combat balance tuning are deferred to a later sprint. The ending dialogue currently uses draft story text.

Extending the Feature

  • Balance changes: edit the relevant stage configuration and retain its validation rules. Check phase thresholds together with the damage controller's health floors, and update timing tests when defaults change.
  • Additional feedback: subscribe to the existing warning, shield or state events where suitable. Keep targeting and damage decisions in the gameplay components.
  • Additional player effects: use the shared status-effect controller and remove only the effect owned by the mechanic. Preserve base stats and unrelated effects during expiry and cleanup.
  • Further Stage 3 work: keep tornado behaviour in FinalBossTornadoController where appropriate. Adding tornado damage remains future work and requires its own combat rules and tests.

Stage 3 still coordinates several mechanics in one controller, so changes to its timings or cleanup can affect multiple behaviours. Further extraction should preserve the existing state and lifecycle contracts and their regression tests.

Art resources

Source Notes

Earlier implementation notes include intermediate tuning and validation results. The documented code revision and the later tornado-finale note take precedence for current statue intervals and Grandpa's return location. Historical local test counts are not presented as the final merged-main CI count.

AI Assistance and Review Status

ChatGPT (Codex) assisted with parts of the Final Boss implementation and regression tests, and with comparing code, feature-ticket content, PRs and CI evidence to draft and organise this wiki.

⚠️ **GitHub.com Fallback** ⚠️