Skip to content

fix(Core/Pet): Keep one current pet per owner in character_pet - #28319

Open
Nyeriah wants to merge 1 commit into
azerothcore:masterfrom
Nyeriah:claude/fix-duplicate-current-pet-6ddd90
Open

Nyeriah wants to merge 1 commit into
azerothcore:masterfrom
Nyeriah:claude/fix-duplicate-current-pet-6ddd90

Conversation

@Nyeriah

@Nyeriah Nyeriah commented Oct 30, 2026

Copy link
Copy Markdown
Member

Changes Proposed:

This PR proposes changes to:

  • Core (units, players, creatures, game systems).
  • Scripts (bosses, spell scripts, creature scripts).
  • Database (SAI, creatures, etc).

A warlock could end up with two demons in character_pet slot 0 (current pet). The character enum joins character_pet on the current slot, so the character then shows up twice on the character select screen.

The cause is a pet being removed while its async load (PetLoadQueryHolder) is still pending. Pet::SavePetToDB skipped every write while m_loading was set, but the pet stable still moved the pet out of the current slot in memory. The row stayed at slot 0, and when the next demon was saved as current there were two. For example: a demon is resummoned from slot 0 after dismounting or zoning in, and a fast summon of another demon finishes before the load does.

Changes:

  • Pet::SavePetToDB: while the pet is loading, spells and auras are still not saved (they are not loaded yet), but a removal to a stable or unslotted slot now writes the new slot, and abandoning the pet deletes its rows. Before, a hunter pet abandoned during the load came back as current on the next login.
  • Saving a non-hunter pet as current now also moves other slot 0 rows of the same owner to PET_SAVE_NOT_IN_SLOT, in the same transaction (new statement CHAR_UPD_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID). Hunter pets keep their existing delete of slot 0 rows.
  • Characters SQL update: for summoned pets (PetType = 0) with several slot 0 rows, keeps the most recently saved one and moves the rest to slot 100. Hunter rows are left alone, since the core does not support a hunter having a current and an unslotted pet at the same time.

Review guide: src/server/game/Entities/Pet/Pet.cpp (SavePetToDB) is where the judgment is. The statement and the SQL update are mechanical.

AI-assisted Pull Requests

Important

Using AI tools to prepare pull requests is allowed, but it must be disclosed and it must follow our AC guidelines for AI Agentic Engineering (link below).

You are expected to fully understand the changes you submit and to be able to explain and justify them when maintainers ask.

  • AI tools (e.g. Claude, ChatGPT, or similar) were used entirely or partially to prepare this pull request. If checked, specify which tools and models below.
    • Tools/models used: Claude Code, Claude Opus 5.5
  • I have read and understood the AC guidelines for AI Agentic Engineering

Issues Addressed:

  • None

SOURCE:

The changes have been validated through:

  • Live research (checked on live servers, e.g Classic WotLK, Retail, etc.)
  • Sniffs (remember to share them with the open source community!)
  • Video evidence, knowledge databases or other public sources (e.g forums, Wowhead, etc.)
  • The changes promoted by this pull request come partially or entirely from another project (cherry-pick). Cherry-picks must be committed using the proper --author tag in order to be accepted, thus crediting the original authors, unless otherwise unable to be found

Tests Performed:

This PR has been:

  • Tested in-game by the author.
  • Tested in-game by other community members/someone else other than the author/has been live on production servers.
  • This pull request requires further testing and may have edge cases to be tested.

How to Test the Changes:

  • This pull request can be tested by following the reproduction steps provided in the linked issue
  • This pull request requires further testing. Provide steps to test your changes. If it requires any specific setup e.g multiple players please specify it as well.
  1. Warlock: swap between demons several times, including a summon right after dismounting or zoning in. The character must show once on character select, and SELECT id, entry, slot FROM character_pet WHERE owner = <guid> must have one row at slot 0.
  2. Hunter: stable, unstable and swap pets at a stable master, including right after Call Pet; also Call Pet, Dismiss Pet, abandon, relog with a pet out, and mount/dismount. No pet should go missing or come back after being abandoned.
  3. Other permanent pets saved as current: DK ghoul with Master of Ghouls, mage Water Elemental with Glyph of Eternal Water.
  4. SQL update: give a warlock two slot 0 demons, apply the update, and check only the most recently saved one stays at slot 0.

Known Issues and TODO List:

  • The character enum and Player::_LoadPetStable still assume a single slot 0 row; they are left unchanged since the writer no longer produces duplicates and the SQL update cleans existing ones.

How to Test AzerothCore PRs

When a PR is ready to be tested, it will be marked as [WAITING TO BE TESTED].

You can help by testing PRs and writing your feedback here on the PR's page on GitHub. Follow the instructions here:

http://www.azerothcore.org/wiki/How-to-test-a-PR

