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>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
f4470b784f
commit
205b4d7071
@@ -0,0 +1,42 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user