Skip to content

Comments

hotfix 23.01.2026#1431

Merged
Rxup merged 1 commit intomasterfrom
hotfix-230126
Jan 23, 2026
Merged

hotfix 23.01.2026#1431
Rxup merged 1 commit intomasterfrom
hotfix-230126

Conversation

@Rxup
Copy link
Owner

@Rxup Rxup commented Jan 22, 2026

Summary by CodeRabbit

Примечания к выпуску

  • Новые функции

    • Интегрирована система крыш на Лаваленде: сущности под крышами теперь защищены от повреждений
    • Улучшена гибкость интеграции GPT API для системы диалогов NPC
  • Улучшения

    • Оптимизирована обработка воспламеняемых объектов в каждом кадре
    • Обновлены карты Лаваленда и руин для совместимости с новой версией движка
    • Улучшена синхронизация состояния крыш при создании процедурных сеток

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions github-actions bot added S: Untriaged size/M Changes: Map Can be reviewed or fixed by people who are knowledgeable with mapping. and removed S: Untriaged size/M labels Jan 22, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 22, 2026

Walkthrough

Изменения интегрируют систему крыш в игровую логику, обновляют версии двигателя на картах Лавленда (270.1.0 → 271.1.0), оптимизируют обработку воспламеняемых компонентов через пакетную обработку и ослабляют проверку API GPT, удаляя требование токена.

Changes

Cohort / File(s) Краткое описание изменений
Системы атмосферы и огня
Content.Server/Atmos/EntitySystems/FlammableSystem.cs
Рефакторинг логики огня за кадр: введена локальная очередь для пакетной обработки FlammableComponent вместо изменения данных в цикле итерации
Интеграция системы крыш
Content.Server/_Lavaland/Procedural/Systems/LavalandPlanetSystem.Grid.cs, Content.Server/_Lavaland/Weather/LavalandWeatherSystem.cs
Добавлена зависимость SharedRoofSystem; расширена логика слияния плиток для отслеживания и применения крыш; реализована ранняя проверка выхода в ProcessLavalandDamage для пропуска урона на покрытых плитках
Инициализация атмосферы
Content.Server/_Lavaland/Procedural/Systems/LavalandPlanetSystem.cs
Инициализирует композицию атмосферы для предзагрузчика (кислород ~21.82, азот ~82.10) и переходит на высокоуровневый API SetMapAtmosphere вместо явной работы с компонентом
API GPT
Content.Server/Backmen/NPC/Systems/NPCConversationSystem.cs
Ослаблена проверка доступности API GPT: SendGptApiRequest больше не требует ненулевого токена, только включение и конфигурацию
Карты Лавленда
Resources/Maps/Backmen/Lavaland/*.yml, Resources/Maps/_Lavaland/Lavaland/*.yml
Обновление версии двигателя на 271.1.0 и временных меток; изменения данных крыш, физики и состояния дверей в различных картах

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰✨ Крыши над Лавлендом поднялись с видом,
Очереди горящих плиток светят чудо-льдом,
Версии взлетели, API слегка раздвинулось,
В пакетной обработке весь огонь сгруппировался,
А караван карт спешит вперёд с числом судьбы! 🎆

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive Название является датой в формате "hotfix 23.01.2026", но не описывает суть изменений. Основные изменения касаются системы крыш (RoofSystem), атмосферы лаваленда, оптимизации обработки воспламеняющихся компонентов и обновления карт, однако название этого не отражает. Используйте более описательное название, указывающее на основную цель изменений, например: "Add roof system integration to Lavaland" или "Refactor flammable batching and add roof support".
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch hotfix-230126

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Content.Server/Backmen/NPC/Systems/NPCConversationSystem.cs (1)

806-824: Очищайте Authorization, когда токен пустой.

Теперь допускается работа без токена, но заголовок может остаться от предыдущего значения (или стать Bearer ), из‑за чего неаутентифицированные эндпоинты будут отклонять запросы. Сбрасывайте заголовок при пустом токене.

🐛 Предлагаемое исправление
-            if (!string.IsNullOrEmpty(_gptApiToken))
-            {
-                _gptHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _gptApiToken);
-            }
+            if (!string.IsNullOrEmpty(_gptApiToken))
+            {
+                _gptHttpClient.DefaultRequestHeaders.Authorization =
+                    new AuthenticationHeaderValue("Bearer", _gptApiToken);
+            }
+            else
+            {
+                _gptHttpClient.DefaultRequestHeaders.Authorization = null;
+            }
🤖 Fix all issues with AI agents
In `@Content.Server/_Lavaland/Procedural/Systems/LavalandPlanetSystem.Grid.cs`:
- Around line 164-168: The call to _map.SetTile(spawned.Value, spawnedGrid,
offsetTile, ...) is using source-grid coordinates (offsetTile) instead of the
spawned target grid coordinates; update the SetTile invocation in the block that
checks _map.TryGetTileRef(...) / lavalandTile.Tile to pass
tileRef.Value.GridIndices (the original spawned-grid indices) instead of
offsetTile so tiles are placed on the correct grid (note SetRoof correctly uses
offsetTile for the source grid and should remain unchanged).

In `@Content.Server/_Lavaland/Weather/LavalandWeatherSystem.cs`:
- Around line 64-71: The code calls Comp<MapGridComponent>(lavaland.Owner) twice
and uses Comp<RoofComponent>(lavaland.Owner) which can throw; cache the
MapGridComponent result in a local variable and replace the second Comp call
with that variable, and change the roof lookup to
TryComp<RoofComponent>(lavaland.Owner, out var roofComp) and only call
_roof.IsRooved when TryComp returns true (pass roofComp instead of
Comp<RoofComponent>(lavaland.Owner)); keep the existing
_mapSystem.TryGetTileRef(lavaland.Owner, ...) and use tile.GridIndices as
before.

In `@Content.Server/Atmos/EntitySystems/FlammableSystem.cs`:
- Around line 429-438: The Update() loop currently allocates a new Queue and
requests an unused TransformComponent; make a class-level Queue<(EntityUid,
FlammableComponent)> (e.g. _flammableQueue) and reuse it by calling
_flammableQueue.Clear() at the start of Update(), and change the query from
EntityQueryEnumerator<FlammableComponent, TransformComponent>() to
EntityQueryEnumerator<FlammableComponent>() (remove the unused
TransformComponent out _), then either enqueue items into the reused
_flammableQueue or—since components aren’t added/removed—process the flammable
entries inline in Update() to eliminate the two-phase allocation entirely;
update references to the local q variable to use the field name (e.g.
_flammableQueue) and keep all logic that modifies
FlammableComponent/IgnitionSourceComponent the same.
🧹 Nitpick comments (4)
Content.Server/_Lavaland/Weather/LavalandWeatherSystem.cs (1)

32-35: Неиспользуемые зависимости.

_mapManager и _transform объявлены, но не используются в этом файле. Если они не планируются к использованию, их следует удалить.

♻️ Предлагаемое исправление
     [Dependency] private readonly RoofSystem _roof = default!;
-    [Dependency] private readonly IMapManager _mapManager = default!;
-    [Dependency] private readonly SharedTransformSystem _transform = default!;
     [Dependency] private readonly SharedMapSystem _mapSystem = default!;
Content.Server/_Lavaland/Procedural/Systems/LavalandPlanetSystem.cs (2)

161-168: Захардкоженные значения газовой смеси.

Значения кислорода (21.824779f) и азота (82.10312f) дублируют константы, которые также используются в других местах (например, в карте на строке 131-132 используется 21.824879 и 82.10312). Небольшое расхождение в значении кислорода (21.824779 vs 21.824879) может быть намеренным или ошибкой.

Рекомендуется вынести эти значения в константы или использовать общий источник.


222-223: Закомментированный код.

Закомментированный вызов _atmos.RebuildGridTiles следует либо удалить, либо добавить TODO-комментарий с пояснением, почему он отключен и когда планируется вернуть.

Content.Server/_Lavaland/Procedural/Systems/LavalandPlanetSystem.Grid.cs (1)

155-159: Дублирующийся вызов SetRoof.

_roofSystem.SetRoof(roofMap, offsetTile, true) вызывается дважды для одних и тех же координат: внутри цикла (строка 157) и после merge (строка 176). Если это сделано намеренно для сохранения состояния крыш после операции merge, добавьте комментарий. В противном случае, первый вызов можно удалить.

♻️ Предлагаемое исправление (если дублирование не требуется)
                            if (_roofSystem.IsRooved(spawnedRoof, tileRef.Value.GridIndices))
                            {
-                                _roofSystem.SetRoof(roofMap, offsetTile, true);
                                tilesToRoof.Add(offsetTile);
                            }

Also applies to: 174-177

Comment on lines +164 to 168
if (_map.TryGetTileRef(sourceGridUid, sourceGrid, offsetTile, out var lavalandTile) &&
!lavalandTile.Tile.IsEmpty)
{
_map.SetTile(spawned.Value, spawnedGrid, tile.GridIndices, lavalandTile.Tile);
_map.SetTile(spawned.Value, spawnedGrid, offsetTile, lavalandTile.Tile);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Find the file and examine the full context around the flagged lines
fd "LavalandPlanetSystem" --type f -x head -n 200 {} \; 2>/dev/null | head -50

Repository: Rxup/space-station-14

Length of output: 1823


🏁 Script executed:

# Search for SetTile usage patterns with spawned
rg -n -B2 -A3 "\.SetTile\(" --type=cs -g "*LavalandPlanetSystem*"

Repository: Rxup/space-station-14

Length of output: 799


🏁 Script executed:

# Check Grid.Merge patterns to understand coordinate conventions
rg -n -B2 -A2 "Grid\.Merge|_gridFixture\.Merge" --type=cs | head -40

Repository: Rxup/space-station-14

Length of output: 1150


🏁 Script executed:

# Find the matrix transformation context to understand source→spawned mapping
rg -n -B5 "Matrix3x2.*transform|offsetTile.*=" --type=cs -g "*LavalandPlanetSystem*" | head -60

Repository: Rxup/space-station-14

Length of output: 915


🏁 Script executed:

# Get the full context of the loop around lines 145-175
sed -n '130,180p' "Content.Server/_Lavaland/Procedural/Systems/LavalandPlanetSystem.Grid.cs"

Repository: Rxup/space-station-14

Length of output: 2734


🏁 Script executed:

# Also check what the matrix represents - look for where it's created
rg -n -B10 "var matrix" --type=cs -g "*LavalandPlanetSystem.Grid.cs*"

Repository: Rxup/space-station-14

Length of output: 1634


🏁 Script executed:

# Double-check by looking at SetTile signature and how Merge uses the matrix
rg -n "public.*SetTile" --type=cs | head -5

Repository: Rxup/space-station-14

Length of output: 47


🏁 Script executed:

# Verify the matrix direction - check if it's meant to be spawned->source or source->spawned
rg -n "CreateTransform" --type=cs | head -10

Repository: Rxup/space-station-14

Length of output: 1666


🏁 Script executed:

# Get the actual implementation of SetTile to confirm it takes Vector2i as coordinates
rg -n -A3 "void SetTile.*Vector2i" --type=cs | head -20

Repository: Rxup/space-station-14

Length of output: 47


🏁 Script executed:

# Check if there are similar patterns elsewhere in the codebase that might validate the coordinate handling
rg -n -B5 -A5 "GetAllTilesEnumerator.*while.*tileRef" --type=cs | head -60

Repository: Rxup/space-station-14

Length of output: 47


🏁 Script executed:

# Search for SetTile method signature
rg -n "SetTile" --type=cs -A2 | grep -E "(public|void|SetTile)" | head -20

Repository: Rxup/space-station-14

Length of output: 2864


🏁 Script executed:

# Look at the actual SharedMapSystem to understand SetTile
fd "SharedMapSystem" --type=f -x cat {} \; | grep -A5 "SetTile" | head -30

Repository: Rxup/space-station-14

Length of output: 47


🏁 Script executed:

# Let me check the loop logic more carefully - maybe offsetTile should actually be inverted before SetTile
rg -n -B20 "SetTile.*spawned" --type=cs -g "*LavalandPlanetSystem*" | tail -40

Repository: Rxup/space-station-14

Length of output: 2911


Использованы неправильные координаты для SetTile на spawned grid.

В строке 167 _map.SetTile вызывается на spawned.Value с координатами offsetTile, которые представляют позицию в системе координат source grid (результат матричного преобразования). Однако SetTile должен получать координаты в системе координат целевого grid — spawned.Value.

Следует использовать tileRef.Value.GridIndices (оригинальные координаты spawned grid) вместо offsetTile:

_map.SetTile(spawned.Value, spawnedGrid, tileRef.Value.GridIndices, lavalandTile.Tile);

Текущая реализация приведёт к тому, что плитки будут установлены на неправильные координаты. Примечание: SetRoof на строке 157 корректно использует offsetTile, так как он устанавливает крышу на source grid.

🤖 Prompt for AI Agents
In `@Content.Server/_Lavaland/Procedural/Systems/LavalandPlanetSystem.Grid.cs`
around lines 164 - 168, The call to _map.SetTile(spawned.Value, spawnedGrid,
offsetTile, ...) is using source-grid coordinates (offsetTile) instead of the
spawned target grid coordinates; update the SetTile invocation in the block that
checks _map.TryGetTileRef(...) / lavalandTile.Tile to pass
tileRef.Value.GridIndices (the original spawned-grid indices) instead of
offsetTile so tiles are placed on the correct grid (note SetRoof correctly uses
offsetTile for the source grid and should remain unchanged).

Comment on lines +64 to +71
if (
_mapSystem.TryGetTileRef(lavaland.Owner, Comp<MapGridComponent>(lavaland.Owner), xform.Coordinates, out var tile) &&
_roof.IsRooved(
(lavaland.Owner, Comp<MapGridComponent>(lavaland.Owner), Comp<RoofComponent>(lavaland.Owner)),
tile.GridIndices))
{
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Дублирующийся вызов Comp и потенциальный NullReferenceException.

  1. Comp<MapGridComponent>(lavaland.Owner) вызывается дважды — следует закэшировать результат.
  2. Comp<RoofComponent>(lavaland.Owner) выбросит исключение, если компонент отсутствует. Используйте TryComp для безопасной проверки.
🐛 Предлагаемое исправление
-        if (
-            _mapSystem.TryGetTileRef(lavaland.Owner, Comp<MapGridComponent>(lavaland.Owner), xform.Coordinates, out var tile) &&
-            _roof.IsRooved(
-                (lavaland.Owner, Comp<MapGridComponent>(lavaland.Owner), Comp<RoofComponent>(lavaland.Owner)),
-                tile.GridIndices))
-        {
-            return;
-        }
+        if (!TryComp<MapGridComponent>(lavaland.Owner, out var gridComp) ||
+            !TryComp<RoofComponent>(lavaland.Owner, out var roofComp))
+            return;
+
+        if (_mapSystem.TryGetTileRef(lavaland.Owner, gridComp, xform.Coordinates, out var tile) &&
+            _roof.IsRooved((lavaland.Owner, gridComp, roofComp), tile.GridIndices))
+        {
+            return;
+        }
🤖 Prompt for AI Agents
In `@Content.Server/_Lavaland/Weather/LavalandWeatherSystem.cs` around lines 64 -
71, The code calls Comp<MapGridComponent>(lavaland.Owner) twice and uses
Comp<RoofComponent>(lavaland.Owner) which can throw; cache the MapGridComponent
result in a local variable and replace the second Comp call with that variable,
and change the roof lookup to TryComp<RoofComponent>(lavaland.Owner, out var
roofComp) and only call _roof.IsRooved when TryComp returns true (pass roofComp
instead of Comp<RoofComponent>(lavaland.Owner)); keep the existing
_mapSystem.TryGetTileRef(lavaland.Owner, ...) and use tile.GridIndices as
before.

Comment on lines +429 to +438
var q = new Queue<(EntityUid, FlammableComponent)>();
var query = EntityQueryEnumerator<FlammableComponent, TransformComponent>();
while (query.MoveNext(out var uid, out var flammable, out _))
{
q.Enqueue((uid, flammable));
}

while (q.TryDequeue(out var d))
{
var (uid, flammable) = d;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Examine the full Update method context around lines 429-438
sed -n '400,470p' Content.Server/Atmos/EntitySystems/FlammableSystem.cs | cat -n

Repository: Rxup/space-station-14

Length of output: 3274


🏁 Script executed:

# Search for FlammableComponent additions/removals within the file
rg -n "AddComp.*Flammable|RemComp.*Flammable|EnsureComp.*Flammable" Content.Server/Atmos/EntitySystems/FlammableSystem.cs

Repository: Rxup/space-station-14

Length of output: 47


🏁 Script executed:

# Check the entire Update method to understand what operations happen in the processing loop
rg -A 150 "public void Update\(" Content.Server/Atmos/EntitySystems/FlammableSystem.cs | head -200

Repository: Rxup/space-station-14

Length of output: 47


🏁 Script executed:

# Look for uses of TransformComponent in FlammableSystem.cs
rg -n "TransformComponent" Content.Server/Atmos/EntitySystems/FlammableSystem.cs

Repository: Rxup/space-station-14

Length of output: 157


Ненужная аллокация Queue и неиспользуемый запрос TransformComponent

Метод Update() выполняется каждый UpdateTime интервал, и на каждой итерации создается новая Queue. Это вызывает давление на сборщик мусора. Очередь следует переиспользовать как поле класса через Clear().

Также TransformComponent запрашивается в query (строка 431), но никогда не используется (out _).

Анализ показывает, что двухфазная обработка, похоже, не требуется, так как операции внутри цикла не добавляют/удаляют FlammableComponent — они лишь изменяют состояние компонента и добавляют другие типы компонентов (IgnitionSourceComponent).

🔧 Предлагаемое исправление

Добавьте поле класса:

 private readonly Dictionary<Entity<FlammableComponent>, float> _fireEvents = new();
+private readonly Queue<(EntityUid, FlammableComponent)> _flammableQueue = new();

Затем обновите метод Update:

-var q = new Queue<(EntityUid, FlammableComponent)>();
-var query = EntityQueryEnumerator<FlammableComponent, TransformComponent>();
+_flammableQueue.Clear();
+var query = EntityQueryEnumerator<FlammableComponent>();
 while (query.MoveNext(out var uid, out var flammable, out _))
 {
-    q.Enqueue((uid, flammable));
+    _flammableQueue.Enqueue((uid, flammable));
 }

-while (q.TryDequeue(out var d))
+while (_flammableQueue.TryDequeue(out var d))
 {
     var (uid, flammable) = d;
🤖 Prompt for AI Agents
In `@Content.Server/Atmos/EntitySystems/FlammableSystem.cs` around lines 429 -
438, The Update() loop currently allocates a new Queue and requests an unused
TransformComponent; make a class-level Queue<(EntityUid, FlammableComponent)>
(e.g. _flammableQueue) and reuse it by calling _flammableQueue.Clear() at the
start of Update(), and change the query from
EntityQueryEnumerator<FlammableComponent, TransformComponent>() to
EntityQueryEnumerator<FlammableComponent>() (remove the unused
TransformComponent out _), then either enqueue items into the reused
_flammableQueue or—since components aren’t added/removed—process the flammable
entries inline in Update() to eliminate the two-phase allocation entirely;
update references to the local q variable to use the field name (e.g.
_flammableQueue) and keep all logic that modifies
FlammableComponent/IgnitionSourceComponent the same.

@Rxup Rxup merged commit c904fe6 into master Jan 23, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Changes: Map Can be reviewed or fixed by people who are knowledgeable with mapping.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant