diff --git a/HarmonySrc/FreezeProbe.cs b/HarmonySrc/FreezeProbe.cs
new file mode 100644
index 0000000..adf60d5
--- /dev/null
+++ b/HarmonySrc/FreezeProbe.cs
@@ -0,0 +1,46 @@
+using UnityEngine;
+
+namespace NecromancerTome
+{
+ ///
+ /// Замер фризов (жалоба 10.10: «в чертогах лагает... это были фризы»). Средний FPS из строк игры «Time: ... FPS»
+ /// их не показывает - он за минуту. Здесь каждый кадр дольше Threshold пишется в лог: длительность, сколько
+ /// сборок мусора прошло за этот кадр (GC поколения 0 - если растёт, фриз от сборки мусора: мод или игра много
+ /// выделяют), режим мода (чертоги/змея/одержимость) и сколько областей мира загружено.
+ /// Строки: «[NecromancerTome] FreezeProbe: ...». Ничего не хранит, кроме пары чисел.
+ ///
+ public static class FreezeProbe
+ {
+ public const float Threshold = 0.1f;
+ static int _gc = -1;
+ static float _skipUntil;
+
+ public static void Init()
+ {
+ ModEvents.UnityUpdate.RegisterHandler(OnUnityUpdate);
+ }
+
+ static void OnUnityUpdate(ref ModEvents.SUnityUpdateData _data)
+ {
+ int gc = System.GC.CollectionCount(0);
+ World world = GameManager.Instance?.World;
+ if (world == null || world.GetPrimaryPlayer() == null)
+ {
+ _gc = gc;
+ _skipUntil = Time.unscaledTime + 20f; // загрузка мира - фризы ожидаемы
+ return;
+ }
+ float dt = Time.unscaledDeltaTime;
+ int dgc = _gc < 0 ? 0 : gc - _gc;
+ _gc = gc;
+ if (dt < Threshold || Time.unscaledTime < _skipUntil || GameManager.Instance.IsPaused())
+ {
+ return;
+ }
+ string mode = MindPalace.Active ? "чертоги" : SnakeMode.Active ? "змея" : Possession.Active ? "одержимость" : "тело";
+ int obs = GameManager.Instance.World?.m_ChunkManager?.m_ObservedEntities?.Count ?? -1;
+ Debug.Log("[NecromancerTome] FreezeProbe: кадр " + Mathf.RoundToInt(dt * 1000f) + " мс, сборок мусора +" + dgc +
+ ", режим " + mode + ", наблюдателей областей " + obs + ", куча " + (System.GC.GetTotalMemory(false) >> 20) + " МБ");
+ }
+ }
+}
diff --git a/HarmonySrc/MindPalace.cs b/HarmonySrc/MindPalace.cs
index de13834..67adca8 100644
--- a/HarmonySrc/MindPalace.cs
+++ b/HarmonySrc/MindPalace.cs
@@ -829,6 +829,7 @@ namespace NecromancerTome
// Дальность как у змеи: при радиусе 2 игра не строила коллизии участка (тест 03.10:
// «чертоги не построились вовремя» - ждали коллизий 30 с).
_observer = GameManager.Instance.AddChunkObserver(center, true, GameUtils.GetViewDistance(), -1);
+ ShrinkBody(_player);
_stage = Stage.Loading;
_deadline = Time.time + 30f;
Active = true;
@@ -868,6 +869,27 @@ namespace NecromancerTome
GameManager.Instance.RemoveChunkObserver(_observer);
}
_observer = null;
+ EntityPlayerLocal p = GameManager.Instance?.World?.GetPrimaryPlayer();
+ if (_bodyViewDim > 0 && p?.ChunkObserver != null)
+ {
+ p.ChunkObserver.viewDim = _bodyViewDim;
+ }
+ _bodyViewDim = -1;
+ }
+
+ /// Область мира у тела до входа (-1 - не сжата). Фризы в чертогах (жалоба 10.10): игра держала две
+ /// полные области - у чертогов на краю карты и у лежащего тела; подгрузка и пересборка участков - мусор
+ /// и паузы его сборки. Тело сжимаем до Possession.BodyViewDim, как у змеи и одержимого.
+ static int _bodyViewDim = -1;
+
+ static void ShrinkBody(EntityPlayerLocal _player)
+ {
+ ChunkManager.ChunkObserver body = _player?.ChunkObserver;
+ if (body != null && _bodyViewDim < 0 && body.viewDim > Possession.BodyViewDim)
+ {
+ _bodyViewDim = body.viewDim;
+ body.viewDim = Possession.BodyViewDim;
+ }
}
static void OnUnityUpdate(ref ModEvents.SUnityUpdateData _data)
@@ -880,6 +902,7 @@ namespace NecromancerTome
_observer = null;
MindControl.End(null);
_slotsFor = null;
+ _bodyViewDim = -1;
return;
}
EntityPlayerLocal player = world.GetPrimaryPlayer();
diff --git a/HarmonySrc/ModEntry.cs b/HarmonySrc/ModEntry.cs
index 5da1a66..71c898d 100644
--- a/HarmonySrc/ModEntry.cs
+++ b/HarmonySrc/ModEntry.cs
@@ -66,6 +66,7 @@ namespace NecromancerTome
NecroMailbox.Init();
Possession.Init();
BloodTide.Init();
+ FreezeProbe.Init();
// PyramidWardPatch.cs's TEFeaturePyramidWard needs no Init() call - it's discovered
// automatically by the engine's own TileEntityCompositeData reflection scan (see that
// file's class doc comment), not registered here like PetFollowPatch's UnityUpdate hook.
diff --git a/NecromancerHarmony.dll b/NecromancerHarmony.dll
index 4d19333..1df9fd4 100644
Binary files a/NecromancerHarmony.dll and b/NecromancerHarmony.dll differ
diff --git a/NecromancerHarmony.pdb b/NecromancerHarmony.pdb
index a438cb1..8f8d700 100644
Binary files a/NecromancerHarmony.pdb and b/NecromancerHarmony.pdb differ