Script engine.cpp
Скриптовые «вылеты»
Общее решение
Решение подобных ошибок[1] - задача нетривиальная. Поэтому их исправлением следует заниматься только тем, кто обладает хотя бы базовыми знаниями скриптинга.
1 вариант
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp Line : 73 Description : Arguments : LUA error: ...\gamedata\scripts\xr_danger.script:116: attempt to index field 'ignore_types' (a nil value)
Ошибка[2]
Попытка взять значение из переменной ignore_types
(может быть любая другая). Движок игры ожидал, что это таблица, а оказалось nil
.
Подсказка скриптеру
Необходимо изменить код таким образом, чтобы там где ожидается таблица, была таблица или чтобы из nil
не пытались прочесть какие-то значения.
Конкретно в данном случае скрипт записывает настройки игнорирования опасности в таблицу db.storage[npc:id()].danger.ignore_types, а пытается проверять по несуществующей таблице db.storage[npc:id()].ignore_types.
2 вариант
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp Line : 73 Description : Arguments : LUA error: ...\gamedata\scripts\.script:34: attempt to call method 'section' (a nil value)
Ошибка
У какого-то объекта пытались вызвать метод section
(название метода может быть любым другим). Обнаружилось, что у этого объекта, такого метода не существует.
Подсказка скриптеру
Возможные варианты:
- Это был объект не того класса, как предполагалось (клиентский вместо серверного, или наоборот, или другие классы).
- Возможно была опечатка в названии метода, и он просто называется не так.
- Возможно невнимательно был изучен данный класс, и у него просто нет и не должно быть такого метода.
Например, это можно проверить конструкциями наподобие этой:
if obj.section and type(obj.section) == 'function' then obj:section() end
Т.е. до вызова метода, проверить, что у объекта существует такое поле, и имеет тип function
, т.е. его возможно вызвать.
Но следует понимать что не стоит обвешивать такими проверками все подряд вызовы везде. Куча проверок займет много времени и вызовет тормоза. Это годится лишь для отладки - узнали есть ли метод или нет. Если нет, значит и не надо пытаться его вызывать, а если есть, то можно вызывать без всяких проверок.
3 вариант
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp Line : 73 Description : Arguments : LUA error: ...w of chernobyl\gamedata\scripts\<имя файла>.script:<номер строки>: attempt to perform arithmetic on a nil value
Ошибка
Попытка выполнения арифметической операции над nil
.
Подсказка скриптеру
Чтобы исправить ошибку, сначала необходимо её найти. Обратите внимание на <номер строки>
, попытка выполнения арифметической оперции над nil
происходит именно в ней. Ещё могут быть указаны имена переменных, это так же является подсказкой.
4 вариант
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp Line : 73 Description : Arguments : LUA error: ...\gamedata\scripts\<имя файла>.script:<номер строки>: attempt to compare number with nil
Ошибка
Попытка сравнения числа с nil
Подсказка скриптеру
Чтобы исправить ошибку, сначала необходимо её найти. Обратите внимание на <номер строки>
, попытка сравнения числа с nil
происходит именно в ней. Ещё могут быть указаны имена переменных, это так же является подсказкой.
5 вариант
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp Line : 73 Description : Arguments : LUA error: ...\gamedata\scripts\<имя файла>.script:<номер строки>: attempt to perform arithmetic on field '?' (a nil value)
Ошибка
Аналог вылетов из вариантов 3 и 4. Попытки арифметических действий над nil
, просто этот nil
не имеет собственного имени и является элементом таблицы.
Подобные же вылеты могут быть и при других попытках каких-то действий, предполагающих, что переменная хранит некое значение, когда в результате обнаруживается что там все же nil
.
Подсказка скриптеру
Чтобы исправить ошибку, сначала необходимо её найти. Здесь, либо данные читаются не оттуда, откуда должны, либо где-то должны были их туда записать, но не записали.
6 вариант
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\sources\trunk\xr_3da\xrGame\script_engine.cpp Line : 73 Description : Arguments : LUA error: error in error handling
Ошибка
Причину вылета назвать достаточно трудно, вероятно это что-то глубоко движковое. Такой вылет может вызывать передача клиентcкого объекта в функцию switch_offline, но не только это.
Подсказка скриптеру
В случае передачи клиентского объекта - устранить ошибку. Но определить причину в большинстве случаев крайне проблематично - попробуйте загрузить последнее сохранение.
Можно предположить, что подобный вылет может возникать в ряде случаев, когда в движковые методы, ожидающие объект определенного класса, передается объект не того класса, который они ожидают. Если предположение верно - проверить правильность данных, передаваемых таким движковым методам.
7 вариант
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\sources\trunk\xr_3da\xrGame\script_engine.cpp Line : 73 Description : Arguments : LUA error: attempt to call a nil value
Ошибка
Происходит при попытке вызвать конструктор класса, которого не существует или локальную функцию, которой не существует.
Подсказка скриптеру
Возможные варианты:
- В имени конструктора/функции допущена опечатка, и он просто не так называется.
- Вызываемое не является конструктором, функцией, или просто не существует.
8 вариант
Expression : fatal error Function : CScriptEngine::lua_error File : D:\xray-svn\xr_3da\xrGame\script_engine.cpp Line : 73 Description : Arguments : LUA error: C stack overflow
Ошибка
Обратите также внимание на текст выше строки FATAL ERROR
из лога.
Строка Arguments
в разных случаях может отличаться. Причина подобных вылетов - передача некорректных значений функциям игры.
А общий смысл - попытка сделать что-то, чего делать нельзя в принципе, т.е. невозможное (как деление на ноль, например).
Суть ошибки в том, что какая-то функция вызвана огромное число раз подряд, вместо одного. Функции иногда вызываются рекурсивно, в цикле, но всегда это имеет ограниченные и разумные пределы. В данном случае, вылет из-за того что эти пределы исчезли.
Решение
Если проблема возникла однократно - загрузите последнее сохранение.
В самом деле помогает, т.к. периодически такие ситуации возникают случайным образом даже с оригинальными GSC-скриптами.
Подсказка скриптеру
Если проблема стабильна - отслеживать вызовы подозреваемых функций, найти функцию которая переполняет стек, и причину почему она вызывается бесконечное число раз. Возможно, неверно указаны условия прекращения цикла и/или прекращения рекурсивного вызова функцией самой себя.
Чтобы исправить ошибку необходимо найти, где и почему она происходит. Для этого установите выводы чекпойнтов вызова функций в лог, сначала самых общих, с которых можно начать поиск. Потихоньку это и выведет на причину.
Наглядный пример:
function actor_item_take(obj, item)
--log("events.actor_item_take")
Тут закомментирован вызов лога, а когда был не закомментирован - в лог сообщалось о каждом вызове этой функции. Так это и делается.
В логе должно быть видно, как какая-то из функций вызывается миллион раз, хотя должна быть вызвана 1 раз - это и есть причина вылета.
Примечание:
Иногда та же самая ошибка, т.е. та же самая причина, может приводить к другому вылету - Ran out of memory
. Это когда вызываемые функции успевают "сожрать" всю память раньше, чем "сожрут" весь стек.
9 вариант
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp Line : 73 Description : Arguments : LUA error: No such operator defined
Ошибка
Попытка использовать для какого-то объекта, несуществующий метод. Зачастую путаница с серверными и клиентскими методами.
Подсказка скриптеру
См. вариант 2, там было про отсутствующий метод section
, здесь имя метода не указано, но смысл тот же. Как правило, объект не того класса, или не существующий у данного класса метод, или попытка вызвать как метод то, что им не является.
10 вариант
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\sources\trunk\xr_3da\xrGame\script_engine.cpp Line : 73 Description : Arguments : LUA error: ...\gamedata\scripts\<имя файла>.script:<номер строки>: unfinished capture
Ошибка
Единственная известная причина данного вылета, это попытка использовать для функции string.find
в качестве шаблона "волшебный символ" открывающуюся круглую скобку, т.е. попытка найти скобку таким образом:
local p = string.find(str, "(")
Подсказка скриптеру
Для поиска открывающейся круглой скобки используйте параметр plain(local p
) для данной функции со значением true
, он выключает возможность поиска по шаблону и в таком случае производится поиск подстроки как есть:
local p = string.find(str, "(", 1, true)
11 вариант
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp Line : 73 Description : Arguments : LUA error: ...ing\s.t.a.l.k.e.r\gamedata\scripts\inv_system.script:1674: attempt to call function 'GetCommand_TakeSlot' (a nil value)
Ошибка
Казалось бы, причина ясна - вызов функции, которой не существует. Однако функция есть, и называется именно так, и с ней все в порядке. Как и с самим файлом скрипта тоже - в нем нет синтаксических ошибок, движок игры не ругается на него самого, заявляя что он a nil value
Причина оказалась вот в чем - в начале скрипта, есть таблица, такого вида:
tbl = {
string_key1 = number,
string_key2 = number,
...
А далее есть еще одна таблица - вот такого вида:
tb_funcs = {
[tbl.string_key1] = function(args...)
...
end,
...
Т.е. значения ее - функции, а ключами являются значения из первой таблицы.
Ну так вот, в первой таблице изменили имя одного из ключей. А во второй - забыли это сделать. Получилось что во второй таблице, одна из функций находится по ключу, который вообще-то равен nil
.
А причем же тут та функция, из-за вызова которой, и произошел вылет с нею в лог? Да вообще ни при чем. Она просто находилась в том же файле ниже по тексту.
Подсказка скриптеру
Вывод - когда делаете в таблицах ключи вида массив/модуль/значение - убедитесь что это значение не равно nil
, а то движок игры об этом нормально не скажет.
12 вариант
Тип №1
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp Line : 73 Description : <no expression> Arguments : LUA error: ...e.r_Закоулки правды\gamedata\scripts\uyman358.script:947: attempt to call field 'get_anomaly_data' (a nil value)
Ошибка[3][4]
Для новичков: скрипт (в данном случае: uyman358.script) не может вызвать указанную в строке (в данном случае: 947) функцию (в данном случае: 'get_anomaly_data'
).
Для опытных: попытка вызова указанной функции (в данном случае: 'get_anomaly_data'
). Движок игры ожидал, что это таблица, а оказалось nil
.
Допустим, в таблице лежат числа. Попытка взять из таблицы значение - пройдет без проблем, а попытка вызова - приведет к вылету, т.к. числа это не функции, их нельзя вызывать.
Подсказка скриптеру
Для новичков: проверить в скрипте, который указан в строке, правильность имени функции, а также её наличие.
Для опытных: необходимо изменить код таким образом, чтобы там где ожидается функция, была функция или чтобы из nil
не пытались прочесть какие-то значения.
Тип №2
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp Line : 73 Description : <no expression> Arguments : LUA error: ....- Народная Солянка\gamedata\scripts\xr_logic.script:1490: attempt to call field '?' (a nil value)
Ошибка[5]
Тут должно было быть имя функции или переменной, но его нет (в данном случае: '?'
). Это значит, что ее, например, вызвали по числовому индексу из таблицы или еще как-то, причины могут быть разные.
А общий смысл - то, с чем пытались совершить указанное действие, не имеет имени.
Например, у типа 1:
uyman358.script:947: attempt to call field 'get_anomaly_data' (a nil value)
Указано имя get_anomaly_data
. Ошибка произошла при попытке действия с именно этой переменной, ее имя указывается всегда, когда движок может указать имя с которым произошла ошибка. Но нередко бывает, что у переменной нет имени. Вот тогда он и пишет '?'
13 вариант
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\sources\trunk\xr_3da\xrGame\script_engine.cpp Line : 73 Description : <no expression> Arguments : LUA error: ...ow of chernobyl\gamedata\scripts\bind_stalker.script:341: attempt to call global 'give_info' (a nil value)
Ошибка
В файле _g.script не найдена указанная глобальная функция (в данном случае: give_info
)
Решение
Проверить правильность имени функции, а также её наличие в _g.script.
14 вариант
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\sources\trunk\xr_3da\xrGame\script_engine.cpp Line : 73 Description : <no expression> Arguments : LUA error: not enough memory
Ошибка[6][7][8]
LuaJIT может использовать память только в младших 2 Гб, а в крупных модах туда складываются крупные текстуры, крупные локации и все остальное такое же крупное. В итоге через какое-то время младшие 2 Гб оказываются забиты и, хотя памяти еще полно, LuaJIT выделить для себя память не может.
Решение[9]
- Попробуйте загрузить последние сохранения или уйти на другую локацию.
В некоторых случаях это помогает из-за того, что при старте LuaJIT успевает отхватить себе память раньше, чем ее захватят текстуры, и какое-то время LuaJIT еще проработает.
или
- Используйте 64-битный движок OGSR Engine.
Он выделяет для LuaJIT память заранее. По нынешним меркам ему нужны сущие крохи - порядка сотни мегабайт.
Expression : fatal error Function : CScriptEngine::lua_error File : E:\priquel\sources\engine\xrServerEntities\script_engine.cpp Line : 180 Description : <no expression> Arguments : LUA error: not enough memory
Ошибка[10][11][12]
Версия игры отличается, см. строчку File:
(в данном случае: ЧН)
Решение
Использовать надо движок X-Ray Engine by Abramcumner
15 вариант
Expression : fatal error Function : CScriptEngine::lua_error File : D:\xray-svn\xr_3da\xrGame\script_engine.cpp Line : 74 Description : <no expression> Arguments : LUA error: ...\gamedata\scripts\_g.script:20: bad argument #2 to 'format' (string expected, got no value)
Expression : fatal error Function : CScriptEngine::lua_error File : E:\priquel\sources\engine\xrServerEntities\script_engine.cpp Line : 180 Description : <no expression> Arguments : LUA error: d:\games\s.t.a.l.k.e.r\cs\gamedata\scripts\_g.script:975: bad argument #2 to 'format' (string expected, got nil)
Ошибка[13]
Для новичков: какой-то скрипт, не может вызвать какую-то функцию, из-за того что вызов функции написан неправильно, а именно, отсутствует имя функции. Должно быть так имя_скрипта.имя_функции_в_скрипте
, а оно вот так имя_скрипта.
.
Для опытных: имя скрипта (в данном случае: _g
), номер строки (в данном случае: 20
) и номер аргумента после симмвола #
(в данном случае: 2
) — могут быть другими.
Ошибка заключается в том, что функция string.format
(может быть и другая) ожидала получить во втором аргументе в указанной строке файла - строку, а получила nil
.
Подсказка скриптеру
Для новичков: проверяйте, что изменяли в скриптах последний раз, а именно — правильность вызова функции (наличие имени функции после имени скрипта).
Для опытных: необходимо дать ей строку, или не давать то, что может не быть строкой, или перед подачей в string.format
проверять значение.
Источники
- ↑ Страница "Справочник вылетов (Line 1 - Line 100)" на AMK форуме
- ↑ Пост пользователя "stalker2002ru" на форуме AP Production
- ↑ Пост пользователя "zevs100111" на форуме stalker-gamers.ru
- ↑ Пост пользователя "vyatkin" на форуме reborn-stalker.ws
- ↑ Пост пользователя "Ника" на форуме AP Production
- ↑ Пост пользователя "MegaStalker" на AMK форуме
- ↑ Пост пользователя "Ааз" на AMK форуме
- ↑ Пост пользователя "abramcumner" на форуме Gameinator от 10:17, 1 июля 2018 года
- ↑ Пост пользователя "abramcumner" на форуме Gameinator от 16:25, 1 июля 2018 года
- ↑ Пост пользователя "Beyonder" на AMK форуме
- ↑ Пост пользователя "Gandzia" на сайте playground.ru
- ↑ Пост пользователя "IlyaMirniy" на форуме AP Production
- ↑ Пост пользователя "sgs-sd" на форуме Gameinator