REMEMBER: when testing a PR that changes something generic (i.e. a part of code that handles more than one specific thing), the tester should not only check that the PR does its job (e.g. fixing spell XXX) but especially check that the PR does not cause any regression (i.e. introducing new bugs).

For example: if a PR fixes spell X by changing a part of code that handles spells X, Y, and Z, we should not only test X, but we should test Y and Z as well.

A pet removed while its async load is still pending skipped
SavePetToDB, but the pet stable still moved it out of the current slot.
Its row stayed at slot 0, and once the next pet was saved as current
the owner had two slot 0 rows, which makes the character show twice on
the character list.

- While loading, a removal to a stable or unslotted slot now writes the
  new slot, and abandoning the pet deletes it, so it no longer returns
  on the next login.
- Saving a non-hunter pet as current moves other slot 0 rows of the
  owner to PET_SAVE_NOT_IN_SLOT.
- Cleanup for existing summoned pet duplicates keeps the most recently
  saved one.
@Nyeriah

Nyeriah commented Oct 30, 2026

Copy link
Copy Markdown
Member Author

Self-review — claude/fix-duplicate-current-pet-6ddd90 → master

Outcome 3 findings — 3 fixed — final round clean

Tested in-game by the author

Reviewed 1ce4bed (claude/fix-duplicate-current-pet-6ddd90 vs master, merge-base diff — 4 files, +38 −2)

By Claude Code, Opus 5.5 (claude-opus-5-5) — self-review v0.10, 2026-10-30

Review details (3 rounds)

Intent Prevent an owner from having more than one character_pet row in the current slot (slot 0), which lists the character twice on character select, and clean up existing duplicates.

Project rules .agents/docs/self-review-rules.md found and applied (pinned review, full depth for shared core code)

Diff 178ab9f9a6af146b97cccc8b5c1bece696c4b862

Metadata 63c77a223d96a909f53ccee5611191d2373bbc85

Not mirrored from another core, so no upstream author credit applies.

Rounds 1–2 (carried forward)

  1. data/sql/updates/pending_db_characters/rev_1793360706597189800.sql:6 — cleanup also demoted hunter slot-0 rows, leaving a current plus unslotted hunter pet that could end with the real pet deleted → fixed (PetType = 0 only)
  2. src/server/game/Entities/Pet/Pet.cpp:517 — loading branch synced only PET_SAVE_NOT_IN_SLOT; a stable swap/unstable during the load left two slot-0 rows → fixed
  3. src/server/game/Entities/Pet/Pet.cpp:515 — abandoning a hunter pet while it loads skipped the DB delete, so it returned as current on next login → fixed (was deferred in round 2, then folded into this change)

Round 3 — 1ce4bed, delta since 49034f0 (finding 3 fix), clean

Copilot AI balanced review requested due to automatic review settings October 30, 2026 12:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@github-actions github-actions Bot added DB related to the SQL database CORE Related to the core file-cpp Used to trigger the matrix build labels Oct 30, 2026
@coderabbitai

coderabbitai Bot commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 993b459 and 1ce4bed.

Files selected for processing: 4
  • data/sql/updates/pending_db_characters/rev_1793360706597189800.sql
  • src/server/database/Database/Implementation/CharacterDatabase.cpp
  • src/server/database/Database/Implementation/CharacterDatabase.h
  • src/server/game/Entities/Pet/Pet.cpp

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Walkthrough

Loading saves can now delete a pet or update its slot without saving spells or auras. Normal saves of a non-hunter pet as current move other current-slot pet rows for the owner out of that slot. A database update also moves qualifying older current-slot rows with PetType = 0 to slot 100.

Priority: Normal

Merge Risk: Minimal · up to 1ce4b

The changes address stale pet slots during loading and clean up duplicate current summoned pets. No concrete merge-blocking issue remains identified; proceed subject to normal build and gameplay checks.

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

Comment @coderabbitai help to get the list of available commands.

@TheSCREWEDSoftware

TheSCREWEDSoftware commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Would it close this? #25301

And sure this would be the bug: #22737

@Nyeriah

Nyeriah commented Oct 30, 2026

Copy link
Copy Markdown
Member Author

Yes, #22737 is this bug. A warlock with two character_pet rows at slot 0 makes the character enum query return the character twice. This PR stops the core from writing the second slot 0 row (a pet removed while it was still loading kept its slot 0 row), and the SQL update moves existing duplicates to slot 100.

#25301 looks like a different problem, so I wouldn't close it with this. The pet named "Voidwalker" comes from a newly summoned demon being saved before it gets its generated name. If the server crashes before the next save, the template name sticks. This PR doesn't touch that. The mount/dismount swap might be related to a duplicate slot 0 row, but I haven't confirmed it, so I'd keep that issue open.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CORE Related to the core DB related to the SQL database file-cpp Used to trigger the matrix build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants