`feat(level-select): open on the player's current campaign by default`

Instead of always starting at campaign 1 (index 0), `LevelSelectScene` now initializes to the campaign containing the first uncleared level in game order, so re-entering the map lands you where you left off. Falls back to campaign 1 if everything is cleared; empty campaigns are skipped since they can't hold the current level.
This commit is contained in:
Brian Fertig 2026-08-23 17:14:09 -06:00
parent c17c0cf7e8
commit 3033c1d62d
1 changed files with 13 additions and 1 deletions

View File

@ -61,7 +61,7 @@ export default class LevelSelectScene extends Phaser.Scene {
// shown; it handles first-time start, campaign-to-campaign swaps, and
// re-entry from the main menu alike.
this.campaignIndex = 0;
this.campaignIndex = this._defaultCampaignIndex();
this._groups = { bg: [], path: [], nodes: [], tags: [] };
this._transitioning = false;
this._pulseTween = null;
@ -108,6 +108,18 @@ export default class LevelSelectScene extends Phaser.Scene {
// ------------------------------------------------------------------ build
// Enter on the campaign the player is currently on: the one containing the
// first uncleared level in game order (levels unlock strictly in that order,
// so the campaign holding it is always a campaign that is unlocked). If
// everything is cleared, fall back to campaign 1 (index 0). An empty
// campaign can't hold the current level, so it's skipped.
_defaultCampaignIndex() {
for (let i = 0; i < CAMPAIGNS.length; i++) {
if (CAMPAIGNS[i].levels.some((l) => !isLevelComplete(l.id))) return i;
}
return 0;
}
_buildCampaign(instant = false) {
for (const key of Object.keys(this._groups)) {
for (const obj of this._groups[key]) obj.destroy();