Engine update v283.1#1488
Conversation
Update Color.TryFromHex call sites for the new bool/out API. Co-authored-by: Cursor <cursoragent@cursor.com>
fix Co-authored-by: MetalSage <metalsage.official@gmail.com> (cherry picked from commit 80b63accb9f7a33147e627d99fb0e844655cfee9)
fix exception Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> (cherry picked from commit a7d4780e76c9948ef0aee9fcaa4889cd5317a6c1)
Fix shooting inside morgue exploit (cherry picked from commit 470acb50b0ddf8e6f24edb23de8728baf429b7b9)
re-enqueue logs if update failed (cherry picked from commit 004639bcdd6dbcb5c1e7a1698624f513319f8e63)
* remove this * move comp removal of ActiveInputMoverComponent to shared (cherry picked from commit c93da79aed320e62bafa5b75a27a8cf0e3a8a18c)
…` (#44486) * Fix items deletion on recycling for entities with `ItemSlotsComponent` * Make it to be dependent on `DestructionEvent` instead * Revert testing changes * Actual proto fix * Fix some other recyclable prototypes with ItemSlots (cherry picked from commit bc9a9207c5b9329e7d12620e7dc17a8b4c8be2a7)
* worldPos * GetInOwningStation: pass range (cherry picked from commit 8f190738f1d89169655698992cabbf3c30c62852)
ParcelWrap: spawn at position, use PopupEntity (cherry picked from commit 8ab888008f12ec59503bc31d7f0b2d07ef52a956)
* Multiply by 1600 * Add admin levels to the shuttle mass variable * Math hard (cherry picked from commit f983f044871c4fd7c78748c54865fff3f77f2b48)
idk (cherry picked from commit 36f1261dbb9f7a761618258422c01a48f7ea2ead)
fix the hands (cherry picked from commit 8b228db4ccc0bed71bbc304821259fe993a751ca)
* fix * cleanup and button disabled * add brackets (cherry picked from commit ad42329f79872781413c41ce57fba05b2bb0e0a5)
Content should check this but okay! (cherry picked from commit c6ea5ae41c68a768a08f0f2dab12f2d1cc19efad)
* stub * Revert "stub" This reverts commit c1204b88d3ae1bbdca2deeb075a9dd0d6c529326. * PoC * As a successful member of society with a stable unflinching psyche and limitless drive, natural affinity for finance and domination, you have been selected, no, you have been effortlessly guided by divine (biological) trauma towards this moment. The gates of destiny fling open, and once again you're left standing on pulsating nothingness. A strobing headache of the soul. * i feel bad * Revert "PoC" This reverts commit fafafac77f9cbd62497376c70e078e0155cb7ef6. --------- Co-authored-by: nomdéraisonnablementlong <you@example.com> (cherry picked from commit 57653e45513990b84f391ff253b558261990ace0)
fix for everything shocking you (cherry picked from commit d873053e47088df70fd1952b37a85b0b75e6477c)
* Fix electrified objects not shocking on world activation * add ordering for event subscription * Something definitely went wrong --------- Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> (cherry picked from commit 16312ac3ac2146a3108111683990e5b813461cfe)
* Fix client mispredict on some storage operations * Actually not needed * retry * Review (cherry picked from commit acad100b880d5a9cf77a2608a053f56e1bbf463d)
(cherry picked from commit 5f1a61c0ff60b90de5b62bbcbde6e5c86c00cfc1)
(cherry picked from commit a80863f9b344cde2bf8de83a2f699d53439654b4)
Local PredictedRandom returns System.Random; map NextVector2Box via NextFloat. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Warning Review limit reached
Next review available in: 1 minute Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (12)
WalkthroughИзменения обновляют административные операции, выбор антагонистов, обработку событий сущностей, перенос умов, хирургическое состояние, детерминированные операции хранения, визуализации, прототипы и интеграцию RobustToolbox. ChangesИгровые и инфраструктурные исправления
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant AirlockSystem
participant ElectrocutionSystem
participant DoorSystem
User->>AirlockSystem: ActivateInWorldEvent
AirlockSystem->>ElectrocutionSystem: обработка ElectrifiedComponent
ElectrocutionSystem->>ElectrocutionSystem: TryDoElectrifiedAct
ElectrocutionSystem->>DoorSystem: событие отмечено обработанным
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Content.Server/Antag/AntagSelectionSystem.cs (1)
501-547: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winИспользование
RemoveSwapнарушает детерминированный приоритет ролей антагонистов.Метод
RemoveSwap(i)удаляет элемент, меняя его местами с последним элементом списка. Старый код (с использованиемArray.Copy) строго сохранял порядок остальных элементов массива.
Поскольку данный цикл выполняется в обратном порядке (for (var i = antags.Count - 1; i >= 0; i--)), перенос последнего элемента в середину списка случайным образом меняет приоритет оставшихся доступных ролей для следующих игроков (что противоречит логике приоритизации ролей по их индексу).Для списков малого размера операция
RemoveAt(i)крайне легковесна, но при этом гарантированно сохраняет правильный приоритет.
(Примечание: та же проблема неявно присутствует и в нетронутом методеPreAssignAntag, где также стоит использоватьRemoveAtвместоRemoveSwap).💡 Предлагаемое исправление
// Reduce the slots left by one // If we finish assigning all slots antag.Count--; if (antag.Count == 0) - antags.RemoveSwap(i); + antags.RemoveAt(i); else antags[i] = antag;🤖 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/Antag/AntagSelectionSystem.cs` around lines 501 - 547, Replace RemoveSwap(i) with RemoveAt(i) in AssignAntag so removing an exhausted role preserves the remaining antag priority order; also make the same replacement in PreAssignAntag. Keep the existing reverse iteration and count-update behavior unchanged.
🧹 Nitpick comments (1)
Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs (1)
10-10: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueУдалите неиспользуемый импорт.
Пространство имен
Content.Shared.Materialsне используется в этом файле. Этот импорт был добавлен случайно и может быть безопасно удален для поддержания чистоты кода.♻️ Предлагаемое исправление
-using Content.Shared.Materials;🤖 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.Shared/Containers/ItemSlot/ItemSlotsSystem.cs` at line 10, Remove the unused Content.Shared.Materials import from ItemSlotsSystem.cs, leaving the rest of the file unchanged.
🤖 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/Administration/Logs/AdminLogManager.cs`:
- Around line 254-289: Переместите вызов LogsSent.Inc(copy.Count) в методе,
содержащем данный try/catch, непосредственно после успешного await task и вне
блока DatabaseUpdateTime.NewTimer. Не изменяйте повторное добавление логов в
очереди при ошибке; метрика должна увеличиваться только после успешного
сохранения.
In `@Content.Server/Zombies/ZombieSystem.cs`:
- Around line 339-343: Update OnMindRemoved to check whether ent.Owner is
terminating before calling MakeGhostRole; skip the ghost-role creation when the
entity is being deleted, while preserving MindRemoveRole execution.
---
Outside diff comments:
In `@Content.Server/Antag/AntagSelectionSystem.cs`:
- Around line 501-547: Replace RemoveSwap(i) with RemoveAt(i) in AssignAntag so
removing an exhausted role preserves the remaining antag priority order; also
make the same replacement in PreAssignAntag. Keep the existing reverse iteration
and count-update behavior unchanged.
---
Nitpick comments:
In `@Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs`:
- Line 10: Remove the unused Content.Shared.Materials import from
ItemSlotsSystem.cs, leaving the rest of the file 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 90a164ab-4b46-4d5c-bd58-8ee068f16ca1
📒 Files selected for processing (40)
Content.Server/Administration/Commands/SetAdminOOC.csContent.Server/Administration/Logs/AdminLogManager.csContent.Server/Administration/UI/PermissionsEui.csContent.Server/Antag/AntagSelectionSystem.API.Assignment.csContent.Server/Antag/AntagSelectionSystem.csContent.Server/Backmen/Sponsors/SponsorsManager.csContent.Server/Cloning/CloningSystem.csContent.Server/Database/ServerDbBase.csContent.Server/Electrocution/ElectrocutionSystem.csContent.Server/Materials/MaterialReclaimerSystem.csContent.Server/Mind/MindSystem.csContent.Server/Physics/Controllers/MoverController.csContent.Server/Sandbox/Commands/ColorNetworkCommand.csContent.Server/Station/Systems/StationSystem.csContent.Server/Zombies/ZombieSystem.Transform.csContent.Server/Zombies/ZombieSystem.csContent.Shared/CCVar/CCVars.Shuttle.csContent.Shared/Containers/ItemSlot/ItemSlotsSystem.csContent.Shared/Electrocution/Components/ElectrifiedComponent.csContent.Shared/Fluids/SharedPuddleSystem.csContent.Shared/Hands/EntitySystems/SharedHandsSystem.csContent.Shared/Movement/Systems/SharedMoverController.Relay.csContent.Shared/ParcelWrap/Systems/ParcelWrappingSystem.ParcelWrap.csContent.Shared/Placeable/PlaceableSurfaceSystem.csContent.Shared/Storage/EntitySystems/DumpableSystem.csContent.Shared/Storage/EntitySystems/SharedStorageSystem.csContent.Shared/Weapons/Ranged/Systems/SharedGunSystem.Revolver.csResources/Changelog/ChangelogBkm.ymlResources/Prototypes/Entities/Clothing/Belt/belts.ymlResources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.ymlResources/Prototypes/Entities/Clothing/Shoes/specific.ymlResources/Prototypes/Entities/Objects/Tools/access_configurator.ymlResources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.ymlResources/Prototypes/Entities/Structures/Machines/Computers/base_structurecomputers.ymlResources/Prototypes/Entities/Structures/Machines/Computers/computers.ymlResources/Prototypes/Entities/Structures/Machines/holopad.ymlResources/Prototypes/Entities/Structures/Storage/morgue.ymlResources/Prototypes/Entities/Structures/Walls/fence_metal.ymlRobustToolboxSpaceStation14.slnx
💤 Files with no reviewable changes (5)
- Content.Server/Physics/Controllers/MoverController.cs
- Resources/Prototypes/Entities/Structures/Machines/Computers/base_structurecomputers.yml
- Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml
- Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml
- Resources/Prototypes/Entities/Structures/Machines/holopad.yml
| try | ||
| { | ||
| LogsSent.Inc(copy.Count); | ||
| if (_metricsEnabled) | ||
| { | ||
| LogsSent.Inc(copy.Count); | ||
|
|
||
| using (DatabaseUpdateTime.NewTimer()) | ||
| using (DatabaseUpdateTime.NewTimer()) | ||
| { | ||
| await task; | ||
| } | ||
| } | ||
| else | ||
| { | ||
| await task; | ||
| return; | ||
| } | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| _sawmill.Error($"Failed to save logs: {ex.Message}"); | ||
| _sawmill.Warning("Re-enqueueing logs and retrying at the next update."); | ||
|
|
||
| await task; | ||
| foreach (var log in copy) | ||
| { | ||
| if (log.RoundId == _currentRoundId) | ||
| { | ||
| _logQueue.Enqueue(log); | ||
| } | ||
| else | ||
| { | ||
| _preRoundLogQueue.Enqueue(log); | ||
| } | ||
| } | ||
|
|
||
| Queue.Set(_logQueue.Count); | ||
| PreRoundQueue.Set(_preRoundLogQueue.Count); | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Перенесите инкремент метрики после успешного выполнения задачи.
Сейчас метрика LogsSent увеличивается до await task. Если задача _db.AddAdminLogs(copy) завершится с ошибкой и логи будут возвращены в очередь (блок catch), при их успешном сохранении в будущем метрика увеличится повторно (double-count).
Следует инкрементировать метрику только после успешного завершения задачи.
💡 Предлагаемое исправление
try
{
if (_metricsEnabled)
{
- LogsSent.Inc(copy.Count);
-
using (DatabaseUpdateTime.NewTimer())
{
await task;
}
+
+ LogsSent.Inc(copy.Count);
}
else
{📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| try | |
| { | |
| LogsSent.Inc(copy.Count); | |
| if (_metricsEnabled) | |
| { | |
| LogsSent.Inc(copy.Count); | |
| using (DatabaseUpdateTime.NewTimer()) | |
| using (DatabaseUpdateTime.NewTimer()) | |
| { | |
| await task; | |
| } | |
| } | |
| else | |
| { | |
| await task; | |
| return; | |
| } | |
| } | |
| catch (Exception ex) | |
| { | |
| _sawmill.Error($"Failed to save logs: {ex.Message}"); | |
| _sawmill.Warning("Re-enqueueing logs and retrying at the next update."); | |
| await task; | |
| foreach (var log in copy) | |
| { | |
| if (log.RoundId == _currentRoundId) | |
| { | |
| _logQueue.Enqueue(log); | |
| } | |
| else | |
| { | |
| _preRoundLogQueue.Enqueue(log); | |
| } | |
| } | |
| Queue.Set(_logQueue.Count); | |
| PreRoundQueue.Set(_preRoundLogQueue.Count); | |
| } | |
| try | |
| { | |
| if (_metricsEnabled) | |
| { | |
| using (DatabaseUpdateTime.NewTimer()) | |
| { | |
| await task; | |
| } | |
| LogsSent.Inc(copy.Count); | |
| } | |
| else | |
| { | |
| await task; | |
| } | |
| } | |
| catch (Exception ex) | |
| { | |
| _sawmill.Error($"Failed to save logs: {ex.Message}"); | |
| _sawmill.Warning("Re-enqueueing logs and retrying at the next update."); | |
| foreach (var log in copy) | |
| { | |
| if (log.RoundId == _currentRoundId) | |
| { | |
| _logQueue.Enqueue(log); | |
| } | |
| else | |
| { | |
| _preRoundLogQueue.Enqueue(log); | |
| } | |
| } | |
| Queue.Set(_logQueue.Count); | |
| PreRoundQueue.Set(_preRoundLogQueue.Count); | |
| } |
🤖 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/Administration/Logs/AdminLogManager.cs` around lines 254 -
289, Переместите вызов LogsSent.Inc(copy.Count) в методе, содержащем данный
try/catch, непосредственно после успешного await task и вне блока
DatabaseUpdateTime.NewTimer. Не изменяйте повторное добавление логов в очереди
при ошибке; метрика должна увеличиваться только после успешного сохранения.
| private void OnMindRemoved(Entity<ZombieComponent> ent, ref MindRemovedMessage args) | ||
| { | ||
| _role.MindRemoveRole<ZombieRoleComponent>((args.Mind.Owner, args.Mind.Comp)); | ||
| MakeGhostRole(ent.Owner); | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Добавьте проверку на удаление сущности, чтобы избежать выброса исключений.
Событие MindRemovedMessage срабатывает в том числе и при удалении сущности (через ComponentShutdown у MindContainerComponent). Если ent.Owner находится в состоянии удаления (Terminating), последующий вызов EnsureComp внутри MakeGhostRole вызовет исключение в RobustToolbox (Cannot add component to a terminating entity), что приведет к ошибкам в консоли или падению логики при удалении зомби.
🐛 Предлагаемое исправление
private void OnMindRemoved(Entity<ZombieComponent> ent, ref MindRemovedMessage args)
{
_role.MindRemoveRole<ZombieRoleComponent>((args.Mind.Owner, args.Mind.Comp));
+
+ if (TerminatingOrDeleted(ent))
+ return;
+
MakeGhostRole(ent.Owner);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private void OnMindRemoved(Entity<ZombieComponent> ent, ref MindRemovedMessage args) | |
| { | |
| _role.MindRemoveRole<ZombieRoleComponent>((args.Mind.Owner, args.Mind.Comp)); | |
| MakeGhostRole(ent.Owner); | |
| } | |
| private void OnMindRemoved(Entity<ZombieComponent> ent, ref MindRemovedMessage args) | |
| { | |
| _role.MindRemoveRole<ZombieRoleComponent>((args.Mind.Owner, args.Mind.Comp)); | |
| if (TerminatingOrDeleted(ent)) | |
| return; | |
| MakeGhostRole(ent.Owner); | |
| } |
🤖 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/Zombies/ZombieSystem.cs` around lines 339 - 343, Update
OnMindRemoved to check whether ent.Owner is terminating before calling
MakeGhostRole; skip the ghost-role creation when the entity is being deleted,
while preserving MindRemoveRole execution.
52c4042 to
b414e5b
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
Content.Server/Backmen/Abilities/Psionics/PsionicAbilitiesSystem.cs (1)
117-119: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low valueИзбегайте лишних аллокаций при получении типа компонента.
Вместо создания нового экземпляра компонента только ради вызова
.GetType(), можно получить тип напрямую из регистрации фабрики компонентов. Это позволит избежать лишних аллокаций памяти.♻️ Предлагаемое изменение
- // component moment - var comp = _componentFactory.GetComponent(compName); - if (TryComp(uid, comp.GetType(), out var psionicPower)) + var compType = _componentFactory.GetRegistration(compName).Type; + if (TryComp(uid, compType, out var psionicPower))🤖 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/Backmen/Abilities/Psionics/PsionicAbilitiesSystem.cs` around lines 117 - 119, Update the component-removal logic in the PsionicAbilitiesSystem flow to obtain the component Type directly from the component factory registration instead of calling GetComponent(compName) solely to invoke GetType(). Keep TryComp and RemComp behavior unchanged, using the registered type associated with compName.
🤖 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.
Nitpick comments:
In `@Content.Server/Backmen/Abilities/Psionics/PsionicAbilitiesSystem.cs`:
- Around line 117-119: Update the component-removal logic in the
PsionicAbilitiesSystem flow to obtain the component Type directly from the
component factory registration instead of calling GetComponent(compName) solely
to invoke GetType(). Keep TryComp and RemComp behavior unchanged, using the
registered type associated with compName.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 4cb4398b-280d-49fe-9683-da3163fe8fda
📒 Files selected for processing (8)
Content.Client/Backmen/AirDrop/AirDropSystem.csContent.Server/Backmen/Abilities/Psionics/PsionicAbilitiesSystem.csContent.Server/Backmen/Surgery/Pain/Systems/ServerPainSystem.csContent.Shared/Backmen/Surgery/Body/Organs/OrganEffectSystem.csContent.Shared/Backmen/Surgery/Pain/Components/NerveOrganComponent.csContent.Shared/Backmen/Surgery/Pain/Systems/PainSystem.csContent.Shared/Backmen/Surgery/SharedSurgerySystem.Steps.csResources/Changelog/ChangelogBkm.yml
💤 Files with no reviewable changes (1)
- Content.Shared/Backmen/Surgery/Body/Organs/OrganEffectSystem.cs
🚧 Files skipped from review as they are similar to previous changes (1)
- Resources/Changelog/ChangelogBkm.yml
fix fix Update ServerPainSystem.cs fix fix
b414e5b to
f4dad30
Compare
🛰️ Обновление Backmen — 18.07.2026
Обновили игровой движок до RobustToolbox 283.1.0 и подтянули важные фиксы с upstream.
🔧 Движок
🐛 Исправления
Движение и взаимодействие
Оружие и предметы
Роли и roundflow
Карта и окружение
shuttle.mass_limitUI / клиент
📝 Примечание
Часть фиксов с upstream (например, связанные со стрельбой по crit / targeting) не переносилась — у нас своя система прицеливания по частям тела.
Приятной смены! Если найдёте баг после обновления — кидайте в баг-репорт с шагами воспроизведения.
Summary by CodeRabbit