Ошибки Luau в Studio: что означают сообщения в Output
Восемь сообщений, которые Studio печатает чаще всего, — с переводом на человеческий, причиной и рабочим кодом вместо сломанного.
Средне 22 минуты проверен 2 часа назад
Что понадобится
Установленная Roblox Studio и открытая панель Output (меню View → Output). Базовый Luau — переменные, функции, события.
Текст гайда «Ошибки Luau в Studio: что означают сообщения в Output»
Содержание
Красная строка в Output выглядит пугающе, но это самое полезное, что есть у начинающего скриптера. Studio почти всегда говорит ровно то, что случилось: какой объект не нашёлся, в какой строке и в каком скрипте. Разберём сообщения, которые встречаются чаще остальных.
Сначала прочитай хвост строки
В конце каждой ошибки Studio пишет путь к скрипту и номер строки, например Script:14. По нему можно щёлкнуть — редактор откроет нужное место. Половина «непонятных» ошибок понимается сразу после этого.
attempt to index nil with ...#
Самая частая ошибка вообще. Переводится буквально: «пытаюсь взять что-то у пустоты». Объект, к которому ты обращаешься, не найден — вместо него nil, а у nil ни свойств, ни детей быть не может.
-- В Workspace модель называется "Door", а в коде "door"
local door = workspace.door
door.Transparency = 0.5
-- attempt to index nil with 'Transparency'Причин ровно три: опечатка в имени, объект лежит в другом месте или он ещё не успел загрузиться. Первые две лечатся вниманием, третья — ожиданием.
local door = workspace:WaitForChild("Door")
door.Transparency = 0.5Infinite yield possible on ...#
Это не ошибка, а предупреждение жёлтым: WaitForChild ждёт объект дольше пяти секунд и, судя по всему, не дождётся никогда. Скрипт при этом не падает — он просто стоит на месте, и всё, что ниже, не выполняется.
- Имя написано с другой буквы или с пробелом на конце — сравни посимвольно в Explorer
- Объект лежит не там: искали в Workspace, а он в ServerStorage
- Объект создаётся другим скриптом позже, и порядок запуска не тот, на который ты рассчитывал
- Объекта нет вовсе: его удалили или он появляется только на сервере, а ждёт его клиент
X is not a valid member of Y#
Объект нашёлся, а вот свойства или ребёнка с таким именем у него нет. Частый случай — путаница между Part и Model: у модели нет Position и BrickColor, потому что модель — это контейнер, а не деталь.
local model = workspace:WaitForChild("Chest")
-- Position is not a valid member of Model
-- print(model.Position)
print(model:GetPivot().Position)attempt to call a nil value#
Ты зовёшь функцию, которой не существует. Обычно это опечатка в названии метода или перепутанные точка и двоеточие: part:Destroy() — метод объекта, part.Destroy() — попытка вызвать поле, и Luau честно сообщает, что вызывать нечего.
local part = workspace:WaitForChild("Trap")
part.Touched:Connect(function(hit)
local humanoid = hit.Parent:FindFirstChildOfClass("Humanoid")
if humanoid then
humanoid:TakeDamage(20)
end
end)attempt to perform arithmetic on a string value#
Складываются число и строка. Чаще всего это значение из текстового поля, из атрибута или из StringValue: выглядит как число, а по типу строка. Лечится приведением через tonumber — и обязательной проверкой результата, потому что tonumber("двадцать") вернёт nil.
local input = script.Parent.Amount.Value -- "25"
local amount = tonumber(input)
if amount then
print(amount * 2)
else
warn("В поле не число: " .. tostring(input))
endUnable to assign property ... expected, got ...#
Свойству дают значение не того типа. Самая частая пара — Vector3 и число: позиция состоит из трёх координат, одним числом её не задать. Такая же история с Color3, CFrame и UDim2.
local part = workspace:WaitForChild("Platform")
part.Position = Vector3.new(0, 10, 0)
part.Color = Color3.fromRGB(91, 92, 246)
part.Size = Vector3.new(8, 1, 8)Script timeout: exhausted allowed execution time#
Бесконечный цикл без паузы. Luau в Roblox однопоточный: пока цикл крутится без остановки, движок не может заняться ничем другим и через несколько секунд убивает скрипт. Пауза внутри цикла обязательна.
while true do
task.wait(1)
print("Прошла секунда")
endtask.wait вместо wait
Старая функция wait() всё ещё работает, но Roblox считает её устаревшей и точность у неё хуже. В новом коде пиши task.wait() — это тот же смысл и более предсказуемое поведение.
Скрипт вообще не запускается#
Ошибки нет, Output пуст, ничего не происходит. Значит, скрипт лежит не там, где его исполняют. Место в дереве объектов для Roblox — это и есть указание, где и когда код запускать.
| Что положил | Куда | Запустится |
|---|---|---|
| Script | ServerScriptService, Workspace | Да, на сервере |
| Script | StarterGui, StarterPlayerScripts | Нет: там место клиентским скриптам |
| LocalScript | StarterPlayerScripts, StarterGui, инструмент игрока | Да, у каждого игрока свой |
| LocalScript | Workspace, ServerScriptService | Нет, молча ничего не делает |
| ModuleScript | Где угодно | Только когда его подключат через require |
Проверь заодно свойство Disabled у скрипта: галочка стоит — кода для движка не существует.
Как искать ошибку, если сообщение не помогло#
- Расставь print перед подозрительным местом и после него — увидишь, до какой строки код доходит
- Печатай не только факт, но и значение: print("hp:", humanoid.Health) говорит больше, чем print("тут")
- Для предупреждений используй warn — они видны в Output жёлтым и не теряются в потоке
- Открой вкладку Server и Client в тестовом режиме: ошибка на сервере и на клиенте выглядит по-разному
- Отключи половину скриптов и проверь снова — так за пару шагов находится тот, который ломает остальное
Если ошибка не в коде, а в самом клиенте Roblox — окно с номером вроде 277 или 267 — это другая история, и разбирается она в справочнике ошибок. Основы языка, на которые всё это опирается, — в гайде «Luau с нуля».
Обсуждение
Пиши по делу и без личных данных. Ссылки на сторонние сайты, обмен и «бесплатные робуксы» мы скрываем — почему.
Комментарии пишут те, кто вошёл — так спокойнее всем.
ВойтиПока никто ничего не написал. Будь первым.