Skip to content

Extract the map transitions of the player and its spawn gate selection - #884

Open
sven-n wants to merge 1 commit into
masterfrom
claude/player-class-refactor-plan-aha5v2
Open

Extract the map transitions of the player and its spawn gate selection#884
sven-n wants to merge 1 commit into
masterfrom
claude/player-class-refactor-plan-aha5v2

Conversation

@sven-n

@sven-n sven-n commented Aug 16, 2026

Copy link
Copy Markdown
Member

Phase 4 of the Player refactoring (docs/PlayerRefactoringPlan.md).

The player doesn't know about duels and soccer matches anymore

GetSpawnGateOfCurrentMapAsync hardcoded two game features: duel rooms and the guild war soccer ground. Both are now plugins of the new IPlayerSpawnGateSelectionPlugIn point — DuelSpawnGatePlugIn and SoccerSpawnGatePlugIn, both active by default. Mini games and castle siege can add their own spawn gate the same way, without touching Player.

The point passes a mutable SpawnGateSelectionArgs, because plugin points can't return values. A plugin only fills the gate when no other plugin selected one, so the result doesn't depend on the (undefined) plugin order. When nothing selects a gate, the safezone gate of the current map is used, exactly as before.

The component

PlayerMapTransitions takes over TeleportAsync, TeleportToMapAsync, WarpToAsync, WarpToSafezoneAsync, RespawnAtAsync, ClientReadyAfterMapChangeAsync and the helpers around them. The public members of Player delegate, so no call site changes.

Player gained three internal members for it — SetCurrentMapSilently, ClearRespawnAfterDeathToken and ClearObservingObjectsListAsync — and the setters of CurrentMap and IsTeleporting became internal instead of private. The death handling itself (and its cancellation token) stays in Player until phase 5.

Bug fix

The null reference I flagged in #872 is fixed here, since this phase restructures the method: in ClientReadyAfterMapChangeAsync, a player arriving at a blocked position is warped to the safezone, which sets CurrentMap to null — and the summon was then added to that null map. It only hit players who had a summon. The warp starts its own map change, which adds the summon when it completes, so the method now returns after the warp.

Player.cs: 2,058 → 1,828 lines (3,098 before this refactoring started).

Tests

New SpawnGateSelectionTests with four cases: a plugin defines the spawn gate, the first selected gate wins over a second plugin, the map's safezone gate is used when no plugin selects one, and a player arriving at a blocked position ends up at its spawn gate. The last one creates a summon and fails with the null reference described above when the fix is reverted — I checked.

PlayerTestHelper now sets up the exit gates of its map mock, which the third case needs.

Full suite: 720 of 720 pass, solution builds with no errors.


Generated by Claude Code

Moves teleport, warp, respawn and the client handshake after a map
change into a PlayerMapTransitions component.

The spawn gate is now determined by the new
IPlayerSpawnGateSelectionPlugIn point, so the player doesn't know about
duels and guild war soccer matches anymore: both are plugins now, and
mini games or castle siege can add their own without touching the
player.

Fixes a null reference which could happen when a player arrived at a
blocked position and had a summon: the warp to the safezone sets the
current map to null, and the summon was added to it afterwards. The
summon is added by the map change which the warp starts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V5grV5oveZNhhjK1mazM2B
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