Feature/evolutions #2

Closed
evc24004 wants to merge 22 commits from feature/evolutions into master
evc24004 commented 2025-08-06 23:39:59 +00:00 (Migrated from github.com)

Summary by CodeRabbit

  • New Features

    • Updated battle stat calculation logic for certain formats, improving accuracy and consistency.
    • Enhanced evolution methods for several Pokémon, including new requirements such as party slot, nickname, and weather conditions.
  • Bug Fixes

    • Corrected evolution triggers and conditions for multiple Pokémon species.
    • Updated tier assignment for Archaludon.
  • Refactor

    • Replaced manual SQL queries with a structured query builder for improved database safety and maintainability.
    • Streamlined and unified stat calculation methods across the battle engine.
  • Chores

    • Updated and simplified documentation, including replacing the README with the official Pokémon Showdown version.
    • Removed obsolete or deprecated Pokémon entries and properties.
    • Improved privacy handling and command structure for team management.
  • Documentation

    • Revised help ticket messaging for password resets to reflect current procedures.
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Updated battle stat calculation logic for certain formats, improving accuracy and consistency. * Enhanced evolution methods for several Pokémon, including new requirements such as party slot, nickname, and weather conditions. * **Bug Fixes** * Corrected evolution triggers and conditions for multiple Pokémon species. * Updated tier assignment for Archaludon. * **Refactor** * Replaced manual SQL queries with a structured query builder for improved database safety and maintainability. * Streamlined and unified stat calculation methods across the battle engine. * **Chores** * Updated and simplified documentation, including replacing the README with the official Pokémon Showdown version. * Removed obsolete or deprecated Pokémon entries and properties. * Improved privacy handling and command structure for team management. * **Documentation** * Revised help ticket messaging for password resets to reflect current procedures. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
coderabbitai[bot] commented 2025-08-06 23:40:05 +00:00 (Migrated from github.com)

Walkthrough

This set of changes refactors stat calculation logic across multiple modules, updates Pokémon evolution data, restructures and renames rulesets for LGPE formats, and overhauls database handling to improve SQL safety and abstraction. The Postgres database module is removed and replaced with a new abstraction, requiring updates to all dependent modules and tests. Documentation, help pages, and error handling are also updated, alongside numerous adjustments to public interfaces and method signatures.

Changes

Cohort / File(s) Change Summary
Documentation and Help Content
README.md, server/chat-plugins/helptickets.ts
README replaced with the official Pokémon Showdown documentation, removing Minecraft-specific details. Help ticket password reset instructions updated to reflect process closure.
LGPE Ruleset Refactor
data/mods/gen7letsgo/rulesets.ts, data/rulesets.ts, sim/dex-formats.ts, sim/team-validator.ts
LGPE ruleset renamed from "Allow AVs" to "LGPE Normal Rules", with corresponding updates to ruleset keys, descriptions, and references in format logic. Stat validation logic for AVs updated to use new rule.
Stat Calculation Refactor
sim/battle.ts, sim/global-types.ts, sim/pokemon.ts, data/mods/gen7letsgo/scripts.ts, config/formats.ts
Stat calculation unified to per-stat statModify methods, replacing batch spreadModify and natureModify. Interfaces and implementations updated accordingly in core simulation and Gen 7 LGPE logic. Format definitions updated to use new stat calculation hooks.
Pokédex Evolution Data Updates
data/pokedex.ts, sim/dex-species.ts
Evolution methods, triggers, and requirements clarified and expanded for several Pokémon. Evolution-related properties in the Species class refined, with obsolete properties removed and new ones added. Entries for certain Pokémon removed.
Format and Tier Adjustments
data/formats-data.ts, config/formats.ts
Tier for Archaludon updated. Specific format rules and spotlight messages adjusted for Gen 9 and Gen 7 Let's Go.
Database Abstraction Overhaul
lib/database.ts, lib/postgres.ts, lib/index.ts, server/chat-plugins/teams.ts, test/lib/postgres.js
The custom Postgres library is removed and replaced with a new database abstraction (PGDatabase). All SQL queries in teams handling and tests refactored to use tagged template literals and structured methods. Exports updated. Integration tests for Postgres are replaced with unit tests for the new SQL template system.
Error Handling and Logging
server/chat-plugins/seasons.ts
Error logging in ladder top retrieval simplified to silently return null on error.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant TeamsHandler
    participant PGDatabase
    participant teamsTable

    User->>TeamsHandler: save({name, packedTeam, format, privacy})
    TeamsHandler->>teamsTable: selectOne(SQL`WHERE name = ...`)
    alt Team exists
        TeamsHandler->>teamsTable: updateOne(SQL`SET ... WHERE teamid = ...`)
    else Team does not exist
        TeamsHandler->>teamsTable: insert(SQL`...`)
    end
    TeamsHandler-->>User: {teamid, teamName, privacy}
sequenceDiagram
    participant Battle
    participant Pokemon

    Battle->>Pokemon: updateMaxHp()
    Pokemon->>Battle: statModify(baseStats, set, 'hp')
    Battle-->>Pokemon: new HP value
    Pokemon-->>Battle: HP updated

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

