Skip to content

Fix K9 identity concealment issue - #5954

Merged
walksanatora merged 1 commit into
ss14Starlight:starlight-devfrom
Sparlight:fix-k9-identity
Sep 3, 2026
Merged

Fix K9 identity concealment issue#5954
walksanatora merged 1 commit into
ss14Starlight:starlight-devfrom
Sparlight:fix-k9-identity

Conversation

@Sparlight

Copy link
Copy Markdown
Contributor

Short description

Adds an AlwaysIdentifiableComponent to the IdentitySystem to ignore the IdentitySystem's concealment code.

Why we need to add this

I added #5816 to allow smart corgis and animals to begin to leverage the identity system.
K9s do NOT have an ID slot and as such immediately fail to identify with their sec mask on.
With this change, K9s will be always identifiable.

This isn't a permanent solution to the matter; there is an in-flight bit of dev work going on in the 'Security K9' channel in #pr-workshop that is working to add collars in lieu of the existing system for K9s (tracking implanter and bespoke job identification code). Collars will act as PDAs with suit coordinates.
Until that's done, this will help maintain gameplay-as-intended. The component is also decent for other situations that might spring up where something may need to be always identifiable.

Media (Video/Screenshots)

Fixes this:
image

Checks

  • I do not require assistance to complete the PR.
  • Before posting/requesting review of a PR, I have verified that the changes work.
  • I have added screenshots/videos of the changes, or this PR does not change in-game mechanics.
  • I affirm that my changes are licensed under the MIT License and grant permission for use in this repository under its conditions.

Changelog
🆑 Sparlight

  • fix: K9s will no longer suffer abject identity concealment issues.

@Sparlight
Sparlight requested a review from a team September 3, 2026 00:29
@github-actions github-actions Bot added S: Untriaged Status: Indicates an item has not been triaged and doesn't have appropriate labels. size/S S: Needs Review Status: Requires additional reviews before being fully accepted. Not to be replaced by S: Approved. Changes: C# Changes: Prototypes and removed S: Untriaged Status: Indicates an item has not been triaged and doesn't have appropriate labels. size/S labels Sep 3, 2026
@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Team

Run ID: bb7ffeb5-7a41-4477-b0f7-9e86f944db4d

📥 Commits

Reviewing files that changed from the base of the PR and between 3637d90 and 3026797.

📒 Files selected for processing (4)
  • Content.Shared/IdentityManagement/IdentitySystem.cs
  • Content.Shared/_Starlight/IdentityManagement/Components/AlwaysIdentifiableComponent.cs
  • Content.Shared/_Starlight/IdentityManagement/IdentitySystem.Starlight.cs
  • Resources/Prototypes/_Starlight/Entities/Mobs/NPCs/k9.yml

Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review.


📝 Summary

Summary

Adds AlwaysIdentifiableComponent to support entities that must always show their real identity.

IdentitySystem now uses IsAlwaysIdentifiable(target) for both borg chassis and entities with the new component. K9s use this component, so they remain identifiable when they lack an ID slot or wear identity-concealing equipment.

This is an interim solution until collar-based identification is implemented.

Gameplay and user impact

  • K9s display their real names during profile and identity checks.
  • Masks and helmets no longer conceal K9 identities.
  • Existing borg identification behavior remains supported.

Notable changes

  • Adds the networked, registered AlwaysIdentifiableComponent.
  • Adds IsAlwaysIdentifiable to the Starlight identity system.
  • Updates the shared IdentitySystem to use the generalized check.
  • Adds the component to the MobK9 prototype.

Risk areas

  • Incorrect component assignment could reveal the identities of entities that should remain concealed.
  • The generalized identity check could affect future entities that use AlwaysIdentifiableComponent.
  • Collar-based identification may require removing or changing this interim behavior.

Guideline gaps

Guideline gaps: None identified from the available PR context.

Walkthrough

The identity system now supports a reusable AlwaysIdentifiableComponent. Borg chassis and entities with this component display their known identity despite identity-concealing items. The K9 prototype now uses the component.

Changes

Identity visibility

Layer / File(s) Summary
Always-identifiable identity handling
Content.Shared/IdentityManagement/IdentitySystem.cs, Content.Shared/_Starlight/IdentityManagement/IdentitySystem.Starlight.cs, Content.Shared/_Starlight/IdentityManagement/Components/AlwaysIdentifiableComponent.cs
Adds the registered component and checks it with existing Borg handling. GetIdentityName uses IsAlwaysIdentifiable.
K9 component wiring
Resources/Prototypes/_Starlight/Entities/Mobs/NPCs/k9.yml
Adds AlwaysIdentifiable to the MobK9 prototype.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: 🔵 Low · up to 30267

K9s will remain identifiable even when concealment equipment would otherwise hide their identity, while existing Borg behavior is preserved. The change is mergeable with explicit owner awareness that future uses of the reusable marker must be restricted to trusted entity-assignment paths to avoid unintended identity disclosure.

Suggested reviewers: redmushie

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains the AlwaysIdentifiableComponent change, the K9 identity issue, and the interim purpose of the fix.
Title check ✅ Passed The title concisely and accurately identifies the main change: fixing identity concealment for K9s.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 3 files. (1 skipped: 1 …
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 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 3 files. (1 skipped: 1 unsupported.)


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.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Content + Integration Test Results

Failed Tests

Failed Tests
❌ JobWeightTest
Multiple failures or warnings in test:
  1) Test was dirty-disposed.
     at Robust.UnitTesting.Pool.TestPair`2.OnDirtyDispose() in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/Pool/TestPair.Recycle.cs:line 44
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Robust.UnitTesting.Pool.TestPair`2.OnDirtyDispose()
   at Robust.UnitTesting.Pool.TestPair`2.DisposeAsync() in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/Pool/TestPair.Recycle.cs:line 146
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Robust.UnitTesting.Pool.TestPair`2.DisposeAsync()
   at Content.IntegrationTests.Fixtures.GameTest.DoTeardown() in /home/runner/work/space-station-14/space-station-14/Content.IntegrationTests/Fixtures/GameTest.cs:line 262
  2) TearDown : System.InvalidOperationException : Collection was modified; enumeration operation may not execute.
  --TearDown
   at Robust.Client.GameStates.ClientGameStateManager.PartialStateReset(GameState state, Boolean resetAllEntities, Boolean deleteClientEntities, Boolean deleteClientChildren) in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Client/GameStates/ClientGameStateManager.cs:line 1294
   at Robust.Client.GameStates.ClientGameStateManager.ApplyGameState() in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Client/GameStates/ClientGameStateManager.cs:line 426
   at Robust.Client.GameController.Tick(FrameEventArgs frameEventArgs) in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Client/GameController/GameController.cs:line 617
   at Robust.UnitTesting.RobustIntegrationTest.IntegrationGameLoop.SingleThreadRunUntilEmpty() in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/RobustIntegrationTest.cs:line 1250
   at Robust.UnitTesting.RobustIntegrationTest.IntegrationGameLoop.Run() in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/RobustIntegrationTest.cs:line 1237
   at Robust.UnitTesting.RobustIntegrationTest.ClientIntegrationInstance.ThreadMain() in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/RobustIntegrationTest.cs:line 1047
--- End of stack trace from previous location ---
   at Robust.UnitTesting.RobustIntegrationTest.IntegrationInstance.WaitIdleImplAsync(Boolean throwOnUnhandled, CancellationToken cancellationToken) in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/RobustIntegrationTest.cs:line 566
   at Robust.UnitTesting.RobustIntegrationTest.IntegrationInstance.WaitRunTicks(Int32 ticks) in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/RobustIntegrationTest.cs:line 653
   at Robust.UnitTesting.Pool.TestPair`2.RunTicksSync(Int32 ticks) in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/Pool/TestPair.Helpers.cs:line 185
   at Robust.UnitTesting.Pool.TestPair`2.RunUntilSynced() in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/Pool/TestPair.Helpers.cs:line 226
   at Content.IntegrationTests.Fixtures.GameTest.DoTeardown() in /home/runner/work/space-station-14/space-station-14/Content.IntegrationTests/Fixtures/GameTest.cs:line 243
   at Content.IntegrationTests.Fixtures.GameTest.DoTeardown() in /home/runner/work/space-station-14/space-station-14/Content.IntegrationTests/Fixtures/GameTest.cs:line 262
   at NUnit.Framework.Internal.Commands.SetUpTearDownItem.RunTearDown(TestExecutionContext context)

Trace:


1)    at Robust.UnitTesting.Pool.TestPair`2.OnDirtyDispose() in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/Pool/TestPair.Recycle.cs:line 44
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Robust.UnitTesting.Pool.TestPair`2.OnDirtyDispose()
   at Robust.UnitTesting.Pool.TestPair`2.DisposeAsync() in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/Pool/TestPair.Recycle.cs:line 146
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Robust.UnitTesting.Pool.TestPair`2.DisposeAsync()
   at Content.IntegrationTests.Fixtures.GameTest.DoTeardown() in /home/runner/work/space-station-14/space-station-14/Content.IntegrationTests/Fixtures/GameTest.cs:line 262
2) --TearDown
   at Robust.Client.GameStates.ClientGameStateManager.PartialStateReset(GameState state, Boolean resetAllEntities, Boolean deleteClientEntities, Boolean deleteClientChildren) in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Client/GameStates/ClientGameStateManager.cs:line 1294
   at Robust.Client.GameStates.ClientGameStateManager.ApplyGameState() in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Client/GameStates/ClientGameStateManager.cs:line 426
   at Robust.Client.GameController.Tick(FrameEventArgs frameEventArgs) in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Client/GameController/GameController.cs:line 617
   at Robust.UnitTesting.RobustIntegrationTest.IntegrationGameLoop.SingleThreadRunUntilEmpty() in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/RobustIntegrationTest.cs:line 1250
   at Robust.UnitTesting.RobustIntegrationTest.IntegrationGameLoop.Run() in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/RobustIntegrationTest.cs:line 1237
   at Robust.UnitTesting.RobustIntegrationTest.ClientIntegrationInstance.ThreadMain() in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/RobustIntegrationTest.cs:line 1047
--- End of stack trace from previous location ---
   at Robust.UnitTesting.RobustIntegrationTest.IntegrationInstance.WaitIdleImplAsync(Boolean throwOnUnhandled, CancellationToken cancellationToken) in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/RobustIntegrationTest.cs:line 566
   at Robust.UnitTesting.RobustIntegrationTest.IntegrationInstance.WaitRunTicks(Int32 ticks) in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/RobustIntegrationTest.cs:line 653
   at Robust.UnitTesting.Pool.TestPair`2.RunTicksSync(Int32 ticks) in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/Pool/TestPair.Helpers.cs:line 185
   at Robust.UnitTesting.Pool.TestPair`2.RunUntilSynced() in /home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.UnitTesting/Pool/TestPair.Helpers.cs:line 226
   at Content.IntegrationTests.Fixtures.GameTest.DoTeardown() in /home/runner/work/space-station-14/space-station-14/Content.IntegrationTests/Fixtures/GameTest.cs:line 243
   at Content.IntegrationTests.Fixtures.GameTest.DoTeardown() in /home/runner/work/space-station-14/space-station-14/Content.IntegrationTests/Fixtures/GameTest.cs:line 262
   at NUnit.Framework.Internal.Commands.SetUpTearDownItem.RunTearDown(TestExecutionContext context)
Tests 📝 Passed ✅ Failed ❌ Duration ⏱️
1698 1677 1 11m 43s

Github Test Reporter by CTRF 💚

@starlightgithub starlightgithub Bot added S: Approved Status: Reviewed and approved by at least one maintainer or dev; a PR may require another approval. and removed S: Needs Review Status: Requires additional reviews before being fully accepted. Not to be replaced by S: Approved. labels Sep 3, 2026
@walksanatora
walksanatora added this pull request to the merge queue Sep 3, 2026
Merged via the queue into ss14Starlight:starlight-dev with commit a05b0b5 Sep 3, 2026
22 of 23 checks passed
starlightgithub Bot added a commit that referenced this pull request Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Changes: C# Changes: Prototypes S: Approved Status: Reviewed and approved by at least one maintainer or dev; a PR may require another approval.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants