Skip to content

Commit 11d4a1c

Browse files
committed
Update handling of dev and beta modes
- Replace the `start` command in `package.json` with `start:prod` and `start:beta`, which run the game in "production" and "beta" mode respectively Previously, `start` would run the game in "development" mode just like `start:dev` due to the `vite` command running in "development" mode by default if no `--mode` arg was passed - Add `IS_DEV` global constant that checks for "development" mode - Remove `Api#isLocal` and replace its uses with `BYPASS_LOGIN` - Add " (Beta)" to window title and game version displayed on the title screen when in "development" or "beta" mode - Replace `.then()` pattern with `await` in `main.ts` - Remove obsolete commented code in `game-data.ts`
1 parent 600f996 commit 11d4a1c

File tree

10 files changed

+55
-99
lines changed

10 files changed

+55
-99
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"version": "0.1.0",
55
"type": "module",
66
"scripts": {
7-
"start": "vite",
7+
"start:prod": "vite --mode production",
8+
"start:beta": "vite --mode beta",
89
"start:dev": "vite --mode development",
910
"build": "vite build",
1011
"build:beta": "vite build --mode beta",

src/constants/app-constants.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,16 @@ export const RUN_HISTORY_LIMIT: number = 25;
6464
/** The number of save slots available to players. */
6565
export const SAVE_SLOT_LIMIT: number = 5;
6666

67-
/** Whether the app is running in beta (or development) mode. */
67+
/**
68+
* `true` if running in "beta" mode via either of:
69+
* - `pnpm start:beta` (which runs `vite --mode beta`)
70+
* - A build created via `pnpm build:beta`
71+
*/
6872
export const IS_BETA = import.meta.env.MODE === "beta";
73+
74+
/**
75+
* `true` if running in "development" mode via either of:
76+
* - `pnpm start:dev` (which runs `vite --mode development`)
77+
* - A build created via `pnpm build:dev`
78+
*/
79+
export const IS_DEV = import.meta.env.MODE === "development";

src/main.ts

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import "#app/polyfills"; // polyfills must be first
22
import "#app/phaser-extensions";
33

4-
// Catch global errors and display them in an alert so users can report the issue.
4+
import { IS_BETA, IS_DEV } from "#constants/app-constants";
5+
6+
if (IS_DEV || IS_BETA) {
7+
document.title += " (Beta)";
8+
}
9+
510
window.onerror = (_message, _source, _lineno, _colno, error) => {
611
console.error(error);
7-
// const errorString = `Received unhandled error. Open browser console and click OK to see details.\nError: ${message}\nSource: ${source}\nLine: ${lineno}\nColumn: ${colno}\nStack: ${error.stack}`;
8-
//alert(errorString);
912
// Avoids logging the error a second time.
1013
return true;
1114
};
1215

13-
// Catch global promise rejections and display them in an alert so users can report the issue.
1416
window.addEventListener("unhandledrejection", (event) => {
15-
// const errorString = `Received unhandled promise rejection. Open browser console and click OK to see details.\nReason: ${event.reason}`;
1617
console.error(event.reason);
17-
//alert(errorString);
1818
});
1919

2020
document.fonts.load("16px emerald").then(() => document.fonts.load("10px pkmnems"));
@@ -36,17 +36,14 @@ const startGame = async (manifest?: any) => {
3636
}
3737
};
3838

39-
fetch("/manifest.json")
40-
.then((res) => res.json())
41-
.then((jsonResponse) => {
42-
startGame(jsonResponse.manifest);
43-
})
44-
.catch(() => {
45-
// Manifest not found (likely local build)
46-
startGame();
47-
})
48-
.finally(() => {
49-
if (import.meta.env.MODE === "development") {
50-
import("./dev");
51-
}
52-
});
39+
try {
40+
const json = await (await fetch("/manifest.json")).json();
41+
await startGame(json.manifest);
42+
} catch {
43+
// The manifest wasn't found, likely due to running locally
44+
await startGame();
45+
}
46+
47+
if (IS_DEV) {
48+
await import("./dev");
49+
}

