SA-MP: скриптовые ошибки при запуске gamemode
Запустил samp03svr, в консоли пробежала пара строк — и тишина, игроки на сервер зайти не могут, хотя порт вроде открыт. Или хуже: сервер стартует, но через секунду сам себя вырубает без внятного сообщения. В девяти случаях из десяти дело не в сети и не в firewall, а в самом Pawn-скрипте — gamemode или один из filterscript-ов не пережил загрузку. Разберём, как читать лог, где искать виновника и что делать с конфликтами версий плагинов, которые эту картину обычно и вызывают.
Содержание
- Где искать: server_log.txt, а не то, что мелькнуло в консоли
- Run time error при загрузке: gamemode или filterscript не найден
- Порядок загрузки filterscripts и как найти виновника методом исключения
- Runtime-ошибки во время игры: unknown native, array out of bounds, стек
- crashdetect: точный call stack вместо гадания по логу
- Конфликт версий: старый .amx против новых плагинов
Где искать: server_log.txt, а не то, что мелькнуло в консоли
Консоль SA-MP скроллится быстро, и если сервер стартовал и упал за секунду-две, разглядеть причину на лету почти нереально. Весь этот же вывод параллельно пишется в server_log.txt в корне сервера — открывай его сразу после падения и смотри с конца файла, а не с начала:
tail -n 60 ~/sampserver/server_log.txt
При штатной загрузке в конце лога будет что-то вроде:
Filterscripts
---------------
Loading filterscript 'admin.amx'
Loading filterscript 'gates.amx'
Loaded 2 filterscripts.
Started server on port: 7777, with maxplayers: 50 lanmode is OFF.
Number of vehicle models: 0
Если вместо этого лог обрывается раньше — на строке загрузки гейммода, на конкретном filterscript-е или сразу после баннера версии — сервер упал именно на этом этапе, и следующая пара строк почти всегда прямо называет причину. Важный нюанс: если правишь server.cfg или пересобираешь .amx, а server_log.txt не создаётся заново — сервер иногда дописывает в старый файл, и можно случайно читать вчерашний краш. Проще всего перед тестовым запуском удалить старый лог или явно проверить дату модификации файла.
Run time error при загрузке: gamemode или filterscript не найден
Самая частая причина, почему сервер вообще не поднимает гейммод — банальная опечатка в server.cfg или отсутствующий скомпилированный файл. В логе это выглядит так:
Unable to load gamemode0: mygamemode
или, если сервер всё же попытался загрузить .amx, но не смог его выполнить:
run time error 19: "file or function is not found"
Причины почти всегда одни из трёх:
- в
gamemode0 mygamemode 1указано имя без расширения.amx, а сам файл называется иначе (опечатка, регистр — на Linux файловая система регистрозависима,MyGameMode.amxиmygamemode.amx— разные файлы); .amxне лежит в папкеgamemodes/(частая ошибка — забыли скопировать файл после компиляции на локальной машине);- компиляция
pawnccзавершилась с ошибками, и.amxвообще не создался или создался старым — тогда сервер запускает вчерашнюю версию скрипта, а не ту, что правили только что.
Проверить последний пункт просто — сверить время модификации файла с временем последней компиляции:
ls -la gamemodes/mygamemode.amx
Если сервер уже поднимал этот же гейммод раньше (например, отладку делаешь на локальной копии перед деплоем на боевой VPS), базовую установку с нуля разумно свериться со статьёй про установку SA-MP сервера с нуля — там разобран правильный порядок файлов и путей.
Поднять сервер SA-MP за пару минут
Готовый образ MAATRIX GAMES: NVMe, AMD EPYC, DDoS-защита, панель управления. Локации UK, US, RU. Оплата картой РФ, СБП или криптой.
Создать серверПорядок загрузки filterscripts и как найти виновника методом исключения
Filterscript-ы грузятся строго в том порядке, в котором перечислены в строке filterscripts конфига, слева направо. Если один из них падает на OnFilterScriptInit (например, обращается к несуществующему native-плагину или читает файл, которого нет), сервер обычно не роняет весь процесс, а просто пропускает загрузку конкретного скрипта — но это не всегда так: некоторые ошибки в критичных для инициализации функциях уводят в краш весь samp03svr.
Если лог не называет виновника явно, самый надёжный способ — бинарный поиск. Берём строку filterscripts:
filterscripts admin gates antycheat spawnselect
Убираем половину скриптов и перезапускаем:
filterscripts admin gates
Если сервер поднялся штатно — проблема в одном из убранных (antycheat или spawnselect), делим их пополам и повторяем. Если не поднялся — проблема осталась среди admin/gates, делим дальше. Три-четыре итерации почти всегда находят конкретный файл даже на списке из 10+ filterscript-ов, и это быстрее, чем вручную разбирать код каждого.
Отдельно стоит помнить: filterscript, который просто не загрузился, не всегда сообщает об этом явно — иногда единственный симптом — отсутствие его функциональности в игре (не работает команда /admin, нет ворот на карте), при этом сервер выглядит запущенным нормально. Тут та же строка Loaded N filterscripts в логе — если число меньше, чем скриптов в конфиге, кто-то не загрузился молча.
Runtime-ошибки во время игры: unknown native, array out of bounds, стек
Отдельный класс проблем — сервер стартует нормально, но падает или сыплет ошибками уже во время работы, когда кто-то заходит на сервер или триггерится конкретная функция. В логе это выглядит как повторяющиеся блоки:
[debug] Run time error 4: "Invalid memory access"
[debug] Run time error 19: "File or function is not found"
[debug] Run time error 21: "Native function calls are not enabled"
Коды встречаются чаще всего такие:
| Код | Что означает | Типичная причина |
|---|---|---|
| 4 | Invalid memory access | обращение к массиву/пулу игроков за пределами размера, часто с невалидным playerid |
| 19 (в рантайме) | native не найден | скрипт скомпилирован с инклюдом плагина, а сам .so/.dll плагина не подключён в server.cfg |
| 21 | native calls not enabled | плагин не загрузился до вызова его функции — обычно порядок plugins в конфиге или сам плагин упал при инициализации |
| 29 | stack/heap collision | рекурсия без выхода или слишком большой локальный массив в функции |
Ошибка «unknown native function» — почти всегда про расхождение между тем, с чем скомпилирован .amx, и тем, что реально подключено на сервере в момент запуска. Если гейммод использует, скажем, streamer или sscanf, а в server.cfg строка plugins не содержит соответствующий .so-файл (или файл не той версии), скрипт скомпилируется без единой ошибки — но упадёт в рантайме в первый же момент вызова функции из этого плагина.
crashdetect: точный call stack вместо гадания по логу
Голый server_log.txt часто говорит только «где-то упало», но не называет ни строку, ни функцию. Плагин crashdetect (стандартный инструмент экосистемы SA-MP, идёт вместе со streamer или ставится отдельно) решает это — при краше он пишет полноценный call stack с номерами строк исходника, если гейммод скомпилирован с отладочной информацией.
Ставится как обычный плагин — кладём crashdetect.so (Linux) в папку plugins/ и добавляем в server.cfg:
plugins crashdetect.so
Дальше важный момент: без флага отладки в компиляции crashdetect покажет только адреса в байт-коде, а не читаемые номера строк. Компилировать нужно с -d3:
../pawno/pawncc -d3 mygamemode.pwn
После этого при падении в логе появится что-то вроде:
[debug] Server crashed while executing mygamemode.amx
[debug] AMX backtrace:
[debug] #0 native PlayerName () from samp-server.exe
[debug] #1 0000a4f0 in OnPlayerConnect (playerid=3) at mygamemode.pwn:284
Строка mygamemode.pwn:284 — это конкретная строка исходника, где произошёл сбой, и дальше искать причину уже не вслепую. Для боевого сервера -d3 в проде обычно не оставляют навсегда (небольшой оверхед и вес .amx растёт), но на время отладки конкретного падения это самый быстрый путь к причине.
Конфликт версий: старый .amx против новых плагинов
Отдельная головная боль — когда всё компилируется без ошибок, сервер стартует, но ведёт себя нестабильно или падает время от времени без явной связи с конкретным действием игрока. Частая причина — рассинхрон версий между тем, с чем гейммод писался, и тем, что реально стоит на сервере:
.inc-файл не совпадает с бинарником плагина. Если скачал новую версиюsscanf.inc, а.so-файл плагина остался старым (или наоборот), сигнатуры некоторых функций могут разойтись — это не всегда даёт ошибку компиляции, но даёт неверные результаты или краш в рантайме.- MySQL-плагин разных мажорных веток. Синтаксис вызовов между старыми R33-R39 и более новыми R41+ отличается заметно (thread-based vs новый API), гейммод, написанный под одну ветку, не запустится корректно на плагине другой — обычно это видно сразу по ошибкам
unknown nativeна первом же SQL-запросе. - Несколько версий streamer в разных филтрскриптах. Если основной гейммод и один из filterscript-ов компилировались с разными версиями
streamer.inc, но на сервере стоит только одна версия.so, тот из скриптов, что рассчитан на другую версию, скорее всего словит ошибки рантайма именно на функциях стриминга объектов. - AMX, скомпилированный более новым pawncc, чем поддерживает сервер. Редкая, но встречающаяся ситуация при переносе
.amxс более свежего окружения на старый билд сервера — версия формата байт-кода не совпадает. Решение — пересобрать.amxлокально тем жеpawncc, что лежит в архиве целевого сервера, а не приносить бинарник с чужой машины.
Практическое правило: если правишь include-файлы плагинов, всегда обновляй одновременно и .inc, и соответствующий бинарник плагина, и не смешивай версии между гейммодом и filterscript-ами — держи весь набор инклюдов в одной папке pawno/include/ и подключай к компиляции всех скриптов проекта именно из неё, а не из разных источников. Если только разворачиваешь SA-MP-проект и подбираешь готовый гейммод, стоит заранее свериться с требованиями конкретной сборки — например, в обзоре популярных RP-геймодов вроде Cops and Robbers обычно прямо указано, под какие версии плагинов писался скрипт.
Поднять сервер SA-MP за пару минут
Готовый образ MAATRIX GAMES: NVMe, AMD EPYC, DDoS-защита, панель управления. Локации UK, US, RU. Оплата картой РФ, СБП или криптой.
Создать серверЧастые вопросы
Сервер запускается, но в игре список серверов его не видит — это тоже скриптовая ошибка?
Нет, это отдельная история про announce 1/query 1 в конфиге и открытые порты, к Pawn-скриптам не относится — если сервер стартовал и держит порт, дело не в gamemode.
Можно ли увидеть причину падения без crashdetect?
Частично да — базовые run time error с кодом пишутся в server_log.txt и без него, но без номера строки исходника искать причину в большом гейммоде долго. crashdetect экономит часы на действительно сложных крашах.
После обновления одного плагина упал весь сервер — как быстро откатиться?
Верни предыдущую версию .so-файла плагина из бэкапа (или пересобери из архива прошлого релиза) и перезапусти — обновления бинарных плагинов SA-MP-экосистемы редко бывают строго обратно совместимы, поэтому такие бинарники стоит держать в отдельной папке с версией в имени на случай отката.
Ошибка «run time error 19» появляется и при загрузке гейммода, и в рантайме — это одно и то же?
Формально один код, но разные ситуации: при загрузке это обычно «файл .amx не найден», в рантайме — «native-функция не найдена», потому что не подключён нужный плагин. Смотри, на каком этапе именно появилась ошибка в логе.
Стоит ли сразу переходить на open.mp, если конфликты версий задолбали?
Как отдельное решение это не панацея — Pawn-скрипты и логика ошибок остаются похожими, но open.mp активнее поддерживается и меньше страдает от разночтений версий классического SA-MP. Если начинаешь новый проект с нуля, а не мигрируешь существующий, присмотреться стоит.