From 3033c1d62dd11f3b5f22056dff6f47c4e0f49edb Mon Sep 17 00:00:00 2001 From: Brian Fertig Date: Sun, 23 Aug 2026 17:14:09 -0600 Subject: [PATCH] `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. --- src/scenes/LevelSelectScene.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/scenes/LevelSelectScene.js b/src/scenes/LevelSelectScene.js index 7fcd7b5..fd534dc 100644 --- a/src/scenes/LevelSelectScene.js +++ b/src/scenes/LevelSelectScene.js @@ -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();