In burrows deep, the rabbits code,
Stat math refactored, evolution's road.
Postgres hops out, new DB hops in,
LGPE rules get a shiny new skin.
With queries safe and logic neat,
This patch is quite the coder's treat!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/evolutions

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.
<!-- This is an auto-generated comment: summarize by coderabbit.ai --> <!-- walkthrough_start --> ## Walkthrough This set of changes refactors stat calculation logic across multiple modules, updates Pokémon evolution data, restructures and renames rulesets for LGPE formats, and overhauls database handling to improve SQL safety and abstraction. The Postgres database module is removed and replaced with a new abstraction, requiring updates to all dependent modules and tests. Documentation, help pages, and error handling are also updated, alongside numerous adjustments to public interfaces and method signatures. ## Changes | Cohort / File(s) | Change Summary | |----------------------------------------------------|---------------| | **Documentation and Help Content**<br> `README.md`, `server/chat-plugins/helptickets.ts` | README replaced with the official Pokémon Showdown documentation, removing Minecraft-specific details. Help ticket password reset instructions updated to reflect process closure. | | **LGPE Ruleset Refactor**<br> `data/mods/gen7letsgo/rulesets.ts`, `data/rulesets.ts`, `sim/dex-formats.ts`, `sim/team-validator.ts` | LGPE ruleset renamed from "Allow AVs" to "LGPE Normal Rules", with corresponding updates to ruleset keys, descriptions, and references in format logic. Stat validation logic for AVs updated to use new rule. | | **Stat Calculation Refactor**<br> `sim/battle.ts`, `sim/global-types.ts`, `sim/pokemon.ts`, `data/mods/gen7letsgo/scripts.ts`, `config/formats.ts` | Stat calculation unified to per-stat `statModify` methods, replacing batch `spreadModify` and `natureModify`. Interfaces and implementations updated accordingly in core simulation and Gen 7 LGPE logic. Format definitions updated to use new stat calculation hooks. | | **Pokédex Evolution Data Updates**<br> `data/pokedex.ts`, `sim/dex-species.ts` | Evolution methods, triggers, and requirements clarified and expanded for several Pokémon. Evolution-related properties in the Species class refined, with obsolete properties removed and new ones added. Entries for certain Pokémon removed. | | **Format and Tier Adjustments**<br> `data/formats-data.ts`, `config/formats.ts` | Tier for Archaludon updated. Specific format rules and spotlight messages adjusted for Gen 9 and Gen 7 Let's Go. | | **Database Abstraction Overhaul**<br> `lib/database.ts`, `lib/postgres.ts`, `lib/index.ts`, `server/chat-plugins/teams.ts`, `test/lib/postgres.js` | The custom Postgres library is removed and replaced with a new database abstraction (`PGDatabase`). All SQL queries in teams handling and tests refactored to use tagged template literals and structured methods. Exports updated. Integration tests for Postgres are replaced with unit tests for the new SQL template system. | | **Error Handling and Logging**<br> `server/chat-plugins/seasons.ts` | Error logging in ladder top retrieval simplified to silently return null on error. | ## Sequence Diagram(s) ```mermaid sequenceDiagram participant User participant TeamsHandler participant PGDatabase participant teamsTable User->>TeamsHandler: save({name, packedTeam, format, privacy}) TeamsHandler->>teamsTable: selectOne(SQL`WHERE name = ...`) alt Team exists TeamsHandler->>teamsTable: updateOne(SQL`SET ... WHERE teamid = ...`) else Team does not exist TeamsHandler->>teamsTable: insert(SQL`...`) end TeamsHandler-->>User: {teamid, teamName, privacy} ``` ```mermaid sequenceDiagram participant Battle participant Pokemon Battle->>Pokemon: updateMaxHp() Pokemon->>Battle: statModify(baseStats, set, 'hp') Battle-->>Pokemon: new HP value Pokemon-->>Battle: HP updated ``` ## Estimated code review effort 🎯 4 (Complex) | ⏱️ ~45 minutes ## Poem > In burrows deep, the rabbits code, > Stat math refactored, evolution's road. > Postgres hops out, new DB hops in, > LGPE rules get a shiny new skin. > With queries safe and logic neat, > This patch is quite the coder's treat! > 🐇✨ <!-- walkthrough_end --> <!-- announcements_start --> > [!NOTE] > <details open="true"> > <summary>⚡️ Unit Test Generation is now available in beta!</summary> > > Learn more [here](https://docs.coderabbit.ai/finishing-touches/unit-test-generation), or try it out under "Finishing Touches" below. > > </details> <!-- announcements_end --> <!-- internal state start --> <!-- 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= --> <!-- internal state end --> <!-- finishing_touch_checkbox_start --> <details> <summary>✨ Finishing Touches</summary> - [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings <details> <summary>🧪 Generate unit tests</summary> - [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Create PR with unit tests - [ ] <!-- {"checkboxId": "07f1e7d6-8a8e-4e23-9900-8731c2c87f58", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Post copyable unit tests in a comment - [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Commit unit tests in branch `feature/evolutions` </details> </details> <!-- finishing_touch_checkbox_end --> <!-- tips_start --> --- Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. <details> <summary>❤️ Share</summary> - [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai) - [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai) - [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai) - [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code) </details> <details> <summary>🪧 Tips</summary> ### Chat There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=smell-of-curry/pokebedrock-showdown&utm_content=2): - Review comments: Directly reply to a review comment made by CodeRabbit. Example: - `I pushed a fix in commit <commit_id>, please review it.` - `Explain this complex logic.` - `Open a follow-up GitHub issue for this discussion.` - Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples: - `@coderabbitai explain this code block.` - PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples: - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.` - `@coderabbitai read src/utils.ts and explain its main purpose.` - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.` ### Support Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions. ### CodeRabbit Commands (Invoked using PR comments) - `@coderabbitai pause` to pause the reviews on a PR. - `@coderabbitai resume` to resume the paused reviews. - `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository. - `@coderabbitai full review` to do a full review from scratch and review all the files again. - `@coderabbitai summary` to regenerate the summary of the PR. - `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR. - `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR. - `@coderabbitai generate unit tests` to generate unit tests for this PR. - `@coderabbitai resolve` resolve all the CodeRabbit review comments. - `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository. - `@coderabbitai help` to get help. ### Other keywords and placeholders - Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed. - Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description. - Add `@coderabbitai` anywhere in the PR title to generate the title automatically. ### CodeRabbit Configuration File (`.coderabbit.yaml`) - You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository. - Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information. - If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json` ### Documentation and Community - Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit. - Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback. - Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements. </details> <!-- tips_end -->
coderabbitai[bot] (Migrated from github.com) reviewed 2025-08-06 23:45:16 +00:00
coderabbitai[bot] (Migrated from github.com) left a comment

Actionable comments posted: 6

🔭 Outside diff range comments (2)
server/chat-plugins/seasons.ts (1)

145-152: Swallowing all exceptions removes observability – keep lightweight logging.

The new catch block now ignores every network/parse error and silently returns null. This makes production issues (API outage, malformed JSON, etc.) invisible and very hard to debug.

Restore minimal reporting (behind a debug gate if noise is a concern):

-	} catch {
-		return null;
+	} catch (e: any) {
+		if (Config.debug) Monitor.warn(`getLadderTop(${format}) failed: ${e?.stack || e}`);
+		return null;
 	}

And extend the import list accordingly:

-import { FS, Net, Utils } from '../../lib';
+import { FS, Net, Utils, Monitor } from '../../lib';

This preserves silent fallback behaviour for callers while still surfacing actionable signals for operators.

README.md (1)

14-37: Unresolved Git conflict markers break the README rendering

The section still contains <<<<<<<, =======, and >>>>>>> markers. These will render literally on GitHub and signal an unfinished merge, confusing readers and breaking the Markdown outline.

-<<<<<<< Updated upstream
-Introduction
-------------------------------------------------------------------------
-=======
-### Evolution System Enhancements:
-...
-  - `changeEvent`: Event that triggers forme changes
->>>>>>> Stashed changes
+<!-- Remove the conflict markers and keep only the intended content -->
+## Introduction
+
+<!-- (If you want the Evolution System Enhancements list, retain it **without** conflict markers) -->
🧹 Nitpick comments (6)
server/chat-plugins/helptickets.ts (1)

1688-1688: Wrap user-facing string in this.tr for i18n consistency

Most help-request UI strings in this file are wrapped with this.tr\`` to enable downstream localisation.
The newly added password-reset notice is plain text, so it will always appear in English even when the rest of the page is translated.

Consider:

-buf += `<p>The password reset process is no longer open to the public.</p>`;
+buf += `<p>${this.tr`The password reset process is no longer open to the public.`}</p>`;

Minor, but keeps the i18n story uniform.

README.md (1)

18-32: Markdown style nitpicks (optional)

Heading on Line 18 is ATX style while the file primarily uses Setext for top-level headings. Also, the trailing : violates MD026. Consider re-styling or removing the colon to silence markdown-lint noise.

test/lib/postgres.js (1)

33-60: Integration tests need updating for the new database API.

The skipped integration tests should be updated to:

  1. Use the new SQL template tag instead of raw SQL strings
  2. Properly configure the PGDatabase instance with connection details
  3. Verify the new API works correctly with an actual database

Would you like me to help update these integration tests to work with the new PGDatabase and SQL API?

sim/battle.ts (1)

3084-3103: Review the useBagItem function implementation.

The function handles item usage correctly but has a few considerations:

  • The commented-out fainted check might be intentional for revival items
  • The health comparison logic properly detects healing
  • Proper cleanup with the ability End event

Consider adding parameter validation and documenting the intended behavior for fainted Pokémon.

sim/dex-species.ts (1)

248-258: Well-designed evolution property additions with minor typo.

The new evolution properties provide comprehensive coverage for complex evolution conditions. The types are appropriately restrictive and the documentation is clear.

Fix the typo in the minDamage comment:

-	/** The minimum amount of damage required for this evolution(in a battle, wihtout fainting) */
+	/** The minimum amount of damage required for this evolution (in a battle, without fainting) */
server/chat-plugins/teams.ts (1)

252-254: Consider avoiding mutation of input parameter.

Mutating the team parameter directly could lead to unexpected side effects for the caller. Consider working with a copy or returning the modified values.