src/phases/game-over-phase.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { api } from "#api/api";
22
import { clientSessionId } from "#app/account";
33
import { globalScene } from "#app/global-scene";
4+
import { BYPASS_LOGIN } from "#constants/app-constants";
45
import { getCharVariantFromDialogue } from "#data/dialogue";
56
import type { PokemonSpecies } from "#data/pokemon-species";
67
import { AchvCategory } from "#enums/achv-category";
@@ -200,12 +201,9 @@ export class GameOverPhase extends BattlePhase {
200201
});
201202
};
202203

203-
/**
204-
* Check to see if the game is running offline
205-
* If Online, execute apiFetch as intended
206-
* If Offline, execute offlineNewClear() only for victory, a localStorage implementation of newClear daily run checks
207-
*/
208-
if (!api.isLocal || api.isConnected) {
204+
// If Online, execute `apiFetch` as intended
205+
// If Offline, execute `offlineNewClear()` only for victory, a localStorage implementation of `newClear` daily run checks
206+
if (!BYPASS_LOGIN || api.isConnected) {
209207
api.savedata.session
210208
.newclear({ slot: globalScene.sessionSlotId, isVictory: this.isVictory, clientSessionId })
211209
.then((success) => doGameOver(success));

src/phases/title-phase.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { loggedInUser } from "#app/account";
33
import { getGameMode, getModeName } from "#app/game-mode";
44
import { globalScene } from "#app/global-scene";
55
import { Phase } from "#app/phase";
6+
import { BYPASS_LOGIN } from "#constants/app-constants";
67
import { fetchDailyRunSeed, getDailyRunStarters } from "#data/daily-run";
78
import { GameModes } from "#enums/game-modes";
89
import { ModifierPoolType } from "#enums/modifier-pool-type";
@@ -247,8 +248,9 @@ export class TitlePhase extends Phase {
247248
});
248249
};
249250

