Files
necromants-tome-7d2d-3-2/HarmonySrc/CVarBindingLeakPatch.cs
T
AlexCubeandClaude Opus 5.5 205b4d7071 1.4.3: сползание FPS и текстура пирамиды - перенос исправлений 1.5.1 на игру 3.2
В 1.4.2 (игра 3.2) оставалась та же утечка, что чинилась в 1.5.1: шкала некромантии
fill="{% cvar('necroNecromancyProgressCVar') / 20 }" набирала по одной отслеживаемой
переменной за кадр (ошибка игры в BindingNcalcFunctions.cvar / BindingInfoNcalc.RegisterVariable;
в 3.2 эти классы совпадают с 3.3 построчно). CVarBindingLeakPatch - без изменений из 888cf1e.

Пирамида Ереси при Texture Quality ниже Full: CustomBlockPaint берёт мип под размер атласа,
бандл necroatlas - пересобранный с ignoreMipmapLimit (оба из 888cf1e).

Сборка: игра на машине уже 3.3, поэтому DLL собрана против справочной сборки 3.2,
сгенерированной из декомпиляции 3.2 (только метаданные). Проверка метода: пересборка
нетронутой 1.4.2 дала те же 1049 ссылок на внешний код, что и опубликованная DLL; в 1.4.3
добавилось 9 ссылок, все есть в DLL 1.5.1, собранной против настоящей игры.
В игре 3.2 НЕ проверено.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:48:20 +03:00

43 lines
2.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using HarmonyLib;
namespace NecromancerTome
{
/// <summary>
/// Утечка в самой игре, на которую наступала шкала некромантии в поясе (1.3.0+,
/// fill="{% cvar('necroNecromancyProgressCVar') / 20 }" в Config/XUi_InGame/windows.xml).
///
/// Найдено 28.09 замером (NecroProfiler): FPS 60 -> 30 за 10-15 минут в любом мире, в теле;
/// группа окон toolbelt росла 2 -> 23 мс/кадр при неизменных 573 элементах; в режиме змеи пояс
/// скрыт - и тормозов нет; перезаход в мир сбрасывает.
///
/// Механика (декомпиляция 3.3): BindingNcalcFunctions.cvar при каждом вычислении выражения
/// регистрирует НОВЫЙ VariableStateCVar, а BindingInfoNcalc.RegisterVariable добавляет его в
/// список без проверки. Новая переменная начинает с 0; если шкала не пуста, её RefreshValue в
/// следующем кадре видит «изменилось» -> выражение пересчитывается -> cvar() добавляет ещё одну.
/// Плюс одна переменная за кадр, пока CVar не 0, и каждый кадр обходится весь список.
///
/// Лечение: одну и ту же CVar в одной привязке регистрируем один раз. Значение cvar() берёт
/// прямо у игрока, так что отслеживающая переменная нужна только одна - для «изменилось».
/// </summary>
[HarmonyPatch(typeof(BindingInfoNcalc), nameof(BindingInfoNcalc.RegisterVariable))]
public static class Patch_BindingInfoNcalc_RegisterVariable_CVarLeak
{
public static bool Prefix(BindingInfoNcalc __instance, BindingInfoNcalc.VariableStateAbs _var, ref bool __result)
{
if (!(_var is BindingInfoNcalc.VariableStateCVar added))
{
return true;
}
foreach (BindingInfoNcalc.VariableStateAbs existing in __instance.variables)
{
if (existing is BindingInfoNcalc.VariableStateCVar known && known.cVarName == added.cVarName)
{
__result = true;
return false;
}
}
return true;
}
}
}