-// eslint-disable-next-line require-atomic-updates
-team.packedTeam = Teams.pack(sets);
+const packedTeam = Teams.pack(sets);

Then use packedTeam in subsequent operations and return it as part of the result.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d3ecadea5 and 0bba0d69a6.

📒 Files selected for processing (20)
  • README.md (2 hunks)
  • config/formats.ts (3 hunks)
  • data/formats-data.ts (1 hunks)
  • data/mods/gen7letsgo/rulesets.ts (1 hunks)
  • data/mods/gen7letsgo/scripts.ts (1 hunks)
  • data/pokedex.ts (8 hunks)
  • data/rulesets.ts (1 hunks)
  • lib/database.ts (6 hunks)
  • lib/index.ts (1 hunks)
  • lib/postgres.ts (0 hunks)
  • server/chat-plugins/helptickets.ts (1 hunks)
  • server/chat-plugins/seasons.ts (1 hunks)
  • server/chat-plugins/teams.ts (14 hunks)
  • sim/battle.ts (1 hunks)
  • sim/dex-formats.ts (1 hunks)
  • sim/dex-species.ts (6 hunks)
  • sim/global-types.ts (1 hunks)
  • sim/pokemon.ts (2 hunks)
  • sim/team-validator.ts (1 hunks)
  • test/lib/postgres.js (2 hunks)
💤 Files with no reviewable changes (1)
  • lib/postgres.ts
🧰 Additional context used
🧬 Code Graph Analysis (3)
test/lib/postgres.js (1)
lib/database.ts (2)
  • PGDatabase (384-415)
  • SQL (144-147)
sim/global-types.ts (3)
sim/battle.ts (1)
  • Battle (110-3442)
sim/dex.ts (2)
  • StatsTable (948-948)
  • StatID (946-946)
sim/teams.ts (1)
  • PokemonSet (33-151)
sim/battle.ts (2)
sim/dex.ts (2)
  • StatsTable (948-948)
  • StatID (946-946)
sim/teams.ts (1)
  • PokemonSet (33-151)
🪛 markdownlint-cli2 (0.17.2)
README.md

18-18: Heading style
Expected: setext; Actual: atx

(MD003, heading-style)


18-18: Trailing punctuation in heading
Punctuation: ':'

(MD026, no-trailing-punctuation)


43-43: Bare URL used

(MD034, no-bare-urls)


67-67: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


68-68: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


69-69: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


70-70: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


71-71: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


121-121: Bare URL used

(MD034, no-bare-urls)

🪛 LanguageTool
README.md

[uncategorized] ~71-~71: Do not mix variants of the same word (‘Pokemon’ and ‘Pokémon’) within a single text.
Context: ...FAQ compiled by Kaiepi regarding making Pokemon Showdown bots - mainly chatbots and bat...

(EN_WORD_COHERENCY)

🔇 Additional comments (27)
data/formats-data.ts (1)

5614-5618: Tier mismatch: archaludon is Uber but natDexTier is RUBL

tier: "Uber" (Line 5615) implies the mon is banned from standard OU, yet natDexTier: "RUBL" (Line 5617) says it’s only banned from RU in NatDex. That’s an unusually large gap and may be a copy-paste error.

Would you double-check Smogon’s current NatDex tiering for Archaludon and update accordingly?

data/mods/gen7letsgo/rulesets.ts (1)

4-9: Confirm new ruleset identifier exists

'LGPE Normal Rules' replaces the old 'Adjust Level = 50'. Ensure:

  1. A format entry named exactly lgpenormalrules is defined in data/rulesets.ts.
  2. Down-stream look-ups (TeamValidator, Battle scripts) use the same canonical id.

A quick grep after rebasing will catch case/spacing mismatches.

sim/team-validator.ts (1)

1108-1108: LGTM! Correct implementation of rule logic inversion.

The change correctly updates the allowAVs logic to reflect the renaming and semantic inversion of the ruleset from 'allowavs' to 'lgpenormalrules'. The new logic properly disables AVs when LGPE normal rules are active (which zero out AVs) and allows them otherwise.

sim/dex-formats.ts (1)

280-280: LGTM! Clean rule renaming from 'allowavs' to 'lgpenormalrules'.

The rule identifier has been updated consistently with the broader refactoring mentioned in the AI summary. The logic remains identical - checking for the rule's presence to set evLimit appropriately for gen7letsgo formats.

lib/index.ts (1)

3-5: Verified re-enabled exports—no issues found

All three exports (crashlogger, ProcessManager, SQL) are present under lib/ and are imported throughout the codebase.
The implementation in lib/sql.ts provides the full SQLDatabaseManager, Statement, DatabaseTable, and SQL template abstractions as expected, and all dependent imports have been updated to use these exports correctly.

data/rulesets.ts (1)

1725-1731: LGTM! Excellent refactoring of the LGPE ruleset.

The rename from allowavs to lgpenormalrules significantly improves clarity:

  1. Better naming: The new ID clearly indicates this is for Let's Go Pokémon Eevee/Pikachu normal rules
  2. Accurate description: The updated description correctly reflects that this rule sets level to 50 and all AVs to 0, rather than "allowing" them
  3. Proper implementation: The addition of ruleset: ['Adjust Level = 50'] provides the actual mechanism for enforcing level 50
  4. Consistent behavior: The rule now clearly communicates that it standardizes LGPE format conditions

This change makes the codebase more maintainable and the rule's purpose much clearer to developers and users.

test/lib/postgres.js (1)

10-31: Comprehensive test coverage for SQL template strings.

The test suite provides excellent coverage of the SQL template functionality, including edge cases like undefined values and empty arrays. Good job testing both the declarative SQL template literals and the imperative appendRaw/append methods.

sim/global-types.ts (1)

370-370: Interface updated for per-stat calculation approach.

The change from batch stat processing (spreadModify/natureModify) to per-stat calculation (statModify) provides more granular control and cleaner separation of concerns. This aligns well with the broader refactoring across the codebase.

sim/pokemon.ts (2)

345-345: Happiness override for Let's Go mechanics.

Setting happiness to 70 for the gen7letsgo mod is consistent with the stat calculation in data/mods/gen7letsgo/scripts.ts. This ensures uniform happiness-based stat modifiers in Let's Go formats.


1514-1520: Improved HP calculation with proper edge case handling.

The refactored updateMaxHp method correctly:

  1. Uses the centralized statModify method for consistency
  2. Properly handles the edge case where HP could be 0 or negative by ensuring it's at least 1
  3. Triggers a silent heal event when HP changes
data/mods/gen7letsgo/scripts.ts (1)

65-82: Well-implemented per-stat calculation for Let's Go mechanics.

The refactored statModify method correctly:

  1. Applies appropriate stat formulas for HP vs other stats
  2. Integrates nature modifiers with proper 16-bit truncation
  3. Applies friendship-based stat modifiers specific to Let's Go
  4. Uses consistent truncation throughout the calculations

The consolidation of stat, nature, and friendship calculations into a single method improves maintainability.

config/formats.ts (2)

851-853: Promotional message addition looks good

The onBegin() method correctly adds a promotional message for the Ladder Achievements Project. The HTML structure is proper and the message provides clear call-to-action with appropriate links.


3423-3423: Removal of “Allow AVs” verified against “lgpenormalrules”
No references to the legacy Allow AVs or allowavs remain, and the code correctly gates EVs and AVs off via the new lgpenormalrules entry:

  • sim/team-validator.ts uses
    const allowAVs = !ruleTable.has('lgpenormalrules');
  • sim/dex-formats.ts applies
    this.evLimit = this.has('lgpenormalrules') ? 0 : null;
  • data/rulesets.ts defines the lgpenormalrules ruleset

This change is intentional and preserves existing functionality.

sim/battle.ts (3)

