Skip to content

Win System

Sarah Preston edited this page Oct 6, 2026 · 1 revision

Win System

Overview

The game is won by defeating Zeus in Level 3. That is the only way to win. How well the player won is then graded into three tiers, with one extra honour:

Tier Level How it is earned
Victory 1 Zeus in Level 3 is defeated
Glory 2 Victory, and the guardian of each of the eight side rooms is also defeated
Legend 3 Glory, and at least 3 quests have been completed
Tortoise Champion honour every hidden tortoise has been found; independent of the tier

Each tier includes the one below it. Quests alone never lift a Victory to Legend.

Why the mini bosses scale the win instead of being another way to win

Making "kill every mini boss" a second route to the ending would make the final fight skippable and the side rooms compulsory for that route, even though nothing gates a side-room door. As a scale, the side rooms and quests stay optional, they pay off, and the game keeps one clear ending.

What happens when Zeus dies

Zeus (Level 3) dies
   |  BossDefeatedWinComponent hears his "death" event and announces "finalBossDefeated"
   |  on a listener entity owned by the LevelGameArea
   v
LevelGameArea.isFinalBossDefeated() becomes true
   v
MainGameScreen, each frame: WinCountdown.update(defeated, frame time)
   |  waits 2.5 seconds so the death is seen
   v
WinEvaluator.evaluateNow(true)
   |  reads EnemyRegistry (kills), QuestLedger (quests), TortoiseLedger (tortoises)
   v
WinResult (tier, counts, what is missing)
   v
WinScreenDisplay.showWinScreen(result)

The announcement goes to an entity owned by the area, not to the boss and not to the player. The boss is disposed the moment it dies, and reviving the player creates a new player entity, so neither outlives the moment reliably.

The classes (com.csse3200.game.win)

Class Kind Responsibility
WinTier enum the four values with a level, a title and a subtitle
BossRoster static data which enemy is the final boss, and which mini bosses count
QuestLedger static state how many quests have been completed, by kind
TortoiseLedger static state which hidden tortoises have been found, and how many exist
WinEvaluator static logic turns kills, quests and tortoises into a WinResult
WinResult immutable value the tier and the numbers behind it
BossDefeatedWinComponent component on the final boss; announces his death once
WinCountdown timer the wait between the death and the win screen

Changes to existing classes

Class Change
LevelGameArea owns the listener and the finalBossDefeated flag; armWinTrigger gives the final boss its component; noteAlreadyKilled handles a save made after the win
MainGameScreen runs the WinCountdown each frame and shows the win screen; loads and resets the two ledgers
WinScreenDisplay showWinScreen(WinResult) and five small methods that build the text
QuestGiverComponent records a quest in the QuestLedger when it is turned in at 100 percent
GameSaveData, PauseMenuActions save the completed quests and found tortoises

The boss roster

A kill is already saved under an id of the form <map name>:<x>,<y> (EnemyId, EnemyRegistry). The roster uses those ids, so no enemy needs a new component to be counted, and kills survive a save and a load.

Final boss: Zeus, Level 3 - Zeus's Palace:26,4.

Room Required guardian Kill id
Hound's Den Cerberus Hound's Den:48,2
Gorgon's Gallery Medusa Gorgon's Gallery:37,11
Minotaur's Labyrinth Minotaur Minotaur's Labyrinth:24,35
Shades' Barracks Minotaur Shades' Barracks:40,17
Cyclops Forge Cyclops Cyclops Forge:30,15
Centaur Pavilion Centaur (upper) Centaur Pavilion:44,12
Zeus's Outer Guard Medusa Zeus's Outer Guard:24,16
Zeus's Thunder Hall Medusa Zeus's Thunder Hall:26,12

The required guardian is the boss on the room's highest storey, beside the exit. Three other boss-type enemies (a Centaur in the Labyrinth, the lower Centaur in the Pavilion, the Cyclops in the Outer Guard) are listed as escorts and are not required.

There is only one Zeus in the game, in Level 3. The Thunder Hall and Level 2 bosses that used to be Zeus are now Medusa, so no other enemy can end the game.

The roster is tied to the maps. Moving a boss marker or renaming a map breaks its id. BossRosterMapsTest reads the real map files and fails as soon as they disagree.

The win screen

The screen shows, top to bottom:

  • the tier's title in capitals, its subtitle, and "Rank n of 3"
  • "Guardians defeated: x of 8"
  • "Quests completed: x of 3"
  • "Tortoises found: x of y", with "- Tortoise Champion" when all were found
  • what is still missing: up to four guardians by name, then "and n more", then the quests still needed
  • the Play Again and Main Menu buttons (unchanged, including keyboard navigation)

The win terminal command shows the screen for the current game without killing Zeus.

