Split player presence events into a #player-events channel - #62
Merged
Conversation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Swap PlayerEventRelay's injected locator from IEventChannelLocator to IPlayerEventChannelLocator so player transitions (login/logout/death/AFK) resolve the #player-events channel instead of #events. Constructor arity, RelayAsync body, and the in-game team-chat send path are unchanged. Also bumps the StringsResourceParityTests sentinel count (365 -> 366) to account for the channel.playerevents.name key already added in Task 1; the sentinel was left stale and was failing dtk dotnet test RustPlusBot.slnx.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This pull request introduces a new per-server Discord channel (#player-events) to separate team-player presence notifications (join/disconnect/death/respawn/AFK) from the existing #events channel, while keeping the in-game team chat broadcast behavior unchanged.
Changes:
- Added a new workspace channel key/spec (
playerevents) and localized channel names (player-events/evenements-joueurs) with ordering between#eventsand#map. - Introduced
IPlayerEventChannelLocator+PlayerEventChannelLocatorand registered it in workspace DI. - Updated
PlayerEventRelay(and related tests/registrations/docs) to resolve/post presence embeds to#player-eventsinstead of#events.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/RustPlusBot.Localization.Tests/StringsResourceParityTests.cs | Updates expected resource-key catalog count after adding new localization entry. |
| tests/RustPlusBot.Features.Workspace.Tests/WorkspaceRegistrationTests.cs | Asserts the new locator interface is registered by AddWorkspace(). |
| tests/RustPlusBot.Features.Workspace.Tests/Specs/ServerChannelSpecTests.cs | Adds regression tests pinning the per-server channel set and relative ordering including ServerPlayerEvents. |
| tests/RustPlusBot.Features.Workspace.Tests/Locating/PlayerEventChannelLocatorTests.cs | Validates the new locator resolves playerevents (not events) from the store. |
| tests/RustPlusBot.Features.Players.Tests/PlayerEventRelayTests.cs | Updates relay tests to substitute the new locator interface. |
| tests/RustPlusBot.Features.Players.Tests/PlayerEventRegistrationTests.cs | Updates DI test to provide IPlayerEventChannelLocator for AddPlayers() resolution. |
| tests/RustPlusBot.Features.Players.Tests/Hosting/PlayersHostedServiceTests.cs | Updates hosted-service test harness to use IPlayerEventChannelLocator. |
| src/RustPlusBot.Localization/Strings.resx | Adds English channel name resource for channel.playerevents.name. |
| src/RustPlusBot.Localization/Strings.fr.resx | Adds French channel name resource for channel.playerevents.name. |
| src/RustPlusBot.Features.Workspace/WorkspaceServiceCollectionExtensions.cs | Registers IPlayerEventChannelLocator → PlayerEventChannelLocator as a singleton locator. |
| src/RustPlusBot.Features.Workspace/WorkspaceKeys.cs | Adds the persisted channel key constant ServerPlayerEvents = "playerevents". |
| src/RustPlusBot.Features.Workspace/Specs/ServerWorkspaceSpecProvider.cs | Inserts the new channel spec at order 5 and shifts subsequent channel orders. |
| src/RustPlusBot.Features.Workspace/Locating/PlayerEventChannelLocator.cs | Adds a CachingChannelLocator-based locator for the playerevents key. |
| src/RustPlusBot.Features.Workspace/Locating/IPlayerEventChannelLocator.cs | Adds the public locator interface consumed by other feature assemblies. |
| src/RustPlusBot.Features.Players/Relaying/PlayerEventRelay.cs | Switches relay dependency from IEventChannelLocator to IPlayerEventChannelLocator and updates XML docs. |
| README.md | Documents the new #player-events channel in the channel tour. |
| docs/superpowers/specs/2026-07-22-player-events-channel-design.md | Adds design spec describing scope, approach, and data flow for the split. |
| docs/superpowers/plans/2026-07-22-player-events-channel.md | Adds an implementation plan capturing steps, constraints, and verification. |
| docs/development/running-locally.md | Updates local-running docs to mention auto-created #player-events behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Team-player presence events (join, disconnect, death, respawn, AFK) now post to a new per-server
#player-eventsDiscord channel instead of the shared#eventschannel.#eventskeeps map events (cargo ship, patrol helicopter, chinook, oil rigs) and wipe announcements. The in-game Rust team-chat broadcast is unchanged for both feeds — the same lines still go to team chat.How
Channels here are declarative, so the split is a new key + a new locator rather than a code move —
Features.Playersalready owned its own relay.WorkspaceChannelKeys.ServerPlayerEvents = "playerevents", declared as a read-onlyChannelSpecat Order 5.map/switches/alarms/storagemonitorsshift to 6–9;eventsstays at 4.IPlayerEventChannelLocator+ a one-lineCachingChannelLocatorsubclass, mirroringIEventChannelLocator/EventChannelLocator.PlayerEventRelayswaps that single injected dependency. Nothing insideRelayAsyncchanges.player-events(en) /evenements-joueurs(fr).EventRelay,WipeAnnouncer,EventChannelLocatorand their tests are untouched — they are the regression proof that in-game events did not move.Deployment
No migration.
WorkspaceReconcilercreates the channel in every existing per-server category on the next reconcile andEnsureChannelOrderAsyncpermutes the existing position slots once, so channels outside the managed block keep their relative places. Historical messages stay in#events.Between deploy and first reconcile — plus up to the locator's 30s cache TTL — presence events go in-game only and are not backfilled to Discord. That matches how every other channel behaves on introduction.
Testing
Full suite: 1245 passed, 1 skipped across 19 projects.
ServerChannelSpecTestspins the channel set, the full ordering sequence, and Order uniqueness.PlayerEventChannelLocatorTestsseeds both aneventsrow (888) and aplayereventsrow (777) and asserts 777 — it fails if the locator reads the wrong key.PlayerEventRelayTestsstill covers the null-channel branch (in-game line sent, no Discord post) and the resolved-channel branch.PlayerEventRelay's constructor only acceptsIPlayerEventChannelLocator.Verified against real code during review: teardown/purge is key-agnostic so the new channel is cleaned up like its siblings, and there is no
playerevents/eventscollision — the store matchesChannelKeywith==only and channel adoption uses exact name equality.Design:
docs/superpowers/specs/2026-07-22-player-events-channel-design.md🤖 Generated with Claude Code