2331-2337: LGTM! Clean refactoring that improves modularity.

The delegation to statModify for each stat calculation follows the single responsibility principle and makes the code more maintainable. The logic remains equivalent while improving code organization.


2339-2357: LGTM! Well-implemented stat calculation consolidation.

The new statModify method correctly consolidates stat calculation logic with proper handling of:

  • Different formulas for HP vs other stats
  • Nature modifications with 16-bit truncation
  • Overflow stat mod rule edge cases for specific Pokémon

The mathematical formulas are accurate and the edge case handling is appropriate. The inline comments provide helpful context for the specialized logic.


2535-2535: @pokebedrock addition looks good.

The killed message addition provides useful logging information without affecting battle mechanics. The implementation correctly passes the source and effect parameters.

sim/dex-species.ts (4)

168-168: Evolution type consolidation looks good.

The simplification of the evoType union type to seven core evolution methods aligns with the broader refactoring mentioned in the summary. This should improve type safety and consistency.


181-187: Excellent improvement to party species evolution requirements.

The rename from evoPartySpecies to partySpecies removes redundancy, and changing from string to string array provides better flexibility for complex evolution requirements. The JSDoc examples are particularly helpful and reflect actual Pokémon game mechanics.


657-657: Good migration to native deep equality checking.

Replacing the custom Utils.isDeepStrictEqual with Node.js native isDeepStrictEqual reduces dependencies on custom utilities and leverages well-tested standard library functionality. This should provide better performance and reliability for the species caching optimization.


3-4: Approve both Node.js and MoonPhase imports

All import changes are valid:

  • The isDeepStrictEqual import replaces custom deep‐equality logic appropriately.
  • The @minecraft/server dependency is declared in package.json ("^2.1.0-beta.1.21.90-stable") and the MoonPhase type is used for evoMoonPhase in:
    • sim/dex-species.ts
    • data/pokedex.ts

No further action required.

data/pokedex.ts (7)

2381-2385: LGTM! New party slot evolution requirement implemented correctly.

The addition of partySlotRequirement with slot and species properties provides a clear structure for the complex evolution requirement. The evoCondition text also clearly describes the requirement for users.


5639-5639: LGTM! Evolution item requirement added correctly.

Adding Thunder Stone as the evolution item for Magneton provides a clear evolution path.


8501-8503: Evolution method change from level-based to item-based.

The change from level-based evolution to Thunder Stone usage represents a significant mechanic change for Probopass. Ensure this aligns with the intended game mechanics and that any dependent code handles the new evolution type correctly.


12333-12333: LGTM! Nickname requirement added for Malamar evolution.

The addition of the "Dinnerbone" nickname requirement is a clever reference to Minecraft's upside-down easter egg, fitting well with the existing upside-down console evolution condition.


12606-12606: LGTM! Weather property added for consistency.

Adding evoWeather: "rain" provides a machine-readable complement to the existing rain condition text, improving data structure consistency.


12625-12625: LGTM! Consistent weather property added.

Adding evoWeather: "rain" maintains consistency with the regular Goodra form and provides machine-readable weather conditions.


15965-15965: LGTM! Evolution condition clarified with specific requirements.

The updated condition text provides clearer, more specific requirements (49+ damage threshold and desert biome), improving user understanding and implementation clarity.

