Skip to content

feat(mate): catching, listing, saving and logging out with pets match the live game - #2513

Merged
erwan-joly merged 15 commits into
NosCoreIO:masterfrom
Nevenit:feat/pets-stage1a
Oct 16, 2026
Merged

erwan-joly merged 15 commits into
NosCoreIO:masterfrom
Nevenit:feat/pets-stage1a

Conversation

@Nevenit

@Nevenit Nevenit commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

What

Catching a pet, the pet window, the party panel, saving pets and logging out now behave as a packet trace of the live game shows. Two older bugs that blocked capture entirely are fixed along the way.

Capture

  • A caught pet joins at once. Before, nothing happened until a relog. The server now sends:

    • ctl and the CaptureSuccessful message;
    • the pet list;
    • the capture animation (su … 15) and effect 197;
    • the monster's out.

    With no pet out, the new pet also:

    • spawns on the cell the monster stood on;
    • joins the party panel;
    • gets its cond and pst.
  • A new pet's loyalty is 3000. Every fresh catch in the trace shows 3000; it used to be 1000.

  • A failed roll sends CaptureFailed and the fail animation (su … 16).

  • The level and half-health refusals send CaptureToHighLevel and CaptureTooMuchLife, followed by cancel 0 <castId> -1. That is the form the live game uses for a refused cast. Without it the client waits for the cast forever and the character cannot act. A Capture aimed at something that is not a monster is cancelled the same way.

  • The monster is claimed as soon as the roll succeeds. Two players catching the same monster at once no longer both get a pet.

  • Capture resolves again for every class. SkillResolver only took skills with UpgradeSkill == 0. Every class's Capture skill (209, 235, 236, 237) carries a non-zero value without being an upgrade, so every capture cast was cancelled. The resolver still prefers the base skill, and now falls back to an owned non-upgrade (type ≠ 2) skill with the same cast id.

Pet window

  • npinfo answers with p_clear and the full sc_p/sc_n list. The handler was bound to the server-side NpInfoPacket twin. The deserializer always hands out the client type, so the handler never ran. A test now pushes npinfo 0 through the real Deserializer.
  • sc_p_cts gets no reply, as in the trace.

Party panel

  • Every pinit the player receives lists their pets that are out, after any group members: 2|<id>|1|<level>|<name>|-1|<vnum>|0|0|0|0. All nine send sites use one builder.
  • Alone, the panel is empty, matching the trace's pinit 0. It used to carry a self entry.
  • On a map change the panel goes out after the pets spawn, and the group's pst follows it.

Saving and logging out

  • Pets are saved with the character. MateService.SaveAsync had no caller.
  • Logging out takes the pet off other players' screens.

How

  • MateService.Adopt builds a live mate from a freshly written row. Loading uses the same builder.
  • Mate.SpawnAsync and Mate.DespawnAsync are now the one path on and off a map. Map change, capture and disconnect all use them.
  • PlayerComponentBundle.GenerateMateRoster is the p_clear and sc burst, used at login, in npinfo and on capture.
  • ICharacterEntity.GeneratePinit is the combined party panel.
  • Comments in touched files no longer name other server implementations.

Known gap

The pet window shows its rows without pictures. ScpPacket serialises 33 fields, while the live client's sc_p has 40:

ours:  sc_p 1 333 … 156 156 10 10 0 15 0 Chicken 1
trace: sc_p 0 333 … 156 156 10 10 1 15 0 @ 0 0 1 0 0 0 0 1

This predates the PR, since the login burst already sent the short form. The fix belongs in NosCore.Packets, together with typing ptctl's move list for the follow-up that lets the client drive pet movement.

Testing

  • dotnet test NosCore.sln: 1241 passed.

  • Tests cover each behaviour above:

    • capture success, failure, refusals and invalid targets;
    • animation order;
    • a double capture;
    • the panel when alone, with a pet, with a pet at home and in a group;
    • map change ordering;
    • the pet window;
    • saving;
    • logout.
  • Live, on a local server:

    • catching a chicken;
    • the pet window answering;
    • the pet following through portals;
    • pets surviving a relog.

    The two capture blockers above were found during this check.

  • manual-test-plan.md has a new "Pets" section.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Captured pets are added to your roster, can join your team, and appear in the pet window and party panel.
    • Pet capture now provides success and failure feedback, with restrictions based on the monster’s level and health.
    • Pets are saved with their progress and appear at the correct position when entering or changing maps.
  • Bug Fixes
    • Pets are removed from the map when their owner logs out or leaves the map.
    • Pet rosters update correctly when opening the pet window, joining or leaving a group, and reviving.
  • Documentation
    • Expanded the manual test plan with pet capture and persistence checks.

Nevenit and others added 15 commits October 16, 2026 05:19
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…apture failed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y sends

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and shows the new pet's bar

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rs' bars

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d resolve again

Every class's Capture skill carries a non-zero UpgradeSkill without being an
upgrade, so the resolver cancelled every capture cast.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he character

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: NosCoreIO/NosCore/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1ba32946-1b93-4da5-b028-8695c4a4818b
📥 Commits

Reviewing files that changed from the base of the PR and between 1497d34 and 54c7328.

📒 Files selected for processing: 29
  • documentation/manual-test-plan.md
  • src/NosCore.GameObject/Ecs/Extensions/CharacterEntityExtension.cs
  • src/NosCore.GameObject/Ecs/Extensions/MateExtensions.cs
  • src/NosCore.GameObject/Ecs/Extensions/PlayerBundleExtensions.cs
  • src/NosCore.GameObject/Networking/ClientSession/DisconnectHandlers/MapDisconnectHandler.cs
  • src/NosCore.GameObject/Services/BattleService/BattleService.cs
  • src/NosCore.GameObject/Services/BattleService/CaptureService.cs
  • src/NosCore.GameObject/Services/BattleService/SkillResolver.cs
  • src/NosCore.GameObject/Services/MapChangeService/MapChangeService.cs
  • src/NosCore.GameObject/Services/MateService/IMateService.cs
  • src/NosCore.GameObject/Services/MateService/MateService.cs
  • src/NosCore.GameObject/Services/SaveService/SaveService.cs
  • src/NosCore.PacketHandlers/Battle/RevivalPacketHandler.cs
  • src/NosCore.PacketHandlers/Game/GameStartPacketHandler.cs
  • src/NosCore.PacketHandlers/Game/NpinfoPacketHandler.cs
  • src/NosCore.PacketHandlers/Game/ScpCtsPacketHandler.cs
  • src/NosCore.PacketHandlers/Group/PjoinPacketHandler.cs
  • src/NosCore.PacketHandlers/Group/PleavePacketHandler.cs
  • test/NosCore.GameObject.Tests/Networking/MapDisconnectHandlerTests.cs
  • test/NosCore.GameObject.Tests/Services/BattleService/CaptureServiceTests.cs
  • test/NosCore.GameObject.Tests/Services/BattleService/SkillResolverTests.cs
  • test/NosCore.GameObject.Tests/Services/MapChangeService/MapChangeServiceTests.cs
  • test/NosCore.GameObject.Tests/Services/MateService/MatePartyPanelTests.cs
  • test/NosCore.GameObject.Tests/Services/MateService/MateServiceTests.cs
  • test/NosCore.GameObject.Tests/Services/MateService/MateSpawnTests.cs
  • test/NosCore.GameObject.Tests/Services/SaveService/SaveServiceTests.cs
  • test/NosCore.PacketHandlers.Tests/Game/GameStartPacketHandlerTests.cs
  • test/NosCore.PacketHandlers.Tests/Game/PetWindowPacketHandlerTests.cs
  • test/NosCore.Tests.Shared/TestMates.cs

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

Walkthrough

This change adds pet capture outcomes, mate adoption and persistence, and pet roster packets. It also updates mate spawning and despawning during map changes and disconnects, and adds tests for these flows.

Changes

Pet lifecycle

Layer / File(s) Summary
Mate adoption and persistence
src/NosCore.GameObject/Services/MateService/*, src/NosCore.GameObject/Services/SaveService/SaveService.cs, test/NosCore.GameObject.Tests/Services/MateService/MateServiceTests.cs, test/NosCore.GameObject.Tests/Services/SaveService/SaveServiceTests.cs, test/NosCore.Tests.Shared/TestMates.cs
MateService builds and adopts mates and assigns pet slots. SaveService saves the character’s mates. Tests cover adoption and persistence of mate data.
Pet roster and party packets
src/NosCore.GameObject/Ecs/Extensions/CharacterEntityExtension.cs, src/NosCore.GameObject/Ecs/Extensions/PlayerBundleExtensions.cs, src/NosCore.PacketHandlers/{Battle,Game,Group}/*, test/NosCore.GameObject.Tests/Services/MateService/MatePartyPanelTests.cs, test/NosCore.PacketHandlers.Tests/Game/*
Character-generated Pinit packets include active pets. Roster, group, revive, level, and game-start flows use character-specific packets. Pet-window tests cover roster refresh behavior.
Mate spawn and map lifecycle
src/NosCore.GameObject/Ecs/Extensions/MateExtensions.cs, src/NosCore.GameObject/Networking/ClientSession/DisconnectHandlers/MapDisconnectHandler.cs, src/NosCore.GameObject/Services/MapChangeService/MapChangeService.cs, test/NosCore.GameObject.Tests/Networking/MapDisconnectHandlerTests.cs, test/NosCore.GameObject.Tests/Services/{MapChangeService, MateService}/*
Mate extensions spawn and despawn mate entities and route spawn packets. Map changes and disconnects use these operations. Tests cover placement, packet routing, and removal.
Capture outcomes and pet creation
src/NosCore.GameObject/Services/BattleService/*, documentation/manual-test-plan.md, test/NosCore.GameObject.Tests/Services/BattleService/*
Capture attempts now report invalid targets and failed rolls. Successful attempts persist and adopt a pet, send capture packets, and spawn team-member pets. Capture and skill-resolution tests cover these cases.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant CaptureService
  participant MateService
  participant MateExtensions
  participant MapInstance
  CaptureService->>MateService: Persist and adopt captured mate
  CaptureService->>MateExtensions: Spawn team-member mate
  MateExtensions->>MapInstance: Add mate entity and send spawn packet
Loading

Suggested reviewers: erwan-joly

Merge Risk: 🔵 Low · up to 54c73

If saving a captured pet fails, the player can lose that monster without receiving a pet or failure feedback. This is a bounded failure-path risk rather than a demonstrated blocker to normal captures.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 4.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 100 functions across 28 files. (1 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly summarizes the main changes: pet capture, listing, saving, and logout behavior aligned with the live game.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 4.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 100 functions across 28 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@erwan-joly
erwan-joly merged commit 9935f04 into NosCoreIO:master Oct 16, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants