Win System - UQcsse3200/2026-studio-1 GitHub Wiki
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.
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.

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.
| 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 |
| 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; on a new game rolls the tortoise plan, and on a load restores the saved plan, total and found tortoises |
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, the found tortoises, the tortoise plan and the tortoise total |
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 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.
QuestGiverComponentrecords 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 throughDialogueComponent. -
Tortoises. The game hides between 3 and 12 tortoises, rolled once per new game by
TortoisePlanner.MainGameScreengives that total toTortoiseLedger.setTotal(n)andTortoiseComponentcallsrecordFound(id)when the player touches one. Where they are, how enemies carry them and how they are saved is on the Tortoise System page.
| Change | Detail | Ticket |
|---|---|---|
| Respawn crash | the game crashed when the player respawned after a death; fixed with tests | #346, PR #357 |
killzeus terminal command |
kills Zeus when he is alive in the current room, so the win flow can be tested without playing the whole game; any argument makes it fail without killing anything | #346, PR #357 |
| Random tortoises | the single fixed tortoise became a planned set of 3 to 12 per game, carried by easy enemies, and Zeus drops one | #402 |
| Tortoise save and load | a tortoise found without saving can be found again after a load | #347, PR #377 |
| Win code clean-up | SonarCloud issues in the win package |
#345 |
| Victory screen layout | the win screen was covered by the shop button and inventory panel | #348 |
The win package now has 139 test methods in 11 classes (it had fewer at the end of Sprint 3), and the tortoise classes have 97 more, described on Tortoise System.
Class diagram of the win package: WinEvaluator, WinResult, WinTier, WinCountdown, BossRoster, BossDefeatedWinComponent and the two ledgers.

What happens from the moment Zeus dies to the win screen showing. Zeus announces finalBossDefeated once, LevelGameArea remembers it, MainGameScreen waits for WinCountdown (2.5 seconds), then WinEvaluator.evaluateNow(true) reads the enemy registry, the quest ledger and the tortoise ledger and returns a WinResult for WinScreenDisplay.
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.
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
-
isAtLeastcompares tiers by level - A tier can be found by its level, and a level outside 0 to 3 is rejected
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
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
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
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
-
isFullyCompleteandisTortoiseChampionreport correctly
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
-
evaluateNowreads the kills, quests and tortoises from the live registries
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
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
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
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
Tests were used to ensure the following situations were working:
- The static holder classes cannot be instantiated
Tests were used to ensure the following situations were working:
- The command succeeds when the final boss was killed
- The command fails when the final boss is not in the room
- Any argument is rejected and nothing is killed
- The command asks for the kill once each time it runs
The tortoise planner, assigner, drop component, factory, component, registry and plan have their own tests, described on the Tortoise System page.
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.
- Type
killzeusin the terminal in Level 3 and the win screen appears after about 2.5 seconds. Type it anywhere else and nothing is killed. - Die and respawn, and the game keeps running.
- Start two new games and check the "Tortoises found: x of y" total can differ.
- Find a tortoise, save, reload, and the count is kept. Find one without saving, reload, and it can be found again.