**Actionable comments posted: 6** <details> <summary>🔭 Outside diff range comments (2)</summary><blockquote> <details> <summary>server/chat-plugins/seasons.ts (1)</summary><blockquote> `145-152`: **Swallowing all exceptions removes observability – keep lightweight logging.** The new `catch` block now ignores every network/parse error and silently returns `null`. This makes production issues (API outage, malformed JSON, etc.) invisible and very hard to debug. Restore minimal reporting (behind a debug gate if noise is a concern): ```diff - } catch { - return null; + } catch (e: any) { + if (Config.debug) Monitor.warn(`getLadderTop(${format}) failed: ${e?.stack || e}`); + return null; } ``` And extend the import list accordingly: ```diff -import { FS, Net, Utils } from '../../lib'; +import { FS, Net, Utils, Monitor } from '../../lib'; ``` This preserves silent fallback behaviour for callers while still surfacing actionable signals for operators. </blockquote></details> <details> <summary>README.md (1)</summary><blockquote> `14-37`: **Unresolved Git conflict markers break the README rendering** The section still contains `<<<<<<<`, `=======`, and `>>>>>>>` markers. These will render literally on GitHub and signal an unfinished merge, confusing readers and breaking the Markdown outline. ```diff -<<<<<<< Updated upstream -Introduction ------------------------------------------------------------------------- -======= -### Evolution System Enhancements: -... - - `changeEvent`: Event that triggers forme changes ->>>>>>> Stashed changes +<!-- Remove the conflict markers and keep only the intended content --> +## Introduction + +<!-- (If you want the Evolution System Enhancements list, retain it **without** conflict markers) --> ``` </blockquote></details> </blockquote></details> <details> <summary>🧹 Nitpick comments (6)</summary><blockquote> <details> <summary>server/chat-plugins/helptickets.ts (1)</summary><blockquote> `1688-1688`: **Wrap user-facing string in `this.tr` for i18n consistency** Most help-request UI strings in this file are wrapped with `this.tr\`\`` to enable downstream localisation. The newly added password-reset notice is plain text, so it will always appear in English even when the rest of the page is translated. Consider: ```diff -buf += `<p>The password reset process is no longer open to the public.</p>`; +buf += `<p>${this.tr`The password reset process is no longer open to the public.`}</p>`; ``` Minor, but keeps the i18n story uniform. </blockquote></details> <details> <summary>README.md (1)</summary><blockquote> `18-32`: **Markdown style nitpicks (optional)** Heading on Line 18 is ATX style while the file primarily uses Setext for top-level headings. Also, the trailing `:` violates MD026. Consider re-styling or removing the colon to silence markdown-lint noise. </blockquote></details> <details> <summary>test/lib/postgres.js (1)</summary><blockquote> `33-60`: **Integration tests need updating for the new database API.** The skipped integration tests should be updated to: 1. Use the new `SQL` template tag instead of raw SQL strings 2. Properly configure the `PGDatabase` instance with connection details 3. Verify the new API works correctly with an actual database Would you like me to help update these integration tests to work with the new `PGDatabase` and `SQL` API? </blockquote></details> <details> <summary>sim/battle.ts (1)</summary><blockquote> `3084-3103`: **Review the useBagItem function implementation.** The function handles item usage correctly but has a few considerations: - The commented-out fainted check might be intentional for revival items - The health comparison logic properly detects healing - Proper cleanup with the ability End event Consider adding parameter validation and documenting the intended behavior for fainted Pokémon. </blockquote></details> <details> <summary>sim/dex-species.ts (1)</summary><blockquote> `248-258`: **Well-designed evolution property additions with minor typo.** The new evolution properties provide comprehensive coverage for complex evolution conditions. The types are appropriately restrictive and the documentation is clear. Fix the typo in the `minDamage` comment: ```diff - /** The minimum amount of damage required for this evolution(in a battle, wihtout fainting) */ + /** The minimum amount of damage required for this evolution (in a battle, without fainting) */ ``` </blockquote></details> <details> <summary>server/chat-plugins/teams.ts (1)</summary><blockquote> `252-254`: **Consider avoiding mutation of input parameter.** Mutating the `team` parameter directly could lead to unexpected side effects for the caller. Consider working with a copy or returning the modified values. ```diff -// eslint-disable-next-line require-atomic-updates -team.packedTeam = Teams.pack(sets); +const packedTeam = Teams.pack(sets); ``` Then use `packedTeam` in subsequent operations and return it as part of the result. </blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used: CodeRabbit UI** **Review profile: CHILL** **Plan: Pro** <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 4d3ecadea59a8e6054be050a3b266ba12ebeaf71 and 0bba0d69a60b55aff05be7759c63f69a4031e25f. </details> <details> <summary>📒 Files selected for processing (20)</summary> * `README.md` (2 hunks) * `config/formats.ts` (3 hunks) * `data/formats-data.ts` (1 hunks) * `data/mods/gen7letsgo/rulesets.ts` (1 hunks) * `data/mods/gen7letsgo/scripts.ts` (1 hunks) * `data/pokedex.ts` (8 hunks) * `data/rulesets.ts` (1 hunks) * `lib/database.ts` (6 hunks) * `lib/index.ts` (1 hunks) * `lib/postgres.ts` (0 hunks) * `server/chat-plugins/helptickets.ts` (1 hunks) * `server/chat-plugins/seasons.ts` (1 hunks) * `server/chat-plugins/teams.ts` (14 hunks) * `sim/battle.ts` (1 hunks) * `sim/dex-formats.ts` (1 hunks) * `sim/dex-species.ts` (6 hunks) * `sim/global-types.ts` (1 hunks) * `sim/pokemon.ts` (2 hunks) * `sim/team-validator.ts` (1 hunks) * `test/lib/postgres.js` (2 hunks) </details> <details> <summary>💤 Files with no reviewable changes (1)</summary> * lib/postgres.ts </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>🧬 Code Graph Analysis (3)</summary> <details> <summary>test/lib/postgres.js (1)</summary><blockquote> <details> <summary>lib/database.ts (2)</summary> * `PGDatabase` (384-415) * `SQL` (144-147) </details> </blockquote></details> <details> <summary>sim/global-types.ts (3)</summary><blockquote> <details> <summary>sim/battle.ts (1)</summary> * `Battle` (110-3442) </details> <details> <summary>sim/dex.ts (2)</summary> * `StatsTable` (948-948) * `StatID` (946-946) </details> <details> <summary>sim/teams.ts (1)</summary> * `PokemonSet` (33-151) </details> </blockquote></details> <details> <summary>sim/battle.ts (2)</summary><blockquote> <details> <summary>sim/dex.ts (2)</summary> * `StatsTable` (948-948) * `StatID` (946-946) </details> <details> <summary>sim/teams.ts (1)</summary> * `PokemonSet` (33-151) </details> </blockquote></details> </details><details> <summary>🪛 markdownlint-cli2 (0.17.2)</summary> <details> <summary>README.md</summary> 18-18: Heading style Expected: setext; Actual: atx (MD003, heading-style) --- 18-18: Trailing punctuation in heading Punctuation: ':' (MD026, no-trailing-punctuation) --- 43-43: Bare URL used (MD034, no-bare-urls) --- 67-67: Unordered list style Expected: dash; Actual: asterisk (MD004, ul-style) --- 68-68: Unordered list style Expected: dash; Actual: asterisk (MD004, ul-style) --- 69-69: Unordered list style Expected: dash; Actual: asterisk (MD004, ul-style) --- 70-70: Unordered list style Expected: dash; Actual: asterisk (MD004, ul-style) --- 71-71: Unordered list style Expected: dash; Actual: asterisk (MD004, ul-style) --- 121-121: Bare URL used (MD034, no-bare-urls) </details> </details> <details> <summary>🪛 LanguageTool</summary> <details> <summary>README.md</summary> [uncategorized] ~71-~71: Do not mix variants of the same word (‘Pokemon’ and ‘Pokémon’) within a single text. Context: ...FAQ compiled by Kaiepi regarding making Pokemon Showdown bots - mainly chatbots and bat... (EN_WORD_COHERENCY) </details> </details> </details> <details> <summary>🔇 Additional comments (27)</summary><blockquote> <details> <summary>data/formats-data.ts (1)</summary> `5614-5618`: **Tier mismatch: `archaludon` is `Uber` but `natDexTier` is `RUBL`** `tier: "Uber"` (Line 5615) implies the mon is banned from standard OU, yet `natDexTier: "RUBL"` (Line 5617) says it’s only banned from RU in NatDex. That’s an unusually large gap and may be a copy-paste error. Would you double-check Smogon’s current NatDex tiering for Archaludon and update accordingly? </details> <details> <summary>data/mods/gen7letsgo/rulesets.ts (1)</summary> `4-9`: **Confirm new ruleset identifier exists** `'LGPE Normal Rules'` replaces the old `'Adjust Level = 50'`. Ensure: 1. A format entry named exactly `lgpenormalrules` is defined in `data/rulesets.ts`. 2. Down-stream look-ups (TeamValidator, Battle scripts) use the same canonical id. A quick grep after rebasing will catch case/spacing mismatches. </details> <details> <summary>sim/team-validator.ts (1)</summary> `1108-1108`: **LGTM! Correct implementation of rule logic inversion.** The change correctly updates the `allowAVs` logic to reflect the renaming and semantic inversion of the ruleset from `'allowavs'` to `'lgpenormalrules'`. The new logic properly disables AVs when LGPE normal rules are active (which zero out AVs) and allows them otherwise. </details> <details> <summary>sim/dex-formats.ts (1)</summary> `280-280`: **LGTM! Clean rule renaming from 'allowavs' to 'lgpenormalrules'.** The rule identifier has been updated consistently with the broader refactoring mentioned in the AI summary. The logic remains identical - checking for the rule's presence to set `evLimit` appropriately for gen7letsgo formats. </details> <details> <summary>lib/index.ts (1)</summary> `3-5`: **Verified re-enabled exports—no issues found** All three exports (`crashlogger`, `ProcessManager`, `SQL`) are present under `lib/` and are imported throughout the codebase. The implementation in `lib/sql.ts` provides the full `SQLDatabaseManager`, `Statement`, `DatabaseTable`, and `SQL` template abstractions as expected, and all dependent imports have been updated to use these exports correctly. </details> <details> <summary>data/rulesets.ts (1)</summary> `1725-1731`: **LGTM! Excellent refactoring of the LGPE ruleset.** The rename from `allowavs` to `lgpenormalrules` significantly improves clarity: 1. **Better naming**: The new ID clearly indicates this is for Let's Go Pokémon Eevee/Pikachu normal rules 2. **Accurate description**: The updated description correctly reflects that this rule sets level to 50 and all AVs to 0, rather than "allowing" them 3. **Proper implementation**: The addition of `ruleset: ['Adjust Level = 50']` provides the actual mechanism for enforcing level 50 4. **Consistent behavior**: The rule now clearly communicates that it standardizes LGPE format conditions This change makes the codebase more maintainable and the rule's purpose much clearer to developers and users. </details> <details> <summary>test/lib/postgres.js (1)</summary> `10-31`: **Comprehensive test coverage for SQL template strings.** The test suite provides excellent coverage of the SQL template functionality, including edge cases like undefined values and empty arrays. Good job testing both the declarative SQL template literals and the imperative `appendRaw`/`append` methods. </details> <details> <summary>sim/global-types.ts (1)</summary> `370-370`: **Interface updated for per-stat calculation approach.** The change from batch stat processing (`spreadModify`/`natureModify`) to per-stat calculation (`statModify`) provides more granular control and cleaner separation of concerns. This aligns well with the broader refactoring across the codebase. </details> <details> <summary>sim/pokemon.ts (2)</summary> `345-345`: **Happiness override for Let's Go mechanics.** Setting happiness to 70 for the gen7letsgo mod is consistent with the stat calculation in `data/mods/gen7letsgo/scripts.ts`. This ensures uniform happiness-based stat modifiers in Let's Go formats. --- `1514-1520`: **Improved HP calculation with proper edge case handling.** The refactored `updateMaxHp` method correctly: 1. Uses the centralized `statModify` method for consistency 2. Properly handles the edge case where HP could be 0 or negative by ensuring it's at least 1 3. Triggers a silent heal event when HP changes </details> <details> <summary>data/mods/gen7letsgo/scripts.ts (1)</summary> `65-82`: **Well-implemented per-stat calculation for Let's Go mechanics.** The refactored `statModify` method correctly: 1. Applies appropriate stat formulas for HP vs other stats 2. Integrates nature modifiers with proper 16-bit truncation 3. Applies friendship-based stat modifiers specific to Let's Go 4. Uses consistent truncation throughout the calculations The consolidation of stat, nature, and friendship calculations into a single method improves maintainability. </details> <details> <summary>config/formats.ts (2)</summary> `851-853`: **Promotional message addition looks good** The `onBegin()` method correctly adds a promotional message for the Ladder Achievements Project. The HTML structure is proper and the message provides clear call-to-action with appropriate links. --- `3423-3423`: **Removal of “Allow AVs” verified against “lgpenormalrules”** No references to the legacy `Allow AVs` or `allowavs` remain, and the code correctly gates EVs and AVs off via the new `lgpenormalrules` entry: - sim/team-validator.ts uses `const allowAVs = !ruleTable.has('lgpenormalrules');` - sim/dex-formats.ts applies `this.evLimit = this.has('lgpenormalrules') ? 0 : null;` - data/rulesets.ts defines the `lgpenormalrules` ruleset This change is intentional and preserves existing functionality. </details> <details> <summary>sim/battle.ts (3)</summary> `2331-2337`: **LGTM! Clean refactoring that improves modularity.** The delegation to `statModify` for each stat calculation follows the single responsibility principle and makes the code more maintainable. The logic remains equivalent while improving code organization. --- `2339-2357`: **LGTM! Well-implemented stat calculation consolidation.** The new `statModify` method correctly consolidates stat calculation logic with proper handling of: - Different formulas for HP vs other stats - Nature modifications with 16-bit truncation - Overflow stat mod rule edge cases for specific Pokémon The mathematical formulas are accurate and the edge case handling is appropriate. The inline comments provide helpful context for the specialized logic. --- `2535-2535`: **@pokebedrock addition looks good.** The killed message addition provides useful logging information without affecting battle mechanics. The implementation correctly passes the source and effect parameters. </details> <details> <summary>sim/dex-species.ts (4)</summary> `168-168`: **Evolution type consolidation looks good.** The simplification of the `evoType` union type to seven core evolution methods aligns with the broader refactoring mentioned in the summary. This should improve type safety and consistency. --- `181-187`: **Excellent improvement to party species evolution requirements.** The rename from `evoPartySpecies` to `partySpecies` removes redundancy, and changing from string to string array provides better flexibility for complex evolution requirements. The JSDoc examples are particularly helpful and reflect actual Pokémon game mechanics. --- `657-657`: **Good migration to native deep equality checking.** Replacing the custom `Utils.isDeepStrictEqual` with Node.js native `isDeepStrictEqual` reduces dependencies on custom utilities and leverages well-tested standard library functionality. This should provide better performance and reliability for the species caching optimization. --- `3-4`: **Approve both Node.js and MoonPhase imports** All import changes are valid: - The `isDeepStrictEqual` import replaces custom deep‐equality logic appropriately. - The `@minecraft/server` dependency is declared in package.json (`"^2.1.0-beta.1.21.90-stable"`) and the `MoonPhase` type is used for `evoMoonPhase` in: - `sim/dex-species.ts` - `data/pokedex.ts` No further action required. </details> <details> <summary>data/pokedex.ts (7)</summary> `2381-2385`: **LGTM! New party slot evolution requirement implemented correctly.** The addition of `partySlotRequirement` with slot and species properties provides a clear structure for the complex evolution requirement. The `evoCondition` text also clearly describes the requirement for users. --- `5639-5639`: **LGTM! Evolution item requirement added correctly.** Adding Thunder Stone as the evolution item for Magneton provides a clear evolution path. --- `8501-8503`: **Evolution method change from level-based to item-based.** The change from level-based evolution to Thunder Stone usage represents a significant mechanic change for Probopass. Ensure this aligns with the intended game mechanics and that any dependent code handles the new evolution type correctly. --- `12333-12333`: **LGTM! Nickname requirement added for Malamar evolution.** The addition of the "Dinnerbone" nickname requirement is a clever reference to Minecraft's upside-down easter egg, fitting well with the existing upside-down console evolution condition. --- `12606-12606`: **LGTM! Weather property added for consistency.** Adding `evoWeather: "rain"` provides a machine-readable complement to the existing rain condition text, improving data structure consistency. --- `12625-12625`: **LGTM! Consistent weather property added.** Adding `evoWeather: "rain"` maintains consistency with the regular Goodra form and provides machine-readable weather conditions. --- `15965-15965`: **LGTM! Evolution condition clarified with specific requirements.** The updated condition text provides clearer, more specific requirements (49+ damage threshold and desert biome), improving user understanding and implementation clarity. </details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
coderabbitai[bot] (Migrated from github.com) commented 2025-08-06 23:45:14 +00:00

⚠️ Potential issue

Critical issue with stat calculation logic - potential division by zero and incorrect formula

The new statModify method has several serious problems:

  1. Division by zero risk: Line 1614 uses tr(tr(stat * 110, 16) / 100) but if stat is 0, this could cause issues
  2. Incorrect base stat swapping: Lines 1600-1606 swap the base stat names based on nature, but this logic seems flawed - it's swapping the stat being calculated rather than the values themselves
  3. Missing validation: No bounds checking on the calculated stats
  4. Complex nested truncation: The double truncation pattern tr(tr(...), 16) on line 1614 is unusual and may not be intended

The stat swapping logic appears fundamentally incorrect. Consider this fix:

-		let baseStatName = statName;
-		if (nature.plus) {
-			if (statName === nature.minus) {
-				baseStatName = nature.plus;
-			} else if (statName === nature.plus) {
-				baseStatName = nature.minus!;
-			}
-		}
-		let stat = baseStats[baseStatName];
+		// Get the actual base stat value for this stat
+		let stat = baseStats[statName];
+		
+		// For nature swap, we need to swap the FINAL calculated values, not the base stats

Additionally, add bounds checking and fix the truncation:

-		stat = tr(tr(stat * 110, 16) / 100);
+		stat = tr(stat * 110 / 100);
+		stat = Math.min(stat, 999); // Add reasonable bounds

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In config/formats.ts between lines 1596 and 1617, fix the statModify method by
correcting the nature-based stat modification logic to adjust the stat value
itself rather than swapping stat names. Remove the nested truncation calls and
replace them with a single truncation using the correct precision. Add
validation to ensure no division by zero occurs and clamp the final stat values
within valid bounds to prevent invalid results.
_⚠️ Potential issue_ **Critical issue with stat calculation logic - potential division by zero and incorrect formula** The new `statModify` method has several serious problems: 1. **Division by zero risk**: Line 1614 uses `tr(tr(stat * 110, 16) / 100)` but if `stat` is 0, this could cause issues 2. **Incorrect base stat swapping**: Lines 1600-1606 swap the base stat names based on nature, but this logic seems flawed - it's swapping the stat being calculated rather than the values themselves 3. **Missing validation**: No bounds checking on the calculated stats 4. **Complex nested truncation**: The double truncation pattern `tr(tr(...), 16)` on line 1614 is unusual and may not be intended The stat swapping logic appears fundamentally incorrect. Consider this fix: ```diff - let baseStatName = statName; - if (nature.plus) { - if (statName === nature.minus) { - baseStatName = nature.plus; - } else if (statName === nature.plus) { - baseStatName = nature.minus!; - } - } - let stat = baseStats[baseStatName]; + // Get the actual base stat value for this stat + let stat = baseStats[statName]; + + // For nature swap, we need to swap the FINAL calculated values, not the base stats ``` Additionally, add bounds checking and fix the truncation: ```diff - stat = tr(tr(stat * 110, 16) / 100); + stat = tr(stat * 110 / 100); + stat = Math.min(stat, 999); // Add reasonable bounds ``` > Committable suggestion skipped: line range outside the PR's diff. <details> <summary>🤖 Prompt for AI Agents</summary> ``` In config/formats.ts between lines 1596 and 1617, fix the statModify method by correcting the nature-based stat modification logic to adjust the stat value itself rather than swapping stat names. Remove the nested truncation calls and replace them with a single truncation using the correct precision. Add validation to ensure no division by zero occurs and clamp the final stat values within valid bounds to prevent invalid results. ``` </details> <!-- fingerprinting:phantom:poseidon:tarantula --> <!-- This is an auto-generated comment by CodeRabbit -->
coderabbitai[bot] (Migrated from github.com) commented 2025-08-06 23:45:15 +00:00

💡 Verification agent

🧩 Analysis chain

Evolution method changed to item-based with Leaders Crest.

The change from level-based to item-based evolution using "Leaders Crest" aligns with the pattern of evolution updates seen throughout this file (similar to Probopass). The item name fits the regal theme of Kingambit.

Verify that the evolution system properly handles the new item-based evolutions and that "Leaders Crest" is properly defined in the items database.


🏁 Script executed:

#!/bin/bash
# Search for Leaders Crest definition and other evolution item usage
rg -A 3 -B 3 "Leaders Crest" --type ts
rg -A 3 "evoType.*useItem" --type ts | head -20

Length of output: 1245


🏁 Script executed:

#!/bin/bash
# Locate the items definition file(s)
fd -e ts items

# Search for "Leaders Crest" in the items database
rg -C3 'name:\s*"Leaders Crest"' data/items.ts
rg -C3 'leaderscrest' data/items.ts

Length of output: 813


🏁 Script executed:

#!/bin/bash
# Comprehensive search for any "Crest" item definitions across data and sim directories
rg --type ts --ignore-case -C3 crest data sim

Length of output: 358


Missing “Leaders Crest” item definition

I wasn’t able to locate a Leaders Crest entry in the items database (e.g. any of data/items.ts, sim/dex-items.ts, or their mod variants). Without that definition, the new evoItem reference will be invalid at runtime.

• data/pokedex.ts (lines ~17929–17931):
evoType: "useItem",
evoItem: "Leaders Crest",
evoCondition: "Give Bisharp a Leaders Crest"

Please add a corresponding Leaders Crest item in your items files (name, id, effects, etc.) so that this evolution method resolves correctly.

🤖 Prompt for AI Agents
In data/pokedex.ts around lines 17929 to 17931, the evoItem "Leaders Crest" is
referenced but there is no corresponding item definition in the items database
files such as data/items.ts or sim/dex-items.ts. To fix this, add a new item
entry for "Leaders Crest" in the appropriate items file, including its name, id,
and any relevant effects or properties, so that the evoItem reference resolves
correctly at runtime.
_💡 Verification agent_ <details> <summary>🧩 Analysis chain</summary> **Evolution method changed to item-based with Leaders Crest.** The change from level-based to item-based evolution using "Leaders Crest" aligns with the pattern of evolution updates seen throughout this file (similar to Probopass). The item name fits the regal theme of Kingambit. Verify that the evolution system properly handles the new item-based evolutions and that "Leaders Crest" is properly defined in the items database. --- 🏁 Script executed: ```shell #!/bin/bash # Search for Leaders Crest definition and other evolution item usage rg -A 3 -B 3 "Leaders Crest" --type ts rg -A 3 "evoType.*useItem" --type ts | head -20 ``` Length of output: 1245 --- 🏁 Script executed: ```shell #!/bin/bash # Locate the items definition file(s) fd -e ts items # Search for "Leaders Crest" in the items database rg -C3 'name:\s*"Leaders Crest"' data/items.ts rg -C3 'leaderscrest' data/items.ts ``` Length of output: 813 --- 🏁 Script executed: ```shell #!/bin/bash # Comprehensive search for any "Crest" item definitions across data and sim directories rg --type ts --ignore-case -C3 crest data sim ``` Length of output: 358 --- </details> **Missing “Leaders Crest” item definition** I wasn’t able to locate a `Leaders Crest` entry in the items database (e.g. any of `data/items.ts`, `sim/dex-items.ts`, or their mod variants). Without that definition, the new evoItem reference will be invalid at runtime. • data/pokedex.ts (lines ~17929–17931): evoType: "useItem", evoItem: "Leaders Crest", evoCondition: "Give Bisharp a Leaders Crest" Please add a corresponding `Leaders Crest` item in your items files (name, id, effects, etc.) so that this evolution method resolves correctly. <details> <summary>🤖 Prompt for AI Agents</summary> ``` In data/pokedex.ts around lines 17929 to 17931, the evoItem "Leaders Crest" is referenced but there is no corresponding item definition in the items database files such as data/items.ts or sim/dex-items.ts. To fix this, add a new item entry for "Leaders Crest" in the appropriate items file, including its name, id, and any relevant effects or properties, so that the evoItem reference resolves correctly at runtime. ``` </details> <!-- fingerprinting:phantom:poseidon:tarantula --> <!-- This is an auto-generated comment by CodeRabbit -->
coderabbitai[bot] (Migrated from github.com) commented 2025-08-06 23:45:15 +00:00

⚠️ Potential issue

Missing LIMIT 1 clause in updateOne method.

The updateOne method no longer includes LIMIT 1, which means it could update multiple rows despite its name suggesting a single row update. This is a breaking change and could lead to unintended data modifications.

Consider adding back the LIMIT clause for MySQL or using a primary key constraint:

 updateOne(partialRow: PartialOrSQL<Row> | SQLStatement):
 (strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise<OkPacketOf<DB>> {
   return (s, ...r) =>
-    this.queryExec()`UPDATE "${this.name}" SET ${partialRow as any} ${new SQLStatement(s, r)}`;
+    this.queryExec()`UPDATE "${this.name}" SET ${partialRow as any} ${new SQLStatement(s, r)} ${this.db.type === 'mysql' ? SQL`LIMIT 1` : SQL``}`;
 }
🤖 Prompt for AI Agents
In lib/database.ts around lines 260 to 264, the updateOne method is missing a
LIMIT 1 clause, which can cause multiple rows to be updated instead of just one.
To fix this, modify the SQL query string to append "LIMIT 1" at the end of the
update statement to ensure only one row is updated, preserving the intended
behavior of the method.
_⚠️ Potential issue_ **Missing LIMIT 1 clause in updateOne method.** The `updateOne` method no longer includes `LIMIT 1`, which means it could update multiple rows despite its name suggesting a single row update. This is a breaking change and could lead to unintended data modifications. Consider adding back the LIMIT clause for MySQL or using a primary key constraint: ```diff updateOne(partialRow: PartialOrSQL<Row> | SQLStatement): (strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise<OkPacketOf<DB>> { return (s, ...r) => - this.queryExec()`UPDATE "${this.name}" SET ${partialRow as any} ${new SQLStatement(s, r)}`; + this.queryExec()`UPDATE "${this.name}" SET ${partialRow as any} ${new SQLStatement(s, r)} ${this.db.type === 'mysql' ? SQL`LIMIT 1` : SQL``}`; } ``` <details> <summary>🤖 Prompt for AI Agents</summary> ``` In lib/database.ts around lines 260 to 264, the updateOne method is missing a LIMIT 1 clause, which can cause multiple rows to be updated instead of just one. To fix this, modify the SQL query string to append "LIMIT 1" at the end of the update statement to ensure only one row is updated, preserving the intended behavior of the method. ``` </details> <!-- fingerprinting:phantom:medusa:armadillo --> <!-- This is an auto-generated comment by CodeRabbit -->
coderabbitai[bot] (Migrated from github.com) commented 2025-08-06 23:45:15 +00:00

⚠️ Potential issue

Remove unsafe non-null assertion in PGDatabase constructor.

Using null! when config is falsy will cause runtime errors. The constructor should properly handle missing configuration.

-super(config ? new pg.Pool(config) : null!);
+if (!config) {
+  throw new Error('PostgreSQL configuration is required');
+}
+super(new pg.Pool(config));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

	// Ensure we have a valid PostgreSQL configuration before calling super
	if (!config) {
		throw new Error('PostgreSQL configuration is required');
	}
	super(new pg.Pool(config));
🤖 Prompt for AI Agents
In lib/database.ts at line 387, the constructor uses a non-null assertion with
null! which can cause runtime errors if config is falsy. Modify the constructor
to properly handle the case when config is missing by either providing a default
configuration, throwing an error, or handling the null case safely without using
the non-null assertion.
_⚠️ Potential issue_ **Remove unsafe non-null assertion in PGDatabase constructor.** Using `null!` when config is falsy will cause runtime errors. The constructor should properly handle missing configuration. ```diff -super(config ? new pg.Pool(config) : null!); +if (!config) { + throw new Error('PostgreSQL configuration is required'); +} +super(new pg.Pool(config)); ``` <!-- suggestion_start --> <details> <summary>📝 Committable suggestion</summary> > ‼️ **IMPORTANT** > Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements. ```suggestion // Ensure we have a valid PostgreSQL configuration before calling super if (!config) { throw new Error('PostgreSQL configuration is required'); } super(new pg.Pool(config)); ``` </details> <!-- suggestion_end --> <details> <summary>🤖 Prompt for AI Agents</summary> ``` In lib/database.ts at line 387, the constructor uses a non-null assertion with null! which can cause runtime errors if config is falsy. Modify the constructor to properly handle the case when config is missing by either providing a default configuration, throwing an error, or handling the null case safely without using the non-null assertion. ``` </details> <!-- fingerprinting:phantom:medusa:armadillo --> <!-- This is an auto-generated comment by CodeRabbit -->
coderabbitai[bot] (Migrated from github.com) commented 2025-08-06 23:45:15 +00:00

⚠️ Potential issue

Remove unsafe non-null assertion that can cause runtime errors.

The non-null assertion null! is dangerous. If Config.usepostgres is falsy, teamsDB will be null but TypeScript will treat it as non-null, leading to runtime errors when any methods are called on it.

Consider using a more defensive approach:

-export const teamsDB = Config.usepostgres ? new PGDatabase(Config.usepostgres) : null!;
-export const teamsTable = teamsDB?.getTable<
-	StoredTeam
->('teams', 'teamid');
+export const teamsDB = Config.usepostgres ? new PGDatabase(Config.usepostgres) : null;
+export const teamsTable = teamsDB ? teamsDB.getTable<StoredTeam>('teams', 'teamid') : null;

Then add null checks where these are used, or throw an error immediately if the database is required but not configured.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

export const teamsDB = Config.usepostgres ? new PGDatabase(Config.usepostgres) : null;
export const teamsTable = teamsDB ? teamsDB.getTable<StoredTeam>('teams', 'teamid') : null;
🤖 Prompt for AI Agents
In server/chat-plugins/teams.ts around lines 17 to 20, remove the unsafe
non-null assertion `null!` when assigning `teamsDB` because it can cause runtime
errors if `Config.usepostgres` is falsy. Instead, assign `teamsDB` to either a
new PGDatabase instance or null without the assertion. Then, add proper null
checks before using `teamsDB` or throw an error early if the database connection
is mandatory to prevent runtime failures.
_⚠️ Potential issue_ **Remove unsafe non-null assertion that can cause runtime errors.** The non-null assertion `null!` is dangerous. If `Config.usepostgres` is falsy, `teamsDB` will be null but TypeScript will treat it as non-null, leading to runtime errors when any methods are called on it. Consider using a more defensive approach: ```diff -export const teamsDB = Config.usepostgres ? new PGDatabase(Config.usepostgres) : null!; -export const teamsTable = teamsDB?.getTable< - StoredTeam ->('teams', 'teamid'); +export const teamsDB = Config.usepostgres ? new PGDatabase(Config.usepostgres) : null; +export const teamsTable = teamsDB ? teamsDB.getTable<StoredTeam>('teams', 'teamid') : null; ``` Then add null checks where these are used, or throw an error immediately if the database is required but not configured. <!-- suggestion_start --> <details> <summary>📝 Committable suggestion</summary> > ‼️ **IMPORTANT** > Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements. ```suggestion export const teamsDB = Config.usepostgres ? new PGDatabase(Config.usepostgres) : null; export const teamsTable = teamsDB ? teamsDB.getTable<StoredTeam>('teams', 'teamid') : null; ``` </details> <!-- suggestion_end --> <details> <summary>🤖 Prompt for AI Agents</summary> ``` In server/chat-plugins/teams.ts around lines 17 to 20, remove the unsafe non-null assertion `null!` when assigning `teamsDB` because it can cause runtime errors if `Config.usepostgres` is falsy. Instead, assign `teamsDB` to either a new PGDatabase instance or null without the assertion. Then, add proper null checks before using `teamsDB` or throw an error early if the database connection is mandatory to prevent runtime failures. ``` </details> <!-- fingerprinting:phantom:medusa:armadillo --> <!-- This is an auto-generated comment by CodeRabbit -->
coderabbitai[bot] (Migrated from github.com) commented 2025-08-06 23:45:15 +00:00

⚠️ Potential issue

Potential issue with uninitialized PGDatabase instance.

Creating a PGDatabase instance without configuration may cause issues. Based on the implementation in lib/database.ts, when no config is provided, the connection is set to null!, which could lead to runtime errors if any methods that require a database connection are called.

Consider either:

  1. Passing a mock configuration to avoid potential null reference issues
  2. Adding a comment explaining this is only for testing the _resolveSQL method which doesn't require a connection
🤖 Prompt for AI Agents
In test/lib/postgres.js at line 5, the PGDatabase instance is created without
any configuration, which sets its connection to null and may cause runtime
errors if methods requiring a connection are called. To fix this, either provide
a mock configuration object when instantiating PGDatabase to ensure a valid
connection or add a clear comment explaining that this instance is only used for
testing the _resolveSQL method, which does not require a database connection.
_⚠️ Potential issue_ **Potential issue with uninitialized PGDatabase instance.** Creating a `PGDatabase` instance without configuration may cause issues. Based on the implementation in `lib/database.ts`, when no config is provided, the connection is set to `null!`, which could lead to runtime errors if any methods that require a database connection are called. Consider either: 1. Passing a mock configuration to avoid potential null reference issues 2. Adding a comment explaining this is only for testing the `_resolveSQL` method which doesn't require a connection <details> <summary>🤖 Prompt for AI Agents</summary> ``` In test/lib/postgres.js at line 5, the PGDatabase instance is created without any configuration, which sets its connection to null and may cause runtime errors if methods requiring a connection are called. To fix this, either provide a mock configuration object when instantiating PGDatabase to ensure a valid connection or add a clear comment explaining that this instance is only used for testing the _resolveSQL method, which does not require a database connection. ``` </details> <!-- fingerprinting:phantom:medusa:armadillo --> <!-- This is an auto-generated comment by CodeRabbit -->

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pokebedrock/pokebedrock-showdown!2
No description provided.