250-
// If Online, calls seed fetch from db to generate daily run. If Offline, generates a daily run based on current date.
251-
if (!api.isLocal || api.isConnected) {
251+
// If Online, calls seed fetch from db to generate daily run.
252+
// If Offline, generates a daily run based on current date.
253+
if (!BYPASS_LOGIN || api.isConnected) {
252254
fetchDailyRunSeed()
253255
.then((seed) => {
254256
if (seed) {

src/plugins/api/api.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ class Api extends ApiBase {
1818
public readonly admin: AdminApi;
1919
public readonly savedata: SavedataApi;
2020

21-
/** Wheter the hostname is 'localhost' or an IP address, and ensure a port is specified. */
22-
private readonly _isLocal: boolean;
2321
/** Whether the server/api is connected. By default we assume `true`. */
2422
private _isConnected: boolean;
2523

@@ -31,22 +29,13 @@ class Api extends ApiBase {
3129
this.daily = new DailyApi(base);
3230
this.admin = new AdminApi(base);
3331
this.savedata = new SavedataApi(base);
34-
this._isLocal =
35-
((window.location.hostname === "localhost" || /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/.test(window.location.hostname))
36-
&& window.location.port !== "")
37-
|| window.location.hostname === "";
3832
}
3933

4034
/** Whether the server/api is connected. By default we assume `true`. */
4135
public get isConnected() {
4236
return this._isConnected;
4337
}
4438

45-
/** Wheter the hostname is 'localhost' or an IP address, and ensure a port is specified. */
46-
public get isLocal() {
47-
return this._isLocal;
48-
}
49-
5039
/**
5140
* Request game title-stats.
5241
*/
@@ -129,7 +118,7 @@ class Api extends ApiBase {
129118
}
130119
}
131120
if (import.meta.env.VITE_API_DEBUG === "1") {
132-
console.log("isLocalServerConnected:", this.isConnected);
121+
console.log("`Api#isConnected`:", this.isConnected);
133122
}
134123
}
135124

src/system/game-data.ts

Lines changed: 6 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ import { randInt } from "#utils/random-utils";
8888
import { AES, enc } from "crypto-js";
8989
import i18next from "i18next";
9090

91-
const saveKey = "x0i2O7WRiANTqPmZ"; // Temporary; secure encryption is not yet necessary
91+
const saveKey = "x0i2O7WRiANTqPmZ";
9292

9393
function encrypt(data: string, bypassLogin: boolean): string {
9494
if (bypassLogin) {
@@ -415,42 +415,12 @@ export class GameData {
415415
* At the moment, only retrievable from locale cache
416416
*/
417417
async getRunHistoryData(): Promise<RunHistoryData> {
418-
if (!api.isLocal) {
419-
/**
420-
* Networking Code DO NOT DELETE!
421-
* Note: Might have to be migrated to `api.ts`
422-
*
423-
const response = await Utils.apiFetch("savedata/runHistory", true);
424-
const data = await response.json();
425-
*/
426-
const lsItemKey = getLocalStorageKey(GameDataType.RUN_HISTORY);
427-
const lsItem = localStorage.getItem(lsItemKey);
428-
if (lsItem) {
429-
const cachedResponse = lsItem;
430-
if (cachedResponse) {
431-
const runHistory = JSON.parse(decrypt(cachedResponse, BYPASS_LOGIN));
432-
return runHistory;
433-
}
434-
return {};
435-
// check to see whether cachedData or serverData is more up-to-date
436-
/**
437-
* Networking Code DO NOT DELETE!
438-
*
439-
if ( Object.keys(cachedRHData).length >= Object.keys(data).length ) {
440-
return cachedRHData;
441-
}
442-
*/
443-
}
444-
localStorage.setItem(lsItemKey, "");
445-
return {};
446-
}
447418
const lsItemKey = getLocalStorageKey(GameDataType.RUN_HISTORY);
448419
const lsItem = localStorage.getItem(lsItemKey);
449420
if (lsItem) {
450421
const cachedResponse = lsItem;
451422
if (cachedResponse) {
452-
const runHistory: RunHistoryData = JSON.parse(decrypt(cachedResponse, BYPASS_LOGIN));
453-
return runHistory;
423+
return JSON.parse(decrypt(cachedResponse, BYPASS_LOGIN));
454424
}
455425
return {};
456426
}
@@ -460,9 +430,10 @@ export class GameData {
460430

461431
/**
462432
* Saves a new entry to Run History
463-
* @param runEntry: most recent SessionSaveData of the run
464-
* @param isVictory: result of the run
465-
* Arbitrary limit of 25 runs per player - Will delete runs, starting with the oldest one, if needed
433+
* @param runEntry - Most recent SessionSaveData of the run
434+
* @param isVictory - Result of the run
435+
* @remarks
436+
* Currently limited to 25 runs. If a 26th run would be saved, the oldest is deleted.
466437
*/
467438
async saveRunHistory(runEntry: SessionSaveData, isVictory: boolean): Promise<boolean> {
468439
const runHistoryData = await this.getRunHistoryData();
@@ -487,20 +458,6 @@ export class GameData {
487458
getLocalStorageKey(GameDataType.RUN_HISTORY),
488459
encrypt(JSON.stringify(runHistoryData), BYPASS_LOGIN),
489460
);
490-
/**
491-
* Networking Code DO NOT DELETE
492-
*
493-
if (!Utils.isLocal) {
494-
try {
495-
await Utils.apiPost("savedata/runHistory", JSON.stringify(runHistoryData), undefined, true);
496-
return true;
497-
} catch (err) {
498-
console.log("savedata/runHistory POST failed : ", err);
499-
return false;
500-
}
501-
}
502-
NOTE: should be adopted to `api.ts`
503-
*/
504461
return true;
505462
}
506463

src/ui/handlers/menu-ui-handler.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { api } from "#api/api";
22
import { loggedInUser, updateUserInfo } from "#app/account";
33
import { globalScene } from "#app/global-scene";
44
import { handleTutorial } from "#app/tutorial";
5-
import { BYPASS_LOGIN, IS_BETA, SAVE_SLOT_LIMIT, SESSION_ID_COOKIE } from "#constants/app-constants";
5+
import { BYPASS_LOGIN, IS_BETA, IS_DEV, SAVE_SLOT_LIMIT, SESSION_ID_COOKIE } from "#constants/app-constants";
66
import { GAME_HEIGHT, GAME_WIDTH } from "#constants/ui-constants";
77
import { AdminMode } from "#enums/admin-mode";
88
import { Button } from "#enums/button";
@@ -223,7 +223,7 @@ export class MenuUiHandler extends OptionSelectUiHandler {
223223
});
224224
};
225225
// Import Session
226-
if (api.isLocal || IS_BETA) {
226+
if (IS_DEV || IS_BETA) {
227227
manageDataOptions.push({
228228
label: i18next.t("menuUiHandler:importSession"),
229229
handler: () => {
@@ -281,7 +281,7 @@ export class MenuUiHandler extends OptionSelectUiHandler {
281281
keepOpen: true,
282282
});
283283
// Import Data
284-
if (api.isLocal || IS_BETA) {
284+
if (IS_DEV || IS_BETA) {
285285
manageDataOptions.push({
286286
label: i18next.t("menuUiHandler:importData"),
287287
handler: () => {
@@ -320,8 +320,7 @@ export class MenuUiHandler extends OptionSelectUiHandler {
320320
);
321321

322322
// TODO: fully remove test dialogue option and related handlers
323-
if (api.isLocal || IS_BETA) {
324-
// this should make sure we don't have this option in live
323+
if (IS_DEV || IS_BETA) {
325324
manageDataOptions.push({
326325
label: "Test Dialogue",
327326
handler: () => {

src/ui/handlers/save-slot-select-ui-handler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { getModeName } from "#app/game-mode";
22
import { globalScene } from "#app/global-scene";
3-
import { SAVE_SLOT_LIMIT } from "#constants/app-constants";
3+
import { IS_BETA, IS_DEV, SAVE_SLOT_LIMIT } from "#constants/app-constants";
44
import { GAME_HEIGHT, GAME_WIDTH } from "#constants/ui-constants";
55
import { Button } from "#enums/button";
66
import { RunDisplayMode } from "#enums/run-display-mode";
@@ -138,7 +138,7 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
138138
},
139139
canBypassInputDelay: true,
140140
yOffset: 28,
141-
inputDelay: import.meta.env.DEV ? 300 : 2000,
141+
inputDelay: IS_DEV || IS_BETA ? 300 : 2000,
142142
};
143143
ui.showText(i18next.t("saveSlotSelectUiHandler:overwriteData"), {
144144
callback: () => ui.setOverlayMode<ConfirmUiHandler>(UiMode.CONFIRM, overwriteDataOptions),

src/ui/handlers/title-ui-handler.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { api } from "#api/api";
22
import { globalScene } from "#app/global-scene";
33
import { timedEventManager } from "#app/timed-event-manager";
4+
import { IS_BETA, IS_DEV } from "#constants/app-constants";
45
import { GAME_HEIGHT, GAME_WIDTH } from "#constants/ui-constants";
56
import { getSplashMessages } from "#data/splash-messages";
67
import { TextStyle } from "#enums/text-style";
@@ -110,7 +111,8 @@ export class TitleUiHandler extends OptionSelectUiHandler {
110111
this.splashMessage = randItem(getSplashMessages());
111112
this.splashMessageText.setText(i18next.t(this.splashMessage, { count: TitleUiHandler.BATTLES_WON_FALLBACK }));
112113

113-
this.appVersionText.setText("v" + version);
114+
const betaText = IS_DEV || IS_BETA ? " (Beta)" : "";
115+
this.appVersionText.setText("v" + version + betaText);
114116

115117
const ui = this.getUi();
116118

0 commit comments

Comments
 (0)