Quests and tortoises

  • Quests. QuestGiverComponent records a completion when a quest is turned in with a progress of 100 or more. A quest cleared below 100 is abandoned and is not counted. NPCs hand out jump, enemies killed and shields collected quests through DialogueComponent.
  • Tortoises. MainGameScreen calls TortoiseLedger.setTotal(n) with how many tortoises the game hides (the TORTOISES_HIDDEN constant, currently 1), and TortoiseComponent calls recordFound(id) when the player touches one. Raise the constant when more tortoises are placed.

Tuning

To change Edit
which bosses count for Glory the table in BossRoster
how many quests Legend needs WinEvaluator.QUESTS_REQUIRED_FOR_LEGEND
the wait before the win screen WIN_SCREEN_DELAY in MainGameScreen
the titles and subtitles WinTier

UML

Class diagram of the win package.

Win system class diagram


Win System: Testing Plan

Every class in the win package has its own JUnit test class in com.csse3200.game.win, and each changed class outside the package has a test beside it. The ledgers are static, so every test resets them before and after it runs.

WinTierTest

Tests were used to ensure the following situations were working:

  • There are exactly four tiers, in ascending order of level
  • Each tier has the level its name implies and its own non-blank title
  • isAtLeast compares tiers by level
  • A tier can be found by its level, and a level outside 0 to 3 is rejected

BossRosterTest, BossRosterMapsTest

Tests were used to ensure the following situations were working:

  • The roster holds eight required guardians and three escorts, with the required ones first
  • The final boss is not in the list of mini bosses, and only its id is the final boss
  • A mini boss with a blank id, label, room or type is rejected
  • The lists handed out cannot be changed by the caller
  • Every id in the roster matches a boss marker in the real map files, and there is only one Zeus

QuestLedgerTest, QuestCompletionLedgerTest

Tests were used to ensure the following situations were working:

  • A completed quest is counted under its kind, and an unknown kind is rejected
  • The ledger can be reset, saved and loaded, ignoring unknown kinds and counts of zero or below
  • Each of the four quest kinds reaches the ledger when it is turned in at 100 percent
  • A quest cleared below 100 percent is not counted

TortoiseChampionTest

Tests were used to ensure the following situations were working:

  • A found tortoise is counted once, however many times it is recorded
  • The honour is earned only when every hidden tortoise is found, and never when none are hidden
  • The ledger can be reset, saved and loaded
  • The honour is independent of the tier

WinResultTest

Tests were used to ensure the following situations were working:

  • A result stores its tier and its counts
  • A negative count is rejected
  • The list of missing guardians cannot be changed by the caller
  • isFullyComplete and isTortoiseChampion report correctly

WinEvaluatorTest

Tests were used to ensure the following situations were working:

  • No tier is given while the final boss is alive, whatever else is done
  • Victory, Glory and Legend are each given at exactly their rule
  • Escorts, unknown ids, duplicate ids and a null collection do not change the tier
  • The guardians still standing are listed in roster order
  • evaluateNow reads the kills, quests and tortoises from the live registries

BossDefeatedWinComponentTest, LevelGameAreaWinTriggerTest

Tests were used to ensure the following situations were working:

  • The final boss's death is announced on the listener entity, not on the boss
  • It is announced once, even if the death is reported again
  • Only the final boss is given the component; any other enemy is left alone
  • The area is won when the armed boss dies, stays won, and a save with the boss already dead loads as won
  • Two areas keep their own flags

WinCountdownTest

Tests were used to ensure the following situations were working:

  • Nothing happens until the final boss is defeated
  • The countdown finishes exactly once, after the delay, frame by frame
  • A negative, infinite or not-a-number delay is rejected

WinScreenDisplayTest

Tests were used to ensure the following situations were working:

  • The rank, guardians, quests and tortoises lines have the right wording
  • At most four missing guardians are named, with the rest summed up
  • The screen is hidden until a result is shown, and shows the tier's title

PauseMenuActionsWinSaveTest

Tests were used to ensure the following situations were working:

  • Completed quests and found tortoises are written into the save
  • A fresh game saves none
  • Both ledgers are restored from what was saved
  • Everything that was saved before is still saved

WinUtilityClassesTest

Tests were used to ensure the following situations were working:

  • The static holder classes cannot be instantiated

Manual testing

The lines in MainGameScreen that connect the countdown to the screen, and the two calls inside LevelGameArea.spawnEnemies(), need a running game. To check them:

  • Kill Zeus in Level 3 and the win screen appears after about 2.5 seconds.
  • Kill the Thunder Hall Medusa and the game does not end.
  • Save after a win, reload, and the guardian, quest and tortoise counts are kept.

Clone this wiki locally