Странные и специфические ошибки¶
Нестандартные и странные ошибки, рассинхронизации, нелогичное поведение, вылеты, которые иногда можно обнаружить и решить только по опыту...
Иногда встречаются ошибки, которые обычными способами вроде лога после каждой строчки либо решаются очень сложно, либо не решаются в принципе. Хорошо, что они попадаются действительно нечасто.
Вылет без сообщения об ошибке из-за изменения актора в CanCollideWith()¶
Движок считает, что взаимодействующие акторы во время работы этой функции не будут изменены. В теле метода и во всех вызываемых из-под неё подпрограммах запрещено использовать любые операции, которые могут нанести урон, уничтожить, или иным образом кардинально изменить объект (первоисточник: #cancollidewith).
Проверьте, что ни в одном переопределённом CanCollideWith() не используются функции, которые любым способом могут повлиять на восприятие другими объектами этого актора.
Отсутствие проверки на NULL внутри OkayToSwitchTarget()¶
Внутри встроенной OkayToSwitchTarget() нет предварительной проверки на существование актора.
Решение: добавить проверку на существование у себя в коде.
Сообщение "Tried to ticked twice"¶
Менять принадлежность тому или иному множеству StatNum, если оно не присваивается сразу после появления Thinker, небезопасно. Исключение — изменение принадлежности в Thinker.STAT_STATIC и похожих, так как у них не вызывается Tick() .
Thinker исполняется только один раз, при появлении¶
Thinker.STAT_STATIC и некоторые другие множества, в которые может входить любой Thinker, вызывают только PostBeginPlay(), но полностью игнорируют (не вызывают) Tick(). Если нужен постоянный Thinker-обработчик, то следует заменить его множество на такое, у которого происходит тактирование — к примеру, Thinker.STAT_USER.
Необходимость Actor.LinkToWorld()¶
Любое действие с актором, не привязанным к миру, может сломать игру (уточнить).
InputEvent¶
Что в нём?.. (Уточнить.)
Несовместимость Actor.Spawn(), сохранений и BlockLinesIterator/BlockThingsIterator¶
Что-то насчёт того, что итераторы перебирают акторы до того, как какой-нибудь из них окончательно заспаунился. (Уточнить.)
Суть в том, что после сохранения-загрузки итераторы теряются.
Рассинхронизация клиентского актора из-за свойств/флагов¶
Если актор использует общий рандомайзер только на одном клиенте (асинхронный рандомайзер), то происходит рассинхронизация, так как Random() у этого клиента сдвинулся вперёд на одно обращение, и поэтому ему начинает возвращать одни числа, а всем остальным — другие. Так, следующие свойства по умолчанию установлены в небезопасные значения для асинхронной работы:
+SYNCHRONIZEDслужит для предотвращения установки случайной задержки первого такта у актора. Его следует убирать.- При инициализации актора свойство
FloatBobPhaseпо умолчанию стоит в "-1", то есть "выбрать рандомом". Установка в любое значение от 0 до 63 удалит случайность. - Что-то было неприятное с
BlockingMobj, надо уточнить.
Игра не сохраняется, пишет что-то насчёт структур и CVar¶
Нативные структуры на данный момент не могут быть сериализованы (то есть преобразованы в текстовый вид для передачи в файл сохранения). Поэтому в объявлении переменной типа CVar необходимо использовать ключевое слово transient, и, в общем случае, при обращении к такой переменной проверять, существует ли она вообще. Подробнее см. статью rabota-s-cvar.md.
Сообщение "Actor 'название' left without states"¶
Самоудалился, да. Уточнить условие появления.