Merge branch 'beta' into fix-rattled-speed-stat-increase-delay
@ -1,10 +1,21 @@
|
|||||||
/** @type {import('dependency-cruiser').IConfiguration} */
|
/** @type {import('dependency-cruiser').IConfiguration} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
forbidden: [
|
forbidden: [
|
||||||
|
{
|
||||||
|
name: "no-non-type-@type-exports",
|
||||||
|
severity: "error",
|
||||||
|
comment:
|
||||||
|
"Files in @types should not export anything but types and interfaces. The folder is intended to house imports that are removed at runtime, and thus should not contain anything with a bearing on runtime code.",
|
||||||
|
from: {},
|
||||||
|
to: {
|
||||||
|
path: "(^|/)src/@types",
|
||||||
|
dependencyTypesNot: ["type-only"],
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "only-type-imports",
|
name: "only-type-imports",
|
||||||
severity: "error",
|
severity: "error",
|
||||||
comment: "Files in enums and @types may only use type imports.",
|
comment: "Files in 'enums/' and '@types/' must only use type imports.",
|
||||||
from: {
|
from: {
|
||||||
path: ["(^|/)src/@types", "(^|/)src/enums"],
|
path: ["(^|/)src/@types", "(^|/)src/enums"],
|
||||||
},
|
},
|
||||||
@ -14,10 +25,9 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no-circular-at-runtime",
|
name: "no-circular-at-runtime",
|
||||||
severity: "warn",
|
severity: "error",
|
||||||
comment:
|
comment:
|
||||||
"This dependency is part of a circular relationship. You might want to revise " +
|
"This dependency is part of a circular relationship. You might want to revise your solution (i.e. use dependency inversion, make sure the modules have a single responsibility) ",
|
||||||
"your solution (i.e. use dependency inversion, make sure the modules have a single responsibility) ",
|
|
||||||
from: {},
|
from: {},
|
||||||
to: {
|
to: {
|
||||||
circular: true,
|
circular: true,
|
||||||
@ -29,12 +39,8 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
name: "no-orphans",
|
name: "no-orphans",
|
||||||
comment:
|
comment:
|
||||||
"This is an orphan module - it's likely not used (anymore?). Either use it or " +
|
"This is an orphan module - it's likely not used (anymore?). Either use it or remove it. If it's logical this module is an orphan (i.e. it's a config file), add an exception for it in your dependency-cruiser configuration. By default this rule does not scrutinize dot-files (e.g. .eslintrc.js), TypeScript declaration files (.d.ts), tsconfig.json and some of the babel and webpack configs.",
|
||||||
"remove it. If it's logical this module is an orphan (i.e. it's a config file), " +
|
severity: "error",
|
||||||
"add an exception for it in your dependency-cruiser configuration. By default " +
|
|
||||||
"this rule does not scrutinize dot-files (e.g. .eslintrc.js), TypeScript declaration " +
|
|
||||||
"files (.d.ts), tsconfig.json and some of the babel and webpack configs.",
|
|
||||||
severity: "warn",
|
|
||||||
from: {
|
from: {
|
||||||
orphan: true,
|
orphan: true,
|
||||||
pathNot: [
|
pathNot: [
|
||||||
@ -42,8 +48,7 @@ module.exports = {
|
|||||||
"[.]d[.]ts$", // TypeScript declaration files
|
"[.]d[.]ts$", // TypeScript declaration files
|
||||||
"(^|/)tsconfig[.]json$", // TypeScript config
|
"(^|/)tsconfig[.]json$", // TypeScript config
|
||||||
"(^|/)(?:babel|webpack)[.]config[.](?:js|cjs|mjs|ts|cts|mts|json)$", // other configs
|
"(^|/)(?:babel|webpack)[.]config[.](?:js|cjs|mjs|ts|cts|mts|json)$", // other configs
|
||||||
// anything in src/@types
|
"(^|/)test/.+[.]setup[.]ts", // Vitest setup files
|
||||||
"(^|/)src/@types/",
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
to: {},
|
to: {},
|
||||||
@ -51,9 +56,8 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
name: "no-deprecated-core",
|
name: "no-deprecated-core",
|
||||||
comment:
|
comment:
|
||||||
"A module depends on a node core module that has been deprecated. Find an alternative - these are " +
|
"A module depends on a node core module that has been deprecated. Find an alternative - these are bound to exist - node doesn't deprecate lightly.",
|
||||||
"bound to exist - node doesn't deprecate lightly.",
|
severity: "error",
|
||||||
severity: "warn",
|
|
||||||
from: {},
|
from: {},
|
||||||
to: {
|
to: {
|
||||||
dependencyTypes: ["core"],
|
dependencyTypes: ["core"],
|
||||||
@ -84,9 +88,8 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
name: "not-to-deprecated",
|
name: "not-to-deprecated",
|
||||||
comment:
|
comment:
|
||||||
"This module uses a (version of an) npm module that has been deprecated. Either upgrade to a later " +
|
"This module uses a (version of an) npm module that has been deprecated. Either upgrade to a later version of that module, or find an alternative. Deprecated modules are a security risk.",
|
||||||
"version of that module, or find an alternative. Deprecated modules are a security risk.",
|
severity: "error",
|
||||||
severity: "warn",
|
|
||||||
from: {},
|
from: {},
|
||||||
to: {
|
to: {
|
||||||
dependencyTypes: ["deprecated"],
|
dependencyTypes: ["deprecated"],
|
||||||
@ -96,10 +99,7 @@ module.exports = {
|
|||||||
name: "no-non-package-json",
|
name: "no-non-package-json",
|
||||||
severity: "error",
|
severity: "error",
|
||||||
comment:
|
comment:
|
||||||
"This module depends on an npm package that isn't in the 'dependencies' section of your package.json. " +
|
"This module depends on an npm package that isn't in the 'dependencies' section of your package.json. That's problematic as the package either (1) won't be available on live (2 - worse) will be available on live with an non-guaranteed version. Fix it by adding the package to the dependencies in your package.json.",
|
||||||
"That's problematic as the package either (1) won't be available on live (2 - worse) will be " +
|
|
||||||
"available on live with an non-guaranteed version. Fix it by adding the package to the dependencies " +
|
|
||||||
"in your package.json.",
|
|
||||||
from: {},
|
from: {},
|
||||||
to: {
|
to: {
|
||||||
dependencyTypes: ["npm-no-pkg", "npm-unknown"],
|
dependencyTypes: ["npm-no-pkg", "npm-unknown"],
|
||||||
@ -108,8 +108,7 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
name: "not-to-unresolvable",
|
name: "not-to-unresolvable",
|
||||||
comment:
|
comment:
|
||||||
"This module depends on a module that cannot be found ('resolved to disk'). If it's an npm " +
|
"This module depends on a module that cannot be found ('resolved to disk'). If it's an npm module: add it to your package.json. In all other cases you likely already know what to do.",
|
||||||
"module: add it to your package.json. In all other cases you likely already know what to do.",
|
|
||||||
severity: "error",
|
severity: "error",
|
||||||
from: {},
|
from: {},
|
||||||
to: {
|
to: {
|
||||||
@ -119,10 +118,8 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
name: "no-duplicate-dep-types",
|
name: "no-duplicate-dep-types",
|
||||||
comment:
|
comment:
|
||||||
"Likely this module depends on an external ('npm') package that occurs more than once " +
|
"Likely this module depends on an external ('npm') package that occurs more than once in your package.json i.e. bot as a devDependencies and in dependencies. This will cause maintenance problems later on.",
|
||||||
"in your package.json i.e. bot as a devDependencies and in dependencies. This will cause " +
|
severity: "error",
|
||||||
"maintenance problems later on.",
|
|
||||||
severity: "warn",
|
|
||||||
from: {},
|
from: {},
|
||||||
to: {
|
to: {
|
||||||
moreThanOneDependencyType: true,
|
moreThanOneDependencyType: true,
|
||||||
@ -133,14 +130,12 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
/* rules you might want to tweak for your specific situation: */
|
// rules you might want to tweak for your specific situation:
|
||||||
|
|
||||||
{
|
{
|
||||||
name: "not-to-spec",
|
name: "not-to-spec",
|
||||||
comment:
|
comment:
|
||||||
"This module depends on a spec (test) file. The sole responsibility of a spec file is to test code. " +
|
"This module depends on a spec (test) file. The sole responsibility of a spec file is to test code. If there's something in a spec that's of use to other modules, it doesn't have that single responsibility anymore. Factor it out into (e.g.) a separate utility/ helper or a mock.",
|
||||||
"If there's something in a spec that's of use to other modules, it doesn't have that single " +
|
|
||||||
"responsibility anymore. Factor it out into (e.g.) a separate utility/ helper or a mock.",
|
|
||||||
severity: "error",
|
severity: "error",
|
||||||
from: {},
|
from: {},
|
||||||
to: {
|
to: {
|
||||||
@ -151,11 +146,7 @@ module.exports = {
|
|||||||
name: "not-to-dev-dep",
|
name: "not-to-dev-dep",
|
||||||
severity: "error",
|
severity: "error",
|
||||||
comment:
|
comment:
|
||||||
"This module depends on an npm package from the 'devDependencies' section of your " +
|
"This module depends on an npm package from the 'devDependencies' section of your package.json. It looks like something that ships to production, though. To prevent problems with npm packages that aren't there on production declare it (only!) in the 'dependencies'section of your package.json. If this module is development only - add it to the from.pathNot re of the not-to-dev-dep rule in the dependency-cruiser configuration",
|
||||||
"package.json. It looks like something that ships to production, though. To prevent problems " +
|
|
||||||
"with npm packages that aren't there on production declare it (only!) in the 'dependencies'" +
|
|
||||||
"section of your package.json. If this module is development only - add it to the " +
|
|
||||||
"from.pathNot re of the not-to-dev-dep rule in the dependency-cruiser configuration",
|
|
||||||
from: {
|
from: {
|
||||||
path: "^(src)",
|
path: "^(src)",
|
||||||
pathNot: ["[.](?:spec|test|setup|script)[.](?:js|mjs|cjs|jsx|ts|mts|cts|tsx)$", "./test"],
|
pathNot: ["[.](?:spec|test|setup|script)[.](?:js|mjs|cjs|jsx|ts|mts|cts|tsx)$", "./test"],
|
||||||
@ -172,10 +163,7 @@ module.exports = {
|
|||||||
name: "optional-deps-used",
|
name: "optional-deps-used",
|
||||||
severity: "info",
|
severity: "info",
|
||||||
comment:
|
comment:
|
||||||
"This module depends on an npm package that is declared as an optional dependency " +
|
"This module depends on an npm package that is declared as an optional dependency in your package.json. As this makes sense in limited situations only, it's flagged here. If you're using an optional dependency here by design - add an exception to yourdependency-cruiser configuration.",
|
||||||
"in your package.json. As this makes sense in limited situations only, it's flagged here. " +
|
|
||||||
"If you're using an optional dependency here by design - add an exception to your" +
|
|
||||||
"dependency-cruiser configuration.",
|
|
||||||
from: {},
|
from: {},
|
||||||
to: {
|
to: {
|
||||||
dependencyTypes: ["npm-optional"],
|
dependencyTypes: ["npm-optional"],
|
||||||
@ -184,11 +172,8 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
name: "peer-deps-used",
|
name: "peer-deps-used",
|
||||||
comment:
|
comment:
|
||||||
"This module depends on an npm package that is declared as a peer dependency " +
|
"This module depends on an npm package that is declared as a peer dependency in your package.json. This makes sense if your package is e.g. a plugin, but in other cases - maybe not so much. If the use of a peer dependency is intentional add an exception to your dependency-cruiser configuration.",
|
||||||
"in your package.json. This makes sense if your package is e.g. a plugin, but in " +
|
severity: "error",
|
||||||
"other cases - maybe not so much. If the use of a peer dependency is intentional " +
|
|
||||||
"add an exception to your dependency-cruiser configuration.",
|
|
||||||
severity: "warn",
|
|
||||||
from: {},
|
from: {},
|
||||||
to: {
|
to: {
|
||||||
dependencyTypes: ["npm-peer"],
|
dependencyTypes: ["npm-peer"],
|
||||||
@ -196,6 +181,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
options: {
|
options: {
|
||||||
|
exclude: ["src/plugins/vite/*", "src/vite.env.d.ts"],
|
||||||
/* Which modules not to follow further when encountered */
|
/* Which modules not to follow further when encountered */
|
||||||
doNotFollow: {
|
doNotFollow: {
|
||||||
/* path: an array of regular expressions in strings to match against */
|
/* path: an array of regular expressions in strings to match against */
|
||||||
@ -235,7 +221,7 @@ module.exports = {
|
|||||||
true: also detect dependencies that only exist before typescript-to-javascript compilation
|
true: also detect dependencies that only exist before typescript-to-javascript compilation
|
||||||
"specify": for each dependency identify whether it only exists before compilation or also after
|
"specify": for each dependency identify whether it only exists before compilation or also after
|
||||||
*/
|
*/
|
||||||
// tsPreCompilationDeps: false,
|
tsPreCompilationDeps: true,
|
||||||
|
|
||||||
/* list of extensions to scan that aren't javascript or compile-to-javascript.
|
/* list of extensions to scan that aren't javascript or compile-to-javascript.
|
||||||
Empty by default. Only put extensions in here that you want to take into
|
Empty by default. Only put extensions in here that you want to take into
|
||||||
@ -310,7 +296,7 @@ module.exports = {
|
|||||||
conditionNames: ["import", "require", "node", "default", "types"],
|
conditionNames: ["import", "require", "node", "default", "types"],
|
||||||
/*
|
/*
|
||||||
The extensions, by default are the same as the ones dependency-cruiser
|
The extensions, by default are the same as the ones dependency-cruiser
|
||||||
can access (run `npx depcruise --info` to see which ones that are in
|
can access (run `pnpm exec depcruise --info` to see which ones that are in
|
||||||
_your_ environment). If that list is larger than you need you can pass
|
_your_ environment). If that list is larger than you need you can pass
|
||||||
the extensions you actually use (e.g. [".js", ".jsx"]). This can speed
|
the extensions you actually use (e.g. [".js", ".jsx"]). This can speed
|
||||||
up module resolution, which is the most expensive step.
|
up module resolution, which is the most expensive step.
|
||||||
|
61
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||||
|
// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
|
||||||
|
{
|
||||||
|
"name": "Node.js & TypeScript",
|
||||||
|
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||||
|
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm",
|
||||||
|
"features": {
|
||||||
|
"ghcr.io/devcontainers/features/github-cli:1": {
|
||||||
|
"installDirectlyFromGitHubRelease": true,
|
||||||
|
"version": "latest"
|
||||||
|
},
|
||||||
|
"ghcr.io/devcontainers-extra/features/pnpm:2": {
|
||||||
|
"version": "latest"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"settings": {
|
||||||
|
// # Formatter configs
|
||||||
|
"editor.defaultFormatter": "biomejs.biome",
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"editor.insertSpaces": true,
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.addMissingImports.ts": "always",
|
||||||
|
"source.removeUnusedImports": "always",
|
||||||
|
"source.fixAll.biome": "always",
|
||||||
|
"source.organizeImports.biome": "always"
|
||||||
|
},
|
||||||
|
"biome.suggestInstallingGlobally": false,
|
||||||
|
|
||||||
|
// # JS/TS setting overrides
|
||||||
|
"javascript.preferences.importModuleSpecifier": "non-relative",
|
||||||
|
"javascript.preferences.importModuleSpecifierEnding": "index",
|
||||||
|
"javascript.preferGoToSourceDefinition": true,
|
||||||
|
"javascript.updateImportsOnFileMove.enabled": "always",
|
||||||
|
|
||||||
|
"typescript.preferences.importModuleSpecifier": "non-relative",
|
||||||
|
"typescript.preferences.importModuleSpecifierEnding": "index",
|
||||||
|
"typescript.preferGoToSourceDefinition": true,
|
||||||
|
"typescript.updateImportsOnFileMove.enabled": "always",
|
||||||
|
|
||||||
|
"typescript.tsserver.experimental.enableProjectDiagnostics": true,
|
||||||
|
|
||||||
|
// # Miscellaneous
|
||||||
|
"npm.packageManager": "pnpm",
|
||||||
|
"npm.scriptRunner": "pnpm",
|
||||||
|
"vitest.cliArguments": "--no-isolate"
|
||||||
|
},
|
||||||
|
"extensions": [
|
||||||
|
"biomejs.biome",
|
||||||
|
"YoavBls.pretty-ts-errors",
|
||||||
|
"vitest.explorer",
|
||||||
|
"adpyke.codesnap", // Bind to a hotkey (ctrl+\, etc) for best results
|
||||||
|
"aaron-bond.better-comments",
|
||||||
|
"MuTsunTsai.jsdoc-link"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"postCreateCommand": "pnpm install",
|
||||||
|
"forwardPorts": [8000]
|
||||||
|
}
|
7
.dockerignore
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# .dockerignore
|
||||||
|
node_modules
|
||||||
|
*.log
|
||||||
|
*.md
|
||||||
|
.gitignore
|
||||||
|
Dockerfile
|
||||||
|
.env
|
@ -3,7 +3,7 @@
|
|||||||
# top-most EditorConfig file
|
# top-most EditorConfig file
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
[src/*.{js,ts}]
|
[**/*.{js,ts,json,jsonc}]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
VITE_BYPASS_LOGIN=1
|
VITE_BYPASS_LOGIN=1
|
||||||
VITE_BYPASS_TUTORIAL=0
|
VITE_BYPASS_TUTORIAL=0
|
||||||
VITE_SERVER_URL=http://localhost:8001
|
VITE_SERVER_URL=http://localhost:8001
|
||||||
|
# IDs for discord/google auth go unused due to VITE_BYPASS_LOGIN
|
||||||
VITE_DISCORD_CLIENT_ID=1234567890
|
VITE_DISCORD_CLIENT_ID=1234567890
|
||||||
VITE_GOOGLE_CLIENT_ID=1234567890
|
VITE_GOOGLE_CLIENT_ID=1234567890
|
||||||
VITE_I18N_DEBUG=0
|
VITE_I18N_DEBUG=0
|
||||||
|
10
.github/CODEOWNERS
vendored
@ -3,9 +3,6 @@
|
|||||||
# everything (whole code-base) - Junior Devs
|
# everything (whole code-base) - Junior Devs
|
||||||
* @pagefaultgames/junior-dev-team
|
* @pagefaultgames/junior-dev-team
|
||||||
|
|
||||||
# github actions/templates etc. - Dev Leads
|
|
||||||
/.github @pagefaultgames/senior-dev-team
|
|
||||||
|
|
||||||
# Art Team
|
# Art Team
|
||||||
/public/**/*.png @pagefaultgames/art-team
|
/public/**/*.png @pagefaultgames/art-team
|
||||||
/public/**/*.json @pagefaultgames/art-team
|
/public/**/*.json @pagefaultgames/art-team
|
||||||
@ -20,3 +17,10 @@
|
|||||||
|
|
||||||
# Balance Files; contain actual code logic and must also be owned by dev team
|
# Balance Files; contain actual code logic and must also be owned by dev team
|
||||||
/src/data/balance @pagefaultgames/balance-team @pagefaultgames/junior-dev-team
|
/src/data/balance @pagefaultgames/balance-team @pagefaultgames/junior-dev-team
|
||||||
|
/src/data/trainers @pagefaultgames/balance-team @pagefaultgames/junior-dev-team
|
||||||
|
|
||||||
|
# GitHub actions/templates etc. - Senior Devs
|
||||||
|
# Should be defined last in the file to make sure these always override all other definitions
|
||||||
|
/.github @pagefaultgames/senior-dev-team
|
||||||
|
package.json @pagefaultgames/senior-dev-team
|
||||||
|
pnpm-lock.yaml @pagefaultgames/senior-dev-team
|
11
.github/pull_request_template.md
vendored
@ -14,13 +14,16 @@ Make sure the title includes categorization (choose the one that best fits):
|
|||||||
- [Balance]: If the PR is related to game balance
|
- [Balance]: If the PR is related to game balance
|
||||||
- [Challenge]: If the PR is adding or modifying challenges
|
- [Challenge]: If the PR is adding or modifying challenges
|
||||||
- [Refactor]: If the PR is primarily rewriting existing code
|
- [Refactor]: If the PR is primarily rewriting existing code
|
||||||
- [Docs]: If the PR is just adding or modifying documentation (such as tsdocs/code comments)
|
- [Dev]: If the PR is primarily changing something pertaining to development (lefthook hooks, linter rules, etc.)
|
||||||
|
- [i18n]: If the PR is primarily adding/changing locale keys or key usage (may come with an associated locales PR)
|
||||||
|
- [Docs]: If the PR is adding or modifying documentation (such as tsdocs/code comments)
|
||||||
- [GitHub]: For changes to GitHub workflows/templates/etc
|
- [GitHub]: For changes to GitHub workflows/templates/etc
|
||||||
- [Misc]: If no other category fits the PR
|
- [Misc]: If no other category fits the PR
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Make sure that this PR is not overlapping with someone else's work
|
Make sure that this PR is not overlapping with someone else's work
|
||||||
Please try to keep the PR self-contained (and small)
|
Please try to keep the PR self-contained (and small!)
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## What are the changes the user will see?
|
## What are the changes the user will see?
|
||||||
@ -65,8 +68,8 @@ Do the reviewers need to do something special in order to test your changes?
|
|||||||
- [ ] The PR is self-contained and cannot be split into smaller PRs?
|
- [ ] The PR is self-contained and cannot be split into smaller PRs?
|
||||||
- [ ] Have I provided a clear explanation of the changes?
|
- [ ] Have I provided a clear explanation of the changes?
|
||||||
- [ ] Have I tested the changes manually?
|
- [ ] Have I tested the changes manually?
|
||||||
- [ ] Are all unit tests still passing? (`npm run test:silent`)
|
- [ ] Are all unit tests still passing? (`pnpm test:silent`)
|
||||||
- [ ] Have I created new automated tests (`npm run create-test`) or updated existing tests related to the PR's changes?
|
- [ ] Have I created new automated tests (`pnpm test:create`) or updated existing tests related to the PR's changes?
|
||||||
- [ ] Have I provided screenshots/videos of the changes (if applicable)?
|
- [ ] Have I provided screenshots/videos of the changes (if applicable)?
|
||||||
- [ ] Have I made sure that any UI change works for both UI themes (default and legacy)?
|
- [ ] Have I made sure that any UI change works for both UI themes (default and legacy)?
|
||||||
|
|
||||||
|
27
.github/workflows/create-release.yml
vendored
@ -20,6 +20,7 @@ permissions:
|
|||||||
jobs:
|
jobs:
|
||||||
create-release:
|
create-release:
|
||||||
if: github.repository == 'pagefaultgames/pokerogue' && (vars.BETA_DEPLOY_BRANCH == '' || ! startsWith(vars.BETA_DEPLOY_BRANCH, 'release'))
|
if: github.repository == 'pagefaultgames/pokerogue' && (vars.BETA_DEPLOY_BRANCH == '' || ! startsWith(vars.BETA_DEPLOY_BRANCH, 'release'))
|
||||||
|
timeout-minutes: 10
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed for github cli commands
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed for github cli commands
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -36,27 +37,40 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
- uses: actions/create-github-app-token@v2
|
||||||
|
id: app-token
|
||||||
|
with:
|
||||||
|
app-id: ${{ secrets.PAGEFAULT_APP_ID }}
|
||||||
|
private-key: ${{ secrets.PAGEFAULT_APP_PRIVATE_KEY }}
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: "recursive"
|
submodules: "recursive"
|
||||||
# Always base off of beta branch, regardless of the branch the workflow was triggered from.
|
# Always base off of beta branch, regardless of the branch the workflow was triggered from.
|
||||||
ref: beta
|
ref: beta
|
||||||
|
token: ${{ steps.app-token.outputs.token }}
|
||||||
|
|
||||||
- name: Create release branch
|
- name: Create release branch
|
||||||
run: git checkout -b release
|
run: git checkout -b release
|
||||||
# In order to be able to open a PR into beta, we need the branch to have at least one change.
|
|
||||||
- name: Overwrite RELEASE file
|
# In order to be able to open a PR into beta, we need the branch to have at least one commit.
|
||||||
|
# The first commit is _usually_ just bumping the version number, so we can kill 2 birds with 1 stone here
|
||||||
|
- name: Bump release version
|
||||||
run: |
|
run: |
|
||||||
git config --local user.name "github-actions[bot]"
|
git config --local user.name "github-actions[bot]"
|
||||||
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||||
echo "Release v${{ github.event.inputs.versionName }}" > RELEASE
|
pnpm --no-git-tag-version version ${{ github.events.inputs.versionName }}
|
||||||
git add RELEASE
|
git commit -am "Stage release for v${{ github.events.inputs.versionName }}"
|
||||||
git commit -m "Stage release v${{ github.event.inputs.versionName }}"
|
|
||||||
- name: Push new branch
|
- name: Push new branch
|
||||||
run: git push origin release
|
run: git push origin release
|
||||||
|
|
||||||
# The repository variable is used by the deploy-beta workflow to determine whether to deploy from beta or release.
|
# The repository variable is used by the deploy-beta workflow to determine whether to deploy from beta or release.
|
||||||
- name: Set repository variable
|
- name: Set repository variable
|
||||||
run: GITHUB_TOKEN="${{ secrets.RW_VARS_PAT }}" gh variable set BETA_DEPLOY_BRANCH --body "release"
|
run: GITHUB_TOKEN="${{ steps.app-token.outputs.token }}" gh variable set BETA_DEPLOY_BRANCH --body "release"
|
||||||
|
|
||||||
- name: Create pull request to main
|
- name: Create pull request to main
|
||||||
run: |
|
run: |
|
||||||
gh pr create --base main \
|
gh pr create --base main \
|
||||||
@ -64,6 +78,7 @@ jobs:
|
|||||||
--title "Release v${{ github.event.inputs.versionName }} to main" \
|
--title "Release v${{ github.event.inputs.versionName }} to main" \
|
||||||
--body "This PR is for the release of v${{ github.event.inputs.versionName }}, and was created automatically by the GitHub Actions workflow invoked by ${{ github.actor }}" \
|
--body "This PR is for the release of v${{ github.event.inputs.versionName }}, and was created automatically by the GitHub Actions workflow invoked by ${{ github.actor }}" \
|
||||||
--draft
|
--draft
|
||||||
|
|
||||||
- name: Create pull request to beta
|
- name: Create pull request to beta
|
||||||
run: |
|
run: |
|
||||||
gh pr create --base beta \
|
gh pr create --base beta \
|
||||||
|
15
.github/workflows/deploy-beta.yml
vendored
@ -11,22 +11,30 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
if: github.repository == 'pagefaultgames/pokerogue' && github.ref_name == ${{ vars.BETA_DEPLOY_BRANCH || 'beta' }}
|
if: github.repository == 'pagefaultgames/pokerogue' && github.ref_name == (vars.BETA_DEPLOY_BRANCH || 'beta')
|
||||||
|
timeout-minutes: 10
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: "recursive"
|
submodules: "recursive"
|
||||||
ref: ${{ vars.BETA_DEPLOY_BRANCH || 'beta'}}
|
ref: ${{ vars.BETA_DEPLOY_BRANCH || 'beta'}}
|
||||||
|
|
||||||
|
- name: Install pnpm
|
||||||
|
uses: pnpm/action-setup@v4
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: pnpm i
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: npm run build:beta
|
run: pnpm build:beta
|
||||||
env:
|
env:
|
||||||
NODE_ENV: production
|
NODE_ENV: production
|
||||||
|
|
||||||
- name: Set up SSH
|
- name: Set up SSH
|
||||||
run: |
|
run: |
|
||||||
mkdir ~/.ssh
|
mkdir ~/.ssh
|
||||||
@ -34,6 +42,7 @@ jobs:
|
|||||||
echo "${{ secrets.BETA_SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
|
echo "${{ secrets.BETA_SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
|
||||||
chmod 600 ~/.ssh/*
|
chmod 600 ~/.ssh/*
|
||||||
ssh-keyscan -H ${{ secrets.BETA_SSH_HOST }} >> ~/.ssh/known_hosts
|
ssh-keyscan -H ${{ secrets.BETA_SSH_HOST }} >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
- name: Deploy build on server
|
- name: Deploy build on server
|
||||||
run: |
|
run: |
|
||||||
rsync --del --no-times --checksum -vrm dist/* ${{ secrets.BETA_SSH_USER }}@${{ secrets.BETA_SSH_HOST }}:${{ secrets.BETA_DESTINATION_DIR }}
|
rsync --del --no-times --checksum -vrm dist/* ${{ secrets.BETA_SSH_USER }}@${{ secrets.BETA_SSH_HOST }}:${{ secrets.BETA_DESTINATION_DIR }}
|
||||||
|
14
.github/workflows/deploy.yml
vendored
@ -11,20 +11,28 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
if: github.repository == 'pagefaultgames/pokerogue'
|
if: github.repository == 'pagefaultgames/pokerogue'
|
||||||
|
timeout-minutes: 10
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
|
|
||||||
|
- name: Install pnpm
|
||||||
|
uses: pnpm/action-setup@v4
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: pnpm i
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: npm run build
|
run: pnpm build
|
||||||
env:
|
env:
|
||||||
NODE_ENV: production
|
NODE_ENV: production
|
||||||
|
|
||||||
- name: Set up SSH
|
- name: Set up SSH
|
||||||
if: github.event_name == 'push' && github.ref_name == 'main'
|
if: github.event_name == 'push' && github.ref_name == 'main'
|
||||||
run: |
|
run: |
|
||||||
@ -33,11 +41,13 @@ jobs:
|
|||||||
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
|
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
|
||||||
chmod 600 ~/.ssh/*
|
chmod 600 ~/.ssh/*
|
||||||
ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
|
ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
- name: Deploy build on server
|
- name: Deploy build on server
|
||||||
if: github.event_name == 'push' && github.ref_name == 'main'
|
if: github.event_name == 'push' && github.ref_name == 'main'
|
||||||
run: |
|
run: |
|
||||||
rsync --del --no-times --checksum -vrm dist/* ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.DESTINATION_DIR }}
|
rsync --del --no-times --checksum -vrm dist/* ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.DESTINATION_DIR }}
|
||||||
ssh -t ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "~/prmanifest --inpath ${{ secrets.DESTINATION_DIR }} --outpath ${{ secrets.DESTINATION_DIR }}/manifest.json"
|
ssh -t ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "~/prmanifest --inpath ${{ secrets.DESTINATION_DIR }} --outpath ${{ secrets.DESTINATION_DIR }}/manifest.json"
|
||||||
|
|
||||||
- name: Purge Cloudflare Cache
|
- name: Purge Cloudflare Cache
|
||||||
if: github.event_name == 'push' && github.ref_name == 'main'
|
if: github.event_name == 'push' && github.ref_name == 'main'
|
||||||
id: purge-cache
|
id: purge-cache
|
||||||
|
55
.github/workflows/github-pages.yml
vendored
@ -4,10 +4,15 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
- beta
|
||||||
|
- release
|
||||||
|
- 'hotfix*'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- beta
|
- beta
|
||||||
|
- release
|
||||||
|
- 'hotfix*'
|
||||||
merge_group:
|
merge_group:
|
||||||
types: [checks_requested]
|
types: [checks_requested]
|
||||||
|
|
||||||
@ -15,26 +20,32 @@ jobs:
|
|||||||
pages:
|
pages:
|
||||||
name: Github Pages
|
name: Github Pages
|
||||||
if: github.repository == 'pagefaultgames/pokerogue'
|
if: github.repository == 'pagefaultgames/pokerogue'
|
||||||
|
timeout-minutes: 10
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
api-dir: ./
|
docs-dir: ./pokerogue_docs
|
||||||
|
# Only push docs when running on pushes to main/beta
|
||||||
strategy:
|
DRY_RUN: ${{github.event_name != 'push' || (github.ref_name != 'beta' && github.ref_name != 'main')}}
|
||||||
fail-fast: false
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository for Typedoc
|
- name: Checkout repository for Typedoc
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: 'recursive'
|
|
||||||
path: pokerogue_docs
|
path: pokerogue_docs
|
||||||
|
sparse-checkout: |
|
||||||
|
/*
|
||||||
|
!/public/
|
||||||
|
/public/images/pokemon/variant/_exp_masterlist.json
|
||||||
|
/public/images/pokemon/variant/_masterlist.json
|
||||||
|
/public/images/logo.png
|
||||||
|
sparse-checkout-cone-mode: false
|
||||||
|
|
||||||
- name: Install OS package
|
- name: Install pnpm
|
||||||
run: |
|
uses: pnpm/action-setup@v4
|
||||||
sudo apt update
|
with:
|
||||||
sudo apt install -y git openssh-client
|
version: 10
|
||||||
|
|
||||||
- name: Setup Node 22.14.1
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: "pokerogue_docs/.nvmrc"
|
node-version-file: "pokerogue_docs/.nvmrc"
|
||||||
@ -47,26 +58,24 @@ jobs:
|
|||||||
ref: gh-pages
|
ref: gh-pages
|
||||||
|
|
||||||
- name: Install Node.js dependencies
|
- name: Install Node.js dependencies
|
||||||
working-directory: ${{env.api-dir}}
|
working-directory: ${{env.docs-dir}}
|
||||||
run: |
|
run: pnpm i
|
||||||
cd pokerogue_docs
|
|
||||||
npm ci
|
|
||||||
|
|
||||||
- name: Generate Typedoc docs
|
- name: Generate Typedoc docs
|
||||||
working-directory: ${{env.api-dir}}
|
working-directory: ${{env.docs-dir}}
|
||||||
run: |
|
env:
|
||||||
cd pokerogue_docs
|
REF_NAME: ${{github.ref_name}}
|
||||||
npm run docs -- --out /tmp/docs --githubPages false --entryPoints ./src/
|
DRY_RUN: ${{env.DRY_RUN}}
|
||||||
|
run: pnpm typedoc
|
||||||
|
|
||||||
- name: Commit & Push docs
|
- name: Commit & Push docs
|
||||||
if: github.event_name == 'push'
|
# env vars are stored as strings instead of booleans (hence why an explicit check is required)
|
||||||
|
if: ${{ env.DRY_RUN == 'false'}}
|
||||||
run: |
|
run: |
|
||||||
cd pokerogue_gh
|
cd pokerogue_gh
|
||||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
git config user.name "github-actions[bot]"
|
git config user.name "github-actions[bot]"
|
||||||
mkdir -p $GITHUB_REF_NAME
|
rsync -rd --delete /tmp/docs/ $GITHUB_REF_NAME
|
||||||
rm -rf $GITHUB_REF_NAME/*
|
|
||||||
cp -r /tmp/docs/. $GITHUB_REF_NAME
|
|
||||||
git add $GITHUB_REF_NAME
|
git add $GITHUB_REF_NAME
|
||||||
git commit --allow-empty -m "[skip ci] Deploy docs"
|
git commit -m "[skip ci] Deploy docs"
|
||||||
git push
|
git push
|
109
.github/workflows/linting.yml
vendored
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
name: Linting
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- beta
|
||||||
|
- release
|
||||||
|
- 'hotfix*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- beta
|
||||||
|
- release
|
||||||
|
- 'hotfix*'
|
||||||
|
merge_group:
|
||||||
|
types: [checks_requested]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run-linters:
|
||||||
|
name: Run all linters
|
||||||
|
timeout-minutes: 10
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out Git repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: "recursive"
|
||||||
|
|
||||||
|
- name: Install pnpm
|
||||||
|
uses: pnpm/action-setup@v4
|
||||||
|
|
||||||
|
- name: Set up Node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: ".nvmrc"
|
||||||
|
cache: "pnpm"
|
||||||
|
|
||||||
|
- name: Install Node modules
|
||||||
|
run: pnpm i
|
||||||
|
|
||||||
|
# Lint files with Biome-Lint - https://biomejs.dev/linter/
|
||||||
|
- name: Run Biome-Lint
|
||||||
|
run: pnpm biome-ci
|
||||||
|
id: biome_lint
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
# Validate dependencies with dependency-cruiser - https://github.com/sverweij/dependency-cruiser
|
||||||
|
- name: Run Dependency-Cruise
|
||||||
|
run: pnpm depcruise
|
||||||
|
id: depcruise
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
# Validate types with tsc - https://www.typescriptlang.org/docs/handbook/compiler-options.html#using-the-cli
|
||||||
|
- name: Run Typecheck
|
||||||
|
run: pnpm typecheck
|
||||||
|
id: typecheck
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
# The exact same thing
|
||||||
|
- name: Run Typecheck (scripts)
|
||||||
|
run: pnpm typecheck:scripts
|
||||||
|
id: typecheck-scripts
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Evaluate for Errors
|
||||||
|
env:
|
||||||
|
BIOME_LINT_OUTCOME: ${{ steps.biome_lint.outcome }}
|
||||||
|
DEPCRUISE_OUTCOME: ${{ steps.depcruise.outcome }}
|
||||||
|
TYPECHECK_OUTCOME: ${{ steps.typecheck.outcome }}
|
||||||
|
TYPECHECK_SCRIPTS_OUTCOME: ${{ steps.typecheck-scripts.outcome }}
|
||||||
|
run: |
|
||||||
|
# Check for Errors
|
||||||
|
|
||||||
|
# Make text red.
|
||||||
|
red () {
|
||||||
|
printf "\e[31m%s\e[0m" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Make text green.
|
||||||
|
green () {
|
||||||
|
printf "\e[32m%s\e[0m" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_result() {
|
||||||
|
local name=$1
|
||||||
|
local outcome=$2
|
||||||
|
if [ "$outcome" == "success" ]; then
|
||||||
|
printf "$(green "✅ $name: $outcome")\n"
|
||||||
|
else
|
||||||
|
printf "$(red "❌ $name: $outcome")\n"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
print_result "Biome" "$BIOME_LINT_OUTCOME"
|
||||||
|
print_result "Depcruise" "$DEPCRUISE_OUTCOME"
|
||||||
|
print_result "Typecheck" "$TYPECHECK_OUTCOME"
|
||||||
|
print_result "Typecheck scripts" "$TYPECHECK_SCRIPTS_OUTCOME"
|
||||||
|
|
||||||
|
if [[ "$BIOME_LINT_OUTCOME" != "success" || \
|
||||||
|
"$DEPCRUISE_OUTCOME" != "success" || \
|
||||||
|
"$TYPECHECK_OUTCOME" != "success" || \
|
||||||
|
"$TYPECHECK_SCRIPTS_OUTCOME" != "success" ]]; then
|
||||||
|
printf "$(red "❌ One or more checks failed!")\n" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "$(green "✅ All checks passed!")\n"
|
1
.github/workflows/post-release-deleted.yml
vendored
@ -6,6 +6,7 @@ jobs:
|
|||||||
# Set the BETA_DEPLOY_BRANCH variable to beta when a release branch is deleted
|
# Set the BETA_DEPLOY_BRANCH variable to beta when a release branch is deleted
|
||||||
update-release-var:
|
update-release-var:
|
||||||
if: github.repository == 'pagefaultgames/pokerogue' && github.event.ref_type == 'branch' && github.event.ref == 'release'
|
if: github.repository == 'pagefaultgames/pokerogue' && github.event.ref_type == 'branch' && github.event.ref == 'release'
|
||||||
|
timeout-minutes: 5
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set BETA_DEPLOY_BRANCH to beta
|
- name: Set BETA_DEPLOY_BRANCH to beta
|
||||||
|
41
.github/workflows/quality.yml
vendored
@ -1,41 +0,0 @@
|
|||||||
name: Biome Code Quality
|
|
||||||
|
|
||||||
on:
|
|
||||||
# Trigger the workflow on push or pull request,
|
|
||||||
# but only for the main branch
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main # Trigger on push events to the main branch
|
|
||||||
- beta # Trigger on push events to the beta branch
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- main # Trigger on pull request events targeting the main branch
|
|
||||||
- beta # Trigger on pull request events targeting the beta branch
|
|
||||||
merge_group:
|
|
||||||
types: [checks_requested]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
run-linters: # Define a job named "run-linters"
|
|
||||||
name: Run linters # Human-readable name for the job
|
|
||||||
runs-on: ubuntu-latest # Specify the latest Ubuntu runner for the job
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Check out Git repository # Step to check out the repository
|
|
||||||
uses: actions/checkout@v4 # Use the checkout action version 4
|
|
||||||
with:
|
|
||||||
submodules: 'recursive'
|
|
||||||
|
|
||||||
- name: Set up Node.js # Step to set up Node.js environment
|
|
||||||
uses: actions/setup-node@v4 # Use the setup-node action version 4
|
|
||||||
with:
|
|
||||||
node-version-file: '.nvmrc'
|
|
||||||
cache: 'npm'
|
|
||||||
|
|
||||||
- name: Install Node.js dependencies # Step to install Node.js dependencies
|
|
||||||
run: npm ci # Use 'npm ci' to install dependencies
|
|
||||||
|
|
||||||
- name: eslint # Step to run linters
|
|
||||||
run: npm run eslint-ci
|
|
||||||
|
|
||||||
- name: Lint with Biome # Step to run linters
|
|
||||||
run: npm run biome-ci
|
|
13
.github/workflows/test-shard-template.yml
vendored
@ -21,6 +21,7 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
# We can't use dynmically named jobs until https://github.com/orgs/community/discussions/13261 is implemented
|
# We can't use dynmically named jobs until https://github.com/orgs/community/discussions/13261 is implemented
|
||||||
name: Shard
|
name: Shard
|
||||||
|
timeout-minutes: 10
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ !inputs.skip }}
|
if: ${{ !inputs.skip }}
|
||||||
steps:
|
steps:
|
||||||
@ -28,12 +29,18 @@ jobs:
|
|||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@v4.2.2
|
||||||
with:
|
with:
|
||||||
submodules: "recursive"
|
submodules: "recursive"
|
||||||
|
|
||||||
|
- name: Install pnpm
|
||||||
|
uses: pnpm/action-setup@v4
|
||||||
|
|
||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
cache: "npm"
|
cache: "pnpm"
|
||||||
|
|
||||||
- name: Install Node.js dependencies
|
- name: Install Node.js dependencies
|
||||||
run: npm ci
|
run: pnpm i
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: npx vitest --project ${{ inputs.project }} --no-isolate --shard=${{ inputs.shard }}/${{ inputs.totalShards }} ${{ !runner.debug && '--silent' || '' }}
|
run: pnpm test:silent --shard=${{ inputs.shard }}/${{ inputs.totalShards }}
|
||||||
|
23
.github/workflows/tests.yml
vendored
@ -1,21 +1,25 @@
|
|||||||
name: Tests
|
name: Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# Trigger the workflow on push or pull request,
|
|
||||||
# but only for the main branch
|
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main # Trigger on push events to the main branch
|
- main
|
||||||
- beta # Trigger on push events to the beta branch
|
- beta
|
||||||
|
- release
|
||||||
|
- 'hotfix*'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- main # Trigger on pull request events targeting the main branch
|
- main
|
||||||
- beta # Trigger on pull request events targeting the beta branch
|
- beta
|
||||||
|
- release
|
||||||
|
- 'hotfix*'
|
||||||
merge_group:
|
merge_group:
|
||||||
types: [checks_requested]
|
types: [checks_requested]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-path-change-filter:
|
check-path-change-filter:
|
||||||
|
timeout-minutes: 5
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
pull-requests: read
|
pull-requests: read
|
||||||
@ -24,6 +28,11 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
sparse-checkout: |
|
||||||
|
.github/test-filters.yml
|
||||||
|
sparse-checkout-cone-mode: false
|
||||||
|
|
||||||
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36
|
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36
|
||||||
id: filter
|
id: filter
|
||||||
with:
|
with:
|
||||||
@ -33,6 +42,8 @@ jobs:
|
|||||||
name: Run Tests
|
name: Run Tests
|
||||||
needs: check-path-change-filter
|
needs: check-path-change-filter
|
||||||
strategy:
|
strategy:
|
||||||
|
# don't stop upon 1 shard failing
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
shard: [1, 2, 3, 4, 5]
|
shard: [1, 2, 3, 4, 5]
|
||||||
uses: ./.github/workflows/test-shard-template.yml
|
uses: ./.github/workflows/test-shard-template.yml
|
||||||
|
6
.gitignore
vendored
@ -11,10 +11,12 @@ node_modules
|
|||||||
dist
|
dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
|
build
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files (excluding `extensions.json` for devcontainer)
|
||||||
.vscode
|
|
||||||
*.code-workspace
|
*.code-workspace
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
.idea
|
.idea
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.suo
|
*.suo
|
||||||
|
29
.ls-lint.yml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Base settings to use
|
||||||
|
# Note that the `_cfg` key isn't part of ls-lint's configuration, it's just a YAML anchor for reuse.
|
||||||
|
_cfg: &cfg
|
||||||
|
.ps1: kebab-case
|
||||||
|
.ts: kebab-case
|
||||||
|
.js: kebab-case
|
||||||
|
.*.ts: kebab-case
|
||||||
|
.*.js: kebab-case
|
||||||
|
.dir: kebab-case
|
||||||
|
.py: snake_case # python files should always use snake_case
|
||||||
|
|
||||||
|
ls:
|
||||||
|
<<: *cfg
|
||||||
|
src: &src
|
||||||
|
<<: *cfg
|
||||||
|
.dir: kebab-case | regex:@types
|
||||||
|
.js: exists:0
|
||||||
|
src/system/version-migration/versions:
|
||||||
|
.ts: snake_case
|
||||||
|
<<: *cfg
|
||||||
|
test: *src
|
||||||
|
ignore:
|
||||||
|
- node_modules
|
||||||
|
- .vscode
|
||||||
|
- .github
|
||||||
|
- .git
|
||||||
|
- public
|
||||||
|
- dist
|
||||||
|
- .devcontainer
|
13
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"biomejs.biome",
|
||||||
|
"YoavBls.pretty-ts-errors",
|
||||||
|
"vitest.explorer",
|
||||||
|
|
||||||
|
// This stuff isn't mandatory - it's just nice to have :)
|
||||||
|
|
||||||
|
"adpyke.codesnap", // Bind to a hotkey (ctrl+\, etc) for best results
|
||||||
|
"aaron-bond.better-comments",
|
||||||
|
"MuTsunTsai.jsdoc-link"
|
||||||
|
]
|
||||||
|
}
|
128
CONTRIBUTING.md
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# Contributing to PokéRogue
|
||||||
|
|
||||||
|
Thank you for taking the time to contribute, every little bit helps. This project is entirely open-source and unmonetized - community contributions are what keep it alive!
|
||||||
|
|
||||||
|
Please make sure you understand everything relevant to your changes from the [Table of Contents](#-table-of-contents), and absolutely *feel free to reach out in the **#dev-corner** channel on [Discord](https://discord.gg/pokerogue)*.
|
||||||
|
We are here to help and the better you understand what you're working on, the easier it will be for it to find its way into the game.
|
||||||
|
|
||||||
|
## 📄 Table of Contents
|
||||||
|
|
||||||
|
- [Development Basics](#️-development-basics)
|
||||||
|
- [Environment Setup](#-environment-setup)
|
||||||
|
- [Getting Started](#-getting-started)
|
||||||
|
- [Documentation](#-documentation)
|
||||||
|
- [Testing Your Changes](#-testing-your-changes)
|
||||||
|
- [Development Save File (Unlock Everything)](#-development-save-file)
|
||||||
|
|
||||||
|
## 🛠️ Development Basics
|
||||||
|
|
||||||
|
PokéRogue is built with [Typescript](https://www.typescriptlang.org/docs/handbook/intro.html), using the [Phaser](https://github.com/phaserjs/phaser) game framework.
|
||||||
|
|
||||||
|
If you have the motivation and experience with Typescript/Javascript (or are willing to learn), you can contribute by forking the repository and making pull requests with contributions.
|
||||||
|
|
||||||
|
## 💻 Environment Setup
|
||||||
|
|
||||||
|
### Codespaces/Devcontainer Environment
|
||||||
|
|
||||||
|
Arguably the easiest way to get started is by using the prepared development environment.
|
||||||
|
|
||||||
|
We have a `.devcontainer/devcontainer.json` file, meaning we are compatible with:
|
||||||
|
|
||||||
|
- [![Open in GitHub Codespaces][codespaces-badge]][codespaces-link], or
|
||||||
|
- the [Visual Studio Code Remote - Containers][devcontainer-ext] extension.
|
||||||
|
|
||||||
|
This Linux environment comes with all required dependencies needed to start working on the project.
|
||||||
|
|
||||||
|
[codespaces-badge]: <https://github.com/codespaces/badge.svg>
|
||||||
|
[codespaces-link]: <https://github.com/codespaces/new?hide_repo_select=true&repo=620476224&ref=beta>
|
||||||
|
[devcontainer-ext]: <https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers>
|
||||||
|
|
||||||
|
### Local Development
|
||||||
|
|
||||||
|
#### Prerequisites
|
||||||
|
|
||||||
|
- node: >=22.14.0 - [manage with pnpm](https://pnpm.io/cli/env) | [manage with fnm](https://github.com/Schniz/fnm) | [manage with nvm](https://github.com/nvm-sh/nvm) | [manage with volta.sh](https://volta.sh/)
|
||||||
|
- pnpm: 10.x - [how to install](https://pnpm.io/installation) (not recommended to install via `npm` on Windows native) | [alternate method - volta.sh](https://volta.sh/)
|
||||||
|
- The repository [forked](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo) and [cloned](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) locally on your device
|
||||||
|
|
||||||
|
#### Running Locally
|
||||||
|
|
||||||
|
1. Run `pnpm install` from the repository root
|
||||||
|
- *if you run into any errors, reach out in the **#dev-corner** channel on Discord*
|
||||||
|
2. Run `pnpm start:dev` to locally run the project at `localhost:8000`
|
||||||
|
|
||||||
|
## 🚀 Getting Started
|
||||||
|
|
||||||
|
A great way to develop an understanding of how the project works is to look at test cases (located in [the `test` folder](./test/)).
|
||||||
|
Tests show you both how things are supposed to work and the expected "flow" to get from point A to point B in battles.
|
||||||
|
|
||||||
|
*This is a big project and you will be confused at times - never be afraid to reach out and ask questions in **#dev-corner***!
|
||||||
|
|
||||||
|
### Where to Look
|
||||||
|
|
||||||
|
Once you have your feet under you, check out the [Issues](https://github.com/pagefaultgames/pokerogue/issues) page to see how you can help us!
|
||||||
|
Most issues are bugs and are labeled with their area, such as `Move`, `Ability`, `UI/UX`, etc. There are also priority labels:
|
||||||
|
- `P0`: Completely gamebreaking (very rare)
|
||||||
|
- `P1`: Major - Game crash
|
||||||
|
- `P2`: Minor - Incorrect (but non-crashing) move/ability/interaction
|
||||||
|
- `P3`: No gameplay impact - typo, minor graphical error, etc.
|
||||||
|
|
||||||
|
Also under issues, you can take a look at the [List of Partial / Unimplemented Moves and Abilities](https://github.com/pagefaultgames/pokerogue/issues/3503) and the [Bug Board](https://github.com/orgs/pagefaultgames/projects/3). The latter is essentially the same as the issues page, so take your pick.
|
||||||
|
|
||||||
|
You are free to comment on any issue so that you may be assigned to it and we can avoid multiple people working on the same thing.
|
||||||
|
|
||||||
|
## 📚 Documentation
|
||||||
|
|
||||||
|
You can find the auto-generated documentation [here](https://pagefaultgames.github.io/pokerogue/main/index.html).
|
||||||
|
|
||||||
|
Additionally, the [docs folder](./docs) contains a variety of in-depth documents and guides useful for aspiring contributors. \
|
||||||
|
Notable topics include:
|
||||||
|
- [Commenting your code](./docs/comments.md)
|
||||||
|
- [Linting & Formatting](./docs/linting.md)
|
||||||
|
- [Localization](./docs/localization.md)
|
||||||
|
- [Enemy AI move selection](./docs/enemy-ai.md)
|
||||||
|
- [Running with Podman](./docs/podman.md)
|
||||||
|
|
||||||
|
Again, if you have unanswered questions please feel free to ask!
|
||||||
|
|
||||||
|
## 🧪 Testing Your Changes
|
||||||
|
|
||||||
|
You've just made a change - how can you check if it works? You have two areas to hit:
|
||||||
|
|
||||||
|
### 1 - Manual Testing
|
||||||
|
|
||||||
|
> This will likely be your first stop. After making a change, you'll want to spin the game up and make sure everything is as you expect. To do this, you will need a way to manipulate the game to produce the situation you're looking to test.
|
||||||
|
|
||||||
|
[src/overrides.ts](../src/overrides.ts) contains overrides for most values you'll need to change for testing, controlled through the `overrides` object.
|
||||||
|
For example, here is how you could test a scenario where the player Pokemon has the ability Drought and the enemy Pokemon has the move Water Gun:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const overrides = {
|
||||||
|
ABILITY_OVERRIDE: AbilityId.DROUGHT,
|
||||||
|
ENEMY_MOVESET_OVERRIDE: MoveId.WATER_GUN,
|
||||||
|
} satisfies Partial<InstanceType<typeof DefaultOverrides>>;
|
||||||
|
```
|
||||||
|
|
||||||
|
Read through `src/overrides.ts` file to find the override that fits your needs - there are a lot of them!
|
||||||
|
If the situation you're trying to test can't be created using existing overrides (or with the [Dev Save](#-development-save-file)), reach out in **#dev-corner**.
|
||||||
|
You can get help testing your specific changes, and you might have found a new override that needs to be created!
|
||||||
|
|
||||||
|
### 2 - Automatic Testing
|
||||||
|
|
||||||
|
> PokéRogue uses [Vitest](https://vitest.dev/) for automatic testing. Checking out the existing tests in the [test](./test/) folder is a great way to understand how this works, and to get familiar with the project as a whole.
|
||||||
|
|
||||||
|
To make sure your changes didn't break any existing test cases, run `pnpm test:silent` in your terminal. You can also provide an argument to the command: to run only the Dancer (ability) tests, you could write `pnpm test:silent dancer`.
|
||||||
|
- __Note that passing all test cases does *not* guarantee that everything is working properly__. The project does not have complete regression testing.
|
||||||
|
|
||||||
|
Most non-trivial changes (*especially bug fixes*) should come along with new test cases.
|
||||||
|
- To make a new test file, run `pnpm test:create` and follow the prompts. If the move/ability/etc. you're modifying already has tests, simply add new cases to the end of the file. As mentioned before, the easiest way to get familiar with the system and understand how to write your own tests is simply to read the existing tests, particularly ones similar to the tests you intend to write.
|
||||||
|
- Ensure that new tests:
|
||||||
|
- Are deterministic. In other words, the test should never pass or fail when it shouldn't due to randomness. This involves primarily ensuring that abilities and moves are never randomly selected.
|
||||||
|
- As much as possible, are unit tests. If you have made two distinct changes, they should be tested in two separate cases.
|
||||||
|
- Test edge cases. A good strategy is to think of edge cases beforehand and create tests for them using `it.todo`. Once the edge case has been handled, you can remove the `todo` marker.
|
||||||
|
|
||||||
|
## 😈 Development Save File
|
||||||
|
> Some issues may require you to have unlocks on your save file which go beyond normal overrides. For this reason, the repository contains a [save file](../test/test-utils/saves/everything.psrv) with _everything_ unlocked (even ones not legitimately obtainable, like unimplemented variant shinies).
|
||||||
|
|
||||||
|
1. Start the game up locally and navigate to `Menu -> Manage Data -> Import Data`
|
||||||
|
2. Select [everything.prsv](test/test-utils/saves/everything.prsv) (`test/test-utils/saves/everything.prsv`) and confirm.
|
@ -24,9 +24,10 @@
|
|||||||
- Pokémon Sword/Shield
|
- Pokémon Sword/Shield
|
||||||
- Pokémon Legends: Arceus
|
- Pokémon Legends: Arceus
|
||||||
- Pokémon Scarlet/Violet
|
- Pokémon Scarlet/Violet
|
||||||
- Firel (Custom Graveyard, Ice Cave, Laboratory, Metropolis, Plains, Power Plant, Seabed, Space, and Volcano biome music)
|
- Firel (Custom Graveyard, Ice Cave, Laboratory, Metropolis, Plains, Power Plant, Seabed, Space, Volcano, and Desert biome music)
|
||||||
- Lmz (Custom Ancient Ruins, Jungle, and Lake biome music)
|
- Lmz (Custom Ancient Ruins, Jungle, and Lake biome music)
|
||||||
- Andr06 (Custom Forest, Slum and Sea biome music)
|
- Andr06 (Custom Forest, Slum, Sea, and Fairy Cave biome music)
|
||||||
|
- Leavannite (Custom Wasteland biome music)
|
||||||
- _tresnoir
|
- _tresnoir
|
||||||
- unveiler
|
- unveiler
|
||||||
|
|
||||||
@ -40,6 +41,7 @@
|
|||||||
## Backgrounds
|
## Backgrounds
|
||||||
- Squip (Paid Commissions)
|
- Squip (Paid Commissions)
|
||||||
- Contributions by Someonealive-QN
|
- Contributions by Someonealive-QN
|
||||||
|
- Contributions by redactedinlight
|
||||||
|
|
||||||
## UI
|
## UI
|
||||||
- GAMEFREAK
|
- GAMEFREAK
|
||||||
|
47
Dockerfile
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
ARG NODE_VERSION=22.14
|
||||||
|
ARG OS=alpine
|
||||||
|
|
||||||
|
FROM node:${NODE_VERSION}-${OS}
|
||||||
|
|
||||||
|
# Create non-root user
|
||||||
|
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
|
||||||
|
|
||||||
|
# Install git (for potential runtime needs)
|
||||||
|
RUN apk add --no-cache git
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Enable and prepare pnpm
|
||||||
|
RUN corepack enable && corepack prepare pnpm@10.14.0 --activate
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Copy package files
|
||||||
|
COPY package.json pnpm-lock.yaml ./
|
||||||
|
|
||||||
|
# Install all dependencies
|
||||||
|
RUN --mount=type=cache,target=/home/appuser/.pnpm-store \
|
||||||
|
pnpm install --frozen-lockfile && \
|
||||||
|
rm -rf /home/appuser/.pnpm-store/*
|
||||||
|
|
||||||
|
# Change ownership
|
||||||
|
RUN chown -R appuser:appgroup /app
|
||||||
|
|
||||||
|
# Switch to non-root user
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV VITE_BYPASS_LOGIN=1 \
|
||||||
|
VITE_BYPASS_TUTORIAL=0 \
|
||||||
|
NEXT_TELEMETRY_DISABLED=1 \
|
||||||
|
PNP_HOME=/home/appuser/.shrc \
|
||||||
|
NODE_ENV=development \
|
||||||
|
PORT=8000
|
||||||
|
|
||||||
|
# Expose port
|
||||||
|
EXPOSE $PORT
|
||||||
|
|
||||||
|
# Start the app in development mode
|
||||||
|
CMD ["pnpm", "run", "start:podman"]
|
51
README.md
@ -1,53 +1,18 @@
|
|||||||
<picture><img src="./public/images/logo.png" width="300" alt="PokéRogue"></picture>
|
<div align="center"><picture><img src="./public/images/logo.png" width="300" alt="PokéRogue"></picture>
|
||||||
|
|
||||||
|
[](https://discord.gg/pokerogue)
|
||||||
|
[](https://pagefaultgames.github.io/pokerogue/beta)
|
||||||
|
[](https://github.com/pagefaultgames/pokerogue/actions/workflows/tests.yml)
|
||||||
|
[](https://www.gnu.org/licenses/agpl-3.0)</div>
|
||||||
|
|
||||||
PokéRogue is a browser based Pokémon fangame heavily inspired by the roguelite genre. Battle endlessly while gathering stacking items, exploring many different biomes, fighting trainers, bosses, and more!
|
PokéRogue is a browser based Pokémon fangame heavily inspired by the roguelite genre. Battle endlessly while gathering stacking items, exploring many different biomes, fighting trainers, bosses, and more!
|
||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
## 🛠️ Development
|
See [CONTRIBUTING.md](./CONTRIBUTING.md), this includes instructions on how to set up the game locally.
|
||||||
|
|
||||||
If you have the motivation and experience with Typescript/Javascript (or are willing to learn) please feel free to fork the repository and make pull requests with contributions. If you don't know what to work on but want to help, reference the below **To-Do** section or the **#feature-vote** channel in the discord.
|
|
||||||
|
|
||||||
### 💻 Environment Setup
|
|
||||||
|
|
||||||
#### Prerequisites
|
|
||||||
|
|
||||||
- node: 22.14.0
|
|
||||||
- npm: [how to install](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
|
|
||||||
|
|
||||||
#### Running Locally
|
|
||||||
|
|
||||||
1. Clone the repo and in the root directory run `npm install`
|
|
||||||
- *if you run into any errors, reach out in the **#dev-corner** channel in discord*
|
|
||||||
2. Run `npm run start:dev` to locally run the project in `localhost:8000`
|
|
||||||
|
|
||||||
#### Linting
|
|
||||||
|
|
||||||
We're using Biome as our common linter and formatter. It will run automatically during the pre-commit hook but if you would like to manually run it, use the `npm run biome` script. To view the complete rules, check out the [biome.jsonc](./biome.jsonc) file.
|
|
||||||
|
|
||||||
### 📚 Documentation
|
|
||||||
|
|
||||||
You can find the auto-generated documentation [here](https://pagefaultgames.github.io/pokerogue/main/index.html).
|
|
||||||
For information on enemy AI, check out the [enemy-ai.md](./docs/enemy-ai.md) file.
|
|
||||||
For detailed guidelines on documenting your code, refer to the [comments.md](./docs/comments.md) file.
|
|
||||||
|
|
||||||
### ❔ FAQ
|
|
||||||
|
|
||||||
**How do I test a new _______?**
|
|
||||||
|
|
||||||
- In the `src/overrides.ts` file there are overrides for most values you'll need to change for testing
|
|
||||||
|
|
||||||
**How do I retrieve the translations?**
|
|
||||||
|
|
||||||
- The translations were moved to the [dedicated translation repository](https://github.com/pagefaultgames/pokerogue-locales) and are now applied as a submodule in this project.
|
|
||||||
- The command to retrieve the translations is `git submodule update --init --recursive`. If you still struggle to get it working, please reach out to #dev-corner channel in Discord.
|
|
||||||
|
|
||||||
## 🪧 To Do
|
|
||||||
|
|
||||||
Check out [Github Issues](https://github.com/pagefaultgames/pokerogue/issues) to see how can you help us!
|
|
||||||
|
|
||||||
# 📝 Credits
|
# 📝 Credits
|
||||||
>
|
|
||||||
> If this project contains assets you have produced and you do not see your name, **please** reach out, either [here on GitHub](https://github.com/pagefaultgames/pokerogue/issues/new) or via [Discord](https://discord.gg/pokerogue).
|
> If this project contains assets you have produced and you do not see your name, **please** reach out, either [here on GitHub](https://github.com/pagefaultgames/pokerogue/issues/new) or via [Discord](https://discord.gg/pokerogue).
|
||||||
|
|
||||||
Thank you to all the wonderful people that have contributed to the PokéRogue project! You can find the credits [here](./CREDITS.md).
|
Thank you to all the wonderful people that have contributed to the PokéRogue project! You can find the credits [here](./CREDITS.md).
|
||||||
|
282
biome.jsonc
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
"$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
|
||||||
"vcs": {
|
"vcs": {
|
||||||
"enabled": false,
|
"enabled": true,
|
||||||
"clientKind": "git",
|
"clientKind": "git",
|
||||||
"useIgnoreFile": true,
|
"useIgnoreFile": true,
|
||||||
"defaultBranch": "beta"
|
"defaultBranch": "beta"
|
||||||
@ -10,85 +10,138 @@
|
|||||||
"enabled": true,
|
"enabled": true,
|
||||||
"useEditorconfig": true,
|
"useEditorconfig": true,
|
||||||
"indentStyle": "space",
|
"indentStyle": "space",
|
||||||
"ignore": ["src/enums/*", "src/data/balance/*"],
|
"includes": ["**", "!**/src/data/balance/**"],
|
||||||
"lineWidth": 120
|
"lineWidth": 120
|
||||||
},
|
},
|
||||||
"files": {
|
"files": {
|
||||||
"ignoreUnknown": true,
|
"ignoreUnknown": true,
|
||||||
// Adding folders to the ignore list is GREAT for performance because it prevents biome from descending into them
|
// Adding folders to the ignore list is GREAT for performance because it prevents biome from descending into them
|
||||||
// and having to verify whether each individual file is ignored
|
// and having to verify whether each individual file is ignored
|
||||||
"ignore": [
|
"includes": [
|
||||||
"**/*.d.ts",
|
"**",
|
||||||
"dist/*",
|
"!**/dist",
|
||||||
"build/*",
|
"!**/coverage",
|
||||||
"coverage/*",
|
"!**/public",
|
||||||
"public/*",
|
"!**/.github",
|
||||||
".github/*",
|
"!**/node_modules",
|
||||||
"node_modules/*",
|
"!**/typedoc",
|
||||||
".vscode/*",
|
// TODO: lint css and html?
|
||||||
"*.css", // TODO?
|
"!**/*.css",
|
||||||
"*.html", // TODO?
|
"!**/*.html",
|
||||||
"src/overrides.ts",
|
// TODO: enable linting this file
|
||||||
// TODO: these files are too big and complex, ignore them until their respective refactors
|
"!**/src/data/moves/move.ts",
|
||||||
"src/data/moves/move.ts",
|
// this file is too big
|
||||||
|
"!**/src/data/balance/tms.ts"
|
||||||
// this file is just too big:
|
|
||||||
"src/data/balance/tms.ts"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"assist": {
|
||||||
// While it'd be nice to enable consistent sorting, enabling this causes issues due to circular import resolution order
|
"actions": {
|
||||||
// TODO: Remove if we ever get down to 0 circular imports
|
"source": {
|
||||||
"organizeImports": { "enabled": false },
|
"organizeImports": {
|
||||||
|
"level": "on",
|
||||||
|
"options": {
|
||||||
|
"groups": [":ALIAS:", ":NODE:", ":PACKAGE_WITH_PROTOCOL:", ":PACKAGE:", ":PATH:"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// TODO: Remove unneeded `options` blocks once biome's JSON schema is fixed to not require them
|
||||||
"linter": {
|
"linter": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"rules": {
|
"rules": {
|
||||||
"recommended": true,
|
"recommended": true,
|
||||||
"correctness": {
|
"correctness": {
|
||||||
"noUndeclaredVariables": "off",
|
"noUndeclaredVariables": "error",
|
||||||
"noUnusedVariables": "error",
|
"noUnusedVariables": "error",
|
||||||
"noSwitchDeclarations": "warn", // TODO: refactor and make this an error
|
"noSwitchDeclarations": "error",
|
||||||
"noVoidTypeReturn": "warn", // TODO: Refactor and make this an error
|
"noVoidTypeReturn": "error",
|
||||||
"noUnusedImports": "error"
|
"noUnusedImports": {
|
||||||
|
"level": "error",
|
||||||
|
"fix": "safe",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"noUnusedFunctionParameters": "error",
|
||||||
|
"noUnusedLabels": "error",
|
||||||
|
"noPrivateImports": "error",
|
||||||
|
"useSingleJsDocAsterisk": "error",
|
||||||
|
"useJsonImportAttributes": "off" // "Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'nodenext', or 'preserve'. ts(2823)"
|
||||||
},
|
},
|
||||||
"style": {
|
"style": {
|
||||||
"noVar": "error",
|
"useExplicitLengthCheck": {
|
||||||
"useEnumInitializers": "off", // large enums like Moves/Species would make this cumbersome
|
"level": "error",
|
||||||
"useBlockStatements": "error",
|
"fix": "safe",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"useAtIndex": "error",
|
||||||
|
"noNegationElse": {
|
||||||
|
"level": "info", // TODO: Promote to error eventually
|
||||||
|
"fix": "unsafe", // duplicates else blocks
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
// TODO: Fix all instances of this and promote to `error` - this and enums are the 2 things
|
||||||
|
// barring us from `esModuleInterop`
|
||||||
|
"noParameterProperties": "warn",
|
||||||
|
"useConsistentBuiltinInstantiation": {
|
||||||
|
"level": "error",
|
||||||
|
"fix": "safe",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"noDefaultExport": "warn", // TODO: Fix `overrides.ts` and enable
|
||||||
|
"noShoutyConstants": "error",
|
||||||
|
"useThrowNewError": {
|
||||||
|
"level": "error",
|
||||||
|
"fix": "safe",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"useThrowOnlyError": "error",
|
||||||
|
"useTrimStartEnd": "error",
|
||||||
|
"useReadonlyClassProperties": {
|
||||||
|
"level": "info", // TODO: Graduate to error eventually
|
||||||
|
// NOTE: "checkAllProperties" has an immature implementation that
|
||||||
|
// causes many false positives across files. Enable if/when maturity improves
|
||||||
|
"options": { "checkAllProperties": false }
|
||||||
|
},
|
||||||
|
"useConsistentObjectDefinitions": {
|
||||||
|
"level": "error",
|
||||||
|
"options": { "syntax": "shorthand" }
|
||||||
|
},
|
||||||
|
"useCollapsedIf": "error",
|
||||||
|
"useCollapsedElseIf": "error",
|
||||||
|
|
||||||
|
"noSubstr": "error",
|
||||||
|
"noYodaExpression": "error",
|
||||||
|
"useForOf": "error",
|
||||||
|
"useEnumInitializers": "off", // large enums like MoveId/SpeciesId would make this cumbersome
|
||||||
|
"useBlockStatements": {
|
||||||
|
"level": "error",
|
||||||
|
"fix": "safe",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
"useConst": "error",
|
"useConst": "error",
|
||||||
"useImportType": "error",
|
"useImportType": "error",
|
||||||
"noNonNullAssertion": "off", // TODO: Turn this on ASAP and fix all non-null assertions in non-test files
|
"noNonNullAssertion": "off", // TODO: Turn this on ASAP and fix all non-null assertions in non-test files
|
||||||
"noParameterAssign": "off",
|
"noParameterAssign": "off",
|
||||||
"useExponentiationOperator": "off", // Too typo-prone and easy to mixup with standard multiplication (* vs **)
|
"useExponentiationOperator": "off", // Too typo-prone and easy to mixup with standard multiplication (* vs **)
|
||||||
"useDefaultParameterLast": "off", // TODO: Fix spots in the codebase where this flag would be triggered, and then enable
|
"useDefaultParameterLast": {
|
||||||
"useSingleVarDeclarator": "off",
|
// TODO: Fix spots in the codebase where this flag would be triggered
|
||||||
|
// and then set to "error" and re-enable the fixer
|
||||||
|
"level": "warn",
|
||||||
|
"fix": "none",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"useSingleVarDeclarator": {
|
||||||
|
"level": "error",
|
||||||
|
"fix": "safe",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
"useNodejsImportProtocol": "off",
|
"useNodejsImportProtocol": "off",
|
||||||
"useTemplate": "off", // string concatenation is faster: https://stackoverflow.com/questions/29055518/are-es6-template-literals-faster-than-string-concatenation
|
"useTemplate": "off", // string concatenation is faster: https://stackoverflow.com/questions/29055518/are-es6-template-literals-faster-than-string-concatenation
|
||||||
"noNamespaceImport": "error"
|
"useAsConstAssertion": "error",
|
||||||
},
|
"noUnusedTemplateLiteral": "error",
|
||||||
"suspicious": {
|
"useNumberNamespace": "error",
|
||||||
"noDoubleEquals": "error",
|
"noInferrableTypes": "error",
|
||||||
// While this would be a nice rule to enable, the current structure of the codebase makes this infeasible
|
"noUselessElse": "error",
|
||||||
// due to being used for move/ability `args` params and save data-related code.
|
|
||||||
// This can likely be enabled for all non-utils files once these are eventually reworked, but until then we leave it off.
|
|
||||||
"noExplicitAny": "off",
|
|
||||||
"noAssignInExpressions": "off",
|
|
||||||
"noPrototypeBuiltins": "off",
|
|
||||||
"noFallthroughSwitchClause": "error", // Prevents accidental automatic fallthroughs in switch cases (use disable comment if needed)
|
|
||||||
"noImplicitAnyLet": "warn", // TODO: Refactor and make this an error
|
|
||||||
"noRedeclare": "info", // TODO: Refactor and make this an error
|
|
||||||
"noGlobalIsNan": "off",
|
|
||||||
"noAsyncPromiseExecutor": "warn" // TODO: Refactor and make this an error
|
|
||||||
},
|
|
||||||
"complexity": {
|
|
||||||
"noExcessiveCognitiveComplexity": "warn", // TODO: Refactor and make this an error
|
|
||||||
"useLiteralKeys": "off",
|
|
||||||
"noForEach": "off", // Foreach vs for of is not that simple.
|
|
||||||
"noUselessSwitchCase": "off", // Explicit > Implicit
|
|
||||||
"noUselessConstructor": "warn", // TODO: Refactor and make this an error
|
|
||||||
"noBannedTypes": "warn" // TODO: Refactor and make this an error
|
|
||||||
},
|
|
||||||
"nursery": {
|
|
||||||
"noRestrictedTypes": {
|
"noRestrictedTypes": {
|
||||||
"level": "error",
|
"level": "error",
|
||||||
"options": {
|
"options": {
|
||||||
@ -99,24 +152,125 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// TODO: Wait until the rule gets options for ignoring doc comments and/or different parameter names,
|
||||||
|
// and THEN enable it codebase-wide
|
||||||
|
"useUnifiedTypeSignatures": {
|
||||||
|
"level": "info",
|
||||||
|
"fix": "none",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"useGroupedAccessorPairs": "error",
|
||||||
|
"useObjectSpread": "error",
|
||||||
|
"useNumericSeparators": "off" // TODO: Consider enabling?
|
||||||
|
},
|
||||||
|
"suspicious": {
|
||||||
|
"useErrorMessage": "error",
|
||||||
|
"noEvolvingTypes": "warn", // TODO: Review and enable ASAP - this is VERY VERY BAD
|
||||||
|
"useNumberToFixedDigitsArgument": "error",
|
||||||
|
"useGuardForIn": "warn", // TODO: Review and enable ASAP - this is EVEN FRICKING WORSE
|
||||||
|
"noDoubleEquals": "error",
|
||||||
|
// While this would be a nice rule to enable, the current structure of the codebase makes this infeasible
|
||||||
|
// due to being used for move/ability `args` params and save data-related code.
|
||||||
|
// This can likely be enabled for all non-utils files once these are eventually reworked, but until then we leave it off.
|
||||||
|
"noExplicitAny": "off",
|
||||||
|
"noAssignInExpressions": "off",
|
||||||
|
"noPrototypeBuiltins": "off", // TODO: enable this
|
||||||
|
"noFallthroughSwitchClause": "error", // Prevents accidental automatic fallthroughs in switch cases (use disable comment if needed)
|
||||||
|
"noImplicitAnyLet": "warn", // TODO: Refactor and make this an error
|
||||||
|
"noRedeclare": "info", // TODO: Refactor and make this an error
|
||||||
|
"noGlobalIsNan": "error",
|
||||||
|
"noAsyncPromiseExecutor": "warn", // TODO: Refactor and make this an error
|
||||||
|
"noVar": "error",
|
||||||
|
"noDocumentCookie": "off", // Firefox has minimal support for the "Cookie Store API"
|
||||||
|
"noConstantBinaryExpressions": "error",
|
||||||
|
"noTsIgnore": "error",
|
||||||
|
"useIterableCallbackReturn": "warn" // TODO: Refactor and change to error
|
||||||
|
},
|
||||||
|
"complexity": {
|
||||||
|
"useWhile": "error",
|
||||||
|
"noVoid": "warn", // TODO: Review and enable ASAP - this is also bad
|
||||||
|
"noUselessStringConcat": "error",
|
||||||
|
"noExcessiveCognitiveComplexity": "info", // TODO: Refactor and make this an error
|
||||||
|
"useLiteralKeys": "off", // TODO: enable?
|
||||||
|
"noForEach": "off", // Foreach vs for of is not that simple.
|
||||||
|
"noUselessSwitchCase": "off", // Explicit > Implicit
|
||||||
|
"noUselessConstructor": "error",
|
||||||
|
"noBannedTypes": "warn", // TODO: Refactor and make this an error
|
||||||
|
"noThisInStatic": "error",
|
||||||
|
"noUselessThisAlias": "error",
|
||||||
|
"noUselessTernary": "error",
|
||||||
|
"useIndexOf": "error"
|
||||||
|
},
|
||||||
|
"performance": {
|
||||||
|
"noNamespaceImport": "error",
|
||||||
|
"noDelete": "error",
|
||||||
|
"noBarrelFile": "error"
|
||||||
|
},
|
||||||
|
"nursery": {
|
||||||
|
"noUselessUndefined": "error",
|
||||||
|
"useMaxParams": {
|
||||||
|
"level": "info", // TODO: Change to "error"... eventually...
|
||||||
|
"options": { "max": 7 }
|
||||||
|
},
|
||||||
|
"noShadow": "warn", // TODO: refactor and make "error"
|
||||||
|
"noNonNullAssertedOptionalChain": "warn", // TODO: refactor and make "error"
|
||||||
|
"noDuplicateDependencies": "error",
|
||||||
|
"noImportCycles": "error",
|
||||||
|
// TODO: Change to error once promises are used properly
|
||||||
|
"noMisusedPromises": "info"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"javascript": {
|
"javascript": {
|
||||||
"formatter": { "quoteStyle": "double", "arrowParentheses": "asNeeded" }
|
"formatter": {
|
||||||
|
"quoteStyle": "double",
|
||||||
|
"arrowParentheses": "asNeeded",
|
||||||
|
"operatorLinebreak": "before"
|
||||||
|
},
|
||||||
|
"globals": ["Phaser"],
|
||||||
|
"parser": {
|
||||||
|
"jsxEverywhere": false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"include": ["test/**/*.test.ts"],
|
"includes": ["**/test/**/*.test.ts"],
|
||||||
"javascript": { "globals": [] },
|
|
||||||
"linter": {
|
"linter": {
|
||||||
"rules": {
|
"rules": {
|
||||||
"performance": {
|
"performance": {
|
||||||
"noDelete": "off" // TODO: evaluate if this is necessary for the test(s) to function
|
"noDelete": "off", // TODO: evaluate if this is necessary for the test(s) to function
|
||||||
|
"noNamespaceImport": "off" // this is required for `vi.spyOn` to work in some tests
|
||||||
},
|
},
|
||||||
"style": {
|
"style": {
|
||||||
"noNamespaceImport": "off" // this is required for `vi.spyOn` to work in some tests
|
"noNonNullAssertion": "off" // tedious in some tests
|
||||||
|
},
|
||||||
|
"nursery": {
|
||||||
|
"noFloatingPromises": "error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Overrides to prevent unused import removal inside `overrides.ts`, enums & `.d.ts` files (for TSDoc linkcodes),
|
||||||
|
// as well as inside script boilerplate files (whose imports will _presumably_ be used in the generated file).
|
||||||
|
{
|
||||||
|
"includes": ["**/src/overrides.ts", "**/src/enums/**/*", "**/*.d.ts", "scripts/**/*.boilerplate.ts"],
|
||||||
|
"linter": {
|
||||||
|
"rules": {
|
||||||
|
"correctness": {
|
||||||
|
"noUnusedImports": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"includes": ["**/src/overrides.ts"],
|
||||||
|
"linter": {
|
||||||
|
"rules": {
|
||||||
|
"style": {
|
||||||
|
"useImportType": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
import { Graphviz } from "@hpcc-js/wasm/graphviz";
|
|
||||||
|
|
||||||
const graphviz = await Graphviz.load();
|
|
||||||
|
|
||||||
const inputFile = [];
|
|
||||||
for await (const chunk of process.stdin) {
|
|
||||||
inputFile.push(chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
const file = Buffer.concat(inputFile).toString("utf-8");
|
|
||||||
|
|
||||||
const svg = graphviz.dot(file, "svg");
|
|
||||||
process.stdout.write(svg);
|
|
@ -23,7 +23,7 @@ When formatted correctly, these comments are shown within VS Code or similar IDE
|
|||||||
- Functions also show the comment for each parameter as you type them, making keeping track of arguments inside lengthy functions much more clear.
|
- Functions also show the comment for each parameter as you type them, making keeping track of arguments inside lengthy functions much more clear.
|
||||||
|
|
||||||
They can also be used to generate a commentated overview of the codebase. There is a GitHub action that automatically updates [this docs site](https://pagefaultgames.github.io/pokerogue/main/index.html)
|
They can also be used to generate a commentated overview of the codebase. There is a GitHub action that automatically updates [this docs site](https://pagefaultgames.github.io/pokerogue/main/index.html)
|
||||||
and you can generate it locally as well via `npm run docs` which will generate into the `typedoc/` directory.
|
and you can generate it locally as well via `pnpm run docs` which will generate into the `typedoc/` directory.
|
||||||
|
|
||||||
## Syntax
|
## Syntax
|
||||||
For an example of how TSDoc comments work, here are some TSDoc comments taken from `src/data/moves/move.ts`:
|
For an example of how TSDoc comments work, here are some TSDoc comments taken from `src/data/moves/move.ts`:
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
# Linting & Formatting
|
# Linting & Formatting
|
||||||
|
|
||||||
> "Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
|
Writing clean, readable code is important, and linters and formatters are an integral part of ensuring code quality and readability. \
|
||||||
>
|
|
||||||
> — Martin Fowler
|
|
||||||
|
|
||||||
Writing clean, readable code is important, and linters and formatters are an integral part of ensuring code quality and readability.
|
|
||||||
It is for this reason we are using [Biome](https://biomejs.dev), an opinionated linter/formatter (akin to Prettier) with a heavy focus on speed and performance.
|
It is for this reason we are using [Biome](https://biomejs.dev), an opinionated linter/formatter (akin to Prettier) with a heavy focus on speed and performance.
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
You probably installed Biome already without noticing it - it's included inside `package.json` and should've been downloaded when you ran `npm install` after cloning the repo (assuming you followed proper instructions, that is). If you haven't done that yet, go do it.
|
You probably installed Biome already without noticing it - it's included inside `package.json` and should've been downloaded when you ran `pnpm install` after cloning the repo. If you haven't done that yet, go do that first.
|
||||||
|
|
||||||
# Using Biome
|
# Using Biome
|
||||||
|
|
||||||
@ -19,47 +15,43 @@ On the other hand, if Biome complains about a piece of code, **there's probably
|
|||||||
Biome has integration with many popular code editors. See [these](https://biomejs.dev/guides/editors/first-party-extensions/) [pages](https://biomejs.dev/guides/editors/third-party-extensions/) for information about enabling Biome in your editor of choice.
|
Biome has integration with many popular code editors. See [these](https://biomejs.dev/guides/editors/first-party-extensions/) [pages](https://biomejs.dev/guides/editors/third-party-extensions/) for information about enabling Biome in your editor of choice.
|
||||||
|
|
||||||
## Automated Runs
|
## Automated Runs
|
||||||
Generally speaking, most users shouldn't need to run Biome directly; in addition to editor integration, [pre-commit hook](../lefthook.yml) will periodically run Biome before each commit.
|
Generally speaking, most users shouldn't need to run Biome directly; in addition to editor integration, a [pre-commit hook](../lefthook.yml) will automatically format and lint all staged files before each commit.
|
||||||
You will **not** be able to push code with `error`-level linting problems - fix them beforehand.
|
|
||||||
|
|
||||||
We also have a [Github Action](../.github/workflows/quality.yml) to verify code quality each time a PR is updated, preventing bad code from inadvertently making its way upstream.
|
> ![WARNING]
|
||||||
|
> You will **not** be able to commit code if any staged files contain `error`-level linting problems. \
|
||||||
|
> If you, for whatever reason, _absolutely need_ to bypass Lefthook for a given commit,
|
||||||
|
> pass the `--no-verify` flag to `git commit`.
|
||||||
|
|
||||||
### Why am I getting errors for code I didn't write?
|
We also have a [Github Action](../.github/workflows/linting.yml) to verify code quality each time a PR is updated, preventing bad code from inadvertently making its way upstream. \
|
||||||
<!-- TODO: Remove this if/when we perform a project wide linting spree -->
|
These are effectively the same commands as run by Lefthook, merely on a project-wide scale.
|
||||||
To save time and minimize friction with existing code, both the pre-commit hook and workflow run will only check files **directly changed** by a given PR or commit.
|
|
||||||
As a result, changes to files not updated since Biome's introduction can cause any _prior_ linting errors in them to resurface and get flagged.
|
|
||||||
This should occur less and less often as time passes and more files are updated to the new standard.
|
|
||||||
|
|
||||||
## Running Biome via CLI
|
## Running Biome via CLI
|
||||||
If you want Biome to check your files manually, you can run it from the command line like so:
|
To run you Biome on your files manually, you have 2 main options:
|
||||||
|
1. Run the scripts included in `package.json` (`pnpm biome` and `pnpm biome:all`). \
|
||||||
|
These have sensible defaults for command-line options, but do not allow altering certain flags (as some cannot be specified twice in the same command)
|
||||||
|
|
||||||
|
2. Execute the Biome executable manually from the command line like so:
|
||||||
```sh
|
```sh
|
||||||
npx biome check --[flags]
|
pnpm exec biome check --[flags]
|
||||||
```
|
```
|
||||||
|
This allows customizing non-overridable flags like `--diagnostic-level` on a more granular level, but requires slightly more verbosity and specifying more options.
|
||||||
|
|
||||||
A full list of flags and options can be found on [their website](https://biomejs.dev/reference/cli/), but here's a few useful ones to keep in mind:
|
A full list of flags and options can be found on [their website](https://biomejs.dev/reference/cli/), but here's a few useful ones to keep in mind:
|
||||||
|
|
||||||
- `--write` will cause Biome to write all "safe" fixes and formatting changes directly to your files (rather than just complaining and doing nothing).
|
- `--write` will cause Biome to write all "safe" fixes and formatting changes directly to your files (rather than just complaining and erroring out).
|
||||||
- `--changed` and `--staged` will only perform checks on all changed or staged files respectively. Biome sources this info from the relevant version control system (in this case Git).
|
- `--changed` and `--staged` will limit checking to all changed or staged files respectively. Biome sources this info from the relevant version control system (in this case `git`).
|
||||||
- `diagnostic-level=XXX` will only show diagnostics with at least the given severity level (`info/warn/error`). Useful to only focus on errors causing a failed workflow run or similar.
|
- `diagnostic-level=XXX` will only show diagnostics with at least the given severity level (`info/warn/error`). Useful to only focus on errors causing a failed workflow run or similar.
|
||||||
|
|
||||||
## Linting Rules
|
## Linting Rules
|
||||||
|
|
||||||
We primarily use Biome's [recommended ruleset](https://biomejs.dev/linter/rules/) for linting JS/TS, with some customizations to better suit our project's needs[^1].
|
We primarily use Biome's [recommended ruleset](https://biomejs.dev/linter/rules/) for linting JS/TS files, with some customizations to better suit our project's needs[^1].
|
||||||
|
|
||||||
Some things to consider:
|
Some things to consider:
|
||||||
|
|
||||||
- We have disabled rules that prioritize style over performance, such as `useTemplate`.
|
- We have disabled rules that prioritize style over performance, such as `useTemplate`.
|
||||||
- Some rules are currently disabled or marked as warnings (`warn`) to allow for gradual refactoring without blocking development. **Do not write new code that triggers these warnings.**
|
- Some rules are currently marked as warnings (`warn`) to allow for gradual refactoring without blocking development. **Do not write new code that triggers these rules!**
|
||||||
- The linter is configured to ignore specific files and folders (such as excessively large files or ones in need of refactoring) to improve performance and focus on actionable areas.
|
- The linter is configured to ignore specific files and folders (such as excessively large files or ones in need of refactoring) to improve performance and focus on actionable areas.
|
||||||
|
|
||||||
Any questions about linting rules should be brought up in the `#dev-corner` channel in the discord.
|
Any questions about linting rules can be brought up in the `#dev-corner` channel in the community Discord.
|
||||||
|
|
||||||
[^1]: A complete list of rules can be found in the `biome.jsonc` file in the project root.
|
[^1]: A complete list of rules can be found in the [`biome.jsonc`](../biome.jsonc) file in the project root. Many rules are accompanied by comments explaining the reasons for their inclusion (or lack thereof).
|
||||||
|
|
||||||
## What about ESLint?
|
|
||||||
|
|
||||||
<!-- Remove if/when we finally ditch eslint for good -->
|
|
||||||
Our project migrated away from ESLint around March 2025 due to it simply not scaling well enough with the codebase's ever-growing size. The [existing eslint rules](../eslint.config.js) are considered _deprecated_, only kept due to Biome lacking the corresponding rules in its current ruleset.
|
|
||||||
|
|
||||||
No additional ESLint rules should be added under any circumstances - even the few currently in circulation take longer to run than the entire Biome formatting/linting suite combined.
|
|
||||||
|
147
docs/localization.md
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
# Localization 101
|
||||||
|
|
||||||
|
PokéRogue's localization team puts immense effort into making the game accessible around the world, supporting over 12 different languages at the time of writing this document. \
|
||||||
|
As a developer, it's important to help maintain global accessibility by effectively coordinating with the Translation Team on any new features or enhancements.
|
||||||
|
|
||||||
|
This document aims to cover everything you need to know to help keep the integration process for localization smooth and simple.
|
||||||
|
|
||||||
|
# Prerequisites
|
||||||
|
Before you continue, this document assumes:
|
||||||
|
- You have already forked the repository and set up a development environment according to [CONTRIBUTING.md](../CONTRIBUTING.md).
|
||||||
|
- You have a basic level of familiarity with Git commands and GitHub repositories.
|
||||||
|
- You have joined the [community Discord](https://discord.gg/pokerogue) and have access to `#dev-corner` and related channels via **[#select-roles](https://discord.com/channels/1125469663833370665/1194825607738052621)**.
|
||||||
|
This is the easiest way to keep in touch with both the Translation Team and other like-minded contributors!
|
||||||
|
|
||||||
|
# About the `pokerogue-locales` submodule
|
||||||
|
|
||||||
|
PokéRogue's translations are managed under a separate dedicated repository, [`pokerogue-locales`](https://github.com/pagefaultgames/pokerogue-locales/).
|
||||||
|
This repository is integrated into the main one as a [git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules) within the `public/locales` folder.
|
||||||
|
|
||||||
|
## What Is a Submodule?
|
||||||
|
|
||||||
|
In essence, a submodule is a way for one repository (i.e. `pokerogue`) to use another repository (i.e. `pokerogue-locales`) internally.
|
||||||
|
The parent repo (the "superproject") houses a cloned version of the 2nd repository (the "submodule") inside it, making locales effectively a "repository within a repository", so to speak.
|
||||||
|
|
||||||
|
>[!TIP]
|
||||||
|
> Many popular IDEs have integrated `git` support with special handling around submodules:
|
||||||
|
>
|
||||||
|
> 
|
||||||
|
>
|
||||||
|
> 
|
||||||
|
|
||||||
|
## Fetching Changes from Submodules
|
||||||
|
|
||||||
|
The following command will initialize your branch's locales repository and update its HEAD:
|
||||||
|
```bash
|
||||||
|
pnpm update-locales
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> This command is run _automatically_ after cloning, merging or changing branches, so you should rarely have to run it manually.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> If you EVER run into issues with the `locales` submodule, try deleting the `.git/modules/public` and `public/locales` folders before re-initializing it again.
|
||||||
|
|
||||||
|
## How Are Translations Integrated?
|
||||||
|
|
||||||
|
This project uses the [i18next library](https://www.i18next.com/) to integrate translations from `public/locales` into the source code.
|
||||||
|
The basic process for fetching translated text goes roughly as follows:
|
||||||
|
1. The source code fetches text by a given key.
|
||||||
|
```ts
|
||||||
|
globalScene.phaseManager.queueMessage(
|
||||||
|
i18next.t("fileName:keyName", { arg1: "Hello", arg2: "an example", ... })
|
||||||
|
);
|
||||||
|
```
|
||||||
|
2. The game looks up the key in the corresponding JSON file for the user's language.
|
||||||
|
```jsonc
|
||||||
|
// from "en/file-name.json"...
|
||||||
|
{
|
||||||
|
"keyName": "{{arg1}}! This is {{arg2}} of translated text!"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
If the key doesn't exist for the given language, the game will default to an appropriate fallback (usually the corresponding English key).
|
||||||
|
3. The game shows the translated text to the user.
|
||||||
|
```ts
|
||||||
|
"Hello! This is an example of translated text!"
|
||||||
|
```
|
||||||
|
|
||||||
|
# Submitting Locales Changes
|
||||||
|
If you have a feature or enhancement that requires additions or changes to in-game text, you will need to make a fork of the `pokerogue-locales` repo and submit your text changes as a pull request _in addition_ to your pull request to the main project. \
|
||||||
|
Since these two PRs aren't _technically_ linked, it's important to coordinate with the Translation Team to ensure that both PRs are integrated safely into the project.
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> **DO NOT HARDCODE PLAYER-FACING TEXT INTO THE CODE!**
|
||||||
|
|
||||||
|
## Making Changes
|
||||||
|
|
||||||
|
One perk of submodules is you don't actually _need_ to clone the locales repository to start contributing - `git` already does that for you on initialization.
|
||||||
|
|
||||||
|
Given `pokerogue-locales` is a full-fledged `git` repository _inside_ `pokerogue`, making changes is roughly the same as normal, merely using `public/locales` as your root directory.
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Make sure to checkout or rebase onto `upstream/main` (`pnpm update-locales:remote`) **BEFORE** creating a locales PR!
|
||||||
|
> The checked-out commit is based on the superproject's SHA-1 by default, so hastily making changes may see you basing your commits on last week's `HEAD`.
|
||||||
|
|
||||||
|
## Requirements for Adding Translated Text
|
||||||
|
When a new feature or enhancement requires adding a new locales key **without changing text in existing keys**, we have the following workflow with regards to localization:
|
||||||
|
1. You (the developer) make a pull request to the main repository for your new feature.
|
||||||
|
If this feature requires new text, the text should be integrated into the code with a new `i18next` key pointing to where you plan to add it into the locales repository.
|
||||||
|
2. You then make another pull request — this time to the `pokerogue-locales` repository — adding a new entry with text for each key you added to your main PR.
|
||||||
|
- You must add the corresponding **English keys** while making the PR; the Translation Team can take care of the rest[^2].
|
||||||
|
- For any feature pulled from the mainline Pokémon games (e.g. a Move or Ability implementation), it's best practice to include a source link for any added text. \
|
||||||
|
[Poké Corpus](https://abcboy101.github.io/poke-corpus/) is a great resource for finding text from the mainline games; otherwise, a video/picture showing the text being displayed should suffice.
|
||||||
|
- You should also [notify the current Head of Translation](#notifying-translation) to ensure a fast response.
|
||||||
|
3. Your locales should use the following format:
|
||||||
|
- File names should be in `kebab-case`. Example: `trainer-names.json`
|
||||||
|
- Key names should be in `camelCase`. Example: `aceTrainer`
|
||||||
|
- If you make use of i18next's inbuilt [context support](https://www.i18next.com/translation-function/context), you need to use `snake_case` for the context key. Example: `aceTrainer_male`
|
||||||
|
4. At this point, you may begin [testing locales integration in your main PR](#documenting-locales-changes).
|
||||||
|
5. The Translation Team will approve the locales PR (after corrections, if necessary), then merge it into `pokerogue-locales`.
|
||||||
|
6. The Dev Team will approve your main PR for your feature, then merge it into PokéRogue's beta environment.
|
||||||
|
|
||||||
|
[^2]: For those wondering, the reason for choosing English specifically is due to it being the master language set in Pontoon (the program used by the Translation Team to perform locale updates).
|
||||||
|
If a key is present in any language _except_ the master language, it won't appear anywhere else in the translation tool, rendering missing English keys quite a hassle.
|
||||||
|
|
||||||
|
### Requirements for Modifying Translated Text
|
||||||
|
|
||||||
|
PRs that modify existing text have different risks with respect to coordination between development and translation, so their requirements are slightly different:
|
||||||
|
- As above, you set up 2 PRs: one for the feature itself in the main repo, and another for the associated locales changes in the locale repo.
|
||||||
|
- Now, however, you need to have your main PR be approved by the Dev Team **before** your corresponding locale changes are merged in.
|
||||||
|
- After your main PR is approved, you may update the submodule and post video evidence of integration into the **locales PR**.
|
||||||
|
- A Lead or Senior Translator from the Translation Team will then approve your main PR (if all is well), clearing your feature for merging into `beta`.
|
||||||
|
|
||||||
|
## Documenting Locales Changes
|
||||||
|
|
||||||
|
After making a PR involving any outwards-facing behavior (but _especially_ locales-related ones), it's generally considered good practice to attach proof of those changes working in-game.
|
||||||
|
|
||||||
|
The basic procedure is roughly as follows:
|
||||||
|
1. Update your locales submodule to point to **the branch you used to make the locales PR**. \
|
||||||
|
Many IDEs with `git` integration support doing this from the GUI, \
|
||||||
|
or you can simply do it via command-line:
|
||||||
|
```bash
|
||||||
|
cd public/locales
|
||||||
|
git checkout your-branch-name-here
|
||||||
|
```
|
||||||
|
2. Set some of the [in-game overrides](../CONTRIBUTING.md#1---manual-testing) inside `overrides.ts` to values corresponding to the interactions being tested.
|
||||||
|
3. Start a local dev server (`pnpm start:dev`) and open localhost in your browser.
|
||||||
|
4. Take screenshots or record a video of the locales changes being displayed in-game using the software of your choice[^2].
|
||||||
|
|
||||||
|
[^2]: For those lacking a screen capture device, [OBS Studio](https://obsproject.com) is a popular open-source option.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> For those aiming to film their changes, bear in mind that GitHub has a hard **10mB limit** on uploaded media content.
|
||||||
|
> If your video is too large, consider making it shorter or downscaling the quality.
|
||||||
|
|
||||||
|
## Notifying Translation
|
||||||
|
Put simply, stating that a PR exists makes it much easier to review and merge.
|
||||||
|
|
||||||
|
The easiest way to do this is by **pinging the current Head of Translation** in the [community Discord](https://discord.gg/pokerogue) (ideally in `#dev-corner` or similar).
|
||||||
|
|
||||||
|
<!-- Remember to update this everytime the head of translation changes! -->
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> The current Head of Translation is: \
|
||||||
|
> ** @lugiadrien **
|
||||||
|
|
||||||
|
# Closing Remarks
|
||||||
|
If you have any questions about the developer process for localization, don't hesitate to ask!
|
||||||
|
Feel free to contact us on Discord - the Dev Team and Translation Team will be happy to answer any questions.
|
27
docs/podman.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Using Podman
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
* `podman >=5.x`
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
|
1. `podman build -t pokerogue -f Dockerfile .`
|
||||||
|
2. `podman create --name temp-pokerogue localhost/pokerogue`
|
||||||
|
3. `podman cp temp-pokerogue:/app/node_modules ./`
|
||||||
|
4. `podman cp temp-pokerogue:/app/public/locales ./public/`
|
||||||
|
5. `podman rm temp-pokerogue`
|
||||||
|
6. `podman run --rm -p 8000:8000 -v $(pwd):/app:Z --userns=keep-id -u $(id -u):$(id -g) localhost/pokerogue`
|
||||||
|
7. Visit `http://localhost:8000/`
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|
||||||
|
1. Steps 2,3,4 are required because mounting working directory without installed `node_modules/` and assets locally will be empty,
|
||||||
|
this way we prevent it by copying them from the container itself to local directory
|
||||||
|
|
||||||
|
2. `podman run` may take a couple of minutes to mount the working directory
|
||||||
|
|
||||||
|
### Running tests inside container
|
||||||
|
|
||||||
|
`podman run --rm -p 8000:8000 -v $(pwd):/app:Z --userns=keep-id -u $(id -u):$(id -g) localhost/pokerogue pnpm test:silent
|
||||||
|
`
|
@ -1,43 +0,0 @@
|
|||||||
/** @ts-check */
|
|
||||||
import tseslint from "typescript-eslint";
|
|
||||||
import stylisticTs from "@stylistic/eslint-plugin-ts";
|
|
||||||
import parser from "@typescript-eslint/parser";
|
|
||||||
import importX from "eslint-plugin-import-x";
|
|
||||||
|
|
||||||
export default tseslint.config(
|
|
||||||
{
|
|
||||||
name: "eslint-config",
|
|
||||||
files: ["src/**/*.{ts,tsx,js,jsx}", "test/**/*.{ts,tsx,js,jsx}"],
|
|
||||||
ignores: ["dist/*", "build/*", "coverage/*", "public/*", ".github/*", "node_modules/*", ".vscode/*"],
|
|
||||||
languageOptions: {
|
|
||||||
parser: parser,
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
"import-x": importX,
|
|
||||||
"@stylistic/ts": stylisticTs,
|
|
||||||
"@typescript-eslint": tseslint.plugin,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
"no-undef": "off", // Disables the rule that disallows the use of undeclared variables (TypeScript handles this)
|
|
||||||
"no-extra-semi": "error", // Disallows unnecessary semicolons for TypeScript-specific syntax
|
|
||||||
"import-x/extensions": ["error", "never", { json: "always" }], // Enforces no extension for imports unless json
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "eslint-tests",
|
|
||||||
files: ["test/**/**.test.ts"],
|
|
||||||
languageOptions: {
|
|
||||||
parser: parser,
|
|
||||||
parserOptions: {
|
|
||||||
project: ["./tsconfig.json"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
"@typescript-eslint": tseslint.plugin,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
"@typescript-eslint/no-floating-promises": "error", // Require Promise-like statements to be handled appropriately. - https://typescript-eslint.io/rules/no-floating-promises/
|
|
||||||
"@typescript-eslint/no-misused-promises": "error", // Disallow Promises in places not designed to handle them. - https://typescript-eslint.io/rules/no-misused-promises/
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
23
global.d.ts
vendored
@ -1,14 +1,31 @@
|
|||||||
|
import type { AnyFn } from "#types/type-helpers";
|
||||||
import type { SetupServerApi } from "msw/node";
|
import type { SetupServerApi } from "msw/node";
|
||||||
|
|
||||||
export {};
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
/**
|
/**
|
||||||
* Only used in testing.
|
* Only used in testing.
|
||||||
* Can technically be undefined/null but for ease of use we are going to assume it is always defined.
|
* Can technically be undefined/null but for ease of use we are going to assume it is always defined.
|
||||||
* Used to load i18n files exclusively.
|
* Used to load i18n files exclusively.
|
||||||
*
|
*
|
||||||
* To set up your own server in a test see `game_data.test.ts`
|
* To set up your own server in a test see `game-data.test.ts`
|
||||||
*/
|
*/
|
||||||
var server: SetupServerApi;
|
var server: SetupServerApi;
|
||||||
|
|
||||||
|
// Overloads for `Function.apply` and `Function.call` to add type safety on matching argument types
|
||||||
|
interface Function {
|
||||||
|
apply<T extends AnyFn>(this: T, thisArg: ThisParameterType<T>, argArray: Parameters<T>): ReturnType<T>;
|
||||||
|
|
||||||
|
call<T extends AnyFn>(this: T, thisArg: ThisParameterType<T>, ...argArray: Parameters<T>): ReturnType<T>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Global augments for `typedoc` to prevent TS from erroring when editing the config JS file
|
||||||
|
declare module "typedoc" {
|
||||||
|
export interface TypeDocOptionMap {
|
||||||
|
coverageLabel: string;
|
||||||
|
coverageColor: string;
|
||||||
|
coverageOutputPath: string;
|
||||||
|
coverageOutputType: "svg" | "json" | "all";
|
||||||
|
coverageSvgWidth: number;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
19
lefthook.yml
@ -1,19 +1,24 @@
|
|||||||
pre-commit:
|
pre-commit:
|
||||||
parallel: true
|
|
||||||
commands:
|
|
||||||
biome-lint:
|
|
||||||
run: npx biome check --write --reporter=summary --staged --no-errors-on-unmatched
|
|
||||||
stage_fixed: true
|
|
||||||
skip:
|
skip:
|
||||||
- merge
|
- merge
|
||||||
- rebase
|
- rebase
|
||||||
|
commands:
|
||||||
|
biome-lint:
|
||||||
|
# Disable colors as certain IDEs don't support it in the output pane.
|
||||||
|
# Summary mode looks decent in plain ASCII anyhow
|
||||||
|
run: pnpm exec biome check --write --colors=off --reporter=summary --staged --no-errors-on-unmatched --diagnostic-level=error
|
||||||
|
stage_fixed: true
|
||||||
|
ls-lint:
|
||||||
|
run: pnpm exec ls-lint
|
||||||
|
|
||||||
post-merge:
|
post-merge:
|
||||||
commands:
|
commands:
|
||||||
update-submodules:
|
update-submodules:
|
||||||
run: git submodule update --init --recursive
|
run: pnpm update-locales
|
||||||
|
|
||||||
post-checkout:
|
post-checkout:
|
||||||
commands:
|
commands:
|
||||||
update-submodules:
|
update-submodules:
|
||||||
run: git submodule update --init --recursive
|
# cf https://git-scm.com/docs/githooks#_post_checkout:
|
||||||
|
# The 3rd argument is 1 for branch checkouts and 0 for file checkouts.
|
||||||
|
run: if test {3} -eq "1"; then pnpm update-locales; fi
|
8029
package-lock.json
generated
84
package.json
@ -1,72 +1,78 @@
|
|||||||
{
|
{
|
||||||
"name": "pokemon-rogue-battle",
|
"name": "pokemon-rogue-battle",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.9.5",
|
"version": "1.10.7",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "vite",
|
"start:prod": "vite --mode production",
|
||||||
|
"start:beta": "vite --mode beta",
|
||||||
"start:dev": "vite --mode development",
|
"start:dev": "vite --mode development",
|
||||||
|
"start:podman": "vite --mode development --host 0.0.0.0 --port $PORT",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"build:beta": "vite build --mode beta",
|
"build:beta": "vite build --mode beta",
|
||||||
|
"build:dev": "vite build --mode development",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"test": "vitest run --no-isolate",
|
"test": "vitest run --no-isolate",
|
||||||
"test:cov": "vitest run --coverage --no-isolate",
|
"test:cov": "vitest run --coverage --no-isolate",
|
||||||
"test:watch": "vitest watch --coverage --no-isolate",
|
"test:watch": "vitest watch --coverage --no-isolate",
|
||||||
"test:silent": "vitest run --silent --no-isolate",
|
"test:silent": "vitest run --silent='passed-only' --no-isolate",
|
||||||
"test:create": "node scripts/create-test/create-test.js",
|
"test:create": "node scripts/create-test/create-test.js",
|
||||||
|
"eggMoves:parse": "node scripts/parse-egg-moves/main.js",
|
||||||
|
"scrape-trainers": "node scripts/scrape-trainer-names/main.js",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"eslint": "eslint --fix .",
|
"typecheck:scripts": "tsc -p scripts/jsconfig.json",
|
||||||
"eslint-ci": "eslint .",
|
"biome": "biome check --write --changed --no-errors-on-unmatched --diagnostic-level=error",
|
||||||
"biome": "biome check --write --changed --no-errors-on-unmatched",
|
"biome:all": "biome check --write --no-errors-on-unmatched --diagnostic-level=error",
|
||||||
"biome-ci": "biome ci --diagnostic-level=error --reporter=github --changed --no-errors-on-unmatched",
|
"biome-ci": "biome ci --diagnostic-level=error --reporter=github --no-errors-on-unmatched",
|
||||||
"docs": "typedoc",
|
"typedoc": "typedoc",
|
||||||
"depcruise": "depcruise src",
|
"depcruise": "depcruise src test",
|
||||||
"depcruise:graph": "depcruise src --output-type dot | node dependency-graph.js > dependency-graph.svg",
|
"postinstall": "lefthook install; git submodule update --init --recursive",
|
||||||
"postinstall": "npx lefthook install && npx lefthook run post-merge",
|
"update-version:patch": "pnpm version patch --force --no-git-tag-version",
|
||||||
"update-version:patch": "npm version patch --force --no-git-tag-version",
|
"update-version:minor": "pnpm version minor --force --no-git-tag-version",
|
||||||
"update-version:minor": "npm version minor --force --no-git-tag-version",
|
"update-locales": "git submodule update --progress --init --recursive",
|
||||||
"update-locales:remote": "git submodule update --progress --init --recursive --force --remote"
|
"update-locales:remote": "git submodule update --progress --init --recursive --force --remote"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "1.9.4",
|
"@biomejs/biome": "2.2.4",
|
||||||
"@eslint/js": "^9.23.0",
|
"@ls-lint/ls-lint": "2.3.1",
|
||||||
"@hpcc-js/wasm": "^2.22.4",
|
"@types/crypto-js": "^4.2.0",
|
||||||
"@stylistic/eslint-plugin-ts": "^4.1.0",
|
|
||||||
"@types/jsdom": "^21.1.7",
|
"@types/jsdom": "^21.1.7",
|
||||||
"@types/node": "^22.13.14",
|
"@types/node": "^22.16.5",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
"@vitest/coverage-istanbul": "^3.2.4",
|
||||||
"@typescript-eslint/parser": "^8.28.0",
|
"@vitest/expect": "^3.2.4",
|
||||||
"@vitest/coverage-istanbul": "^3.0.9",
|
"@vitest/utils": "^3.2.4",
|
||||||
"dependency-cruiser": "^16.3.10",
|
"chalk": "^5.4.1",
|
||||||
"eslint": "^9.23.0",
|
"dependency-cruiser": "^16.10.4",
|
||||||
"eslint-plugin-import-x": "^4.9.4",
|
"inquirer": "^12.8.2",
|
||||||
"inquirer": "^12.4.2",
|
"jsdom": "^26.1.0",
|
||||||
"jsdom": "^26.0.0",
|
"lefthook": "^1.12.2",
|
||||||
"lefthook": "^1.11.5",
|
"msw": "^2.10.4",
|
||||||
"msw": "^2.7.3",
|
|
||||||
"phaser3spectorjs": "^0.0.8",
|
"phaser3spectorjs": "^0.0.8",
|
||||||
"typedoc": "^0.28.1",
|
"typedoc": "^0.28.13",
|
||||||
"typescript": "^5.8.2",
|
"typedoc-github-theme": "^0.3.1",
|
||||||
"typescript-eslint": "^8.28.0",
|
"typedoc-plugin-coverage": "^4.0.1",
|
||||||
"vite": "^6.3.4",
|
"typedoc-plugin-mdn-links": "^5.0.9",
|
||||||
|
"typescript": "^5.9.2",
|
||||||
|
"vite": "^7.0.7",
|
||||||
"vite-tsconfig-paths": "^5.1.4",
|
"vite-tsconfig-paths": "^5.1.4",
|
||||||
"vitest": "^3.0.9",
|
"vitest": "^3.2.4",
|
||||||
"vitest-canvas-mock": "^0.3.3"
|
"vitest-canvas-mock": "^0.3.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material/material-color-utilities": "^0.2.7",
|
"@material/material-color-utilities": "^0.2.7",
|
||||||
"compare-versions": "^6.1.1",
|
"compare-versions": "^6.1.1",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"i18next": "^24.2.2",
|
"i18next": "^24.2.3",
|
||||||
"i18next-browser-languagedetector": "^8.0.4",
|
"i18next-browser-languagedetector": "^8.2.0",
|
||||||
"i18next-http-backend": "^3.0.2",
|
"i18next-http-backend": "^3.0.2",
|
||||||
"i18next-korean-postposition-processor": "^1.0.0",
|
"i18next-korean-postposition-processor": "^1.0.0",
|
||||||
"json-stable-stringify": "^1.2.0",
|
"json-stable-stringify": "^1.3.0",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
"phaser": "^3.88.2",
|
"phaser": "^3.90.0",
|
||||||
"phaser3-rex-plugins": "^1.80.15"
|
"phaser3-rex-plugins": "^1.80.16"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=22.0.0"
|
"node": ">=22.0.0"
|
||||||
}
|
},
|
||||||
|
"packageManager": "pnpm@10.17.0"
|
||||||
}
|
}
|
||||||
|
3898
pnpm-lock.yaml
Normal file
6
pnpm-workspace.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
onlyBuiltDependencies:
|
||||||
|
- esbuild
|
||||||
|
- msw
|
||||||
|
- lefthook
|
||||||
|
|
||||||
|
shellEmulator: true
|
BIN
public/audio/bgm/battle_legendary_eternatus_p1.mp3
Normal file
BIN
public/audio/bgm/battle_legendary_eternatus_p2.mp3
Normal file
@ -1102,6 +1102,112 @@
|
|||||||
"volume": 100,
|
"volume": 100,
|
||||||
"pitch": 136,
|
"pitch": 136,
|
||||||
"eventType": "AnimTimedSoundEvent"
|
"eventType": "AnimTimedSoundEvent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frameIndex": 0,
|
||||||
|
"resourceName": "PRAS- Strong Winds",
|
||||||
|
"bgX": 0,
|
||||||
|
"bgY": 0,
|
||||||
|
"opacity": 0,
|
||||||
|
"duration": 4,
|
||||||
|
"eventType": "AnimTimedAddBgEvent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frameIndex": 0,
|
||||||
|
"resourceName": "",
|
||||||
|
"bgX": 0,
|
||||||
|
"bgY": 0,
|
||||||
|
"opacity": 32,
|
||||||
|
"duration": 4,
|
||||||
|
"eventType": "AnimTimedUpdateBgEvent"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"4": [
|
||||||
|
{
|
||||||
|
"frameIndex": 4,
|
||||||
|
"resourceName": "",
|
||||||
|
"bgX": 10,
|
||||||
|
"bgY": 0,
|
||||||
|
"opacity": 64,
|
||||||
|
"duration": 4,
|
||||||
|
"eventType": "AnimTimedUpdateBgEvent"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"8": [
|
||||||
|
{
|
||||||
|
"frameIndex": 8,
|
||||||
|
"resourceName": "",
|
||||||
|
"bgX": 20,
|
||||||
|
"bgY": 0,
|
||||||
|
"opacity": 128,
|
||||||
|
"duration": 4,
|
||||||
|
"eventType": "AnimTimedUpdateBgEvent"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"12": [
|
||||||
|
{
|
||||||
|
"frameIndex": 12,
|
||||||
|
"resourceName": "",
|
||||||
|
"bgX": 30,
|
||||||
|
"bgY": 0,
|
||||||
|
"opacity": 128,
|
||||||
|
"duration": 4,
|
||||||
|
"eventType": "AnimTimedUpdateBgEvent"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"16": [
|
||||||
|
{
|
||||||
|
"frameIndex": 16,
|
||||||
|
"resourceName": "",
|
||||||
|
"bgX": 40,
|
||||||
|
"bgY": 0,
|
||||||
|
"opacity": 128,
|
||||||
|
"duration": 4,
|
||||||
|
"eventType": "AnimTimedUpdateBgEvent"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"20": [
|
||||||
|
{
|
||||||
|
"frameIndex": 20,
|
||||||
|
"resourceName": "",
|
||||||
|
"bgX": 50,
|
||||||
|
"bgY": 0,
|
||||||
|
"opacity": 128,
|
||||||
|
"duration": 4,
|
||||||
|
"eventType": "AnimTimedUpdateBgEvent"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"24": [
|
||||||
|
{
|
||||||
|
"frameIndex": 24,
|
||||||
|
"resourceName": "",
|
||||||
|
"bgX": 60,
|
||||||
|
"bgY": 0,
|
||||||
|
"opacity": 64,
|
||||||
|
"duration": 4,
|
||||||
|
"eventType": "AnimTimedUpdateBgEvent"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"28": [
|
||||||
|
{
|
||||||
|
"frameIndex": 28,
|
||||||
|
"resourceName": "",
|
||||||
|
"bgX": 70,
|
||||||
|
"bgY": 0,
|
||||||
|
"opacity": 32,
|
||||||
|
"duration": 4,
|
||||||
|
"eventType": "AnimTimedUpdateBgEvent"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"32": [
|
||||||
|
{
|
||||||
|
"frameIndex": 32,
|
||||||
|
"resourceName": "",
|
||||||
|
"bgX": 80,
|
||||||
|
"bgY": 0,
|
||||||
|
"opacity": 0,
|
||||||
|
"duration": 3,
|
||||||
|
"eventType": "AnimTimedUpdateBgEvent"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -333,8 +333,6 @@
|
|||||||
"671-yellow",
|
"671-yellow",
|
||||||
"6713",
|
"6713",
|
||||||
"6713",
|
"6713",
|
||||||
"672",
|
|
||||||
"672",
|
|
||||||
"6724",
|
"6724",
|
||||||
"6724",
|
"6724",
|
||||||
"673",
|
"673",
|
||||||
@ -377,10 +375,6 @@
|
|||||||
"690",
|
"690",
|
||||||
"691",
|
"691",
|
||||||
"691",
|
"691",
|
||||||
"692",
|
|
||||||
"692",
|
|
||||||
"693",
|
|
||||||
"693",
|
|
||||||
"695",
|
"695",
|
||||||
"695",
|
"695",
|
||||||
"696",
|
"696",
|
||||||
@ -503,10 +497,6 @@
|
|||||||
"751",
|
"751",
|
||||||
"752",
|
"752",
|
||||||
"752",
|
"752",
|
||||||
"753",
|
|
||||||
"753",
|
|
||||||
"754",
|
|
||||||
"754",
|
|
||||||
"755",
|
"755",
|
||||||
"755",
|
"755",
|
||||||
"756",
|
"756",
|
||||||
@ -535,10 +525,6 @@
|
|||||||
"767",
|
"767",
|
||||||
"768",
|
"768",
|
||||||
"768",
|
"768",
|
||||||
"769",
|
|
||||||
"769",
|
|
||||||
"770",
|
|
||||||
"770",
|
|
||||||
"771",
|
"771",
|
||||||
"771",
|
"771",
|
||||||
"772",
|
"772",
|
||||||
@ -595,6 +581,20 @@
|
|||||||
"774-yellow",
|
"774-yellow",
|
||||||
"774",
|
"774",
|
||||||
"774",
|
"774",
|
||||||
|
"774-blue-meteor",
|
||||||
|
"774-blue-meteor",
|
||||||
|
"774-green-meteor",
|
||||||
|
"774-green-meteor",
|
||||||
|
"774-indigo-meteor",
|
||||||
|
"774-indigo-meteor",
|
||||||
|
"774-orange-meteor",
|
||||||
|
"774-orange-meteor",
|
||||||
|
"774-red-meteor",
|
||||||
|
"774-red-meteor",
|
||||||
|
"774-violet-meteor",
|
||||||
|
"774-violet-meteor",
|
||||||
|
"774-yellow-meteor",
|
||||||
|
"774-yellow-meteor",
|
||||||
"775",
|
"775",
|
||||||
"775",
|
"775",
|
||||||
"776",
|
"776",
|
||||||
@ -747,10 +747,6 @@
|
|||||||
"841",
|
"841",
|
||||||
"842",
|
"842",
|
||||||
"842",
|
"842",
|
||||||
"843",
|
|
||||||
"843",
|
|
||||||
"844",
|
|
||||||
"844",
|
|
||||||
"845-gorging",
|
"845-gorging",
|
||||||
"845-gorging",
|
"845-gorging",
|
||||||
"845-gulping",
|
"845-gulping",
|
||||||
@ -889,10 +885,6 @@
|
|||||||
"900",
|
"900",
|
||||||
"901",
|
"901",
|
||||||
"901",
|
"901",
|
||||||
"902-female",
|
|
||||||
"902-female",
|
|
||||||
"902",
|
|
||||||
"902",
|
|
||||||
"903",
|
"903",
|
||||||
"903",
|
"903",
|
||||||
"904",
|
"904",
|
||||||
@ -1445,8 +1437,6 @@
|
|||||||
"671b-yellow",
|
"671b-yellow",
|
||||||
"6713b",
|
"6713b",
|
||||||
"6713b",
|
"6713b",
|
||||||
"672b",
|
|
||||||
"672b",
|
|
||||||
"6724b",
|
"6724b",
|
||||||
"6724b",
|
"6724b",
|
||||||
"673b",
|
"673b",
|
||||||
@ -1489,10 +1479,6 @@
|
|||||||
"690b",
|
"690b",
|
||||||
"691b",
|
"691b",
|
||||||
"691b",
|
"691b",
|
||||||
"692b",
|
|
||||||
"692b",
|
|
||||||
"693b",
|
|
||||||
"693b",
|
|
||||||
"695b",
|
"695b",
|
||||||
"695b",
|
"695b",
|
||||||
"696b",
|
"696b",
|
||||||
@ -1615,10 +1601,6 @@
|
|||||||
"751b",
|
"751b",
|
||||||
"752b",
|
"752b",
|
||||||
"752b",
|
"752b",
|
||||||
"753b",
|
|
||||||
"753b",
|
|
||||||
"754b",
|
|
||||||
"754b",
|
|
||||||
"755b",
|
"755b",
|
||||||
"755b",
|
"755b",
|
||||||
"756b",
|
"756b",
|
||||||
@ -1647,10 +1629,6 @@
|
|||||||
"767b",
|
"767b",
|
||||||
"768b",
|
"768b",
|
||||||
"768b",
|
"768b",
|
||||||
"769b",
|
|
||||||
"769b",
|
|
||||||
"770b",
|
|
||||||
"770b",
|
|
||||||
"771b",
|
"771b",
|
||||||
"771b",
|
"771b",
|
||||||
"772b",
|
"772b",
|
||||||
@ -1705,6 +1683,20 @@
|
|||||||
"774b-violet",
|
"774b-violet",
|
||||||
"774b-yellow",
|
"774b-yellow",
|
||||||
"774b-yellow",
|
"774b-yellow",
|
||||||
|
"774b-blue-meteor",
|
||||||
|
"774b-blue-meteor",
|
||||||
|
"774b-green-meteor",
|
||||||
|
"774b-green-meteor",
|
||||||
|
"774b-indigo-meteor",
|
||||||
|
"774b-indigo-meteor",
|
||||||
|
"774b-orange-meteor",
|
||||||
|
"774b-orange-meteor",
|
||||||
|
"774b-red-meteor",
|
||||||
|
"774b-red-meteor",
|
||||||
|
"774b-violet-meteor",
|
||||||
|
"774b-violet-meteor",
|
||||||
|
"774b-yellow-meteor",
|
||||||
|
"774b-yellow-meteor",
|
||||||
"774b",
|
"774b",
|
||||||
"774b",
|
"774b",
|
||||||
"775b",
|
"775b",
|
||||||
@ -1859,10 +1851,6 @@
|
|||||||
"841b",
|
"841b",
|
||||||
"842b",
|
"842b",
|
||||||
"842b",
|
"842b",
|
||||||
"843b",
|
|
||||||
"843b",
|
|
||||||
"844b",
|
|
||||||
"844b",
|
|
||||||
"845b-gorging",
|
"845b-gorging",
|
||||||
"845b-gorging",
|
"845b-gorging",
|
||||||
"845b-gulping",
|
"845b-gulping",
|
||||||
@ -2001,10 +1989,6 @@
|
|||||||
"900b",
|
"900b",
|
||||||
"901b",
|
"901b",
|
||||||
"901b",
|
"901b",
|
||||||
"902b-female",
|
|
||||||
"902b-female",
|
|
||||||
"902b",
|
|
||||||
"902b",
|
|
||||||
"903b",
|
"903b",
|
||||||
"903b",
|
"903b",
|
||||||
"904b",
|
"904b",
|
||||||
@ -2557,8 +2541,6 @@
|
|||||||
"671sb-yellow",
|
"671sb-yellow",
|
||||||
"6713sb",
|
"6713sb",
|
||||||
"6713sb",
|
"6713sb",
|
||||||
"672sb",
|
|
||||||
"672sb",
|
|
||||||
"6724sb",
|
"6724sb",
|
||||||
"6724sb",
|
"6724sb",
|
||||||
"673sb",
|
"673sb",
|
||||||
@ -2601,10 +2583,6 @@
|
|||||||
"690sb",
|
"690sb",
|
||||||
"691sb",
|
"691sb",
|
||||||
"691sb",
|
"691sb",
|
||||||
"692sb",
|
|
||||||
"692sb",
|
|
||||||
"693sb",
|
|
||||||
"693sb",
|
|
||||||
"695sb",
|
"695sb",
|
||||||
"695sb",
|
"695sb",
|
||||||
"696sb",
|
"696sb",
|
||||||
@ -2727,10 +2705,6 @@
|
|||||||
"751sb",
|
"751sb",
|
||||||
"752sb",
|
"752sb",
|
||||||
"752sb",
|
"752sb",
|
||||||
"753sb",
|
|
||||||
"753sb",
|
|
||||||
"754sb",
|
|
||||||
"754sb",
|
|
||||||
"755sb",
|
"755sb",
|
||||||
"755sb",
|
"755sb",
|
||||||
"756sb",
|
"756sb",
|
||||||
@ -2759,10 +2733,6 @@
|
|||||||
"767sb",
|
"767sb",
|
||||||
"768sb",
|
"768sb",
|
||||||
"768sb",
|
"768sb",
|
||||||
"769sb",
|
|
||||||
"769sb",
|
|
||||||
"770sb",
|
|
||||||
"770sb",
|
|
||||||
"771sb",
|
"771sb",
|
||||||
"771sb",
|
"771sb",
|
||||||
"772sb",
|
"772sb",
|
||||||
@ -2817,6 +2787,20 @@
|
|||||||
"774sb-violet",
|
"774sb-violet",
|
||||||
"774sb-yellow",
|
"774sb-yellow",
|
||||||
"774sb-yellow",
|
"774sb-yellow",
|
||||||
|
"774sb-blue-meteor",
|
||||||
|
"774sb-blue-meteor",
|
||||||
|
"774sb-green-meteor",
|
||||||
|
"774sb-green-meteor",
|
||||||
|
"774sb-indigo-meteor",
|
||||||
|
"774sb-indigo-meteor",
|
||||||
|
"774sb-orange-meteor",
|
||||||
|
"774sb-orange-meteor",
|
||||||
|
"774sb-red-meteor",
|
||||||
|
"774sb-red-meteor",
|
||||||
|
"774sb-violet-meteor",
|
||||||
|
"774sb-violet-meteor",
|
||||||
|
"774sb-yellow-meteor",
|
||||||
|
"774sb-yellow-meteor",
|
||||||
"774sb",
|
"774sb",
|
||||||
"774sb",
|
"774sb",
|
||||||
"775sb",
|
"775sb",
|
||||||
@ -2971,10 +2955,6 @@
|
|||||||
"841sb",
|
"841sb",
|
||||||
"842sb",
|
"842sb",
|
||||||
"842sb",
|
"842sb",
|
||||||
"843sb",
|
|
||||||
"843sb",
|
|
||||||
"844sb",
|
|
||||||
"844sb",
|
|
||||||
"845sb-gorging",
|
"845sb-gorging",
|
||||||
"845sb-gorging",
|
"845sb-gorging",
|
||||||
"845sb-gulping",
|
"845sb-gulping",
|
||||||
@ -3113,10 +3093,6 @@
|
|||||||
"900sb",
|
"900sb",
|
||||||
"901sb",
|
"901sb",
|
||||||
"901sb",
|
"901sb",
|
||||||
"902sb-female",
|
|
||||||
"902sb-female",
|
|
||||||
"902sb",
|
|
||||||
"902sb",
|
|
||||||
"903sb",
|
"903sb",
|
||||||
"903sb",
|
"903sb",
|
||||||
"904sb",
|
"904sb",
|
||||||
@ -3674,8 +3650,6 @@
|
|||||||
"671s-yellow",
|
"671s-yellow",
|
||||||
"6713s",
|
"6713s",
|
||||||
"6713s",
|
"6713s",
|
||||||
"672s",
|
|
||||||
"672s",
|
|
||||||
"6724s",
|
"6724s",
|
||||||
"6724s",
|
"6724s",
|
||||||
"673s",
|
"673s",
|
||||||
@ -3718,10 +3692,6 @@
|
|||||||
"690s",
|
"690s",
|
||||||
"691s",
|
"691s",
|
||||||
"691s",
|
"691s",
|
||||||
"692s",
|
|
||||||
"692s",
|
|
||||||
"693s",
|
|
||||||
"693s",
|
|
||||||
"695s",
|
"695s",
|
||||||
"695s",
|
"695s",
|
||||||
"696s",
|
"696s",
|
||||||
@ -3844,10 +3814,6 @@
|
|||||||
"751s",
|
"751s",
|
||||||
"752s",
|
"752s",
|
||||||
"752s",
|
"752s",
|
||||||
"753s",
|
|
||||||
"753s",
|
|
||||||
"754s",
|
|
||||||
"754s",
|
|
||||||
"755s",
|
"755s",
|
||||||
"755s",
|
"755s",
|
||||||
"756s",
|
"756s",
|
||||||
@ -3876,10 +3842,6 @@
|
|||||||
"767s",
|
"767s",
|
||||||
"768s",
|
"768s",
|
||||||
"768s",
|
"768s",
|
||||||
"769s",
|
|
||||||
"769s",
|
|
||||||
"770s",
|
|
||||||
"770s",
|
|
||||||
"771s",
|
"771s",
|
||||||
"771s",
|
"771s",
|
||||||
"772s",
|
"772s",
|
||||||
@ -3934,6 +3896,20 @@
|
|||||||
"774s-violet",
|
"774s-violet",
|
||||||
"774s-yellow",
|
"774s-yellow",
|
||||||
"774s-yellow",
|
"774s-yellow",
|
||||||
|
"774s-blue-meteor",
|
||||||
|
"774s-blue-meteor",
|
||||||
|
"774s-green-meteor",
|
||||||
|
"774s-green-meteor",
|
||||||
|
"774s-indigo-meteor",
|
||||||
|
"774s-indigo-meteor",
|
||||||
|
"774s-orange-meteor",
|
||||||
|
"774s-orange-meteor",
|
||||||
|
"774s-red-meteor",
|
||||||
|
"774s-red-meteor",
|
||||||
|
"774s-violet-meteor",
|
||||||
|
"774s-violet-meteor",
|
||||||
|
"774s-yellow-meteor",
|
||||||
|
"774s-yellow-meteor",
|
||||||
"774s",
|
"774s",
|
||||||
"774s",
|
"774s",
|
||||||
"775s",
|
"775s",
|
||||||
@ -4088,10 +4064,6 @@
|
|||||||
"841s",
|
"841s",
|
||||||
"842s",
|
"842s",
|
||||||
"842s",
|
"842s",
|
||||||
"843s",
|
|
||||||
"843s",
|
|
||||||
"844s",
|
|
||||||
"844s",
|
|
||||||
"845s-gorging",
|
"845s-gorging",
|
||||||
"845s-gorging",
|
"845s-gorging",
|
||||||
"845s-gulping",
|
"845s-gulping",
|
||||||
@ -4230,10 +4202,6 @@
|
|||||||
"900s",
|
"900s",
|
||||||
"901s",
|
"901s",
|
||||||
"901s",
|
"901s",
|
||||||
"902s-female",
|
|
||||||
"902s-female",
|
|
||||||
"902s",
|
|
||||||
"902s",
|
|
||||||
"903s",
|
"903s",
|
||||||
"903s",
|
"903s",
|
||||||
"904s",
|
"904s",
|
||||||
@ -4569,8 +4537,6 @@
|
|||||||
"730",
|
"730",
|
||||||
"747",
|
"747",
|
||||||
"748",
|
"748",
|
||||||
"753",
|
|
||||||
"754",
|
|
||||||
"755",
|
"755",
|
||||||
"756",
|
"756",
|
||||||
"761",
|
"761",
|
||||||
|
Before Width: | Height: | Size: 607 B After Width: | Height: | Size: 333 B |
BIN
public/fonts/pokemon-bw.ttf
Normal file
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 637 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 654 B |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 773 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 474 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 558 B |
Before Width: | Height: | Size: 772 B After Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 552 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 667 B |
Before Width: | Height: | Size: 767 B After Width: | Height: | Size: 302 B |
Before Width: | Height: | Size: 764 B After Width: | Height: | Size: 318 B |
Before Width: | Height: | Size: 1008 B After Width: | Height: | Size: 384 B |
Before Width: | Height: | Size: 789 B After Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 852 B After Width: | Height: | Size: 390 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 701 B |
Before Width: | Height: | Size: 779 B After Width: | Height: | Size: 340 B |
Before Width: | Height: | Size: 489 B After Width: | Height: | Size: 195 B |
Before Width: | Height: | Size: 694 B After Width: | Height: | Size: 285 B |
Before Width: | Height: | Size: 789 B After Width: | Height: | Size: 267 B |
Before Width: | Height: | Size: 943 B After Width: | Height: | Size: 420 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 635 B |
Before Width: | Height: | Size: 909 B After Width: | Height: | Size: 369 B |
Before Width: | Height: | Size: 706 B After Width: | Height: | Size: 276 B |
Before Width: | Height: | Size: 766 B After Width: | Height: | Size: 309 B |
Before Width: | Height: | Size: 781 B After Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 703 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 652 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 422 B |
Before Width: | Height: | Size: 868 B After Width: | Height: | Size: 352 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 501 B |
Before Width: | Height: | Size: 788 B After Width: | Height: | Size: 266 B |
Before Width: | Height: | Size: 624 B After Width: | Height: | Size: 242 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 479 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 610 B |
Before Width: | Height: | Size: 617 B After Width: | Height: | Size: 252 B |
Before Width: | Height: | Size: 729 B After Width: | Height: | Size: 287 B |
Before Width: | Height: | Size: 667 B After Width: | Height: | Size: 260 B |
Before Width: | Height: | Size: 784 B After Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 777 B After Width: | Height: | Size: 351 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 554 B |
Before Width: | Height: | Size: 785 B After Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 670 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 470 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 858 B After Width: | Height: | Size: 422 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 755 B |
Before Width: | Height: | Size: 713 B After Width: | Height: | Size: 273 B |
Before Width: | Height: | Size: 596 B After Width: | Height: | Size: 239 B |
Before Width: | Height: | Size: 756 B After Width: | Height: | Size: 289 B |
Before Width: | Height: | Size: 781 B After Width: | Height: | Size: 264 B |