[Fix] Upstream fix Part 1 - #161
Conversation
|
Это то что я нашёл от Шимори в ПРах. Мб ещё найду какие-то фиксы от Диммона но уже в коммитах. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📜 Recent review details⏰ Context from checks skipped due to timeout. (5)
🧰 Additional context used📓 Path-based instructions (4)Resources/**/*.{yml,ftl,json}📄 CodeRabbit inference engine (.cursor/rules/ss14-resources.mdc)
Files:
Resources/**/*.yml📄 CodeRabbit inference engine (.cursor/rules/ss14-resources.mdc)
Files:
Resources/**/*.{yml,ftl}📄 CodeRabbit inference engine (.cursor/rules/ss14-resources.mdc)
Files:
**/*.{cs,xaml,yml,yaml}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (2)📚 Learning: 2026-07-07T17:55:50.395ZApplied to files:
📚 Learning: 2026-07-28T15:44:38.498ZApplied to files:
🔇 Additional comments (1)
Главное изменение
Prediction / networking
Resources / localization
Validation / risk
WalkthroughPR изменяет игровые системы, прототипы сущностей, правила, локализацию, машинные конфигурации и карты. Добавлены проверки состояний, точки появления и безопасная обработка отсутствующих прототипов. ChangesИгровые системы и контент
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
Короче че ещё найду то и сюда закину |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Content.Server/Dragon/DragonSystem.cs`:
- Line 290: Update the Dragon shutdown cleanup flow around DeleteRifts so
cleanup or round-end does not reset CarpRiftsConditionComponent.RiftsCharged.
Preserve progress when RiftDestroyed is triggered by ComponentShutdown, and use
an explicit cause distinguishing crew destruction from cleanup/round-end instead
of relying on the already-cleared comp.Rifts or TryComp lookup.
In `@Content.Server/Electrocution/ElectrocutionSystem.cs`:
- Line 92: Переименуйте ElectrifiedComponent.OnHandInteract в общее имя,
отражающее активацию как через InteractHandEvent, так и через
ActivateInWorldEvent, и обновите проверки в OnElectrifiedActivate и связанных
обработчиках. Проверьте взаимодействие подписок ActivateInWorldEvent и
InteractHandEvent, чтобы одна активация предмета не вызывала повторный удар.
In `@Content.Shared/_DV/Construction/UpgradeKitSystem.cs`:
- Line 83: Replace the trailing comment on the IsWhitelistPass condition in
UpgradeKitSystem with the standard // Arcane-Edit fork marker; leave the
condition and its blacklist behavior unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 5291193a-f5c5-43d5-975d-b3433e5cd975
📒 Files selected for processing (23)
Content.Client/RoundEnd/RoundEndSummaryWindow.csContent.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.csContent.Goobstation.Shared/Vehicles/SharedVehicleSystem.csContent.Server/Dragon/DragonSystem.csContent.Server/Electrocution/ElectrocutionSystem.csContent.Server/Holosign/HolosignSystem.csContent.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.csContent.Shared/Blocking/BlockingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Shared/Throwing/ThrowingSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csResources/Locale/ru-RU/_Shitmed/surgery/status.ftlResources/Prototypes/Body/Prototypes/Specific/smartcorgi.ymlResources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.ymlResources/Prototypes/Entities/Objects/Materials/Sheets/metal.ymlResources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.ymlResources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.ymlResources/Prototypes/GameRules/subgamemodes.ymlResources/Prototypes/Stacks/Specific/medical.ymlResources/Prototypes/_Goobstation/Entities/Objects/Specific/Robotics/borg_modules.ymlResources/Prototypes/_Goobstation/Entities/Objects/Vehicles/clowncar.ymlResources/Prototypes/_Goobstation/GameRules/roundstart.yml
📜 Review details
⏰ Context from checks skipped due to timeout. (5)
- GitHub Check: build (ubuntu-latest)
- GitHub Check: build (ubuntu-latest)
- GitHub Check: YAML map schema validator
- GitHub Check: YAML Linter
- GitHub Check: Test Packaging
🧰 Additional context used
📓 Path-based instructions (21)
Resources/**/*.{yml,ftl,json}
📄 CodeRabbit inference engine (.cursor/rules/ss14-resources.mdc)
Resources/**/*.{yml,ftl,json}: Follow SS14 naming conventions when editing prototype, localization, and resource files
Follow SS14 upstream maintenance practices when editing resource files
Files:
Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.ymlResources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.ymlResources/Prototypes/GameRules/subgamemodes.ymlResources/Prototypes/_Goobstation/GameRules/roundstart.ymlResources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.ymlResources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.ymlResources/Prototypes/_Goobstation/Entities/Objects/Vehicles/clowncar.ymlResources/Prototypes/Stacks/Specific/medical.ymlResources/Prototypes/_Goobstation/Entities/Objects/Specific/Robotics/borg_modules.ymlResources/Prototypes/Body/Prototypes/Specific/smartcorgi.ymlResources/Locale/ru-RU/_Shitmed/surgery/status.ftl
Resources/**/*.yml
📄 CodeRabbit inference engine (.cursor/rules/ss14-resources.mdc)
Resources/**/*.yml: Follow SS14 ECS prototype patterns and conventions
Follow SS14 graphics generic visualizer appearance conventions and patterns
Resources/**/*.yml: Loadss14-naming-conventionsdocumentation for Resources work
Loadss14-ecs-prototypesdocumentation for Resources work
Loadss14-upstream-maintenancedocumentation for Resources work
Loadss14-prototypes-localedocumentation for Resources work
Loadss14-localization-stringsdocumentation for Resources work
Loadss14-sprite-overlays-shadersdocumentation when working with RSI metadata, textures, sprite layers, overlays, or shader resources
Validate YAML after editsRun
dotnet run --project Content.YAMLLinter/Content.YAMLLinter.csproj -c DebugOptto validate YAML and resource edits.
Files:
Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.ymlResources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.ymlResources/Prototypes/GameRules/subgamemodes.ymlResources/Prototypes/_Goobstation/GameRules/roundstart.ymlResources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.ymlResources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.ymlResources/Prototypes/_Goobstation/Entities/Objects/Vehicles/clowncar.ymlResources/Prototypes/Stacks/Specific/medical.ymlResources/Prototypes/_Goobstation/Entities/Objects/Specific/Robotics/borg_modules.ymlResources/Prototypes/Body/Prototypes/Specific/smartcorgi.yml
Resources/**/*.{yml,ftl}
📄 CodeRabbit inference engine (.cursor/rules/ss14-resources.mdc)
Follow SS14 prototype locale integration rules and practices
Files:
Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.ymlResources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.ymlResources/Prototypes/GameRules/subgamemodes.ymlResources/Prototypes/_Goobstation/GameRules/roundstart.ymlResources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.ymlResources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.ymlResources/Prototypes/_Goobstation/Entities/Objects/Vehicles/clowncar.ymlResources/Prototypes/Stacks/Specific/medical.ymlResources/Prototypes/_Goobstation/Entities/Objects/Specific/Robotics/borg_modules.ymlResources/Prototypes/Body/Prototypes/Specific/smartcorgi.ymlResources/Locale/ru-RU/_Shitmed/surgery/status.ftl
**/*.{cs,xaml,yml,yaml}
📄 CodeRabbit inference engine (AGENTS.md)
If the task adds tests or you need to choose the right test layer, load skill
ss14-tests-authoring.
Files:
Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.ymlResources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.ymlResources/Prototypes/GameRules/subgamemodes.ymlResources/Prototypes/_Goobstation/GameRules/roundstart.ymlContent.Server/Holosign/HolosignSystem.csContent.Shared/Throwing/ThrowingSystem.csResources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.ymlResources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.ymlContent.Shared/Movement/Systems/MovementModStatusSystem.csResources/Prototypes/_Goobstation/Entities/Objects/Vehicles/clowncar.ymlResources/Prototypes/Stacks/Specific/medical.ymlResources/Prototypes/_Goobstation/Entities/Objects/Specific/Robotics/borg_modules.ymlContent.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csResources/Prototypes/Body/Prototypes/Specific/smartcorgi.ymlContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Server/Electrocution/ElectrocutionSystem.csContent.Client/RoundEnd/RoundEndSummaryWindow.csContent.Shared/Blocking/BlockingSystem.csContent.Goobstation.Shared/Vehicles/SharedVehicleSystem.csContent.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.csContent.Server/Dragon/DragonSystem.cs
Resources/Prototypes/**/*.yml
📄 CodeRabbit inference engine (AGENTS.md)
Resources/Prototypes/**/*.yml: Put prototypes under the most specific existing subtree inResources/Prototypes/. If you introduce a new prototype parent tree, put parent prototypes inbase.ymland variants in sibling files.
Keep entity prototype field order astype,abstract,parent,id,categories,name,suffix,description,components. Do not insert blank lines between- type:entries inside acomponents:list. Separate prototype blocks with one blank line.
Prefersuffixfor spawn-menu distinctions instead of changing prototypename.
Files:
Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.ymlResources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.ymlResources/Prototypes/GameRules/subgamemodes.ymlResources/Prototypes/_Goobstation/GameRules/roundstart.ymlResources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.ymlResources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.ymlResources/Prototypes/_Goobstation/Entities/Objects/Vehicles/clowncar.ymlResources/Prototypes/Stacks/Specific/medical.ymlResources/Prototypes/_Goobstation/Entities/Objects/Specific/Robotics/borg_modules.ymlResources/Prototypes/Body/Prototypes/Specific/smartcorgi.yml
⚙️ CodeRabbit configuration file
Resources/Prototypes/**/*.yml: Review SS14 prototypes carefully:
- Use the narrowest existing subtree and avoid duplicating nearby prototype files or parent trees.
- Keep entity field order as: type, abstract, parent, id, categories, name, suffix, description, components.
- Prefer base.yml for parent trees and sibling files for variants.
- Do not add blank lines inside components lists.
- Call out broken inheritance, risky prototype ID changes, missing paired locale updates, and Appearance / GenericVisualizer mismatches.
Files:
Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.ymlResources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.ymlResources/Prototypes/GameRules/subgamemodes.ymlResources/Prototypes/_Goobstation/GameRules/roundstart.ymlResources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.ymlResources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.ymlResources/Prototypes/_Goobstation/Entities/Objects/Vehicles/clowncar.ymlResources/Prototypes/Stacks/Specific/medical.ymlResources/Prototypes/_Goobstation/Entities/Objects/Specific/Robotics/borg_modules.ymlResources/Prototypes/Body/Prototypes/Specific/smartcorgi.yml
**/*.cs
📄 CodeRabbit inference engine (GEMINI.md)
**/*.cs: Keep components data-only and behavior in systems
UseOn... -> Try... -> Can... -> Do...pattern for gameplay actions
PreferEntity<T?>,ProtoId<T>,EntProtoId, and localized strings for type usage
**/*.cs: When writing or editing C# gameplay code, load skills:ss14-ecs-components,ss14-ecs-entities,ss14-ecs-prototypes,ss14-ecs-systems,ss14-events, andss14-prediction.
If the C# change is large or the task needs reviewable notes, load skillss14-documentation-writing.
If the code touches hot paths,Update(), or frequently raised events, load skillss14-standard-optimizations.
If the task adds or changes player-facing text, load skillsss14-localization-stringsandss14-localization-codewhen the change also touchesLoc.GetString(...),LocId, popup text, or localized component fields.
If the task touches network events,NetEntity, replicated state routing, or shared/server/client message flow, load skillss14-netcode.
If the task touchesAppearance,GenericVisualizer, visual state enums, or sprite-layer toggles, load skillss14-graphics-generic-visualizer-appearance.
If the task touches sprites, RSI metadata, overlays, shaders, or custom client visual effects, load skillss14-sprite-overlays-shaders.
If the task is about learning or explaining SS14 architecture, first features, or where code belongs, load skillsss14-prototype-basics,ss14-ecs-basics, andss14-client-server-shared.
If the task is about bug hunting, VV, logs, breakpoints, or runtime inspection, load skillsss14-debugging-workflowandss14-common-api-patterns.
If the task touches common gameplay helpers such as entity-system methods, spawning, prototypes, audio, popups, or random, load skillsss14-common-api-patternsandss14-audiowhen the work changes audio routing, sound assets, sound collections, or predicted sound feedback.
If the task ports code or assets from another repository, or needs license or attribution guidance,...
Files:
Content.Server/Holosign/HolosignSystem.csContent.Shared/Throwing/ThrowingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Server/Electrocution/ElectrocutionSystem.csContent.Client/RoundEnd/RoundEndSummaryWindow.csContent.Shared/Blocking/BlockingSystem.csContent.Goobstation.Shared/Vehicles/SharedVehicleSystem.csContent.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.csContent.Server/Dragon/DragonSystem.cs
+(Content.Shared|Content.Server|Content.Client|Content.Goobstation.Shared|Content.Goobstation.Server|Content.Goobstation.Client|Content.Goobstation.Common|Content.Goobstation.Maths|Content.Goobstation.UIKit|Content.Server.Database|Content.Shared.Database|Content.Tests|Content.IntegrationTests)/**/*.cs
📄 CodeRabbit inference engine (.cursor/rules/ss14-csharp.mdc)
+(Content.Shared|Content.Server|Content.Client|Content.Goobstation.Shared|Content.Goobstation.Server|Content.Goobstation.Client|Content.Goobstation.Common|Content.Goobstation.Maths|Content.Goobstation.UIKit|Content.Server.Database|Content.Shared.Database|Content.Tests|Content.IntegrationTests)/**/*.cs: Apply C# ECS style rules from ss14-interaction-flow.md
Apply ss14-csharp-style.md rules for C# code formatting and conventions
Follow ss14-naming-conventions for variable, method, and type naming in C# gameplay code
Files:
Content.Server/Holosign/HolosignSystem.csContent.Shared/Throwing/ThrowingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Server/Electrocution/ElectrocutionSystem.csContent.Client/RoundEnd/RoundEndSummaryWindow.csContent.Shared/Blocking/BlockingSystem.csContent.Goobstation.Shared/Vehicles/SharedVehicleSystem.csContent.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.csContent.Server/Dragon/DragonSystem.cs
{Content.Server,Content.Goobstation.Server}/**/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
Put main server-only authority and non-predicted server simulation in
Content.Server/; useContent.Goobstation.Server/for features already rooted in that module.
Files:
Content.Server/Holosign/HolosignSystem.csContent.Server/Electrocution/ElectrocutionSystem.csContent.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.csContent.Server/Dragon/DragonSystem.cs
**/*System.cs
📄 CodeRabbit inference engine (AGENTS.md)
Public entity-system APIs that operate on entities should usually take
Entity<T?>orEntityUidfirst and callResolve(...)early.
Files:
Content.Server/Holosign/HolosignSystem.csContent.Shared/Throwing/ThrowingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Server/Electrocution/ElectrocutionSystem.csContent.Shared/Blocking/BlockingSystem.csContent.Goobstation.Shared/Vehicles/SharedVehicleSystem.csContent.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.csContent.Server/Dragon/DragonSystem.cs
Content.Server/**/*.cs
⚙️ CodeRabbit configuration file
Content.Server/**/*.cs: Review Content.Server for authority and fork-maintenance discipline:
- Server owns authority, persistence, round logic, and non-predicted side effects.
- If a player action should feel immediate, call out missing shared prediction rather than accepting a server-only path.
- Keep upstream diffs narrow and prefer fork-scoped extensions over broad edits to upstream behavior.
- When player-visible behavior changes, check whether matching prototype and locale updates are missing.
Files:
Content.Server/Holosign/HolosignSystem.csContent.Server/Electrocution/ElectrocutionSystem.csContent.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.csContent.Server/Dragon/DragonSystem.cs
Content.Shared/**
📄 CodeRabbit inference engine (Content.Shared/AGENTS.md)
Content.Shared/**: Load ss14-naming-conventions agent notes for Content.Shared work
Load ss14-ecs-prototypes, ss14-ecs-components, ss14-ecs-entities, and ss14-ecs-systems agent notes for Content.Shared work
Load ss14-upstream-maintenance agent notes for Content.Shared work
Load ss14-events agent notes for Content.Shared work
Load ss14-prediction and ss14-netcode agent notes for Content.Shared work
Load ss14-localization-code agent notes when shared code emits player text or stores LocId
Load ss14-graphics-generic-visualizer-appearance agent notes when shared gameplay state drives Appearance or GenericVisualizer
Load ss14-audio agent notes when shared components or events carry sound specifiers or predicted audio intent
Load ss14-atmos agent notes when shared components, UI messages, or enums belong to atmos features
Load ss14-transform-physics agent notes for shared coordinates, movement, collision, anchoring, or physics contracts
Load ss14-pvs agent notes for PVS-sensitive shared/network contracts
Load ss14-npc-ai agent notes for shared NPC, HTN, steering, pathfinding, or debug contracts
Shared code must own replicated state, shared events, and prediction-aware logic without adding direct client-only or server-only dependencies
Files:
Content.Shared/Throwing/ThrowingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Shared/Blocking/BlockingSystem.cs
{Content.Shared,Content.Goobstation.Shared,Content.Goobstation.Common,Content.Goobstation.Maths,Content.Shared.Database}/**/*.cs
📄 CodeRabbit inference engine (.cursor/rules/ss14-shared.mdc)
{Content.Shared,Content.Goobstation.Shared,Content.Goobstation.Common,Content.Goobstation.Maths,Content.Shared.Database}/**/*.cs: Apply SS14 C# style guidelines from @.agents/rules/ss14-csharp-style.md
Follow SS14 ECS component patterns as defined in @.agents/skills/ss14-ecs-components/SKILL.md
Follow SS14 ECS entity patterns as defined in @.agents/skills/ss14-ecs-entities/SKILL.md
Follow SS14 ECS system patterns as defined in @.agents/skills/ss14-ecs-systems/SKILL.md
Follow SS14 event patterns as defined in @.agents/skills/ss14-events/SKILL.md
Follow SS14 prediction-aware gameplay code patterns as defined in @.agents/skills/ss14-prediction/SKILL.md
Follow SS14 netcode patterns as defined in @.agents/skills/ss14-netcode/SKILL.md
Follow SS14 localization identifier patterns as defined in @.agents/skills/ss14-localization-code/SKILL.md
Files:
Content.Shared/Throwing/ThrowingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Shared/Blocking/BlockingSystem.csContent.Goobstation.Shared/Vehicles/SharedVehicleSystem.cs
{Content.Shared,Content.Goobstation.Shared}/**/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
{Content.Shared,Content.Goobstation.Shared}/**/*.cs: Put main shared data, shared events, networked state, and predicted logic inContent.Shared/; useContent.Goobstation.Shared/only for code that belongs to that existing module path.
Do not make shared projects depend on client-only or server-only projects.
Predicted systems and their relevant components belong inContent.Shared/. Shared predicted components should useNetworkedComponent,AutoGenerateComponentState, andAutoNetworkedFieldwhere appropriate.
Files:
Content.Shared/Throwing/ThrowingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Shared/Blocking/BlockingSystem.csContent.Goobstation.Shared/Vehicles/SharedVehicleSystem.cs
Content.Shared/**/*.cs
⚙️ CodeRabbit configuration file
Content.Shared/**/*.cs: Review Content.Shared as shared gameplay and prediction code:
- Shared owns replicated state, shared events, prediction, and data both client and server must understand.
- Flag client-only or server-only dependencies in Shared.
- For local-player actions, verify prediction support instead of accepting delayed server-only UX.
- When state is networked, check NetworkedComponent, AutoGenerateComponentState, AutoNetworkedField, and Dirty/DirtyField usage.
- Prefer entity-system APIs and Entity<T?> / Resolve patterns over ad-hoc tuples or old-style access.
- Flag EntityUid.Invalid used as a "missing" sentinel.
Files:
Content.Shared/Throwing/ThrowingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Shared/Blocking/BlockingSystem.cs
{Content.Client,Content.Goobstation.Client,Content.Goobstation.UIKit}/**/*.{cs,xaml}
📄 CodeRabbit inference engine (.cursor/rules/ss14-ui.mdc)
{Content.Client,Content.Goobstation.Client,Content.Goobstation.UIKit}/**/*.{cs,xaml}: Follow SS14 naming conventions when editing UI, XAML, and client-state files
Maintain upstream compatibility when editing SS14 client code
Follow SS14 UI and BUI conventions when implementing UI components and behavior-driven user interfaces
Files:
Content.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.csContent.Client/RoundEnd/RoundEndSummaryWindow.cs
{Content.Client,Content.Goobstation.Client,Content.Goobstation.UIKit}/**/*.cs
📄 CodeRabbit inference engine (.cursor/rules/ss14-ui.mdc)
{Content.Client,Content.Goobstation.Client,Content.Goobstation.UIKit}/**/*.cs: Apply SS14 prediction patterns when working with predicted client-state in SS14 client code
Follow SS14 localization code practices in UI and client-state implementationsPut main client-only visuals, overlays, XAML, and BUI front-ends in
Content.Client/; useContent.Goobstation.Client/orContent.Goobstation.UIKit/only when matching existing references and ownership.
Files:
Content.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.csContent.Client/RoundEnd/RoundEndSummaryWindow.cs
{**/_Orion,**/_Goobstation,**/_EinsteinEngines,**/_Shitmed,**/_DV,**/_NF,**/_Mono,**/_RMC14,**/_White}/**/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
For Orion-only behavior, prefer existing
_Orionfolders when they exist. This repository also contains inherited/vendor-specific trees such as_Goobstation,_EinsteinEngines,_Shitmed,_DV,_NF,_Mono,_RMC14,_White, and others; extend the tree that already owns the feature instead of assuming all fork code belongs under_Orion.
Files:
Content.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.cs
Content.Client/**/*.cs
⚙️ CodeRabbit configuration file
Content.Client/**/*.cs: Review Content.Client for presentation-only behavior:
- Keep authority out of the client.
- Prefer reading already-networked component state instead of duplicating BUI state unless the pattern requires it.
- Flag missing localization for player-visible text.
- Prefer nearby established UI and visual patterns over custom one-off structures.
Files:
Content.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.csContent.Client/RoundEnd/RoundEndSummaryWindow.cs
Resources/**/*.ftl
📄 CodeRabbit inference engine (.cursor/rules/ss14-resources.mdc)
Follow SS14 localization string standards and formatting rules
Files:
Resources/Locale/ru-RU/_Shitmed/surgery/status.ftl
**/*.ftl
📄 CodeRabbit inference engine (AGENTS.md)
Use specific
kebab-caselocalization IDs.
Files:
Resources/Locale/ru-RU/_Shitmed/surgery/status.ftl
Resources/Locale/**/*.ftl
📄 CodeRabbit inference engine (AGENTS.md)
Resources/Locale/**/*.ftl: Add or update FTL entries underResources/Locale/, starting withen-US; add/update matchingru-RUentries when the same feature already maintains Russian locale or the change is Orion-facing and you can do so without guessing translations.
Use specifickebab-caselocalization IDs.
Files:
Resources/Locale/ru-RU/_Shitmed/surgery/status.ftl
⚙️ CodeRabbit configuration file
Resources/Locale/**/*.ftl: Treat localization as mandatory:
- Every player-facing string should be localized.
- Prefer specific kebab-case keys.
- Flag raw strings in code or gameplay/resource changes that are missing locale updates.
- Check consistency when prototype names, descriptions, markings, or UI text changed.
Files:
Resources/Locale/ru-RU/_Shitmed/surgery/status.ftl
🧠 Learnings (11)
📚 Learning: 2026-06-29T05:34:31.137Z
Learnt from: Alazell
Repo: ArcaneSS14/arcane-station PR: 99
File: Resources/Prototypes/Entities/Clothing/Belt/belts.yml:973-974
Timestamp: 2026-06-29T05:34:31.137Z
Learning: В SS14 YAML-прототипах для компонента `Storage` поле `grid` задаёт **включительные** координаты прямоугольника. При подсчёте вместимости учитывайте оффсет-инклюзивность: прямоугольник `x1,y1,x2,y2` означает размеры `width = (x2 - x1 + 1)` и `height = (y2 - y1 + 1)`, а число ячеек `width * height`. Например, `0,0,0,0` = 1 ячейка, а `0,0,6,2` = (6-0+1)*(2-0+1)=7*3=21. При ревью файлов наподобие `Resources/Prototypes/Entities/Clothing/Belt/belts.yml` не интерпретируйте `x2/y2` как эксклюзивные (чтобы не ошибиться на 1 в ширине/высоте).
Applied to files:
Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.ymlResources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.ymlResources/Prototypes/GameRules/subgamemodes.ymlResources/Prototypes/_Goobstation/GameRules/roundstart.ymlResources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.ymlResources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.ymlResources/Prototypes/_Goobstation/Entities/Objects/Vehicles/clowncar.ymlResources/Prototypes/Stacks/Specific/medical.ymlResources/Prototypes/_Goobstation/Entities/Objects/Specific/Robotics/borg_modules.ymlResources/Prototypes/Body/Prototypes/Specific/smartcorgi.yml
📚 Learning: 2026-07-29T08:12:37.068Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane PR: 153
File: Resources/Prototypes/_Orion/Entities/Objects/Tools/energy_dome.yml:137-137
Timestamp: 2026-07-29T08:12:37.068Z
Learning: In ArcaneSS14 prototype YAMLs, the YAML field that disables synchronization for `Content.Shared.Power.Components.BatteryComponent` is spelled exactly `netsync` (all lowercase), not `netSync`. For prototypes derived from `PowerNetworkBattery` (including `BaseAPC`, `CoreSubstation`, `BaseSMES`, `TeslaCoil`), set `netsync: false`; otherwise `Content.Server.Power.EntitySystems.BatterySystem.OnStartup` can throw `DebugAssertException` for a predicted battery connected to a power net. For `Resources/Prototypes/_Orion/Entities/Objects/Tools/energy_dome.yml`, ensure `EnergyDomeWiredTest` uses `netsync: false`.
Applied to files:
Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.ymlResources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.ymlResources/Prototypes/GameRules/subgamemodes.ymlResources/Prototypes/_Goobstation/GameRules/roundstart.ymlResources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.ymlResources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.ymlResources/Prototypes/_Goobstation/Entities/Objects/Vehicles/clowncar.ymlResources/Prototypes/Stacks/Specific/medical.ymlResources/Prototypes/_Goobstation/Entities/Objects/Specific/Robotics/borg_modules.ymlResources/Prototypes/Body/Prototypes/Specific/smartcorgi.yml
📚 Learning: 2026-07-07T17:55:50.395Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane-old PR: 101
File: Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs:192-194
Timestamp: 2026-07-07T17:55:50.395Z
Learning: When reviewing ArcaneSS14/arcane-old changes related to `MobState` thresholds/visuals/actions, treat the `Critical` enum value as requiring explicit mappings (it no longer implicitly behaves as an alias of `SoftCritical`). If any YAML prototype `thresholds:` (for `MobThresholdsComponent.Thresholds`) uses the bare `Critical` key (e.g., `MobThresholdsComponent.Thresholds: { Critical: ... }` for entities like `MobMouseCancer`), ensure the prototype (or referenced config) provides corresponding explicit `StateAlertDict` entries and any required `MobStateActions.actions` and `DamageStateVisuals.states` mappings for `Critical`. Otherwise, review should expect failures because the default `StateAlertDict` in `MobThresholdsComponent.cs` typically maps only `Alive`, `SoftCritical`, `HardCritical`, and `Dead`—not `Critical`.
Applied to files:
Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.ymlResources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.ymlResources/Prototypes/GameRules/subgamemodes.ymlResources/Prototypes/_Goobstation/GameRules/roundstart.ymlResources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.ymlResources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.ymlResources/Prototypes/_Goobstation/Entities/Objects/Vehicles/clowncar.ymlResources/Prototypes/Stacks/Specific/medical.ymlResources/Prototypes/_Goobstation/Entities/Objects/Specific/Robotics/borg_modules.ymlResources/Prototypes/Body/Prototypes/Specific/smartcorgi.yml
📚 Learning: 2026-07-28T15:44:38.498Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane PR: 152
File: Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/pistol.yml:69-72
Timestamp: 2026-07-28T15:44:38.498Z
Learning: В ArcaneSS14/arcane не выполняйте форматирующие перестановки полей (в т.ч. изменение порядка полей) в upstream-файлах: делайте это только если правка добавляет Arcane-специфичную сущность или напрямую требуется для функциональности. Иначе сохраняйте upstream-порядок полей, даже если он противоречит локальным рекомендациям, чтобы не создавать лишние diff и конфликты при upstream-синхронизации. Исключение: допустимо переупорядочивание/форматирование в `Resources/Prototypes/_Arcane` (и только там).
Applied to files:
Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.ymlResources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.ymlResources/Prototypes/GameRules/subgamemodes.ymlResources/Prototypes/_Goobstation/GameRules/roundstart.ymlResources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.ymlResources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.ymlResources/Prototypes/_Goobstation/Entities/Objects/Vehicles/clowncar.ymlResources/Prototypes/Stacks/Specific/medical.ymlResources/Prototypes/_Goobstation/Entities/Objects/Specific/Robotics/borg_modules.ymlResources/Prototypes/Body/Prototypes/Specific/smartcorgi.yml
📚 Learning: 2026-06-04T21:17:36.815Z
Learnt from: MataVsn
Repo: ArcaneSS14/arcane-station PR: 31
File: Content.Client/Fluids/PuddleSystem.cs:41-41
Timestamp: 2026-06-04T21:17:36.815Z
Learning: In this repo (ArcaneSS14/arcane-station), reviewers should use the Arcane inline fork-edit marker naming for single-line edits outside `_Arcane` paths: prefer `// Arcane` or `// Arcane-edit` and do not use `// Orion` for this purpose. Repo-specific AGENTS guidance that mentions `// Orion` does not apply to these single-line changes; only `_Arcane` paths follow the applicable different convention.
Applied to files:
Content.Server/Holosign/HolosignSystem.csContent.Shared/Throwing/ThrowingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Server/Electrocution/ElectrocutionSystem.csContent.Client/RoundEnd/RoundEndSummaryWindow.csContent.Shared/Blocking/BlockingSystem.csContent.Goobstation.Shared/Vehicles/SharedVehicleSystem.csContent.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.csContent.Server/Dragon/DragonSystem.cs
📚 Learning: 2026-06-28T19:37:26.732Z
Learnt from: MataVsn
Repo: ArcaneSS14/arcane-station PR: 96
File: Content.Client/IoC/ClientContentIoC.cs:151-151
Timestamp: 2026-06-28T19:37:26.732Z
Learning: For ArcaneSS14/arcane-station C# files whose path is outside any `_Arcane` directories, avoid adding an inline fork marker (e.g., `// Arcane` or `// Arcane-edit`) to `using` directives when the imported namespace already clearly indicates the `_Arcane` fork. For example, if the `using` namespace itself contains `_Arcane` (such as `using Content.Client._Arcane.ERP.Preferences;`), the `// Arcane`/`// Arcane-edit` marker is unnecessary.
Applied to files:
Content.Server/Holosign/HolosignSystem.csContent.Shared/Throwing/ThrowingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Server/Electrocution/ElectrocutionSystem.csContent.Client/RoundEnd/RoundEndSummaryWindow.csContent.Shared/Blocking/BlockingSystem.csContent.Goobstation.Shared/Vehicles/SharedVehicleSystem.csContent.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.csContent.Server/Dragon/DragonSystem.cs
📚 Learning: 2026-07-04T03:37:47.373Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane-station PR: 101
File: Content.Goobstation.Server/Chemistry/EntitySystems/EnergyReagentDispenserSystem.cs:59-59
Timestamp: 2026-07-04T03:37:47.373Z
Learning: In ArcaneSS14/arcane-station, C# source files must never have fork-edit markers (e.g., comments like `// Arcane`, `// Arcane-edit`, `// Orion`) on `using` directives. During code review, do not flag existing markers on any `using` line and do not suggest adding/removing them based on `_Arcane` folder placement or whether the imported namespace contains `_Arcane`—this rule applies universally to all `using` statements.
Applied to files:
Content.Server/Holosign/HolosignSystem.csContent.Shared/Throwing/ThrowingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Server/Electrocution/ElectrocutionSystem.csContent.Client/RoundEnd/RoundEndSummaryWindow.csContent.Shared/Blocking/BlockingSystem.csContent.Goobstation.Shared/Vehicles/SharedVehicleSystem.csContent.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.csContent.Server/Dragon/DragonSystem.cs
📚 Learning: 2026-07-28T16:30:37.419Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane PR: 133
File: Content.Server/Speech/EntitySystems/StutteringSystem.cs:28-29
Timestamp: 2026-07-28T16:30:37.419Z
Learning: При внесении одиночных fork-правок в репозитории ArcaneSS14/arcane вне путей `_Arcane` добавляйте в конец каждой изменённой строки комментарий-маркер `// Arcane-Edit`. Это нужно для упрощения последующего поиска/обновления подобных правок при код-ревью и синхронизациях.
Applied to files:
Content.Server/Holosign/HolosignSystem.csContent.Shared/Throwing/ThrowingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Server/Electrocution/ElectrocutionSystem.csContent.Client/RoundEnd/RoundEndSummaryWindow.csContent.Shared/Blocking/BlockingSystem.csContent.Goobstation.Shared/Vehicles/SharedVehicleSystem.csContent.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.csContent.Server/Dragon/DragonSystem.cs
📚 Learning: 2026-07-01T17:19:52.100Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane-station PR: 101
File: Content.Shared/Mobs/MobState.cs:0-0
Timestamp: 2026-07-01T17:19:52.100Z
Learning: When reviewing ArcaneSS14/arcane-station C# code, ensure all usages of the `MobState` enum (`MobState.Dead`, `MobState.SoftCritical`, `MobState.HardCritical`, `MobState.Critical`) reference the enum members symbolically rather than via hardcoded numeric literals or casts from numeric values (e.g., avoid patterns like `(MobState)4` or `MobState` comparisons to `byte`/`int` literals). Treat direct numeric usage as a code-level dependency that should be flagged. Also avoid persisting `MobState` numeric values in `Content.Server.Database` or `Content.Replay`; if persistence/replay of the raw byte value is introduced, renumbering the `[NetSerializable] MobState : byte` enum becomes a data-compatibility risk. Renumbering the enum is compile-safe as long as there are no numeric literal dependencies, but the remaining risk is network wire-protocol mismatch if mixed old/new client-server builds are running during a rolling update—coordinate deployment to maintain net compatibility.
Applied to files:
Content.Server/Holosign/HolosignSystem.csContent.Shared/Throwing/ThrowingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Server/Electrocution/ElectrocutionSystem.csContent.Client/RoundEnd/RoundEndSummaryWindow.csContent.Shared/Blocking/BlockingSystem.csContent.Goobstation.Shared/Vehicles/SharedVehicleSystem.csContent.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.csContent.Server/Dragon/DragonSystem.cs
📚 Learning: 2026-07-03T18:41:44.286Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane-station PR: 101
File: Content.Shared/_Orion/EntityEffects/Effects/Special/ChemConvermol.cs:0-0
Timestamp: 2026-07-03T18:41:44.286Z
Learning: In ArcaneSS14/arcane-station, the hardcoded 1.2f base used by RefreshPartsEvent.GetLinearMultiplier(tier, step, min, max) (Math.Clamp(1.2f - tier * step, min, max)) is an intentional repo-wide balance convention: callers typically pass max: 1.2f, so a tier-1 part yields a 10% penalty (e.g., GetLinearMultiplier(tier: 1, step: 0.1f, min: 0.5f, max: 1.2f) => 1.1), while tier-2 is the neutral baseline. Do not flag the hardcoded 1.2f as a bug when reviewing shared multiplier/linear scaling usage. If a specific system needs a tier-1 baseline that produces 0% penalty instead, implement a locally-scoped formula in that system (e.g., adjust the constant to match the desired neutral baseline) rather than changing the shared helper, since modifying it would affect all callers’ balance.
Applied to files:
Content.Server/Holosign/HolosignSystem.csContent.Shared/Throwing/ThrowingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Server/Electrocution/ElectrocutionSystem.csContent.Shared/Blocking/BlockingSystem.csContent.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.csContent.Server/Dragon/DragonSystem.cs
📚 Learning: 2026-06-28T12:09:12.409Z
Learnt from: MataVsn
Repo: ArcaneSS14/arcane-station PR: 96
File: Content.Shared/Humanoid/HumanoidVisualLayers.cs:65-67
Timestamp: 2026-06-28T12:09:12.409Z
Learning: In ArcaneSS14/arcane-station, for any C# enum annotated with `[NetSerializable]` in shared code, treat the enum member order/implicit underlying numeric values as part of the network wire-protocol. During code review, disallow inserting new enum members in the middle (or otherwise changing existing members’ numeric values), since it breaks network compatibility. Instead, add new members only at the end or explicitly pin stable values by assigning numeric literals to members.
Applied to files:
Content.Shared/Throwing/ThrowingSystem.csContent.Shared/Movement/Systems/MovementModStatusSystem.csContent.Shared/_DV/Construction/UpgradeKitSystem.csContent.Shared/SubFloor/SharedTrayScannerSystem.csContent.Shared/Blocking/BlockingSystem.cs
🔇 Additional comments (20)
Content.Shared/Movement/Systems/MovementModStatusSystem.cs (1)
182-182: LGTM!Resources/Prototypes/GameRules/subgamemodes.yml (1)
34-34: LGTM!Resources/Prototypes/_Goobstation/GameRules/roundstart.yml (1)
424-424: LGTM!Resources/Prototypes/_Goobstation/Entities/Objects/Vehicles/clowncar.yml (1)
36-36: LGTM!Content.Client/RoundEnd/RoundEndSummaryWindow.cs (1)
89-89: LGTM!Resources/Locale/ru-RU/_Shitmed/surgery/status.ftl (1)
1-3: LGTM!Resources/Prototypes/Stacks/Specific/medical.yml (2)
11-11: LGTM!Also applies to: 19-19, 27-27, 35-35, 43-43, 51-51, 59-59
11-59: 🎯 Functional CorrectnessПроверьте оба YAML-файла перед слиянием.
Resources/Prototypes/Stacks/Specific/medical.yml#L11-L59: запустите YAML-линер.Resources/Prototypes/_Goobstation/Entities/Objects/Specific/Robotics/borg_modules.yml#L89-L115: запустите YAML-линер.Команда:
dotnet run --project Content.YAMLLinter/Content.YAMLLinter.csproj -c DebugOpt.As per path instructions, изменённые YAML-ресурсы необходимо валидировать указанным линтером.
Source: Path instructions
Resources/Prototypes/_Goobstation/Entities/Objects/Specific/Robotics/borg_modules.yml (1)
89-89: LGTM!Also applies to: 115-115
Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml (1)
252-252: 🎯 Functional CorrectnessПроверьте область наследования
Grabbable.Компонент добавлен в
BaseBorgChassisNotIonStormable. Поэтому его получаютBaseBorgChassis,BaseXenoborgChassisи их наследники. Если grabbable-поведение требуется только обычным borg, перенесите компонент в более узкий прототип. Если область намеренная, добавьте проверку взаимодействий с xenoborg.Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml (1)
83-83: LGTM!Resources/Prototypes/Body/Prototypes/Specific/smartcorgi.yml (1)
10-22: 🗄️ Data Integrity & IntegrationОпределения связанных частей тела уже есть.
LeftHandSmartCorgiиRightHandSmartCorgiопределены вResources/Prototypes/Body/Parts/animal.ymlи используют стандартные родителские прототипыBaseLeftHand/BaseRightHand, поэтому ссылки изSmartCorgiкорректны.Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.yml (1)
18-18: 🎯 Functional CorrectnessПроверьте, подключён ли
TileFrictionControllerк прототипам.
TileFrictionModifierзарегистрирован в shared-сборке, значение по умолчанию —0f, аTileFrictionControllerприменит его к динамическим телам иKinematicControllers. Осталось проверить подключение этого контроллера кSingularityиBaseEnergyBall, если оно не реализовано в родительских/стартовых прототипах.Content.Goobstation.Shared/Vehicles/SharedVehicleSystem.cs (1)
59-77: LGTM!Content.Client/_White/ItemSlotRenderer/ItemSlotRendererSystem.cs (1)
118-128: LGTM!Content.Server/Holosign/HolosignSystem.cs (1)
76-76: LGTM!Content.Shared/Blocking/BlockingSystem.cs (1)
172-186: LGTM!Content.Shared/Throwing/ThrowingSystem.cs (1)
155-156: LGTM!Content.Shared/SubFloor/SharedTrayScannerSystem.cs (1)
36-42: LGTM!Content.Server/_Shitmed/ItemSwitch/ItemSwitchSystem.cs (1)
47-47: 🗄️ Data Integrity & IntegrationЗамечание не нужно.
Кортеж
(uid, component)соответствуетEntity<BatteryComponent?>, аGetRemainingUses((uid, battery), cost)возвращаетGetCharge((uid, battery)) / costдо округления.
|
Уже так и думал сделать. Можешь отдельно заносить каждый PR с фиксами сюда, если на губы не заносят пачкой. |
|
Ладно я не нашёл... |
|
@coderabbitai Подробно напиши все причины провала теста интегралок с разбором. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
pr="161"
echo '=== PR checks ==='
gh pr checks "$pr" --repo "$repo" --required=false || true
echo '=== PR workflow runs ==='
gh run list --repo "$repo" --branch "$(gh pr view "$pr" --repo "$repo" --json headRefName --jq .headRefName)" --limit 20 \
--json databaseId,name,status,conclusion,event,headSha,createdAt,updatedAt,url
echo '=== Failed jobs and logs for relevant failed runs ==='
gh run list --repo "$repo" --branch "$(gh pr view "$pr" --repo "$repo" --json headRefName --jq .headRefName)" --limit 20 \
--json databaseId,name,conclusion \
--jq '.[] | select(.conclusion == "failure") | [.databaseId, .name] | `@tsv`' |
while IFS=$'\t' read -r run_id run_name; do
echo "----- RUN ${run_id}: ${run_name} -----"
gh run view "$run_id" --repo "$repo" --json jobs \
--jq '.jobs[] | select(.conclusion == "failure") | {name, databaseId, startedAt, completedAt, steps}'
gh run view "$run_id" --repo "$repo" --log-failed || true
doneLength of output: 10893 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
run_id="30629301734"
job_id="91151709493"
echo '=== Run metadata ==='
gh api "repos/$repo/actions/runs/$run_id" \
--jq '{status, conclusion, event, run_attempt, created_at, updated_at, run_started_at, head_sha, actor: .actor.login, triggering_actor: .triggering_actor.login, cancel_url, workflow_url}'
echo '=== Job metadata ==='
gh api "repos/$repo/actions/jobs/$job_id" \
--jq '{name, status, conclusion, started_at, completed_at, check_run_url, steps}'
echo '=== Job log archive listing and matching excerpts ==='
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
if gh api "repos/$repo/actions/jobs/$job_id/logs" > "$tmp/job-logs.zip"; then
unzip -l "$tmp/job-logs.zip" || true
unzip -p "$tmp/job-logs.zip" > "$tmp/job.log" || true
rg -n -i -C 8 'Run Content\.IntegrationTests|error|failed|fail:|exception|timeout|cancel|killed|hang' "$tmp/job.log" || true
else
echo 'Could not retrieve job log archive.'
fi
echo '=== Workflow files with integration-test or timeout configuration ==='
fd -t f -e yml -e yaml .github . 2>/dev/null | while read -r file; do
if rg -q -i 'Content\.IntegrationTests|timeout-minutes|concurrency' "$file"; then
echo "----- $file -----"
rg -n -i -C 4 'Content\.IntegrationTests|timeout-minutes|concurrency|cancel-in-progress' "$file"
fi
done
echo '=== Integration test project and current PR changes that reference it ==='
fd -t f '.*IntegrationTests.*\.(csproj|cs)$' . 2>/dev/null | head -80
git diff --name-status "$(git merge-base origin/master HEAD)" HEADLength of output: 7076 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
pr="161"
run_id="30629301734"
job_id="91151709493"
echo '=== Response to job-log request ==='
gh api -i "repos/$repo/actions/jobs/$job_id/logs" | sed -n '1,80p'
echo '=== Workflow definition at the PR head ==='
gh api "repos/$repo/actions/workflows/275074948" \
--jq '{name, path, state, created_at, updated_at}'
workflow_path=$(gh api "repos/$repo/actions/workflows/275074948" --jq .path)
echo "Workflow path: $workflow_path"
git show "HEAD:$workflow_path" 2>&1 || true
echo '=== All repository files that configure or invoke integration tests ==='
rg --hidden -n -i -C 4 \
'Content\.IntegrationTests|Run Content\.IntegrationTests|timeout-minutes|dotnet test.*Integration' \
.github Content.IntegrationTests 2>/dev/null || true
echo '=== Integration test project ==='
cat -n Content.IntegrationTests/Content.IntegrationTests.csproj
echo '=== All PR commits and associated check suites ==='
gh pr view "$pr" --repo "$repo" --json commits \
--jq '.commits[] | [.oid, .committedDate, .messageHeadline] | `@tsv`'
echo '=== Debug workflow runs for all PR commits ==='
gh pr view "$pr" --repo "$repo" --json commits --jq '.commits[].oid' |
while read -r sha; do
echo "----- $sha -----"
gh api "repos/$repo/actions/runs?head_sha=$sha&event=pull_request&per_page=100" \
--jq '.workflow_runs[] | select(.name == "Build & Test Debug") | {id, status, conclusion, created_at, updated_at, run_attempt, url}'
done
echo '=== Failed check annotations ==='
gh api "repos/$repo/check-runs/$job_id/annotations?per_page=100" \
--jq '.[] | {path, start_line, end_line, level, title, message}' || trueLength of output: 236926 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
current_job="91151709493"
previous_run="30619953289"
dump_job_log() {
local job_id="$1"
local output="$2"
gh api "repos/$repo/actions/jobs/$job_id/logs" > "$output"
echo "=== $output: test step start/end and cancellation markers ==="
rg -n -i -C 12 \
'Run Content\.IntegrationTests|Starting test execution|Passed!|Failed!|Total tests|The operation was canceled|cancelled|canceling|SIGINT|SIGTERM|Process completed|Error:' \
"$output" || true
echo '=== Final 160 lines ==='
tail -n 160 "$output"
}
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
dump_job_log "$current_job" "$tmp/current.log"
echo '=== Previous failed workflow jobs ==='
gh api "repos/$repo/actions/runs/$previous_run/jobs?per_page=100" \
--jq '.jobs[] | {id, name, conclusion, started_at, completed_at, steps}'
gh api "repos/$repo/actions/runs/$previous_run/jobs?per_page=100" \
--jq '.jobs[] | select(.name == "build (ubuntu-latest)") | .id' |
while read -r job_id; do
dump_job_log "$job_id" "$tmp/previous.log"
doneLength of output: 54555 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
job_id="91151709493"
tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT
gh api "repos/$repo/actions/jobs/$job_id/logs" > "$tmp"
echo '=== Current integration test failures ==='
rg -n -i -C 5 '^\S+.*\sFailed\s|^.*Failed [A-Za-z_].*\[[0-9<]|^.*Error Message:|^.*Expected:|^.*But was:' "$tmp" || true
echo '=== Current test-host/process termination markers ==='
rg -n -i -C 4 'test host|process crashed|process terminated|test run aborted|death report|shutdown signal|operation was canceled' "$tmp" || true
echo '=== PR paths that could affect the known failed assets ==='
git diff --name-only "$(git merge-base origin/master HEAD)" HEAD |
rg -i 'figurines|smartfridge|locale|locali[sz]|machine.*board|board.*machine|dataset' || true
echo '=== Definitions and recent last-change commits for known failed assets ==='
rg -n -i -C 2 'FigurinesQM|figurines-qm-9|SmartFridgeCircuitboard|SmartFridgeMachineCircuitboard' \
Resources Content.IntegrationTests 2>/dev/null || true
git log -1 --format='%H%n%ad%n%s' --date=iso-strict -- \
Resources Content.IntegrationTests || trueLength of output: 51067
Что прошло
Ошибки
|
|
@coderabbitai Как я могу запустить тест Build & Test Debug / build (ubuntu-latest) на своём ПК? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Build & Test Debug workflow ==='
cat -n .github/workflows/build-test-debug.yml
echo '=== SDK and build configuration files ==='
fd -HI -t f '^(global\.json|.*\.(sln|slnx)|Directory\.(Build|Packages)\.(props|targets))$' . \
-x sh -c 'echo "----- $1 -----"; cat -n "$1"' sh {}
echo '=== Test project definitions ==='
fd -HI -t f '.*(Tests|IntegrationTests).*\.csproj$' . \
-x sh -c 'echo "----- $1 -----"; cat -n "$1"' sh {}Length of output: 18669
git submodule update --init --recursive
# Обновляет engine dependency так же, как action space-wizards/submodule-dependency.
# Если submodule уже соответствует PR, команда изменений не внесёт.
git submodule update --init --recursive
cd RobustToolbox
git submodule update --init --recursive
cd ..
dotnet --info
dotnet restore
dotnet build --configuration DebugOpt --no-restore /m
dotnet test --no-build --configuration DebugOpt \
Content.Tests/Content.Tests.csproj \
-- NUnit.ConsoleOut=0
DOTNET_gcServer=1 dotnet test --no-build --configuration DebugOpt \
Content.IntegrationTests/Content.IntegrationTests.csproj \
-- NUnit.ConsoleOut=0 NUnit.MapWarningTo=FailedПоследняя команда воспроизводит этап На Windows PowerShell задайте переменную окружения так: $env:DOTNET_gcServer=1
dotnet test --no-build --configuration DebugOpt `
Content.IntegrationTests/Content.IntegrationTests.csproj `
-- NUnit.ConsoleOut=0 NUnit.MapWarningTo=FailedДля сохранения полного лога добавьте перенаправление: DOTNET_gcServer=1 dotnet test --no-build --configuration DebugOpt \
Content.IntegrationTests/Content.IntegrationTests.csproj \
-- NUnit.ConsoleOut=0 NUnit.MapWarningTo=Failed \
2>&1 | tee integration-tests.logВажно: workflow также выполняет action You are interacting with an AI system. |
|
@coderabbitai Пофиксили. Какие ещё недоработки остались, которые могут провалить тесты? |
|
Oops, something went wrong! Please try again later. 🐰 💔 |
UmbiMax
left a comment
There was a problem hiding this comment.
Если и решать, то в основном последнее
|
|
||
| if (!_physicsQuery.TryComp(entity, out var physics)) | ||
| if (!_physicsQuery.TryComp(entity, out var physics) | ||
| || !physics.CanCollide || !physics.Hard) // Arcane-Add |
|
|
||
| status.Comp.SprintSpeedModifier = sprintSpeedModifier; | ||
| status.Comp.WalkSpeedModifier = walkSpeedModifier; | ||
| Dirty(status); // Arcane-Edit |
| requireAll: true | ||
| tags: | ||
| - VehicleKey | ||
| #- VehicleKey # CorvaxGoob |
There was a problem hiding this comment.
Тут Arcane-Edit
и решётка в самом начале строчки
|
@coderabbitai В тесте жалуется на inhand спрайты кваса, но имеется лишь icon. Посмотри на другие напитки. Как лучше и быстрее решить данную проблему? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Kvass references ==='
rg -n -i -C 8 'DrinkKvassGlass|kvass\.rsi|InHandsMaxFillLevels|inhand-left-fill' \
Resources Content Content.IntegrationTests 2>/dev/null || true
echo '=== Candidate drink prototypes with solution visuals and in-hand configuration ==='
rg -n -i -C 6 'SolutionContainerVisuals|InHandsMaxFillLevels|inhandVisuals|inhand.*fill' \
Resources/Prototypes 2>/dev/null | head -160 || true
echo '=== Kvass RSI files ==='
fd -HI -t f . Resources | rg -i 'kvass(\.rsi|/)' || true
kvass_meta="$(fd -HI -t f 'meta\.json$' Resources | while read -r f; do
case "$f" in *'/kvass.rsi/meta.json') echo "$f";; esac
done | head -1)"
if [ -n "$kvass_meta" ]; then
echo "=== $kvass_meta ==="
cat -n "$kvass_meta"
fi
echo '=== Metadata of comparable drink RSIs that declare in-hand fill states ==='
fd -HI -t f 'meta\.json$' Resources | while read -r f; do
if rg -q '"inhand-(left|right)-fill-[1-3]"' "$f"; then
echo "----- $f -----"
rg -n '"(icon|inhand-(left|right)-fill-[1-3])"' "$f" | head -24
fi
done | head -160Length of output: 1164 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
pr="161"
sha="$(gh pr view "$pr" --repo "$repo" --json headRefOid --jq '.headRefOid')"
tree="$(mktemp)"
trap 'rm -f "$tree"' EXIT
gh api "repos/$repo/git/trees/$sha?recursive=1" > "$tree"
echo '=== Kvass-related paths ==='
jq -r '.tree[] | select(.type == "blob") | .path' "$tree" | rg -i 'kvass|drink' | head -250
echo '=== Prototype files containing DrinkKvassGlass ==='
jq -r '.tree[] | select(.type == "blob") | .path' "$tree" |
while read -r path; do
case "$path" in
Resources/Prototypes/*.yml|Resources/Prototypes/*.yaml)
if gh api -H 'Accept: application/vnd.github.raw' "repos/$repo/contents/$path?ref=$sha" 2>/dev/null |
rg -q 'DrinkKvassGlass'; then
echo "----- $path -----"
gh api -H 'Accept: application/vnd.github.raw' "repos/$repo/contents/$path?ref=$sha" |
rg -n -i -C 12 'DrinkKvassGlass|kvass\.rsi|InHandsMaxFillLevels|SolutionContainerVisuals'
fi
;;
esac
done
echo '=== kvass.rsi metadata ==='
jq -r '.tree[] | select(.type == "blob") | .path' "$tree" |
rg -i '(^|/)kvass\.rsi/meta\.json$' |
while read -r path; do
echo "----- $path -----"
gh api -H 'Accept: application/vnd.github.raw' "repos/$repo/contents/$path?ref=$sha" | jq .
done
echo '=== Example drink RSI metadata with in-hand fill states ==='
jq -r '.tree[] | select(.type == "blob") | .path' "$tree" |
rg -i '(^|/)(beer|wine|glass|drink).*\.rsi/meta\.json$' |
head -80 |
while read -r path; do
raw="$(gh api -H 'Accept: application/vnd.github.raw' "repos/$repo/contents/$path?ref=$sha" 2>/dev/null || true)"
if printf '%s' "$raw" | rg -q '"inhand-(left|right)-fill-[1-3]"'; then
echo "----- $path -----"
printf '%s' "$raw" | jq -r '.states[]?.name' | rg '^(icon|inhand-(left|right)-fill-[1-3])$' || true
break
fi
doneLength of output: 1923
Ошибка возникает только потому, что у Если у - type: SolutionContainerVisuals
inHandsMaxFillLevels: 0Либо удалите Результат:
Добавлять шесть Проверка репозитория через sandbox дважды не выполнилась, поэтому я не смог подтвердить точный файл и источник наследования. После восстановления доступа проверьте, где задан You are interacting with an AI system. |
|
@coderabbitai Смотри на тест. Сообщи об оставшихся ошибках с вариантами фиксов. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
pr="161"
sha="$(gh pr view "$pr" --repo "$repo" --json headRefOid --jq .headRefOid)"
echo "=== PR head ==="
echo "$sha"
echo "=== Checks for current PR head ==="
gh pr checks "$pr" --repo "$repo" --required=false || true
echo "=== Build & Test Debug runs for PR head ==="
gh api "repos/$repo/actions/runs?head_sha=$sha&event=pull_request&per_page=100" \
--jq '.workflow_runs[]
| select(.name == "Build & Test Debug")
| {id, status, conclusion, run_attempt, created_at, updated_at, html_url}'
run_id="$(gh api "repos/$repo/actions/runs?head_sha=$sha&event=pull_request&per_page=100" \
--jq '[.workflow_runs[] | select(.name == "Build & Test Debug")] | sort_by(.created_at) | last | .id // empty')"
if [ -z "$run_id" ]; then
echo "No Build & Test Debug workflow run found for the current PR head."
exit 0
fi
echo "=== Jobs for run $run_id ==="
gh api "repos/$repo/actions/runs/$run_id/jobs?per_page=100" \
--jq '.jobs[] | {id, name, status, conclusion, started_at, completed_at, steps}'
job_id="$(gh api "repos/$repo/actions/runs/$run_id/jobs?per_page=100" \
--jq '.jobs[]
| select(.name == "build (ubuntu-latest)")
| .id' | tail -1)"
if [ -z "$job_id" ]; then
echo "No build (ubuntu-latest) job found."
exit 0
fi
tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT
gh api "repos/$repo/actions/jobs/$job_id/logs" > "$tmp"
echo "=== Test failure blocks ==="
rg -n -i -C 10 \
'Failed [A-Za-z0-9_.]+|Error Message:|Expected:|But was:|Missing prototype|does not exist in RSI|specifies [0-9]+ entries|Test Run Failed|Total tests|The runner has received a shutdown signal|operation was canceled' \
"$tmp" || true
echo "=== Final test summary ==="
rg -n -i -C 5 \
'Passed!|Failed!|Total tests|Test Run Aborted|Run Content\.IntegrationTests|Process completed' \
"$tmp" || true
echo "=== Related content definitions in the PR checkout ==="
rg -n -i -C 3 \
'DrinkKvassGlass|HellfireFreezerMachineCircuitBoard|AirlockHatchSyndicate|AutolatheHyperConvection|FigurinesQM|figurines-qm-9|SmartFridge(Machine)?Circuitboard' \
Resources Content.IntegrationTests 2>/dev/null || trueLength of output: 60706
1.
|
|
@coderabbitai На каких картах ещё нет данных ролей. Сразу с готовой вставкой отпиши мне |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Candidate map files ==='
fd -HI -t f -e yml -e yaml . Resources/Maps | sort
echo '=== Required spawn point prototypes ==='
rg -n -A8 -B3 \
'^\s*id:\s*(SpawnPointAdjutant|SpawnPointCommandMaid|SpawnPointIAA)\s*$' \
Resources/Prototypes --glob '*.{yml,yaml}' || true
echo '=== Per-map role spawner and bridge beacon audit ==='
while IFS= read -r map; do
case "$map" in
*.yml|*.yaml) ;;
*) continue ;;
esac
if ! rg -q '^\s*entities:\s*$' "$map"; then
continue
fi
adj="$(rg -c '^- proto: SpawnPointAdjutant$' "$map" || true)"
maid="$(rg -c '^- proto: SpawnPointCommandMaid$' "$map" || true)"
iaa="$(rg -c '^- proto: SpawnPointIAA$' "$map" || true)"
beacon="$(rg -c '^- proto: DefaultStationBeaconBridge$' "$map" || true)"
count="$(rg -n '^\s*entityCount:\s*[0-9]+' "$map" | head -1 || true)"
max_uid="$(rg -o '^\s*- uid: [0-9]+$' "$map" | sed -E 's/.*: //' | sort -n | tail -1 || true)"
printf '\nMAP=%s\nadjutant=%s command_maid=%s iaa=%s bridge_beacons=%s\n%s\nmax_uid=%s\n' \
"$map" "$adj" "$maid" "$iaa" "$beacon" "$count" "${max_uid:-none}"
if [ "$adj" -eq 0 ] || [ "$maid" -eq 0 ] || [ "$iaa" -eq 0 ]; then
echo '--- bridge beacon blocks ---'
rg -n -A14 -B2 '^- proto: DefaultStationBeaconBridge$' "$map" || true
echo '--- existing target spawn points ---'
rg -n -A12 -B2 '^- proto: SpawnPoint(Adjutant|CommandMaid|IAA)$' "$map" || true
echo '--- duplicate UIDs ---'
rg -o '^\s*- uid: [0-9]+$' "$map" |
sed -E 's/.*: //' | sort -n | uniq -d | head -20 || true
fi
done < <(fd -HI -t f -e yml -e yaml . Resources/Maps | sort)Length of output: 19362 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Station-map audit: required spawn points and bridge beacons ==='
python3 - <<'PY'
from pathlib import Path
import re
root = Path("Resources/Maps")
targets = ("SpawnPointAdjutant", "SpawnPointCommandMaid", "SpawnPointIAA")
for path in sorted(root.rglob("*.yml")):
parts = set(path.parts)
if parts & {"Dungeon", "Lavaland", "Ruins", "Salvage", "Shuttles", "Test", "Misc", "Nonstations", "InfinityDorms", "Bitrun"}:
continue
text = path.read_text(encoding="utf-8")
if not re.search(r"(?m)^- proto: DefaultStationBeaconBridge$", text):
continue
present = {target: bool(re.search(rf"(?m)^- proto: {re.escape(target)}$", text)) for target in targets}
missing = [target for target, exists in present.items() if not exists]
if not missing:
continue
entity_count = re.search(r"(?m)^\s*entityCount:\s*(\d+)\s*$", text)
uids = [int(value) for value in re.findall(r"(?m)^\s*- uid: (\d+)\s*$", text)]
print(f"MAP={path}")
print(f"MISSING={','.join(missing)}")
print(f"ENTITY_COUNT={entity_count.group(1) if entity_count else 'none'}")
print(f"MAX_UID={max(uids) if uids else 'none'}")
print()
PY
echo '=== Bridge-beacon blocks and insertion context for every incomplete station map ==='
python3 - <<'PY' > /tmp/incomplete_station_maps.txt
from pathlib import Path
import re
root = Path("Resources/Maps")
targets = ("SpawnPointAdjutant", "SpawnPointCommandMaid", "SpawnPointIAA")
for path in sorted(root.rglob("*.yml")):
parts = set(path.parts)
if parts & {"Dungeon", "Lavaland", "Ruins", "Salvage", "Shuttles", "Test", "Misc", "Nonstations", "InfinityDorms", "Bitrun"}:
continue
text = path.read_text(encoding="utf-8")
if not re.search(r"(?m)^- proto: DefaultStationBeaconBridge$", text):
continue
if any(not re.search(rf"(?m)^- proto: {re.escape(target)}$", text) for target in targets):
print(path)
PY
while IFS= read -r map; do
[ -n "$map" ] || continue
echo "===== $map ====="
rg -n -A16 -B2 '^- proto: DefaultStationBeaconBridge$' "$map"
echo '--- header ---'
sed -n '1,40p' "$map"
echo '--- existing target spawners ---'
rg -n -A10 -B2 '^- proto: SpawnPoint(Adjutant|CommandMaid|IAA)$' "$map" || true
echo '--- highest UIDs ---'
rg -o '^\s*- uid: [0-9]+$' "$map" | sed -E 's/.*: //' | sort -n | tail -5
done < /tmp/incomplete_station_maps.txt
echo '=== Job spawn test map list and current CI errors ==='
rg -n -C 8 \
'SpawnPointAdjutant|SpawnPointCommandMaid|SpawnPointIAA|missing.*spawn|spawn.*point|GameMaps' \
Content.IntegrationTests Resources/Prototypes --glob '*.{cs,yml,yaml}' || trueLength of output: 96125 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Active map IDs in PostMapInitTest ==='
sed -n '110,225p' Content.IntegrationTests/Tests/PostMapInitTest.cs
echo '=== GameMapPrototype definitions for active-map path resolution ==='
rg -n -A18 -B3 \
'^\s*id:\s*(Aspid|Atlas|Bagel|Barratry|Box|CentComm|Chloris|Cluster|Cog|Core|Delta|Elkridge|Europa|Fland|Kettle|Lambda|Leonid|Loop|Marathon|Meta|Oasis|Omega|Origin|Packed|Plasma|Reach|Relic|Saltern|Serpentcrest|Snowball|Train|WonderBox)\s*$|^\s*mapPath:' \
Resources/Prototypes --glob '*.{yml,yaml}' || true
echo '=== Ready insertions for incomplete active maps ==='
python3 - <<'PY'
from pathlib import Path
import re
# IDs currently exercised by GameMapsInCurrentPool. The map files are resolved
# from the active _Goobstation/Arcane map variants in this PR checkout.
active = {
"Amber": Path("Resources/Maps/_Goobstation/amber.yml"),
"Box": Path("Resources/Maps/_Goobstation/box.yml"),
"Chloris": Path("Resources/Maps/_Goobstation/chloris.yml"),
"Core": Path("Resources/Maps/_Goobstation/core.yml"),
"Delta": Path("Resources/Maps/_Goobstation/delta.yml"),
"Kettle": Path("Resources/Maps/_Goobstation/kettle.yml"),
"Lambda": Path("Resources/Maps/_Goobstation/lambda.yml"),
"Leonid": Path("Resources/Maps/_Goobstation/leonid.yml"),
"Loop": Path("Resources/Maps/_Goobstation/loop.yml"),
"Meta": Path("Resources/Maps/_Goobstation/meta.yml"),
"Omega": Path("Resources/Maps/_Goobstation/omega.yml"),
"Reach": Path("Resources/Maps/_Goobstation/reach.yml"),
"Saltern": Path("Resources/Maps/_Goobstation/saltern.yml"),
"Serpentcrest": Path("Resources/Maps/_Goobstation/serpentcrest.yml"),
"Train": Path("Resources/Maps/_Goobstation/train.yml"),
}
targets = ("SpawnPointAdjutant", "SpawnPointCommandMaid", "SpawnPointIAA")
for name, path in active.items():
if not path.exists():
print(f"SKIP {name}: {path} does not exist")
continue
text = path.read_text(encoding="utf-8")
missing = [x for x in targets if not re.search(rf"(?m)^- proto: {x}$", text)]
if not missing:
continue
match = re.search(
r"(?m)^- proto: DefaultStationBeaconBridge$\n entities:\n"
r" - uid: \d+\n components:\n - type: Transform\n"
r"(?: rot: .*\n)?"
r" pos: ([^ \n]+)\n parent: (\d+)",
text,
)
if not match:
print(f"ERROR {name}: cannot parse first bridge beacon")
continue
count_match = re.search(r"(?m)^ entityCount: (\d+)$", text)
uids = {int(x) for x in re.findall(r"(?m)^ - uid: (\d+)$", text)}
next_uid = max(uids) + 1
new_uids = []
while len(new_uids) < len(missing):
if next_uid not in uids:
new_uids.append(next_uid)
next_uid += 1
print(f"MAP={name}")
print(f"PATH={path}")
print(f"ENTITY_COUNT={count_match.group(1) if count_match else 'none'} -> "
f"{int(count_match.group(1)) + len(missing) if count_match else 'none'}")
print(f"MISSING={','.join(missing)}")
print(f"POS={match.group(1)} PARENT={match.group(2)}")
print("INSERT:")
for proto, uid in zip(missing, new_uids):
print(f"- proto: {proto}")
print(" entities:")
print(f" - uid: {uid}")
print(" components:")
print(" - type: Transform")
print(f" pos: {match.group(1)}")
print(f" parent: {match.group(2)}")
print()
PYLength of output: 136660 🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
wanted_maps = {
"Atlas", "Bagel", "Chloris", "Cluster", "Cog", "Delta", "Exo",
"FlandHighPop", "Kettle", "Leonid", "Loop", "Marathon", "Meta",
"OasisHighPop", "Omega", "Origin", "Packed", "Reach", "Saltern",
"Serpentcrest",
}
wanted_jobs = {
"Adjutant": "SpawnPointAdjutant",
"CommandMaid": "SpawnPointCommandMaid",
"IAA": "SpawnPointIAA",
}
# Split every prototype file into YAML entity blocks. All relevant GameMapPrototype
# blocks are flat enough for extracting id, mapPath, and indented availableJobs.
game_maps = {}
for proto_file in Path("Resources/Prototypes").rglob("*.yml"):
text = proto_file.read_text(encoding="utf-8")
blocks = re.split(r"(?m)^- type: gameMap\s*$", text)[1:]
for block in blocks:
block = block.split("\n- type:", 1)[0]
id_match = re.search(r"(?m)^ id: ([^\s#]+)", block)
path_match = re.search(r"(?m)^ mapPath: ([^\s#]+)", block)
if not id_match or not path_match:
continue
map_id = id_match.group(1)
if map_id not in wanted_maps:
continue
jobs = set()
available = re.search(
r"(?ms)^ - type: StationJobs\s*\n\s+availableJobs:\s*\n(.*?)(?=^ - type:|\Z)",
block,
)
if available:
for job in wanted_jobs:
if re.search(rf"(?m)^\s+{job}:\s*\[", available.group(1)):
jobs.add(job)
game_maps[map_id] = (proto_file, path_match.group(1), jobs)
print("=== Exact active game maps with requested jobs ===")
for map_id in sorted(game_maps):
proto_file, map_path, jobs = game_maps[map_id]
print(f"{map_id}: prototype={proto_file}, mapPath={map_path}, jobs={','.join(sorted(jobs)) or 'none'}")
print("\n=== Required map insertions ===")
for map_id in sorted(game_maps):
proto_file, res_path, jobs = game_maps[map_id]
if not jobs:
continue
path = Path("Resources") / res_path.lstrip("/")
if not path.exists():
print(f"ERROR {map_id}: missing map file {path}")
continue
text = path.read_text(encoding="utf-8")
needed = [wanted_jobs[job] for job in sorted(jobs) if not re.search(rf"(?m)^- proto: {wanted_jobs[job]}$", text)]
if not needed:
continue
beacon = re.search(
r"(?m)^- proto: DefaultStationBeaconBridge$\n entities:\n"
r" - uid: \d+\n components:\n - type: Transform\n"
r"(?: rot: .*\n)?"
r" pos: ([^ \n]+)\n parent: (\d+)",
text,
)
if not beacon:
print(f"ERROR {map_id}: missing or unsupported bridge beacon in {path}")
continue
count = re.search(r"(?m)^ entityCount: (\d+)$", text)
uids = {int(uid) for uid in re.findall(r"(?m)^ - uid: (\d+)$", text)}
uid = max(uids) + 1
new_uids = []
while len(new_uids) < len(needed):
if uid not in uids:
new_uids.append(uid)
uid += 1
print(f"\nMAP={map_id}")
print(f"PATH={path}")
print(f"ENTITY_COUNT={count.group(1) if count else 'no entityCount'}"
+ (f" -> {int(count.group(1)) + len(needed)}" if count else ""))
print(f"BRIDGE_POS={beacon.group(1)} PARENT={beacon.group(2)}")
print("MISSING=" + ",".join(needed))
for proto, new_uid in zip(needed, new_uids):
print(f"- proto: {proto}")
print(" entities:")
print(f" - uid: {new_uid}")
print(" components:")
print(" - type: Transform")
print(f" pos: {beacon.group(1)}")
print(f" parent: {beacon.group(2)}")
PYLength of output: 8126
Остальные активные карты либо уже имеют нужные spawn point, либо не включают эти роли в KettleФайл: Измени - entityCount: 26994
+ entityCount: 26997Добавь после - proto: SpawnPointAdjutant
entities:
- uid: 600001
components:
- type: Transform
pos: 7.5,-11.5
parent: 2
- proto: SpawnPointCommandMaid
entities:
- uid: 600002
components:
- type: Transform
pos: 7.5,-11.5
parent: 2
- proto: SpawnPointIAA
entities:
- uid: 600003
components:
- type: Transform
pos: 7.5,-11.5
parent: 2
LeonidФайл: Измени - entityCount: 35968
+ entityCount: 35971Добавь после - proto: SpawnPointAdjutant
entities:
- uid: 35969
components:
- type: Transform
pos: -16.5,12.5
parent: 2
- proto: SpawnPointCommandMaid
entities:
- uid: 35970
components:
- type: Transform
pos: -16.5,12.5
parent: 2
- proto: SpawnPointIAA
entities:
- uid: 35971
components:
- type: Transform
pos: -16.5,12.5
parent: 2LoopФайл: Измени - entityCount: 18076
+ entityCount: 18079Добавь после - proto: SpawnPointAdjutant
entities:
- uid: 18077
components:
- type: Transform
pos: -22.5,72.5
parent: 2
- proto: SpawnPointCommandMaid
entities:
- uid: 18078
components:
- type: Transform
pos: -22.5,72.5
parent: 2
- proto: SpawnPointIAA
entities:
- uid: 18079
components:
- type: Transform
pos: -22.5,72.5
parent: 2You are interacting with an AI system. |
|
@coderabbitai Узнай по какой причине не работает ТТС, если кто-то говорит по рации, а также эффекты рации, которые ранее добавили в Content.Shared/Radio/RadioChannelPrototype.cs и Content.Shared/Radio/RadioChannelPrototype.cs + Resources/Prototypes/radio_channels.yml |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Radio and TTS candidate files ==='
fd -HI -t f . Content Resources \
| rg '(^|/)(RadioChannelPrototype|.*Radio.*System|.*Radio.*Event|.*TTS.*|.*TextToSpeech.*)\.(cs|yml|yaml)$|radio_channels\.yml$' \
| sort
echo '=== Prototype and radio-channel definitions ==='
for file in \
Content.Shared/Radio/RadioChannelPrototype.cs \
Resources/Prototypes/radio_channels.yml
do
if [ -f "$file" ]; then
echo "----- $file -----"
ast-grep outline "$file" --items all --view expanded 2>/dev/null || true
cat -n "$file"
fi
done
echo '=== Definitions and uses of RadioChannelPrototype fields ==='
rg -n -i -C 10 \
'RadioChannelPrototype|radio.*channel|channel.*(sound|effect|color|tts)|TTS|TextToSpeech|Speak.*Radio|Radio.*Speak' \
Content \
--glob '*.cs' || true
echo '=== Radio network-event declarations and client handlers ==='
rg -n -i -C 14 \
'(NetEvent|EntityEvent).*Radio|Radio.*(NetEvent|EntityEvent)|Broadcast.*Radio|Raise.*Radio|Subscribe.*Radio|On.*Radio' \
Content \
--glob '*.cs' || true
echo '=== PR changes and recent commits involving radio/TTS ==='
git diff --name-status "$(git merge-base origin/master HEAD)" HEAD -- \
Content.Shared/Radio Resources/Prototypes/radio_channels.yml Content.Client Content.Server || true
git log --all --oneline -G 'RadioChannelPrototype|radio_channels|TTS|TextToSpeech' -- \
Content.Shared/Radio Resources/Prototypes/radio_channels.yml Content.Client Content.Server \
| head -80 || trueLength of output: 1588 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
pr="161"
sha="$(gh pr view "$pr" --repo "$repo" --json headRefOid --jq .headRefOid)"
echo "PR_HEAD=$sha"
echo '=== Changed files related to radio or TTS ==='
gh api "repos/$repo/pulls/$pr/files?per_page=100" --paginate \
--jq '.[] | select(.filename | test("(?i)(radio|tts|texttospeech)")) | {filename, status, additions, deletions, patch}'
echo '=== Required files at PR head ==='
for path in \
Content.Shared/Radio/RadioChannelPrototype.cs \
Resources/Prototypes/radio_channels.yml
do
echo "----- $path -----"
gh api -H 'Accept: application/vnd.github.raw' \
"repos/$repo/contents/$path?ref=$sha" 2>/dev/null || echo "NOT FOUND"
done
echo '=== GitHub code search: declarations and uses ==='
for query in \
'repo:ArcaneSS14/arcane RadioChannelPrototype language:C#' \
'repo:ArcaneSS14/arcane "RadioChannelPrototype" language:C#' \
'repo:ArcaneSS14/arcane "TextToSpeech" language:C#' \
'repo:ArcaneSS14/arcane "TTS" language:C#' \
'repo:ArcaneSS14/arcane "radio_channels.yml"'
do
echo "----- $query -----"
gh api "search/code?q=$(printf '%s' "$query" | jq -sRr `@uri`)&per_page=100" \
--jq '.items[] | {path, html_url}' 2>/dev/null || true
done
echo '=== History of the target files ==='
for path in \
Content.Shared/Radio/RadioChannelPrototype.cs \
Resources/Prototypes/radio_channels.yml
do
echo "----- $path -----"
gh api "repos/$repo/commits?path=$(printf '%s' "$path" | jq -sRr `@uri`)&sha=$sha&per_page=15" \
--jq '.[] | {sha: .sha[0:12], date: .commit.author.date, message: .commit.message}' \
2>/dev/null || true
doneLength of output: 16436 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
sha="ca579fba181b0069e8bb7f0cf8253240d441bd2c"
radio_commit="a5391bcca954"
echo '=== Files changed by Radio 2.0 ==='
gh api "repos/$repo/commits/$radio_commit" \
--jq '.files[] | {filename, status, patch}'
echo '=== Radio/TTS-related paths at PR head ==='
tree="$(mktemp)"
trap 'rm -f "$tree"' EXIT
gh api "repos/$repo/git/trees/$sha?recursive=1" > "$tree"
jq -r '.tree[] | select(.type == "blob") | .path' "$tree" \
| rg -i '(^|/)(radio|headset|tts|texttospeech|speech|chat).*\.(cs|yml|yaml)$|/(radio|headset|tts|texttospeech)/' \
| sort
echo '=== Read source files changed by Radio 2.0 that still exist at PR head ==='
gh api "repos/$repo/commits/$radio_commit" --jq -r '.files[].filename' \
| while IFS= read -r path; do
case "$path" in
*.cs)
echo "----- $path -----"
gh api -H 'Accept: application/vnd.github.raw' \
"repos/$repo/contents/$path?ref=$sha" 2>/dev/null \
| nl -ba \
| sed -n '1,420p' || true
;;
esac
done
echo '=== Commit metadata and parent diff for the later volume change ==='
gh api "repos/$repo/commits/3c703150fd3a" \
--jq '{sha, message: .commit.message, files: [.files[] | {filename, patch}]}'Length of output: 30133 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
sha="ca579fba181b0069e8bb7f0cf8253240d441bd2c"
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
paths=(
"Content.Server/Radio/EntitySystems/HeadsetSystem.cs"
"Content.Client/_Orion/Radio/RadioBarkAudioSystem.cs"
"Content.Shared/_Orion/Radio/PlayRadioBarkEvent.cs"
"Content.Shared/_Art/TTS/TTSRadioPlayEvent.cs"
"Content.Client/_Art/TTS/TTSSystem.cs"
"Content.Server/_Art/TTS/TTSSystem.cs"
"Content.Server/_Art/TTS/TTSManager.cs"
"Content.Server/Chat/Systems/ChatSystem.cs"
"Content.Server/Radio/EntitySystems/RadioSystem.cs"
"Content.Shared/Radio/EntitySystems/SharedHeadsetSystem.cs"
)
for path in "${paths[@]}"; do
output="$tmp/$(basename "$path")"
if gh api -H 'Accept: application/vnd.github.raw' \
"/repos/$repo/contents/$path?ref=$sha" > "$output" 2>/dev/null; then
echo "===== $path ====="
rg -n -i -C 18 \
'OnEntitySpoke|EntitySpokeEvent|OnSendSound|PlayEntity|TTSRadioPlayEvent|PlayRadioBarkEvent|RadioReceiveEvent|Raise.*Event|Subscribe.*Event|Speak|radio' \
"$output" || true
else
echo "===== $path: NOT AVAILABLE ====="
fi
doneLength of output: 92495 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
sha="ca579fba181b0069e8bb7f0cf8253240d441bd2c"
tree="$(mktemp)"
trap 'rm -f "$tree"' EXIT
gh api "repos/$repo/git/trees/$sha?recursive=1" > "$tree"
echo '=== Files that can reference radio TTS/bark events or OnSendSound ==='
jq -r '.tree[] | select(.type == "blob") | .path' "$tree" \
| rg '\.cs$' \
| while IFS= read -r path; do
content="$(gh api -H 'Accept: application/vnd.github.raw' \
"/repos/$repo/contents/$path?ref=$sha" 2>/dev/null || true)"
if printf '%s' "$content" | rg -q \
'TTSRadioPlayEvent|PlayRadioBarkEvent|OnSendSound|RadioReceiveRelayEvent|HeadsetRadioReceiveRelayEvent'; then
echo "===== $path ====="
printf '%s\n' "$content" \
| rg -n -C 12 \
'TTSRadioPlayEvent|PlayRadioBarkEvent|OnSendSound|RadioReceiveRelayEvent|HeadsetRadioReceiveRelayEvent'
fi
done
echo '=== Current HeadsetSystem versus Radio 2.0 implementation ==='
for ref in "$sha" "a5391bcca954^" "a5391bcca954"; do
echo "----- ref=$ref -----"
gh api -H 'Accept: application/vnd.github.raw' \
"/repos/$repo/contents/Content.Server/Radio/EntitySystems/HeadsetSystem.cs?ref=$ref" \
2>/dev/null \
| rg -n -C 10 'SharedAudioSystem|OnSendSound|DefaultOnSound|OnSpeak|OnEntitySpoke|PlayEntity' \
|| true
doneLength of output: 1424
1. TTS не передаётся получателям радиоВ _radio.SendRadioMessage(uid, args.Message, args.Channel, component.Headset);
args.Channel = null;В SubscribeLocalEvent<TTSComponent, EntitySpokeEvent>(
OnEntitySpoke,
after: [typeof(RadioSystem), typeof(HeadsetSystem)]);Он проверяет канал так: if (args.Channel != null)
return;Но При этом отдельный путь для радио существует: TTSRadioPlayEvent
→ TTSSystem.OnTTSRadioPlayEvent
→ HandleReceiveRadio(...)Но в подтверждённой цепочке Нужный фиксСоздавать При этом обработчик 2. Эффекты рации не вызываются
[DataField]
public SoundSpecifier? OnSendSound = null;
Но текущий
Следовательно, Ранее Radio 2.0 добавлял код вида: var sound = args.Channel.OnSendSound ?? DefaultOnSound;
_audio.PlayEntity(sound, uid, uid);Этот код отсутствует на текущем
Итог
Последняя широкая проверка всех вызовов не выполнилась из-за ошибки доступа к репозиторию. Однако причины выше подтверждаются текущими реализациями You are interacting with an AI system. |
|
Уже занимаюсь фиксом ттса в другом пре чтобы макароны не делать |
|
@coderabbitai Как будем фиксить проблему? Звук само собой должен быть персональным для каждой сущности. Наушники не динамики. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Radio and audio source maps ==='
for file in \
Content.Server/Radio/EntitySystems/HeadsetSystem.cs \
Content.Shared/Radio/RadioChannelPrototype.cs \
Content.Client/_Orion/Radio/RadioBarkAudioSystem.cs \
Content.Shared/_Orion/Radio/PlayRadioBarkEvent.cs \
Content.Shared/_Art/TTS/TTSRadioPlayEvent.cs \
Content.Client/_Art/TTS/TTSSystem.cs \
Content.Server/_Art/TTS/TTSSystem.cs
do
if [ -f "$file" ]; then
echo "----- OUTLINE: $file -----"
ast-grep outline "$file" --items all --type class,method --view expanded || true
echo "----- RELEVANT CONTEXT: $file -----"
rg -n -C 18 \
'OnSpeak|OnSendSound|PlayEntity|PlayGlobal|Play.*Event|Raise.*Event|TTSRadioPlayEvent|PlayRadioBarkEvent|RadioReceive|EntitySpokeEvent|Filter|Session' \
"$file" || true
else
echo "MISSING: $file"
fi
done
echo '=== All uses of the existing radio audio/TTS events ==='
rg -n -C 12 \
'TTSRadioPlayEvent|PlayRadioBarkEvent|OnSendSound|DefaultOnSound|RadioReceiveAttemptEvent|RadioReceiveEvent' \
Content --glob '*.cs' || true
echo '=== Examples of client-targeted sound events ==='
rg -n -C 10 \
'RaiseNetworkEvent\(.*Filter|RaiseNetworkEvent\(.*session|Filter\.SinglePlayer|Filter\.Empty\(\)\.AddPlayer|PlayEntity\(.*Filter|PlayGlobal\(.*Filter' \
Content.Server Content.Shared --glob '*.cs' | head -500 || trueLength of output: 75257
1. Звук отправки канала
Порядок:
Схема: if (TryComp(uid, out ActorComponent? actor)
&& args.Channel.OnSendSound is { } sound)
{
_audio.PlayGlobal(sound, Filter.SinglePlayer(actor.PlayerSession), false);
}Такой звук слышит только отправитель. Игроки рядом не услышат его без наушников. 2. Звук приёма рацииПриёмный звук надо отправлять в Уже есть нужная точка: if (TryComp(parent, out ActorComponent? actor))Она означает, что данный headset принадлежит конкретному игроку. Сервер должен послать
_audio.PlayGlobal(..., Filter.Local(), false, audioParams);Это правильно на клиенте. Нужно отправлять событие так: RaiseNetworkEvent(
new PlayRadioBarkEvent
{
Path = "...",
Params = AudioParams.Default,
Source = GetNetEntity(uid),
},
actor.PlayerSession);Не отправлять его через 3. Не смешивать с TTSФикс TTS должен использовать тот же принцип: сервер создаёт Но этот PR должен чинить только radio bark и
ПроверкаПроверить минимум четыре случая:
Failed to handle agent chat message. Please try again. You are interacting with an AI system. |
|
@coderabbitai По какой причине нельзя надеть наушник на второй слот для него? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Candidate headset, slot, and equipment files ==='
fd -HI -t f . Content Resources |
rg -i '(^|/)(.*(headset|earpiece|slot|inventory|clothing|equipment).*\.(cs|yml|yaml))$' |
head -300
echo '=== Headset prototypes and slot definitions ==='
rg -n -i -C 8 \
'Headset|Radio|earpiece|ears|ear slot|slotId|slots:|SlotContainer|Clothing' \
Resources/Prototypes \
--glob '*.{yml,yaml}' | head -1200 || true
echo '=== Equipment validation and headset-specific code ==='
rg -n -i -C 10 \
'Headset|Radio|CanEquip|CanUnequip|Equip.*Slot|Slot.*Equip|slotId|SlotContainer|ClothingSlot' \
Content \
--glob '*.cs' | head -1400 || true
echo '=== Changed files in this PR that may affect equipment ==='
git diff --name-only "$(git merge-base origin/master HEAD)" HEAD |
rg -i '(headset|radio|slot|inventory|clothing|equipment)' || trueLength of output: 115530 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Human inventory ear slots ==='
sed -n '/- name: ears$/,/^ - name:/p' \
Resources/Prototypes/InventoryTemplates/human_inventory_template.yml
sed -n '/- name: earsright$/,/^ - name:/p' \
Resources/Prototypes/InventoryTemplates/human_inventory_template.yml
echo '=== Base headset prototypes and their Clothing slot flags ==='
for file in \
Resources/Prototypes/Entities/Clothing/Ears/headsets.yml \
Resources/Prototypes/Entities/Clothing/Ears/headsets_alt.yml \
Resources/Prototypes/_Orion/Entities/Clothing/Ears/headsets.yml \
Resources/Prototypes/_Orion/Entities/Clothing/Ears/headsets_alt.yml \
Resources/Prototypes/_Arcane/Entities/Clothing/Ears/headsets.yml \
Resources/Prototypes/_Shitmed/Entities/Clothing/Ears/headsets_alt.yml
do
[ -f "$file" ] || continue
echo "----- $file -----"
rg -n -C 8 'BaseHeadset|Headset|type: Clothing|slots:|EARS|EARSRIGHT' "$file" || true
done
echo '=== Slot-flag declaration and equipment compatibility checks ==='
rg -n -i -C 12 \
'EARSRIGHT|\bEARS\b|SlotFlags|CanEquip.*slot|slotFlags.*Clothing|Clothing.*Slots' \
Content.Shared Content.Server Content.Client RobustToolbox \
--glob '*.cs' 2>/dev/null | head -1200 || trueLength of output: 137823
В
Это разные флаги. Второй слот не является вторым экземпляром Базовый прототип - type: Clothing
slots:
- earsПоэтому проверка экипировки отклоняет гарнитуру для Минимальная правка должна быть в базовом прототипе, чтобы она применялась ко всем наследникам: - type: Clothing
slots:
- ears
- earsrightПосле этого две гарнитуры можно будет надеть одновременно. Нужно отдельно проверить визуальный слой правого уха. У гарнитур может не быть отдельного спрайта для You are interacting with an AI system. |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Content.Server/Radio/EntitySystems/HeadsetSystem.cs`:
- Around line 75-88: Replace the Orion markers surrounding the inventory
examination block in Content.Server/Radio/EntitySystems/HeadsetSystem.cs lines
75-88, the active headset selection block at lines 111-140, the speech
transmission block at lines 142-171, and the radio sound block at lines 208-211:
use Orion-Edit-Start and Orion-Edit-End consistently instead of Orion-Start and
Orion-End.
- Around line 36-37: Update the OnEntitySpoke event subscription in
HeadsetSystem to use InventoryComponent instead of ActorComponent, so speaking
entities with an equipped headset are handled regardless of whether they have a
game session. Preserve the existing OnEntitySpoke behavior and the
OnInventoryExamined subscription.
- Around line 147-169: В цикле обработки гарнитур вокруг HeadsetSystem и вызовов
_radio.SendRadioMessage обеспечьте отправку args.Channel только один раз: после
первой успешной отправки немедленно завершайте перебор, сохраняя все
существующие проверки совместимости гарнитуры и канала.
- Around line 241-245: Update the PlayRadioBarkEvent construction in the headset
radio flow to set its Source field to parent before raising the event, so the
client receives the speaking entity. Do not modify the client-side
OnPlayRadioBark handling.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: ad0b30b6-7e0d-4666-a873-cf178dda9c9e
📒 Files selected for processing (2)
Content.Server/Radio/EntitySystems/HeadsetSystem.csResources/Prototypes/Entities/Clothing/Ears/headsets.yml
📜 Review details
⏰ Context from checks skipped due to timeout. (5)
- GitHub Check: Test Packaging
- GitHub Check: YAML Linter
- GitHub Check: YAML map schema validator
- GitHub Check: build (ubuntu-latest)
- GitHub Check: build (ubuntu-latest)
🧰 Additional context used
📓 Path-based instructions (10)
Resources/**/*.{yml,ftl,json}
📄 CodeRabbit inference engine (.cursor/rules/ss14-resources.mdc)
Resources/**/*.{yml,ftl,json}: Follow SS14 naming conventions when editing prototype, localization, and resource files
Follow SS14 upstream maintenance practices when editing resource files
Files:
Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
Resources/**/*.yml
📄 CodeRabbit inference engine (.cursor/rules/ss14-resources.mdc)
Resources/**/*.yml: Follow SS14 ECS prototype patterns and conventions
Follow SS14 graphics generic visualizer appearance conventions and patterns
Resources/**/*.yml: Loadss14-naming-conventionsdocumentation for Resources work
Loadss14-ecs-prototypesdocumentation for Resources work
Loadss14-upstream-maintenancedocumentation for Resources work
Loadss14-prototypes-localedocumentation for Resources work
Loadss14-localization-stringsdocumentation for Resources work
Loadss14-sprite-overlays-shadersdocumentation when working with RSI metadata, textures, sprite layers, overlays, or shader resources
Validate YAML after editsRun
dotnet run --project Content.YAMLLinter/Content.YAMLLinter.csproj -c DebugOptto validate YAML and resource edits.
Files:
Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
Resources/**/*.{yml,ftl}
📄 CodeRabbit inference engine (.cursor/rules/ss14-resources.mdc)
Follow SS14 prototype locale integration rules and practices
Files:
Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
**/*.{cs,xaml,yml,yaml}
📄 CodeRabbit inference engine (AGENTS.md)
If the task adds tests or you need to choose the right test layer, load skill
ss14-tests-authoring.
Files:
Resources/Prototypes/Entities/Clothing/Ears/headsets.ymlContent.Server/Radio/EntitySystems/HeadsetSystem.cs
Resources/Prototypes/**/*.yml
📄 CodeRabbit inference engine (AGENTS.md)
Resources/Prototypes/**/*.yml: Put prototypes under the most specific existing subtree inResources/Prototypes/. If you introduce a new prototype parent tree, put parent prototypes inbase.ymland variants in sibling files.
Keep entity prototype field order astype,abstract,parent,id,categories,name,suffix,description,components. Do not insert blank lines between- type:entries inside acomponents:list. Separate prototype blocks with one blank line.
Prefersuffixfor spawn-menu distinctions instead of changing prototypename.
Files:
Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
⚙️ CodeRabbit configuration file
Resources/Prototypes/**/*.yml: Review SS14 prototypes carefully:
- Use the narrowest existing subtree and avoid duplicating nearby prototype files or parent trees.
- Keep entity field order as: type, abstract, parent, id, categories, name, suffix, description, components.
- Prefer base.yml for parent trees and sibling files for variants.
- Do not add blank lines inside components lists.
- Call out broken inheritance, risky prototype ID changes, missing paired locale updates, and Appearance / GenericVisualizer mismatches.
Files:
Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
**/*.cs
📄 CodeRabbit inference engine (GEMINI.md)
**/*.cs: Keep components data-only and behavior in systems
UseOn... -> Try... -> Can... -> Do...pattern for gameplay actions
PreferEntity<T?>,ProtoId<T>,EntProtoId, and localized strings for type usage
**/*.cs: When writing or editing C# gameplay code, load skills:ss14-ecs-components,ss14-ecs-entities,ss14-ecs-prototypes,ss14-ecs-systems,ss14-events, andss14-prediction.
If the C# change is large or the task needs reviewable notes, load skillss14-documentation-writing.
If the code touches hot paths,Update(), or frequently raised events, load skillss14-standard-optimizations.
If the task adds or changes player-facing text, load skillsss14-localization-stringsandss14-localization-codewhen the change also touchesLoc.GetString(...),LocId, popup text, or localized component fields.
If the task touches network events,NetEntity, replicated state routing, or shared/server/client message flow, load skillss14-netcode.
If the task touchesAppearance,GenericVisualizer, visual state enums, or sprite-layer toggles, load skillss14-graphics-generic-visualizer-appearance.
If the task touches sprites, RSI metadata, overlays, shaders, or custom client visual effects, load skillss14-sprite-overlays-shaders.
If the task is about learning or explaining SS14 architecture, first features, or where code belongs, load skillsss14-prototype-basics,ss14-ecs-basics, andss14-client-server-shared.
If the task is about bug hunting, VV, logs, breakpoints, or runtime inspection, load skillsss14-debugging-workflowandss14-common-api-patterns.
If the task touches common gameplay helpers such as entity-system methods, spawning, prototypes, audio, popups, or random, load skillsss14-common-api-patternsandss14-audiowhen the work changes audio routing, sound assets, sound collections, or predicted sound feedback.
If the task ports code or assets from another repository, or needs license or attribution guidance,...
Files:
Content.Server/Radio/EntitySystems/HeadsetSystem.cs
+(Content.Shared|Content.Server|Content.Client|Content.Goobstation.Shared|Content.Goobstation.Server|Content.Goobstation.Client|Content.Goobstation.Common|Content.Goobstation.Maths|Content.Goobstation.UIKit|Content.Server.Database|Content.Shared.Database|Content.Tests|Content.IntegrationTests)/**/*.cs
📄 CodeRabbit inference engine (.cursor/rules/ss14-csharp.mdc)
+(Content.Shared|Content.Server|Content.Client|Content.Goobstation.Shared|Content.Goobstation.Server|Content.Goobstation.Client|Content.Goobstation.Common|Content.Goobstation.Maths|Content.Goobstation.UIKit|Content.Server.Database|Content.Shared.Database|Content.Tests|Content.IntegrationTests)/**/*.cs: Apply C# ECS style rules from ss14-interaction-flow.md
Apply ss14-csharp-style.md rules for C# code formatting and conventions
Follow ss14-naming-conventions for variable, method, and type naming in C# gameplay code
Files:
Content.Server/Radio/EntitySystems/HeadsetSystem.cs
{Content.Server,Content.Goobstation.Server}/**/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
Put main server-only authority and non-predicted server simulation in
Content.Server/; useContent.Goobstation.Server/for features already rooted in that module.
Files:
Content.Server/Radio/EntitySystems/HeadsetSystem.cs
**/*System.cs
📄 CodeRabbit inference engine (AGENTS.md)
Public entity-system APIs that operate on entities should usually take
Entity<T?>orEntityUidfirst and callResolve(...)early.
Files:
Content.Server/Radio/EntitySystems/HeadsetSystem.cs
Content.Server/**/*.cs
⚙️ CodeRabbit configuration file
Content.Server/**/*.cs: Review Content.Server for authority and fork-maintenance discipline:
- Server owns authority, persistence, round logic, and non-predicted side effects.
- If a player action should feel immediate, call out missing shared prediction rather than accepting a server-only path.
- Keep upstream diffs narrow and prefer fork-scoped extensions over broad edits to upstream behavior.
- When player-visible behavior changes, check whether matching prototype and locale updates are missing.
Files:
Content.Server/Radio/EntitySystems/HeadsetSystem.cs
🧠 Learnings (11)
📚 Learning: 2026-06-28T12:10:10.819Z
Learnt from: MataVsn
Repo: ArcaneSS14/arcane-station PR: 96
File: Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml:170-174
Timestamp: 2026-06-28T12:10:10.819Z
Learning: В YAML-прототипах для компонента `HideLayerClothing` предпочитайте поле `layers:` вместо устаревшего `slots:`. Из-за того, что в `FoldableClothingSystem.OnMapInit` перезаписывается `Slots`, наличие `slots: []` может стать артефактом и приводить к падениям/ложным срабатываниям проверок (например, `UninitializedSaveTest`). Использование `layers` не затрагивается этой перезаписью и безопаснее для существующих проверок.
Applied to files:
Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
📚 Learning: 2026-06-29T05:34:31.137Z
Learnt from: Alazell
Repo: ArcaneSS14/arcane-station PR: 99
File: Resources/Prototypes/Entities/Clothing/Belt/belts.yml:973-974
Timestamp: 2026-06-29T05:34:31.137Z
Learning: В SS14 YAML-прототипах для компонента `Storage` поле `grid` задаёт **включительные** координаты прямоугольника. При подсчёте вместимости учитывайте оффсет-инклюзивность: прямоугольник `x1,y1,x2,y2` означает размеры `width = (x2 - x1 + 1)` и `height = (y2 - y1 + 1)`, а число ячеек `width * height`. Например, `0,0,0,0` = 1 ячейка, а `0,0,6,2` = (6-0+1)*(2-0+1)=7*3=21. При ревью файлов наподобие `Resources/Prototypes/Entities/Clothing/Belt/belts.yml` не интерпретируйте `x2/y2` как эксклюзивные (чтобы не ошибиться на 1 в ширине/высоте).
Applied to files:
Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
📚 Learning: 2026-07-29T08:12:37.068Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane PR: 153
File: Resources/Prototypes/_Orion/Entities/Objects/Tools/energy_dome.yml:137-137
Timestamp: 2026-07-29T08:12:37.068Z
Learning: In ArcaneSS14 prototype YAMLs, the YAML field that disables synchronization for `Content.Shared.Power.Components.BatteryComponent` is spelled exactly `netsync` (all lowercase), not `netSync`. For prototypes derived from `PowerNetworkBattery` (including `BaseAPC`, `CoreSubstation`, `BaseSMES`, `TeslaCoil`), set `netsync: false`; otherwise `Content.Server.Power.EntitySystems.BatterySystem.OnStartup` can throw `DebugAssertException` for a predicted battery connected to a power net. For `Resources/Prototypes/_Orion/Entities/Objects/Tools/energy_dome.yml`, ensure `EnergyDomeWiredTest` uses `netsync: false`.
Applied to files:
Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
📚 Learning: 2026-07-07T17:55:50.395Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane-old PR: 101
File: Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs:192-194
Timestamp: 2026-07-07T17:55:50.395Z
Learning: When reviewing ArcaneSS14/arcane-old changes related to `MobState` thresholds/visuals/actions, treat the `Critical` enum value as requiring explicit mappings (it no longer implicitly behaves as an alias of `SoftCritical`). If any YAML prototype `thresholds:` (for `MobThresholdsComponent.Thresholds`) uses the bare `Critical` key (e.g., `MobThresholdsComponent.Thresholds: { Critical: ... }` for entities like `MobMouseCancer`), ensure the prototype (or referenced config) provides corresponding explicit `StateAlertDict` entries and any required `MobStateActions.actions` and `DamageStateVisuals.states` mappings for `Critical`. Otherwise, review should expect failures because the default `StateAlertDict` in `MobThresholdsComponent.cs` typically maps only `Alive`, `SoftCritical`, `HardCritical`, and `Dead`—not `Critical`.
Applied to files:
Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
📚 Learning: 2026-07-28T15:44:38.498Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane PR: 152
File: Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/pistol.yml:69-72
Timestamp: 2026-07-28T15:44:38.498Z
Learning: В ArcaneSS14/arcane не выполняйте форматирующие перестановки полей (в т.ч. изменение порядка полей) в upstream-файлах: делайте это только если правка добавляет Arcane-специфичную сущность или напрямую требуется для функциональности. Иначе сохраняйте upstream-порядок полей, даже если он противоречит локальным рекомендациям, чтобы не создавать лишние diff и конфликты при upstream-синхронизации. Исключение: допустимо переупорядочивание/форматирование в `Resources/Prototypes/_Arcane` (и только там).
Applied to files:
Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
📚 Learning: 2026-06-04T21:17:36.815Z
Learnt from: MataVsn
Repo: ArcaneSS14/arcane-station PR: 31
File: Content.Client/Fluids/PuddleSystem.cs:41-41
Timestamp: 2026-06-04T21:17:36.815Z
Learning: In this repo (ArcaneSS14/arcane-station), reviewers should use the Arcane inline fork-edit marker naming for single-line edits outside `_Arcane` paths: prefer `// Arcane` or `// Arcane-edit` and do not use `// Orion` for this purpose. Repo-specific AGENTS guidance that mentions `// Orion` does not apply to these single-line changes; only `_Arcane` paths follow the applicable different convention.
Applied to files:
Content.Server/Radio/EntitySystems/HeadsetSystem.cs
📚 Learning: 2026-06-28T19:37:26.732Z
Learnt from: MataVsn
Repo: ArcaneSS14/arcane-station PR: 96
File: Content.Client/IoC/ClientContentIoC.cs:151-151
Timestamp: 2026-06-28T19:37:26.732Z
Learning: For ArcaneSS14/arcane-station C# files whose path is outside any `_Arcane` directories, avoid adding an inline fork marker (e.g., `// Arcane` or `// Arcane-edit`) to `using` directives when the imported namespace already clearly indicates the `_Arcane` fork. For example, if the `using` namespace itself contains `_Arcane` (such as `using Content.Client._Arcane.ERP.Preferences;`), the `// Arcane`/`// Arcane-edit` marker is unnecessary.
Applied to files:
Content.Server/Radio/EntitySystems/HeadsetSystem.cs
📚 Learning: 2026-07-04T03:37:47.373Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane-station PR: 101
File: Content.Goobstation.Server/Chemistry/EntitySystems/EnergyReagentDispenserSystem.cs:59-59
Timestamp: 2026-07-04T03:37:47.373Z
Learning: In ArcaneSS14/arcane-station, C# source files must never have fork-edit markers (e.g., comments like `// Arcane`, `// Arcane-edit`, `// Orion`) on `using` directives. During code review, do not flag existing markers on any `using` line and do not suggest adding/removing them based on `_Arcane` folder placement or whether the imported namespace contains `_Arcane`—this rule applies universally to all `using` statements.
Applied to files:
Content.Server/Radio/EntitySystems/HeadsetSystem.cs
📚 Learning: 2026-07-28T16:30:37.419Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane PR: 133
File: Content.Server/Speech/EntitySystems/StutteringSystem.cs:28-29
Timestamp: 2026-07-28T16:30:37.419Z
Learning: При внесении одиночных fork-правок в репозитории ArcaneSS14/arcane вне путей `_Arcane` добавляйте в конец каждой изменённой строки комментарий-маркер `// Arcane-Edit`. Это нужно для упрощения последующего поиска/обновления подобных правок при код-ревью и синхронизациях.
Applied to files:
Content.Server/Radio/EntitySystems/HeadsetSystem.cs
📚 Learning: 2026-07-01T17:19:52.100Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane-station PR: 101
File: Content.Shared/Mobs/MobState.cs:0-0
Timestamp: 2026-07-01T17:19:52.100Z
Learning: When reviewing ArcaneSS14/arcane-station C# code, ensure all usages of the `MobState` enum (`MobState.Dead`, `MobState.SoftCritical`, `MobState.HardCritical`, `MobState.Critical`) reference the enum members symbolically rather than via hardcoded numeric literals or casts from numeric values (e.g., avoid patterns like `(MobState)4` or `MobState` comparisons to `byte`/`int` literals). Treat direct numeric usage as a code-level dependency that should be flagged. Also avoid persisting `MobState` numeric values in `Content.Server.Database` or `Content.Replay`; if persistence/replay of the raw byte value is introduced, renumbering the `[NetSerializable] MobState : byte` enum becomes a data-compatibility risk. Renumbering the enum is compile-safe as long as there are no numeric literal dependencies, but the remaining risk is network wire-protocol mismatch if mixed old/new client-server builds are running during a rolling update—coordinate deployment to maintain net compatibility.
Applied to files:
Content.Server/Radio/EntitySystems/HeadsetSystem.cs
📚 Learning: 2026-07-03T18:41:44.286Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane-station PR: 101
File: Content.Shared/_Orion/EntityEffects/Effects/Special/ChemConvermol.cs:0-0
Timestamp: 2026-07-03T18:41:44.286Z
Learning: In ArcaneSS14/arcane-station, the hardcoded 1.2f base used by RefreshPartsEvent.GetLinearMultiplier(tier, step, min, max) (Math.Clamp(1.2f - tier * step, min, max)) is an intentional repo-wide balance convention: callers typically pass max: 1.2f, so a tier-1 part yields a 10% penalty (e.g., GetLinearMultiplier(tier: 1, step: 0.1f, min: 0.5f, max: 1.2f) => 1.1), while tier-2 is the neutral baseline. Do not flag the hardcoded 1.2f as a bug when reviewing shared multiplier/linear scaling usage. If a specific system needs a tier-1 baseline that produces 0% penalty instead, implement a locally-scoped formula in that system (e.g., adjust the constant to match the desired neutral baseline) rather than changing the shared helper, since modifying it would affect all callers’ balance.
Applied to files:
Content.Server/Radio/EntitySystems/HeadsetSystem.cs
🔇 Additional comments (6)
Resources/Prototypes/Entities/Clothing/Ears/headsets.yml (1)
24-28: LGTM!Content.Server/Radio/EntitySystems/HeadsetSystem.cs (5)
6-14: LGTM!Also applies to: 26-28
61-73: LGTM!
90-109: LGTM!
183-206: LGTM!
247-250: 🎯 Functional CorrectnessОставьте предупреждение как есть.
Текущие радиоканалы не используют
SoundCollectionSpecifierвonSendSound, поэтому этот путь не блокирует ни одну существующую радиопередачу.
| SubscribeLocalEvent<ActorComponent, EntitySpokeEvent>(OnEntitySpoke); // Orion-Edit | ||
| SubscribeLocalEvent<InventoryComponent, ExaminedEvent>(OnInventoryExamined); // Orion |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Не ограничивайте передачу радио ActorComponent.
ActorComponent есть только у сущностей с игровой сессией. Говорящие NPC и другие сущности без этого компонента больше не вызовут OnEntitySpoke, хотя прежний обработчик работал через WearingHeadsetComponent.
Подпишитесь на InventoryComponent. Сущность с экипированной гарнитурой уже имеет инвентарь.
Предлагаемое исправление
- SubscribeLocalEvent<ActorComponent, EntitySpokeEvent>(OnEntitySpoke);
+ SubscribeLocalEvent<InventoryComponent, EntitySpokeEvent>(OnEntitySpoke);
- private void OnEntitySpoke(EntityUid uid, ActorComponent component, EntitySpokeEvent args)
+ private void OnEntitySpoke(EntityUid uid, InventoryComponent component, EntitySpokeEvent args)Also applies to: 142-142
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Content.Server/Radio/EntitySystems/HeadsetSystem.cs` around lines 36 - 37,
Update the OnEntitySpoke event subscription in HeadsetSystem to use
InventoryComponent instead of ActorComponent, so speaking entities with an
equipped headset are handled regardless of whether they have a game session.
Preserve the existing OnEntitySpoke behavior and the OnInventoryExamined
subscription.
| RaiseNetworkEvent(new PlayRadioBarkEvent | ||
| { | ||
| Path = sps.Path.ToString(), | ||
| Params = sps.Params, | ||
| }, actor.PlayerSession.Channel); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Найти создание и обработчики сетевого события.
ast-grep run --lang csharp \
--pattern 'new PlayRadioBarkEvent { $$$ }' \
Content.Server Content.Shared Content.Client
rg -n -C 6 --glob '*.cs' \
'\bPlayRadioBarkEvent\b|Subscribe.*PlayRadioBark|Raise.*PlayRadioBark' .Repository: ArcaneSS14/arcane
Length of output: 5282
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== HeadsetSystem context =="
sed -n '200,270p' Content.Server/Radio/EntitySystems/HeadsetSystem.cs
echo
echo "== PlayRadioBarkEvent =="
cat -n Content.Shared/_Orion/Radio/PlayRadioBarkEvent.cs
echo
echo "== Client handler context =="
sed -n '1,60p' Content.Client/_Orion/Radio/RadioBarkAudioSystem.cs
echo
echo "== Nearby PlayGlobal/PlayFiltered patterns =="
rg -n --glob '*.cs' '\bPlay(Filtered|Global|Entity)\(' Content.Client/_Orion/Radio Content.Shared/_Orion Content.Server/Radio Content.Client Content.Shared Content.Server | head -120Repository: ArcaneSS14/arcane
Length of output: 17926
Передавайте Source в PlayRadioBarkEvent.
Создание сетевого события не задаёт Source, поэтому клиент получает default NetEntity. На текущий момент OnPlayRadioBark() игнорирует ev.Source и вызывает PlayGlobal(..., Filter.Local(), ...), поэтому звук не привязывается к говорящему. Передайте Source: parent сервером и игнорируйте лишнее исправление на клиенте.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Content.Server/Radio/EntitySystems/HeadsetSystem.cs` around lines 241 - 245,
Update the PlayRadioBarkEvent construction in the headset radio flow to set its
Source field to parent before raising the event, so the client receives the
speaking entity. Do not modify the client-side OnPlayRadioBark handling.
|
@coderabbitai Глянь на причины провала тестов у коммита Roles 3 |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
sha="ca579fba181b0069e8bb7f0cf8253240d441bd2c"
echo "=== Workflow runs for commit ==="
gh api "repos/$repo/actions/runs?head_sha=$sha&per_page=100" \
--jq '.workflow_runs[] | {id, name, event, status, conclusion, run_attempt, created_at, updated_at, html_url}'
echo "=== Pull-request checks for commit ==="
gh pr checks 161 --repo "$repo" --json name,state,link,workflow,bucket 2>/dev/null || true
run_id="$(
gh api "repos/$repo/actions/runs?head_sha=$sha&per_page=100" \
--jq '[.workflow_runs[]
| select(.name == "Build & Test Debug" and .status == "completed")
| {id, created_at}] | sort_by(.created_at) | last.id // empty'
)"
if [ -z "$run_id" ]; then
echo "No completed Build & Test Debug run exists for this commit."
exit 0
fi
echo "=== Jobs for Build & Test Debug run $run_id ==="
gh api "repos/$repo/actions/runs/$run_id/jobs?per_page=100" \
--jq '.jobs[] | {id, name, status, conclusion, started_at, completed_at, steps}'
job_id="$(
gh api "repos/$repo/actions/runs/$run_id/jobs?per_page=100" \
--jq '.jobs[] | select(.name == "build (ubuntu-latest)") | .id' | tail -1
)"
if [ -z "$job_id" ]; then
echo "No build (ubuntu-latest) job exists in this run."
exit 0
fi
log="$(mktemp)"
trap 'rm -f "$log"' EXIT
gh api "repos/$repo/actions/jobs/$job_id/logs" > "$log"
echo "=== First test error and stack trace ==="
rg -n -i -m 1 -B 35 -A 130 \
'Error Message:|Failed [A-Za-z0-9_.]+|Unhandled exception|Exception:|Test Run Aborted|Attempted to resolve invalid ProtoId|Missing prototype|does not exist in RSI|Expected:|But was:' \
"$log" || true
echo "=== All test failure headers ==="
rg -n -i -C 12 \
'^\s*Failed [A-Za-z0-9_.]+|Error Message:|Attempted to resolve invalid ProtoId|Missing prototype|does not exist in RSI|Expected:|But was:|Test Run Aborted|Failed!|Passed!' \
"$log" || true
echo "=== Integration-test summary ==="
rg -n -i -C 8 \
'Run Content\.IntegrationTests|Total tests|Failed!|Passed!|Test Run Aborted|Process completed' \
"$log" || true
echo "=== Relevant current source ==="
for file in \
Content.Shared/Roles/Jobs/SharedJobSystem.cs \
Content.Server/_Orion/Economy/Systems/PayrollSystem.cs \
Content.Server/Radio/EntitySystems/HeadsetSystem.cs \
Content.IntegrationTests/Tests/Minds/MindTests.cs \
Content.IntegrationTests/Tests/PostMapInitTest.cs
do
if [ -f "$file" ]; then
echo "----- $file -----"
rg -n -C 12 \
'MindTryGetJob|TryIndex|GetPayrollData|JobPrototype|TestAddRemoveHasRoles|SpawnPoint|Error' \
"$file" || true
fi
doneLength of output: 129271 🏁 Script executed: #!/bin/bash
set -euo pipefail
sha="ca579fba181b0069e8bb7f0cf8253240d441bd2c"
repo="ArcaneSS14/arcane"
job_id="91234704946"
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
echo "=== All failed test names and pool-abort context ==="
gh api "repos/$repo/actions/jobs/$job_id/logs" > "$tmp/ci.log"
rg -n -i -C 30 \
'Failed [A-Za-z0-9_.]+|`#0`: ResearchTest\.DisciplineValidTierPrerequesitesTest|FailFast|Pool manager|pool.*(error|fail|abort)|Test Run Aborted' \
"$tmp/ci.log" || true
echo "=== Entity 27273 in maps at tested commit ==="
git grep -n -C 18 'uid: 27273' "$sha" -- 'Resources/Maps/**/*.yml' || true
echo "=== DeviceNetwork references near entity 27273 ==="
git grep -n -C 8 '27273' "$sha" -- 'Resources/Maps/**/*.yml' || true
echo "=== consul.yml: Stack components that do not define stackType ==="
git show "$sha:Resources/Maps/_Goobstation/Shuttles/consul.yml" > "$tmp/consul.yml"
python3 - "$tmp/consul.yml" <<'PY'
import re
import sys
text = open(sys.argv[1], encoding="utf-8").read()
blocks = re.split(r'(?m)^- proto: ', text)
for block in blocks[1:]:
proto, _, body = block.partition('\n')
if re.search(r'(?m)^ - type: Stack\s*$', body) and not re.search(r'(?m)^ stackType:\s*\S+', body):
uid = re.search(r'(?m)^ - uid: (\d+)\s*$', body)
print(f"proto={proto}; uid={uid.group(1) if uid else 'unknown'}")
lines = body.splitlines()
for i, line in enumerate(lines):
if line == ' - type: Stack':
print('\n'.join(lines[max(0,i-8):i+12]))
print('---')
PY
echo "=== DeviceLink and DeviceNetwork blocks in consul.yml ==="
rg -n -C 14 'type: (DeviceNetwork|DeviceLinkSource|DeviceLinkSink|Stack)|stackType:|links:|devices:' "$tmp/consul.yml" || true
echo "=== Research and lathe definitions for the first failing recipes at tested commit ==="
for needle in \
'id: Bloodpack' \
'id: SawElectric' \
'id: ClothingNeckStethoscope' \
'id: MedicalEquipment' \
'id: SmartFridgeCircuitboard'
do
echo "--- $needle ---"
git grep -n -C 10 -F "$needle" "$sha" -- 'Resources/Prototypes/**/*.yml' || true
done
echo "=== Changes introduced by Roles 3 commit ==="
git diff --stat "${sha}^" "$sha"
git diff --name-status "${sha}^" "$sha"Length of output: 241864
1.
|
|
@coderabbitai Где рецепты у латов? В каком файле? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Files with lathe recipe definitions ==='
rg -l -g '*.yml' -g '*.yaml' '^\s*- type: latheRecipe\s*$' Resources/Prototypes | sort
echo '=== Files that assign static or dynamic recipes to lathe prototypes ==='
rg -l -g '*.yml' -g '*.yaml' '^\s*(staticRecipes|dynamicRecipes):\s*$' Resources/Prototypes | sort
echo '=== Representative context ==='
rg -n -C 4 -g '*.yml' -g '*.yaml' \
'^\s*- type: latheRecipe\s*$|^\s*(staticRecipes|dynamicRecipes):\s*$' \
Resources/Prototypes | head -220Length of output: 6149 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Definitions of recipe IDs from the CI failure ==='
rg -n -C 8 -g '*.yml' -g '*.yaml' \
'^\s*id:\s*(Bloodpack|SawElectric|ClothingNeckStethoscope|SmartFridgeCircuitboard)\s*$' \
Resources/Prototypes
echo '=== Lathe prototype recipe-list fields ==='
rg -n -i -C 8 -g '*.yml' -g '*.yaml' \
'static.*recipe|dynamic.*recipe|type:\s*Lathe|type:\s*MaterialStorage' \
Resources/Prototypes/Entities Resources/Prototypes/_Orion Resources/Prototypes/DeltaV \
|| trueLength of output: 201041
Сами рецепты определяются через Списки пакетов, доступных конкретному лату, находятся в: Там у компонента staticPacks:
dynamicPacks:Например, То есть при фиксе надо проверить два уровня:
Пакеты рецептов имеют тип You are interacting with an AI system. |
This reverts commit e2bdced.
|
@coderabbitai На консуле всего 32 - type: Stack. Можешь подобрать для каждого вставку? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
map='Resources/Maps/_Goobstation/Shuttles/consul.yml'
echo '=== Map Stack overrides ==='
python3 - "$map" <<'PY'
from pathlib import Path
import re, sys
text = Path(sys.argv[1]).read_text(encoding='utf-8')
for m in re.finditer(r'(?ms)^- proto: ([^\s#]+)\s*\n(.*?)(?=^- proto:|\Z)', text):
proto, body = m.group(1), m.group(2)
stack = re.search(r'(?m)^ - type: Stack\s*\n((?: .*(?:\n|$))*)', body)
if stack:
stack_body = stack.group(1)
uid = re.search(r'(?m)^ - uid: (\d+)\s*$', body)
print(f'proto={proto}\tuid={uid.group(1) if uid else "unknown"}\t'
f'has_stackType={"stackType:" in stack_body}\t'
f'fields={stack_body.strip().replace(chr(10), " | ")}')
PY
echo '=== Prototype definitions and inherited Stack components ==='
rg -n -C 8 \
'^\s*id:\s*(CableApcStack1|CableHVStack1|CableMVStack1|CapacitorStockPart|MatterBinStockPart|MicroManipulatorStockPart|SheetSteel1)\s*$|^\s*stackType:\s*' \
Resources/Prototypes --glob '*.{yml,yaml}' || true
echo '=== All candidate Stack prototype blocks for Consul entity prototypes ==='
python3 - "$map" <<'PY'
from pathlib import Path
import re, sys
map_text = Path(sys.argv[1]).read_text(encoding='utf-8')
protos = []
for m in re.finditer(r'(?ms)^- proto: ([^\s#]+)\s*\n(.*?)(?=^- proto:|\Z)', map_text):
if re.search(r'(?m)^ - type: Stack\s*$', m.group(2)):
protos.append(m.group(1))
print('\n'.join(sorted(set(protos))))
PYLength of output: 202031 🏁 Script executed: #!/bin/bash
set -euo pipefail
map='Resources/Maps/_Goobstation/Shuttles/consul.yml'
targets='CableApcStack1|CableHVStack1|CableMVStack1|CapacitorStockPart|MatterBinStockPart|MicroManipulatorStockPart|SheetSteel1'
echo '=== Все map override Stack: proto, UID, count ==='
python3 - "$map" <<'PY'
from pathlib import Path
import re, sys
text = Path(sys.argv[1]).read_text(encoding="utf-8")
n = 0
for m in re.finditer(r'(?ms)^- proto: ([^\s#]+)\s*\n(.*?)(?=^- proto:|\Z)', text):
proto, body = m.group(1), m.group(2)
stack = re.search(r'(?m)^ - type: Stack\s*\n((?: .*(?:\n|$))*)', body)
if not stack or 'stackType:' in stack.group(1):
continue
uid = re.search(r'(?m)^ - uid: (\d+)\s*$', body)
count = re.search(r'(?m)^ count: (\d+)\s*$', stack.group(1))
n += 1
print(f'{n:02d}. proto={proto}; uid={uid.group(1) if uid else "unknown"}; '
f'count={count.group(1) if count else "default"}')
print(f'TOTAL={n}')
PY
echo '=== Точные объявления этих прототипов ==='
rg -n -A35 -B4 \
"^[[:space:]]*id:[[:space:]]*(${targets})[[:space:]]*$" \
Resources/Prototypes --glob '*.{yml,yaml}' || true
echo '=== Точные родительские цепочки ==='
rg -n -A4 -B3 \
"^[[:space:]]*(id|parent):[[:space:]]*(${targets}|CableStack|CableHVStack|CableMVStack|StockPart|SheetSteel)[[:space:]]*$" \
Resources/Prototypes --glob '*.{yml,yaml}' || trueLength of output: 44475 🏁 Script executed: #!/bin/bash
set -euo pipefail
map='Resources/Maps/_Goobstation/Shuttles/consul.yml'
echo '=== Все Stack override по UID ==='
python3 - "$map" <<'PY'
from pathlib import Path
import re, sys
text = Path(sys.argv[1]).read_text(encoding="utf-8")
rows = []
# Map format: a proto block contains one or more " - uid:" entity instances.
for proto_match in re.finditer(r'(?ms)^- proto: ([^\s#]+)\s*\n(.*?)(?=^- proto:|\Z)', text):
proto, proto_body = proto_match.group(1), proto_match.group(2)
for entity_match in re.finditer(r'(?ms)^ - uid: (\d+)\s*\n(.*?)(?=^ - uid:|\Z)', proto_body):
uid, entity_body = entity_match.group(1), entity_match.group(2)
stack = re.search(r'(?m)^ - type: Stack\s*\n((?: .*(?:\n|$))*)', entity_body)
if not stack:
continue
stack_body = stack.group(1)
if re.search(r'(?m)^ stackType:', stack_body):
continue
count = re.search(r'(?m)^ count: ([^\s#]+)', stack_body)
rows.append((proto, uid, count.group(1) if count else 'default'))
for index, (proto, uid, count) in enumerate(rows, 1):
print(f'{index:02d}. proto={proto}; uid={uid}; count={count}')
print(f'TOTAL={len(rows)}')
PY
echo '=== Базовые Stack-компоненты для оставшихся типов ==='
rg -n -A38 -B3 \
'^\s*id:\s*(CableStack|CableApcStack|BaseStockPart|MicroManipulatorStockPart)\s*$' \
Resources/Prototypes --glob '*.{yml,yaml}' || true
echo '=== Все stackType в cable_coils.yml и machines_parts.yml ==='
rg -n -C2 '^\s*stackType:\s*' \
Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml \
Resources/Prototypes/_Orion/Entities/Objects/Misc/machines_parts.yml \
2>/dev/null || trueLength of output: 21806 🏁 Script executed: #!/bin/bash
set -euo pipefail
map='Resources/Maps/_Goobstation/Shuttles/consul.yml'
python3 - "$map" <<'PY'
from pathlib import Path
import re, sys
path = Path(sys.argv[1])
text = path.read_text(encoding="utf-8")
stack_types = {
"CableApcStack1": "Cable",
"CableHVStack1": "CableHV",
"CableMVStack1": "CableMV",
"SheetSteel1": "Steel",
}
remove_stack = {
"CapacitorStockPart",
"MatterBinStockPart",
"MicroManipulatorStockPart",
}
out = []
pos = 0
changes = []
for proto_match in re.finditer(r'(?ms)^- proto: ([^\s#]+)\s*\n(.*?)(?=^- proto:|\Z)', text):
proto, proto_body = proto_match.group(1), proto_match.group(2)
block_start = proto_match.start(2)
for entity_match in re.finditer(r'(?ms)^ - uid: (\d+)\s*\n(.*?)(?=^ - uid:|\Z)', proto_body):
uid, entity_body = entity_match.group(1), entity_match.group(2)
entity_start = block_start + entity_match.start(2)
stack = re.search(r'(?m)^ - type: Stack\s*\n((?: .*(?:\n|$))*)', entity_body)
if not stack or re.search(r'(?m)^ stackType:', stack.group(1)):
continue
absolute_start = entity_start + stack.start()
absolute_end = entity_start + stack.end()
original = text[absolute_start:absolute_end]
if proto in remove_stack:
replacement = ""
action = "remove"
elif proto in stack_types:
replacement = original.replace(
" - type: Stack\n",
f" - type: Stack\n stackType: {stack_types[proto]}\n",
1,
)
action = f"add stackType: {stack_types[proto]}"
else:
raise SystemExit(f"Unhandled prototype: {proto}, uid={uid}")
changes.append((absolute_start, absolute_end, replacement, proto, uid, action))
for start, end, replacement, *_ in sorted(changes, reverse=True):
text = text[:start] + replacement + text[end:]
print("=== Изменения ===")
for _, _, _, proto, uid, action in changes:
print(f"uid {uid}: {proto} -> {action}")
print(f"TOTAL={len(changes)}")
print("\n=== Полный diff ===")
import difflib
original = path.read_text(encoding="utf-8").splitlines(keepends=True)
modified = text.splitlines(keepends=True)
print("".join(difflib.unified_diff(
original, modified,
fromfile=str(path),
tofile=str(path),
)))
print("=== Проверка результата ===")
missing = 0
for proto_match in re.finditer(r'(?ms)^- proto: ([^\s#]+)\s*\n(.*?)(?=^- proto:|\Z)', text):
proto, proto_body = proto_match.group(1), proto_match.group(2)
for entity_match in re.finditer(r'(?ms)^ - uid: (\d+)\s*\n(.*?)(?=^ - uid:|\Z)', proto_body):
uid, entity_body = entity_match.group(1), entity_match.group(2)
stack = re.search(r'(?m)^ - type: Stack\s*\n((?: .*(?:\n|$))*)', entity_body)
if stack and not re.search(r'(?m)^ stackType:', stack.group(1)):
missing += 1
print(f"MISSING stackType: proto={proto}; uid={uid}")
print(f"Stack components without stackType after patch: {missing}")
PY
echo '=== Stock part definitions: Stack должен отсутствовать ==='
rg -n -A34 -B3 \
'^\s*id:\s*(BaseStockPart|CapacitorStockPart|MatterBinStockPart|MicroManipulatorStockPart)\s*$|^\s*#.*type: Stack' \
Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml \
Resources/Prototypes/_Orion/Entities/Objects/Misc/machines_parts.yml \
2>/dev/null || trueLength of output: 22413
Добавить
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Resources/Maps/_Goobstation/Shuttles/consul.yml (1)
3286-3324: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winИсправьте скопированное значение
stackType: Cable.Один тип стека не подходит для разных материалов. Неверный тип нарушает stacking и взаимодействия с объектами карты.
Resources/Maps/_Goobstation/Shuttles/consul.yml#L3286-L3324: заменитеCableнаCableHV.Resources/Maps/_Goobstation/Shuttles/consul.yml#L3667-L3705: заменитеCableнаCableMV.Resources/Maps/_Goobstation/Shuttles/consul.yml#L10878-L11087: заменитеCableнаSteelили удалите override, если тип уже задан базовым prototype.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Resources/Maps/_Goobstation/Shuttles/consul.yml` around lines 3286 - 3324, Исправьте скопированные значения stackType в Resources/Maps/_Goobstation/Shuttles/consul.yml: в диапазоне 3286-3324 замените Cable на CableHV, в диапазоне 3667-3705 замените Cable на CableMV, а в диапазоне 10878-11087 замените Cable на Steel либо удалите override, если тип уже задан базовым prototype.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@Resources/Maps/_Goobstation/Shuttles/consul.yml`:
- Around line 3286-3324: Исправьте скопированные значения stackType в
Resources/Maps/_Goobstation/Shuttles/consul.yml: в диапазоне 3286-3324 замените
Cable на CableHV, в диапазоне 3667-3705 замените Cable на CableMV, а в диапазоне
10878-11087 замените Cable на Steel либо удалите override, если тип уже задан
базовым prototype.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: cdd151a5-4549-476e-a230-98d1b9739fc0
📒 Files selected for processing (3)
Resources/Maps/_Goobstation/Shuttles/consul.ymlResources/Maps/_Goobstation/box.ymlResources/Prototypes/Entities/Structures/Machines/lathe.yml
💤 Files with no reviewable changes (1)
- Resources/Maps/_Goobstation/box.yml
📜 Review details
⏰ Context from checks skipped due to timeout. (5)
- GitHub Check: build (ubuntu-latest)
- GitHub Check: YAML Linter
- GitHub Check: Test Packaging
- GitHub Check: build (ubuntu-latest)
- GitHub Check: YAML map schema validator
🧰 Additional context used
📓 Path-based instructions (5)
Resources/**/*.{yml,ftl,json}
📄 CodeRabbit inference engine (.cursor/rules/ss14-resources.mdc)
Resources/**/*.{yml,ftl,json}: Follow SS14 naming conventions when editing prototype, localization, and resource files
Follow SS14 upstream maintenance practices when editing resource files
Files:
Resources/Maps/_Goobstation/Shuttles/consul.ymlResources/Prototypes/Entities/Structures/Machines/lathe.yml
Resources/**/*.yml
📄 CodeRabbit inference engine (.cursor/rules/ss14-resources.mdc)
Resources/**/*.yml: Follow SS14 ECS prototype patterns and conventions
Follow SS14 graphics generic visualizer appearance conventions and patterns
Resources/**/*.yml: Loadss14-naming-conventionsdocumentation for Resources work
Loadss14-ecs-prototypesdocumentation for Resources work
Loadss14-upstream-maintenancedocumentation for Resources work
Loadss14-prototypes-localedocumentation for Resources work
Loadss14-localization-stringsdocumentation for Resources work
Loadss14-sprite-overlays-shadersdocumentation when working with RSI metadata, textures, sprite layers, overlays, or shader resources
Validate YAML after editsRun
dotnet run --project Content.YAMLLinter/Content.YAMLLinter.csproj -c DebugOptto validate YAML and resource edits.
Files:
Resources/Maps/_Goobstation/Shuttles/consul.ymlResources/Prototypes/Entities/Structures/Machines/lathe.yml
Resources/**/*.{yml,ftl}
📄 CodeRabbit inference engine (.cursor/rules/ss14-resources.mdc)
Follow SS14 prototype locale integration rules and practices
Files:
Resources/Maps/_Goobstation/Shuttles/consul.ymlResources/Prototypes/Entities/Structures/Machines/lathe.yml
**/*.{cs,xaml,yml,yaml}
📄 CodeRabbit inference engine (AGENTS.md)
If the task adds tests or you need to choose the right test layer, load skill
ss14-tests-authoring.
Files:
Resources/Maps/_Goobstation/Shuttles/consul.ymlResources/Prototypes/Entities/Structures/Machines/lathe.yml
Resources/Prototypes/**/*.yml
📄 CodeRabbit inference engine (AGENTS.md)
Resources/Prototypes/**/*.yml: Put prototypes under the most specific existing subtree inResources/Prototypes/. If you introduce a new prototype parent tree, put parent prototypes inbase.ymland variants in sibling files.
Keep entity prototype field order astype,abstract,parent,id,categories,name,suffix,description,components. Do not insert blank lines between- type:entries inside acomponents:list. Separate prototype blocks with one blank line.
Prefersuffixfor spawn-menu distinctions instead of changing prototypename.
Files:
Resources/Prototypes/Entities/Structures/Machines/lathe.yml
⚙️ CodeRabbit configuration file
Resources/Prototypes/**/*.yml: Review SS14 prototypes carefully:
- Use the narrowest existing subtree and avoid duplicating nearby prototype files or parent trees.
- Keep entity field order as: type, abstract, parent, id, categories, name, suffix, description, components.
- Prefer base.yml for parent trees and sibling files for variants.
- Do not add blank lines inside components lists.
- Call out broken inheritance, risky prototype ID changes, missing paired locale updates, and Appearance / GenericVisualizer mismatches.
Files:
Resources/Prototypes/Entities/Structures/Machines/lathe.yml
🧠 Learnings (4)
📚 Learning: 2026-07-07T17:55:50.395Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane-old PR: 101
File: Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs:192-194
Timestamp: 2026-07-07T17:55:50.395Z
Learning: When reviewing ArcaneSS14/arcane-old changes related to `MobState` thresholds/visuals/actions, treat the `Critical` enum value as requiring explicit mappings (it no longer implicitly behaves as an alias of `SoftCritical`). If any YAML prototype `thresholds:` (for `MobThresholdsComponent.Thresholds`) uses the bare `Critical` key (e.g., `MobThresholdsComponent.Thresholds: { Critical: ... }` for entities like `MobMouseCancer`), ensure the prototype (or referenced config) provides corresponding explicit `StateAlertDict` entries and any required `MobStateActions.actions` and `DamageStateVisuals.states` mappings for `Critical`. Otherwise, review should expect failures because the default `StateAlertDict` in `MobThresholdsComponent.cs` typically maps only `Alive`, `SoftCritical`, `HardCritical`, and `Dead`—not `Critical`.
Applied to files:
Resources/Maps/_Goobstation/Shuttles/consul.ymlResources/Prototypes/Entities/Structures/Machines/lathe.yml
📚 Learning: 2026-07-28T15:44:38.498Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane PR: 152
File: Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/pistol.yml:69-72
Timestamp: 2026-07-28T15:44:38.498Z
Learning: В ArcaneSS14/arcane не выполняйте форматирующие перестановки полей (в т.ч. изменение порядка полей) в upstream-файлах: делайте это только если правка добавляет Arcane-специфичную сущность или напрямую требуется для функциональности. Иначе сохраняйте upstream-порядок полей, даже если он противоречит локальным рекомендациям, чтобы не создавать лишние diff и конфликты при upstream-синхронизации. Исключение: допустимо переупорядочивание/форматирование в `Resources/Prototypes/_Arcane` (и только там).
Applied to files:
Resources/Maps/_Goobstation/Shuttles/consul.ymlResources/Prototypes/Entities/Structures/Machines/lathe.yml
📚 Learning: 2026-06-29T05:34:31.137Z
Learnt from: Alazell
Repo: ArcaneSS14/arcane-station PR: 99
File: Resources/Prototypes/Entities/Clothing/Belt/belts.yml:973-974
Timestamp: 2026-06-29T05:34:31.137Z
Learning: В SS14 YAML-прототипах для компонента `Storage` поле `grid` задаёт **включительные** координаты прямоугольника. При подсчёте вместимости учитывайте оффсет-инклюзивность: прямоугольник `x1,y1,x2,y2` означает размеры `width = (x2 - x1 + 1)` и `height = (y2 - y1 + 1)`, а число ячеек `width * height`. Например, `0,0,0,0` = 1 ячейка, а `0,0,6,2` = (6-0+1)*(2-0+1)=7*3=21. При ревью файлов наподобие `Resources/Prototypes/Entities/Clothing/Belt/belts.yml` не интерпретируйте `x2/y2` как эксклюзивные (чтобы не ошибиться на 1 в ширине/высоте).
Applied to files:
Resources/Prototypes/Entities/Structures/Machines/lathe.yml
📚 Learning: 2026-07-29T08:12:37.068Z
Learnt from: UmbiMax
Repo: ArcaneSS14/arcane PR: 153
File: Resources/Prototypes/_Orion/Entities/Objects/Tools/energy_dome.yml:137-137
Timestamp: 2026-07-29T08:12:37.068Z
Learning: In ArcaneSS14 prototype YAMLs, the YAML field that disables synchronization for `Content.Shared.Power.Components.BatteryComponent` is spelled exactly `netsync` (all lowercase), not `netSync`. For prototypes derived from `PowerNetworkBattery` (including `BaseAPC`, `CoreSubstation`, `BaseSMES`, `TeslaCoil`), set `netsync: false`; otherwise `Content.Server.Power.EntitySystems.BatterySystem.OnStartup` can throw `DebugAssertException` for a predicted battery connected to a power net. For `Resources/Prototypes/_Orion/Entities/Objects/Tools/energy_dome.yml`, ensure `EnergyDomeWiredTest` uses `netsync: false`.
Applied to files:
Resources/Prototypes/Entities/Structures/Machines/lathe.yml
🔇 Additional comments (4)
Resources/Prototypes/Entities/Structures/Machines/lathe.yml (2)
116-116: 🗄️ Data Integrity & IntegrationПроверьте слияние
MaterialStorageв итоговых прототипах.
BaseSiloUtilizerдобавляетMaterialStorage.connectToSilo: true, но каждый изменённый prototype повторно объявляетMaterialStorage. Если наследование заменяет компонент целиком, новые машины не подключатся к silo, несмотря на добавленный parent.Проверьте resolved-прототипы для всех десяти сущностей. В каждом должны сохраниться
SiloUtilizer,DeviceNetwork,DeviceLinkSinkиconnectToSilo: true. Контракт определён вResources/Prototypes/_Goobstation/Entities/Structures/Machines/material_silo.yml, Lines 43-57.Also applies to: 211-211, 291-291, 361-361, 469-469, 539-539, 575-575, 651-651, 748-748, 847-847
116-116: 🗄️ Data Integrity & IntegrationЗапустите обязательную проверку YAML.
Перед слиянием выполните
dotnet run --project Content.YAMLLinter/Content.YAMLLinter.csproj -c DebugOpt.As per coding guidelines: для изменений в
Resources/**/*.ymlтребуется валидировать YAML и resource-изменения.Also applies to: 211-211, 291-291, 361-361, 469-469, 539-539, 575-575, 651-651, 748-748, 847-847
Source: Coding guidelines
Resources/Maps/_Goobstation/Shuttles/consul.yml (2)
3208-3208: LGTM!Also applies to: 3732-3807, 9777-9788, 9852-9855
3208-11087: 🗄️ Data Integrity & IntegrationЗапустите обязательную проверку YAML.
После исправления
stackTypeвыполнитеdotnet run --project Content.YAMLLinter/Content.YAMLLinter.csproj -c DebugOpt.As per coding guidelines: для изменений в
Resources/**/*.ymlтребуется валидировать YAML и resource-изменения.Source: Coding guidelines
|
@coderabbitai Какие ещё ошибки в тестах и как их фиксить? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
pr="161"
sha="$(gh pr view "$pr" --repo "$repo" --json headRefOid --jq .headRefOid)"
echo "=== PR head ==="
echo "$sha"
echo "=== Checks ==="
gh pr checks "$pr" --repo "$repo" --required=false || true
echo "=== Workflow runs for current head ==="
gh api "repos/$repo/actions/runs?head_sha=$sha&per_page=100" \
--jq '.workflow_runs[] | {id, name, status, conclusion, run_attempt, created_at, updated_at, html_url}'
run_id="$(
gh api "repos/$repo/actions/runs?head_sha=$sha&per_page=100" \
--jq '[.workflow_runs[] | select(.name == "Build & Test Debug" and .status == "completed")]
| sort_by(.created_at) | last.id // empty'
)"
echo "=== Selected Build & Test Debug run ==="
echo "${run_id:-none}"
if [ -n "${run_id:-}" ]; then
echo "=== Jobs ==="
gh api "repos/$repo/actions/runs/$run_id/jobs?per_page=100" \
--jq '.jobs[] | {id, name, status, conclusion, started_at, completed_at}'
job_id="$(
gh api "repos/$repo/actions/runs/$run_id/jobs?per_page=100" \
--jq '.jobs[] | select(.name == "build (ubuntu-latest)") | .id' | tail -1
)"
echo "=== Selected build job ==="
echo "${job_id:-none}"
if [ -n "${job_id:-}" ]; then
log="$(mktemp)"
trap 'rm -f "$log"' EXIT
gh api "repos/$repo/actions/jobs/$job_id/logs" > "$log"
echo "=== First failure ==="
rg -n -i -m 1 -B 30 -A 120 \
'Error Message:|^\s*Failed [A-Za-z0-9_.]+|Unhandled exception|Exception:|Test Run Aborted|FailFast|Missing prototype|does not exist in RSI|Expected:|But was:' \
"$log" || true
echo "=== Failure headers and summaries ==="
rg -n -i -C 12 \
'^\s*Failed [A-Za-z0-9_.]+|Error Message:|Test Run Aborted|FailFast|Failed!|Passed!|Total tests|Run Content\.IntegrationTests' \
"$log" || true
fi
fi
echo "=== Current relevant PR diff ==="
gh api "repos/$repo/pulls/$pr/files?per_page=100" --paginate \
--jq '.[] | select(.filename | test("(^Resources/Maps/_Goobstation/(box|kettle|leonid|loop)\\.yml$)|(^Resources/Maps/_Goobstation/Shuttles/consul\\.yml$)|(^Resources/Prototypes/.*(lathe|research)|^Content\\.IntegrationTests)")) | {filename, additions, deletions}' || trueLength of output: 89145 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
job_id="91342184086"
log="$(mktemp)"
trap 'rm -f "$log"' EXIT
gh api "repos/$repo/actions/jobs/$job_id/logs" > "$log"
echo "=== AllTechPrintableTest: only violation messages ==="
rg -n \
"Recipe '.+' from tech '.+' cannot be unlocked on any lathes|Recipe '.+' is dynamic on lathe.*but is not unlocked|dynamic.*not.*tech|cannot.*print" \
"$log" || true
echo "=== AllTechPrintableTest: full block ==="
start="$(rg -n 'Failed AllTechPrintableTest' "$log" | head -1 | cut -d: -f1)"
end="$(rg -n 'GetPair: Pair 5 Test History End|Failed RepairTest' "$log" | head -1 | cut -d: -f1)"
if [ -n "${start:-}" ] && [ -n "${end:-}" ]; then
sed -n "${start},${end}p" "$log"
fi
echo "=== RepairTest: full failure and preceding server/client errors ==="
repair="$(rg -n 'Failed RepairTest' "$log" | head -1 | cut -d: -f1)"
if [ -n "${repair:-}" ]; then
from=$((repair - 260))
[ "$from" -lt 1 ] && from=1
to=$((repair + 180))
sed -n "${from},${to}p" "$log"
fi
echo "=== Error-level logs near RepairTest ==="
rg -n -i -C 14 \
'RepairTest|Unhandled|exception|fatal|critical|server.*(error|exception)|client.*(error|exception)|pair 6|Dirty return|state\. Dead' \
"$log" | tail -900 || true
echo "=== Recipe / research / lathe source map ==="
for file in \
Resources/Prototypes/Entities/Structures/Machines/lathe.yml \
Content.IntegrationTests/Tests/ResearchTest.cs
do
echo "----- OUTLINE $file -----"
ast-grep outline "$file" --items all --type class,method --view expanded 2>/dev/null || true
done
rg -n -i -C 5 \
'^\s*(staticPacks|dynamicPacks):|MedicalEquipment|UnregulatedBluespaceResearch|Consoles|GeneEngineering|NightVision|BasicArms' \
Resources/Prototypes --glob '*.{yml,yaml}' || trueLength of output: 202184 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
pr="161"
job_id="91342184086"
log="$(mktemp)"
trap 'rm -f "$log"' EXIT
gh api "repos/$repo/actions/jobs/$job_id/logs" > "$log"
echo "=== Unique AllTechPrintableTest violations ==="
python3 - "$log" <<'PY'
from pathlib import Path
import re, sys
text = Path(sys.argv[1]).read_text(errors="replace")
start = text.find("Failed AllTechPrintableTest")
end = text.find("GetPair: Pair 5 Test History End", start)
block = text[start:end if end != -1 else None]
block = re.sub(r'\x1b\[[0-9;]*m', '', block)
patterns = [
r"Recipe '([^']+)' from tech '([^']+)' cannot be unlocked on any lathes\.",
r"Recipe '([^']+)' is dynamic on (?:lathe|lathes).*?(?:but|and).*?(?:not unlocked|not.*tech).*",
r"Recipe '([^']+)'.{0,180}(?:dynamic).{0,180}(?:not unlocked|not.*tech).*",
]
seen = set()
for line in block.splitlines():
for pattern in patterns:
match = re.search(pattern, line, re.I)
if match:
value = match.group(0)
if value not in seen:
seen.add(value)
print(value)
break
print(f"TOTAL={len(seen)}")
PY
echo "=== RepairTest source ==="
file="$(fd -HI -t f '^VendingInteractionTest\.cs$' Content.IntegrationTests | head -1)"
echo "$file"
ast-grep outline "$file" --items all --type class,method --match 'VendingInteractionTest|RepairTest' --view expanded
sed -n '130,205p' "$file"
echo "=== InteractionTest.Activate source ==="
helpers="$(fd -HI -t f '^InteractionTest\.Helpers\.cs$' Content.IntegrationTests | head -1)"
echo "$helpers"
sed -n '350,410p' "$helpers"
echo "=== Repair-related prototypes and systems ==="
rg -n -i -C 10 \
'RepairTest|Repair.*Vending|Vending.*Repair|Repairable|Repair.*(Weld|Wire|Crowbar)|Broken.*Vending|VendingMachine' \
Content Resources --glob '*.{cs,yml,yaml}' \
-g '!Content.IntegrationTests/Tests/Vending/VendingInteractionTest.cs' | head -700
echo "=== PR files that could affect vending or interaction ==="
gh api "repos/$repo/pulls/$pr/files?per_page=100" --paginate \
--jq '.[] | select(.filename | test("(?i)(vending|interaction|repair|tool|lathe|research)")) | .filename'Length of output: 51876 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
job_id="91342184086"
log="$(mktemp)"
trap 'rm -f "$log"' EXIT
gh api "repos/$repo/actions/jobs/$job_id/logs" > "$log"
echo "=== All AllTechPrintableTest numbered assertions ==="
rg -n -A4 -B1 \
'^[0-9]+\) +Recipe |AllTechPrintableTest>b__1\(\).*ResearchTest\.cs:line (93|100)' \
"$log" | sed -n '1,500p'
echo "=== ResearchTest assertions ==="
sed -n '51,112p' Content.IntegrationTests/Tests/ResearchTest.cs
echo "=== Test-only vending prototype ==="
rg -n -A90 -B5 \
'id:\s*InteractionTestVendingMachine|id:\s*InteractionTestItem|id:\s*InteractionTestRestockBox' \
Content.IntegrationTests Resources --glob '*.{yml,yaml,cs}' || trueLength of output: 42471 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo="ArcaneSS14/arcane"
job_id="91342184086"
log="$(mktemp)"
trap 'rm -f "$log"' EXIT
gh api "repos/$repo/actions/jobs/$job_id/logs" > "$log"
echo "=== Dynamic recipes without a research unlock ==="
rg -o "Recipe '[^']+' is dynamic on a lathe but cannot be unlocked by research\." "$log" \
| sed -E "s/.*Recipe '([^']+)'.*/\1/" \
| sort -u
echo "=== Counts by AllTechPrintableTest invariant ==="
printf 'tech unlock without dynamic lathe recipe: '
rg -c "cannot be unlocked on any lathes\." "$log" || true
printf 'dynamic lathe recipe without research unlock: '
rg -c "is dynamic on a lathe but cannot be unlocked by research\." "$log" || true
echo "=== Test target prototype location ==="
rg -n -l --glob '*.{cs,yml,yaml}' 'InteractionTestVendingMachine' . | while IFS= read -r file; do
echo "--- $file ---"
rg -n -A80 -B5 'InteractionTestVendingMachine' "$file"
doneLength of output: 4621
1.
|
| Technology | Recipe |
|---|---|
MedicalEquipment |
Bloodpack, SawElectric, ClothingNeckStethoscope |
UnregulatedBluespaceResearch |
MedicalBeamGunSyndicate |
Consoles |
MedicalRecordsComputerCircuitboard, CrewMonitoringComputerCircuitboard |
GeneEngineering |
MedicalScannerMachineCircuitboard |
NightVision |
ClothingEyesNightVisionMedicalGoggles |
BasicArms |
MagazineShotgun, MagazineShotgunEmpty, MagazineShotgunSlug |
Cytology |
MedicalBiofabMachineBoard, DiagnoserMachineCircuitboard, VaccinatorMachineCircuitboard |
Фикс: для каждого recipe добавить содержащий его latheRecipePack в dynamicPacks нужного лата.
Основные файлы:
Resources/Prototypes/Entities/Structures/Machines/lathe.ymlResources/Prototypes/_Goobstation/Entities/Structures/Machines/lathe.ymlResources/Prototypes/_Orion/Research/Nodes/*.ymlResources/Prototypes/**/Recipes/Lathes/Packs/*.yml
Не переносите весь набор staticPacks в dynamicPacks без проверки баланса. Например, medical recipes должны быть dynamic на MedicalTechFab, а security ammo — на AmmoTechFab или SecurityTechFab.
B. Lathe содержит dynamic recipe без research unlock
Нарушений: 20.
AdvancedJetInjector
BorgModuleAdvancedTopical
BorgModuleArtistry
BorgModuleInflatable
BoxFolderClipboardEmpty
BoxFolderPlasticClipboardEmpty
CableDetStack1
ChemistryEmptyVialSmall
EmptyDetonator
FauxTileAstroIronsand
FauxTileAstroIronsandBorderless
FauxTileDarkAstroGrass
FauxTileDesertAstroSand
FauxTileLightAstroGrass
JetInjector
MaterialDurathread
SmartFridgeCircuitboard
TowelColorWhite
UtilityKnife
VoiceSensor
Фикс: для каждого recipe выбрать одно из двух действий:
- Добавить recipe в
recipeUnlocksподходящей technology. - Перенести recipe из
dynamicPacksвstaticPacks, если research не должен быть нужен.
Рекомендуемый принцип:
SmartFridgeCircuitboard,VoiceSensor,AdvancedJetInjector, borg modules иMaterialDurathread— добавить в подходящие research nodes.TowelColorWhite, пустые папки,EmptyDetonator, базовыйUtilityKnife, базовые кабели и часть faux tiles — вероятнее должны быть static recipes. Проверьте игровой дизайн перед переносом.- Не исправляйте это удалением assertion из
ResearchTest. Тест обнаруживает недоступный игроку контент и контент без легального unlock.
2. Vending.VendingInteractionTest.RepairTest
Это вторая независимая ошибка.
BreakVendor() наносит vending machine 100 blunt damage:
var damage = new DamageSpecifier(damageType, FixedPoint2.New(100));После этого Target уже отсутствует на сервере. Первый Activate() после BreakVendor() падает на проверке:
SEntMan.TryGetEntity(target!.Value, out var sTarget)
Expected: True
But was: False
То есть vending machine не остаётся в состоянии «сломана, но ремонтируема». Она удаляется. Вероятная причина — 100 damage теперь достигает destruction threshold, а не только broken threshold.
Фикс теста:
- В
BreakVendor()применяйте damage, который переводит machine в broken state, но не достигает destruction threshold. - Либо переопределите
Destructibleтолько уInteractionTestVendingMachine, чтобы100damage не удалял test entity. - Добавьте assertion сразу после
BreakVendor():
Assert.That(SEntMan.EntityExists(SEntMan.GetEntity(Target)), Is.True);Лучше не менять production destruction thresholds ради integration test. Тест должен создавать именно repairable state.
Каскадные ошибки
Ошибки вида:
Pool manager has not been initialized
не являются отдельными дефектами. Они начинаются после смерти pair 6 в RepairTest.
После исправления research/lathe и RepairTest нужен новый запуск Build & Test Debug. Только он покажет ошибки, которые сейчас маскирует каскад.
You are interacting with an AI system.

Описание PR
Фиксы взяли отсюда:
space-syndicate/Goob-Station#991
space-syndicate/Goob-Station#1013
space-syndicate/Goob-Station#1022
машина клоуна больше не требует доп ключ
борги могут брать материалы и вырываться из граба.
в
ItemSlotRendererSystemесли слот ссылается на удаленную сущность , то вместо того чтобы отрисовать удаленный энтити , будет использоваться пустая текстураЗакуп антагонистов в манифесте теперь отображается
Транспорт больше не может ездить по космосу
Если сломать 1 разлом дракона, то ломаются все
Теперь можно поставить голобарьер(проектор) на тайл где есть лужа
Сабля ГСБ теперь заряжается
Борги могут брать органы
У умного корги вновь две руки
Сингулярность и тесла больше не ломают барьеры(наверное)
Улучшения для латов теперь можно вставлять
Вору убран пацифизм
Взаимодействие через E с наэлектризованными ентити бьют током
У дрона корректно работает т-лучевой сканер
При использовании разных стимуляторов, увеличивающих скорость, кукла игрока больше не лагает
Теперь наборов для ушибов/мазей/пакетов с кровью/бинтов реально 15
Живая сущность в инвентаре больше не мешает поднять щит через хотбар
Также отдельно были пофикшены тесты. Ыыы.
Тип PR
🆑 ReWAFFlution, Umbi_Max, shimorio