[Dev] Add isApp & build:app for AdmiralBilly's offline app (#6632)

- Consolidate `isBeta`/etc into `src/constants/app-constants.ts`

- Rename `isLocal` to `isDev`

- Replace `import.meta.env.DEV` with `isBeta || isDev`
This commit is contained in:
NightKev 2025-10-06 18:51:33 -07:00 committed by GitHub
parent b25c3b082a
commit b76ecf55fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 82 additions and 97 deletions

8
.env.app Normal file
View File

@ -0,0 +1,8 @@
VITE_BYPASS_LOGIN=1
VITE_BYPASS_TUTORIAL=0
VITE_SERVER_URL=http://localhost:8001
# IDs for discord/google auth go unused due to VITE_BYPASS_LOGIN
VITE_DISCORD_CLIENT_ID=1234567890
VITE_GOOGLE_CLIENT_ID=1234567890
VITE_I18N_DEBUG=0
VITE_PORT=8000

View File

@ -11,6 +11,7 @@
"build": "vite build && node scripts/sync-dist-assets.js",
"build:beta": "vite build --mode beta && node scripts/sync-dist-assets.js",
"build:dev": "vite build --mode development && node scripts/sync-dist-assets.js",
"build:app": "vite build --mode app && node scripts/sync-dist-assets.js",
"preview": "vite preview",
"test": "vitest run --no-isolate",
"test:cov": "vitest run --coverage --no-isolate",

View File

@ -1,5 +1,5 @@
import { pokerogueApi } from "#api/pokerogue-api";
import { bypassLogin } from "#app/global-vars/bypass-login";
import { bypassLogin } from "#constants/app-constants";
import type { UserInfo } from "#types/user-info";
import { randomString } from "#utils/common";

View File

@ -21,6 +21,7 @@ import {
ULTRA_TM_MOVESET_WEIGHT,
} from "#balance/moveset-generation";
import { speciesTmMoves, tmPoolTiers } from "#balance/tms";
import { isBeta, isDev } from "#constants/app-constants";
import { allMoves } from "#data/data-lists";
import { ModifierTier } from "#enums/modifier-tier";
import { MoveCategory } from "#enums/move-category";
@ -632,7 +633,7 @@ function fillInRemainingMovesetSlots(
* @param note - Short note to include in the log for context
*/
function debugMoveWeights(pokemon: Pokemon, pool: Map<MoveId, number>, note: string): void {
if (import.meta.env.DEV && import.meta.env.NODE_ENV !== "test") {
if ((isBeta || isDev) && import.meta.env.NODE_ENV !== "test") {
const moveNameToWeightMap = new Map<string, number>();
const sortedByValue = Array.from(pool.entries()).sort((a, b) => b[1] - a[1]);
for (const [moveId, weight] of sortedByValue) {

View File

@ -1,4 +1,5 @@
import { globalScene } from "#app/global-scene";
import { isBeta, isDev } from "#constants/app-constants";
import type { PokemonSpecies } from "#data/pokemon-species";
import { getTypeDamageMultiplier } from "#data/type";
import { AbilityId } from "#enums/ability-id";
@ -278,7 +279,7 @@ export function getRandomRivalPartyMemberFunc(
): (level: number, strength: PartyMemberStrength) => EnemyPokemon {
// Protect against out of range slots.
// Only care about this in dev to be caught during development; it will be excluded in production builds.
if (import.meta.env.DEV && slot > config.length) {
if ((isBeta || isDev) && slot > config.length) {
throw new Error(`Slot ${slot} is out of range for the provided config of length ${config.length}`);
}
return (level: number, _strength: PartyMemberStrength) => {

View File

@ -0,0 +1,18 @@
/**
* `true` if running in "development" mode which happens when:
* - The build mode is "development" (`pnpm build:dev` which runs `vite build --mode development`) or
* - The Vite server is started via `pnpm start:dev` (which runs `vite --mode development`)
*/
export const isDev = import.meta.env.MODE === "development";
/**
* `true` if running in "beta" mode which happens when:
* - The build mode is "beta" (`pnpm build:beta` which runs `vite build --mode beta`) or
* - The Vite server is started via `pnpm start:beta` (which runs `vite --mode beta`)
*/
export const isBeta = import.meta.env.MODE === "beta";
/** `true` if running via "app" mode (`pnpm build:app` which runs `vite build --mode app`) */
export const isApp = import.meta.env.MODE === "app";
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";

View File

@ -1 +0,0 @@
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";

View File

@ -3,6 +3,7 @@ import "#app/polyfills";
import { InvertPostFX } from "#app/pipelines/invert";
import { initI18n } from "#app/plugins/i18n";
import { isBeta, isDev } from "#constants/app-constants";
import { version } from "#package.json";
import Phaser from "phaser";
import BBCodeTextPlugin from "phaser3-rex-plugins/plugins/bbcodetext-plugin";
@ -10,7 +11,7 @@ import InputTextPlugin from "phaser3-rex-plugins/plugins/inputtext-plugin";
import TransitionImagePackPlugin from "phaser3-rex-plugins/templates/transitionimagepack/transitionimagepack-plugin";
import UIPlugin from "phaser3-rex-plugins/templates/ui/ui-plugin";
if (import.meta.env.DEV) {
if (isBeta || isDev) {
document.title += " (Beta)";
}
@ -59,9 +60,9 @@ Phaser.GameObjects.Text.prototype.setPositionRelative = setPositionRelative;
Phaser.GameObjects.Rectangle.prototype.setPositionRelative = setPositionRelative;
document.fonts.load("16px emerald").then(() => document.fonts.load("10px pkmnems"));
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
// biome-ignore lint: TODO
let game;
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
// biome-ignore lint: TODO
let manifest;
const startGame = async () => {

View File

@ -2,6 +2,7 @@ import { pokerogueApi } from "#api/pokerogue-api";
import { clientSessionId } from "#app/account";
import { globalScene } from "#app/global-scene";
import { pokemonEvolutions } from "#balance/pokemon-evolutions";
import { bypassLogin } from "#constants/app-constants";
import { modifierTypes } from "#data/data-lists";
import { getCharVariantFromDialogue } from "#data/dialogue";
import type { PokemonSpecies } from "#data/pokemon-species";
@ -24,7 +25,7 @@ import { TrainerData } from "#system/trainer-data";
import { trainerConfigs } from "#trainers/trainer-config";
import type { SessionSaveData } from "#types/save-data";
import { checkSpeciesValidForChallenge, isNuzlockeChallenge } from "#utils/challenge-utils";
import { isLocal, isLocalServerConnected } from "#utils/common";
import { isLocalServerConnected } from "#utils/common";
import { getPokemonSpecies } from "#utils/pokemon-utils";
import i18next from "i18next";
@ -247,10 +248,9 @@ export class GameOverPhase extends BattlePhase {
});
};
/* Added a local check to see if the game is running offline
If Online, execute apiFetch as intended
If Offline, execute offlineNewClear() only for victory, a localStorage implementation of newClear daily run checks */
if (!isLocal || isLocalServerConnected) {
// If Online, execute apiFetch as intended
// If Offline, execute offlineNewClear() only for victory, a localStorage implementation of newClear daily run checks
if (!bypassLogin || isLocalServerConnected) {
pokerogueApi.savedata.session
.newclear({
slot: globalScene.sessionSlotId,

View File

@ -1,8 +1,8 @@
import { updateUserInfo } from "#app/account";
import { globalScene } from "#app/global-scene";
import { bypassLogin } from "#app/global-vars/bypass-login";
import { Phase } from "#app/phase";
import { handleTutorial, Tutorial } from "#app/tutorial";
import { bypassLogin } from "#constants/app-constants";
import { UiMode } from "#enums/ui-mode";
import { executeIf, sessionIdKey } from "#utils/common";
import { getCookie, removeCookie } from "#utils/cookies";

View File

@ -3,6 +3,7 @@ import { GameMode, getGameMode } from "#app/game-mode";
import { globalScene } from "#app/global-scene";
import Overrides from "#app/overrides";
import { Phase } from "#app/phase";
import { bypassLogin } from "#constants/app-constants";
import { fetchDailyRunSeed, getDailyRunStarters } from "#data/daily-run";
import { modifierTypes } from "#data/data-lists";
import { Gender } from "#data/gender";
@ -18,7 +19,7 @@ import { vouchers } from "#system/voucher";
import type { SessionSaveData } from "#types/save-data";
import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
import { SaveSlotUiMode } from "#ui/save-slot-select-ui-handler";
import { isLocal, isLocalServerConnected } from "#utils/common";
import { isLocalServerConnected } from "#utils/common";
import { getPokemonSpecies } from "#utils/pokemon-utils";
import i18next from "i18next";
@ -271,7 +272,7 @@ export class TitlePhase extends Phase {
};
// If Online, calls seed fetch from db to generate daily run. If Offline, generates a daily run based on current date.
if (!isLocal || isLocalServerConnected) {
if (!bypassLogin || isLocalServerConnected) {
fetchDailyRunSeed()
.then(seed => {
if (seed) {

View File

@ -3,12 +3,12 @@ import { clientSessionId, loggedInUser, updateUserInfo } from "#app/account";
import { defaultStarterSpecies, saveKey } from "#app/constants";
import { getGameMode } from "#app/game-mode";
import { globalScene } from "#app/global-scene";
import { bypassLogin } from "#app/global-vars/bypass-login";
import Overrides from "#app/overrides";
import { Tutorial } from "#app/tutorial";
import { speciesEggMoves } from "#balance/egg-moves";
import { pokemonPrevolutions } from "#balance/pokemon-evolutions";
import { speciesStarterCosts } from "#balance/starters";
import { bypassLogin, isBeta, isDev } from "#constants/app-constants";
import { EntryHazardTag } from "#data/arena-tag";
import { allMoves, allSpecies } from "#data/data-lists";
import type { Egg } from "#data/egg";
@ -74,7 +74,7 @@ import type {
} from "#types/save-data";
import { RUN_HISTORY_LIMIT } from "#ui/run-history-ui-handler";
import { applyChallenges } from "#utils/challenge-utils";
import { executeIf, fixedInt, isLocal, NumberHolder, randInt, randSeedItem } from "#utils/common";
import { executeIf, fixedInt, NumberHolder, randInt, randSeedItem } from "#utils/common";
import { decrypt, encrypt } from "#utils/data";
import { getEnumKeys } from "#utils/enums";
import { getPokemonSpecies } from "#utils/pokemon-utils";
@ -413,7 +413,7 @@ export class GameData {
}
}
if (import.meta.env.DEV) {
if (isBeta || isDev) {
try {
console.debug(
GameData.parseSystemData(
@ -446,36 +446,8 @@ export class GameData {
* Retrieves current run history data, organized by time stamp.
* At the moment, only retrievable from locale cache
*/
// TODO: save run history data to server?
async getRunHistoryData(): Promise<RunHistoryData> {
if (!isLocal) {
/**
* Networking Code DO NOT DELETE!
* Note: Might have to be migrated to `pokerogue-api.ts`
*
const response = await Utils.apiFetch("savedata/runHistory", true);
const data = await response.json();
*/
const lsItemKey = `runHistoryData_${loggedInUser?.username}`;
const lsItem = localStorage.getItem(lsItemKey);
if (lsItem) {
const cachedResponse = lsItem;
if (cachedResponse) {
const runHistory = JSON.parse(decrypt(cachedResponse, bypassLogin));
return runHistory;
}
return {};
// check to see whether cachedData or serverData is more up-to-date
/**
* Networking Code DO NOT DELETE!
*
if ( Object.keys(cachedRHData).length >= Object.keys(data).length ) {
return cachedRHData;
}
*/
}
localStorage.setItem(`runHistoryData_${loggedInUser?.username}`, "");
return {};
}
const lsItemKey = `runHistoryData_${loggedInUser?.username}`;
const lsItem = localStorage.getItem(lsItemKey);
if (lsItem) {
@ -496,6 +468,7 @@ export class GameData {
* @param isVictory: result of the run
* Arbitrary limit of 25 runs per player - Will delete runs, starting with the oldest one, if needed
*/
// TODO: save run history data to server?
async saveRunHistory(runEntry: SessionSaveData, isVictory: boolean): Promise<boolean> {
const runHistoryData = await this.getRunHistoryData();
// runHistoryData should always return run history or {} empty object
@ -518,20 +491,6 @@ export class GameData {
`runHistoryData_${loggedInUser?.username}`,
encrypt(JSON.stringify(runHistoryData), bypassLogin),
);
/**
* Networking Code DO NOT DELETE
*
if (!Utils.isLocal) {
try {
await Utils.apiPost("savedata/runHistory", JSON.stringify(runHistoryData), undefined, true);
return true;
} catch (err) {
console.log("savedata/runHistory POST failed : ", err);
return false;
}
}
NOTE: should be adopted to `pokerogue-api.ts`
*/
return true;
}
@ -954,7 +913,7 @@ export class GameData {
const { promise, resolve, reject } = Promise.withResolvers<boolean>();
try {
const initSessionFromData = (fromSession: SessionSaveData) => {
if (import.meta.env.DEV) {
if (isBeta || isDev) {
try {
console.debug(
this.parseSessionData(

View File

@ -1,5 +1,6 @@
import { globalScene } from "#app/global-scene";
import { hasTouchscreen } from "#app/touch-controls";
import { isDev } from "#constants/app-constants";
import { EaseType } from "#enums/ease-type";
import { MoneyFormat } from "#enums/money-format";
import { PlayerGender } from "#enums/player-gender";
@ -7,7 +8,6 @@ import { ShopCursorTarget } from "#enums/shop-cursor-target";
import { UiMode } from "#enums/ui-mode";
import { CandyUpgradeNotificationChangedEvent } from "#events/battle-scene";
import { updateWindowType } from "#ui/ui-theme";
import { isLocal } from "#utils/common";
import i18next from "i18next";
import { languageOptions } from "./settings-language";
@ -716,7 +716,7 @@ export const Setting: Array<Setting> = [
},
];
if (isLocal) {
if (isDev) {
Setting.push({
key: SettingKeys.Dex_For_Devs,
label: i18next.t("settings:dexForDevs"),

View File

@ -1,6 +1,6 @@
import { pokerogueApi } from "#api/pokerogue-api";
import { globalScene } from "#app/global-scene";
import { bypassLogin } from "#app/global-vars/bypass-login";
import { bypassLogin } from "#constants/app-constants";
import { AdminMode } from "#enums/admin-mode";
import { Button } from "#enums/buttons";
import { TextStyle } from "#enums/text-style";

View File

@ -1,8 +1,8 @@
import { pokerogueApi } from "#api/pokerogue-api";
import { loggedInUser, updateUserInfo } from "#app/account";
import { globalScene } from "#app/global-scene";
import { bypassLogin } from "#app/global-vars/bypass-login";
import { handleTutorial, Tutorial } from "#app/tutorial";
import { bypassLogin, isApp, isBeta, isDev } from "#constants/app-constants";
import { AdminMode, getAdminModeName } from "#enums/admin-mode";
import { Button } from "#enums/buttons";
import { GameDataType } from "#enums/game-data-type";
@ -237,7 +237,7 @@ export class MenuUiHandler extends MessageUiHandler {
});
};
if (import.meta.env.DEV) {
if (isBeta || isDev || isApp) {
manageDataOptions.push({
label: i18next.t("menuUiHandler:importSession"),
handler: () => {
@ -291,7 +291,7 @@ export class MenuUiHandler extends MessageUiHandler {
},
keepOpen: true,
});
if (import.meta.env.DEV) {
if (isBeta || isDev || isApp) {
manageDataOptions.push({
label: i18next.t("menuUiHandler:importData"),
handler: () => {
@ -338,8 +338,7 @@ export class MenuUiHandler extends MessageUiHandler {
keepOpen: true,
},
);
if (import.meta.env.DEV) {
// this should make sure we don't have this option in live
if (isBeta || isDev) {
manageDataOptions.push({
label: "Test Dialogue",
handler: () => {

View File

@ -1,5 +1,6 @@
import { GameMode } from "#app/game-mode";
import { globalScene } from "#app/global-scene";
import { isBeta, isDev } from "#constants/app-constants";
import { Button } from "#enums/buttons";
import { GameModes } from "#enums/game-modes";
import { TextStyle } from "#enums/text-style";
@ -202,7 +203,7 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
false,
0,
19,
import.meta.env.DEV ? 300 : 2000,
isBeta || isDev ? 300 : 2000,
);
});
return true;
@ -251,7 +252,7 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
false,
0,
19,
import.meta.env.DEV ? 300 : 2000,
isBeta || isDev ? 300 : 2000,
);
});
} else if (this.sessionSlots[cursor].hasData === false) {

View File

@ -3,6 +3,7 @@ import { FAKE_TITLE_LOGO_CHANCE } from "#app/constants";
import { timedEventManager } from "#app/global-event-manager";
import { globalScene } from "#app/global-scene";
import { TimedEventDisplay } from "#app/timed-event-manager";
import { isBeta, isDev } from "#constants/app-constants";
import { getSplashMessages } from "#data/splash-messages";
import { PlayerGender } from "#enums/player-gender";
import type { SpeciesId } from "#enums/species-id";
@ -141,7 +142,7 @@ export class TitleUiHandler extends OptionSelectUiHandler {
}),
);
const betaText = import.meta.env.DEV ? " (Beta)" : "";
const betaText = isBeta || isDev ? " (Beta)" : "";
this.appVersionText.setText("v" + version + betaText);
const ui = this.getUi();

View File

@ -1,4 +1,5 @@
import { pokerogueApi } from "#api/pokerogue-api";
import { bypassLogin, isDev } from "#constants/app-constants";
import { BiomeId } from "#enums/biome-id";
import { MoneyFormat } from "#enums/money-format";
import type { Variant } from "#sprites/variant";
@ -269,11 +270,8 @@ export function executeIf<T>(condition: boolean, promiseFunc: () => Promise<T>):
export const sessionIdKey = "pokerogue_sessionId";
/** `true` when run via `pnpm start:dev` (which runs `vite --mode development`) */
export const isLocal = import.meta.env.MODE === "development";
/** Used to disable api calls when isLocal is true and a server is not found */
export let isLocalServerConnected = true;
/** Used to disable api calls when `isDev` is true and a server is not found */
export let isLocalServerConnected = !bypassLogin;
/**
* When locally running the game, "pings" the local server
@ -281,7 +279,7 @@ export let isLocalServerConnected = true;
* sets isLocalServerConnected based on results
*/
export async function localPing(): Promise<void> {
if (isLocal) {
if (isDev) {
const titleStats = await pokerogueApi.getGameTitleStats();
isLocalServerConnected = !!titleStats;
console.log("isLocalServerConnected:", isLocalServerConnected);

View File

@ -1,4 +1,4 @@
import { isBeta } from "#utils/utility-vars";
import { isBeta } from "#constants/app-constants";
export function setCookie(cName: string, cValue: string): void {
const expiration = new Date();

View File

@ -1,4 +0,0 @@
// TODO: move this (and other global constants) to `src/constants/*-constants.ts`
/** `true` if running on `beta.pokerogue.net` or via `pnpm start:beta` (which runs `vite --mode beta`) */
export const isBeta = import.meta.env.MODE === "beta";

View File

@ -1,6 +1,6 @@
import { pokerogueApi } from "#api/pokerogue-api";
import { initLoggedInUser, loggedInUser, updateUserInfo } from "#app/account";
import * as bypassLogin from "#app/global-vars/bypass-login";
import * as appConstants from "#constants/app-constants";
import { describe, expect, it, vi } from "vitest";
describe("account", () => {
@ -15,7 +15,7 @@ describe("account", () => {
describe("updateUserInfo", () => {
it("should set loggedInUser! to Guest if bypassLogin is true", async () => {
vi.spyOn(bypassLogin, "bypassLogin", "get").mockReturnValue(true);
vi.spyOn(appConstants, "bypassLogin", "get").mockReturnValue(true);
const [success, status] = await updateUserInfo();
@ -26,7 +26,7 @@ describe("account", () => {
});
it("should fetch user info from the API if bypassLogin is false", async () => {
vi.spyOn(bypassLogin, "bypassLogin", "get").mockReturnValue(false);
vi.spyOn(appConstants, "bypassLogin", "get").mockReturnValue(false);
vi.spyOn(pokerogueApi.account, "getInfo").mockResolvedValue([
{
username: "test",
@ -47,7 +47,7 @@ describe("account", () => {
});
it("should handle resolved API errors", async () => {
vi.spyOn(bypassLogin, "bypassLogin", "get").mockReturnValue(false);
vi.spyOn(appConstants, "bypassLogin", "get").mockReturnValue(false);
vi.spyOn(pokerogueApi.account, "getInfo").mockResolvedValue([null, 401]);
const [success, status] = await updateUserInfo();
@ -57,7 +57,7 @@ describe("account", () => {
});
it("should handle 500 API errors", async () => {
vi.spyOn(bypassLogin, "bypassLogin", "get").mockReturnValue(false);
vi.spyOn(appConstants, "bypassLogin", "get").mockReturnValue(false);
vi.spyOn(pokerogueApi.account, "getInfo").mockResolvedValue([null, 500]);
const [success, status] = await updateUserInfo();

View File

@ -1,6 +1,6 @@
import { pokerogueApi } from "#api/pokerogue-api";
import * as account from "#app/account";
import * as bypassLoginModule from "#app/global-vars/bypass-login";
import * as appConstants from "#constants/app-constants";
import { AbilityId } from "#enums/ability-id";
import { MoveId } from "#enums/move-id";
import { GameManager } from "#test/test-utils/game-manager";
@ -33,13 +33,13 @@ describe("System - Game Data", () => {
describe("tryClearSession", () => {
beforeEach(() => {
vi.spyOn(bypassLoginModule, "bypassLogin", "get").mockReturnValue(false);
vi.spyOn(appConstants, "bypassLogin", "get").mockReturnValue(false);
vi.spyOn(game.scene.gameData, "getSessionSaveData").mockReturnValue({} as SessionSaveData);
vi.spyOn(account, "updateUserInfo").mockImplementation(async () => [true, 1]);
});
it("should return [true, true] if bypassLogin is true", async () => {
vi.spyOn(bypassLoginModule, "bypassLogin", "get").mockReturnValue(true);
vi.spyOn(appConstants, "bypassLogin", "get").mockReturnValue(true);
const result = await game.scene.gameData.tryClearSession(0);

View File

@ -1,6 +1,6 @@
import * as account from "#app/account";
import * as bypassLoginModule from "#app/global-vars/bypass-login";
import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
import * as appConstants from "#constants/app-constants";
import { AbilityId } from "#enums/ability-id";
import { MoveId } from "#enums/move-id";
import { GameManager } from "#test/test-utils/game-manager";
@ -33,7 +33,7 @@ describe("System - Rename Run", () => {
describe("renameSession", () => {
beforeEach(() => {
vi.spyOn(bypassLoginModule, "bypassLogin", "get").mockReturnValue(false);
vi.spyOn(appConstants, "bypassLogin", "get").mockReturnValue(false);
vi.spyOn(account, "updateUserInfo").mockImplementation(async () => [true, 1]);
});
@ -52,7 +52,7 @@ describe("System - Rename Run", () => {
});
it("should return true if bypassLogin is true", async () => {
vi.spyOn(bypassLoginModule, "bypassLogin", "get").mockReturnValue(true);
vi.spyOn(appConstants, "bypassLogin", "get").mockReturnValue(true);
vi.spyOn(game.scene.gameData, "getSession").mockResolvedValue({} as SessionSaveData);
const result = await game.scene.gameData.renameSession(0, "Named Run");

View File

@ -2,7 +2,7 @@
import { BattleScene } from "#app/battle-scene";
// biome-ignore lint/performance/noNamespaceImport: Necessary in order to mock the var
import * as bypassLoginModule from "#app/global-vars/bypass-login";
import * as appConstants from "#constants/app-constants";
import { MoveAnim } from "#data/battle-anims";
import { Pokemon } from "#field/pokemon";
import { version } from "#package.json";
@ -32,7 +32,7 @@ export class GameWrapper {
Phaser.Math.RND.sow(["test"]);
// vi.spyOn(Utils, "apiFetch", "get").mockReturnValue(fetch);
if (bypassLogin) {
vi.spyOn(bypassLoginModule, "bypassLogin", "get").mockReturnValue(true);
vi.spyOn(appConstants, "bypassLogin", "get").mockReturnValue(true);
}
this.game = phaserGame;
MoveAnim.prototype.getAnim = () => ({

View File

@ -32,6 +32,7 @@
"#abilities/*": ["./src/data/abilities/*.ts"],
"#api/*": ["./src/plugins/api/*.ts"],
"#balance/*": ["./src/data/balance/*.ts"],
"#constants/*": ["./src/constants/*.ts"],
"#enums/*": ["./src/enums/*.ts"],
"#events/*": ["./src/events/*.ts"],
"#field/*": ["./src/field/*.ts"],