Перейти к основному содержимому

Roblox / Luau — скрипты для новичков

Подборка готовых скриптов Roblox Studio на Luau с подробным разбором каждой строки — «что написано», «что происходит в Play» и «зачем так». Страница для тех, кто в Google ищет roblox script, luau script example, kill brick touched, leaderstats coins, LocalScript walkspeed, RemoteEvent FireServer или собирает первый obby, лабораторную и мини-игру.


Основы скриптов в Roblox Studio

Luau — язык Roblox (диалект Lua). Код живёт не в отдельном .lua на диске, а в объектах Script, LocalScript и ModuleScript в дереве Explorer. Нажали Play (F5) — Studio запускает локальный сервер и клиент; скрипты начинают выполняться.

С чего начать

Установка Studio и первый Place — Roblox Studio — первая игра. Синтаксис — основы Lua, API Roblox — Luau в Roblox. Рисование на Python — Turtle; те же идеи «событие → действие» — здесь, в 3D. Unity-аналог — скрипты C#.

Как запустить пример за 30 секунд

  1. Откройте Roblox Studio → шаблон Baseplate.
  2. В Explorer найдите папку из инструкции к примеру (чаще всего ServerScriptService).
  3. ПКМ → Insert ObjectScript или LocalScript → переименуйте (HelloServer, CoinPickup…).
  4. Дважды щёлкните скрипт → вставьте код целикомCtrl+S.
  5. Test → Play (F5). Окно View → Output — белые print и красные ошибки.
Где смотреть результатЧто увидите
OutputТекст print, ошибки с номером строки
ViewportДвижение Part, смерть на лаве, исчезновение монетки
Tab (клавиша Tab в Play)Таблица leaderstats с Coins
Экран игрокаUI из StarterGui

Скрипты не запускаются на этой странице сайта — только в Studio или в опубликованной игре.


Что ищут в Google — быстрый переход

Типичный запросКуда на странице
roblox script example, luau scriptПервый print, каркас
roblox script templateОбязательный каркас
ServerScriptService scriptКаркас Script
roblox print helloПервый print
Players.PlayerAddedПриветствие игрока
roblox rotate partВращение Part
roblox lava script killКирпич-смерть
roblox collect coin scriptМонетка и leaderstats
leaderstats robloxМонетка и leaderstats
roblox jump pad scriptПрыжковая платформа
roblox sprint script LocalScriptСпринт
WalkSpeed script robloxСпринт
roblox gui TextLabel scoreUI счёт
RemoteEvent FireServer exampleRemoteEvent
require ModuleScript robloxModuleScript
roblox Touched not workingЧастые ошибки
LocalPlayer is nilЧастые ошибки
how to make obby robloxМини-проект obby

Базовые термины — за 2 минуты

ТерминПростыми словами
ScriptКод на сервере — счёт, урон, спавн, античит
LocalScriptКод на вашем ПК — UI, камера, ввод клавиш
ModuleScriptБиблиотека функций; подключается через require
PartКуб, шар, платформа на карте
Humanoid«Жизнь» персонажа — здоровье, прыжок, скорость
TouchedСобытие «что-то коснулось этого Part»
ConnectПодписка на событие — «когда случится X, вызови функцию»
leaderstatsПапка у Player; Roblox показывает её в Tab как таблицу счёта
RemoteEventСигнал клиент → сервер (и обратно) по сети
CFrameПозиция и поворот объекта в 3D

Какую механику выбрать

Вы ищете…Пример нижеИдея
Проверить, что Studio работаетPrintОдна строка в Output
Покрасить платформуЦвет PartСвойства объекта из кода
Лава / смертьКирпич-смертьTouchedHealth = 0
Монетки, очкиМонеткаleaderstats + IntValue
Прыжок вышеJump padHumanoid.JumpPower / JumpHeight
Бег по ShiftСпринтLocalScript + WalkSpeed
Текст на экранеUITextLabel + Changed
Кнопка E → действиеRemoteEventКлиент просит, сервер решает
Общий код в одном местеModuleScriptrequire

Клиент и сервер — где какой скрипт

В Roblox один сервер (главный по правилам игры) и клиент у каждого игрока (его экран и клавиатура). Счёт монет и урон от лавы делают на сервере. Подпись «Монеты: 5» на экране и реакция на Shift — часто на клиенте, но цифру монет всё равно меняет сервер.

ТипПапка в ExplorerКто выполняет
ScriptServerScriptService, иногда внутри PartСервер
LocalScriptStarterPlayerScripts, StarterGuiТолько этот игрок
ModuleScriptReplicatedStorage, ServerScriptServiceОткуда вызвали require
Turtle PythonUnityRoblox Luau
Запускpython file.pyКнопка PlayF5 в Studio
Мирокно черепашкиSceneWorkspace + Explorer
Цикл кадровontimer / циклUpdate()RunService.Heartbeat
КасаниенетOnTriggerEnterTouched
LocalPlayer только на клиенте

В Script на сервере Players.LocalPlayer всегда nil. Свой персонаж на клиенте — LocalScript и Players.LocalPlayer. Очки, которые видят все игроки, создавайте в leaderstats на сервере.


Обязательный каркас

Любой учебный скрипт повторяет одну схему: получить сервис → подписаться на событие или цикл → менять объекты.

Script на сервере (ServerScriptService)

--!strict

local Players = game:GetService("Players")

print("Сервер запущен")

-- обработчики: PlayerAdded, Touched, task.wait, require

Разбор построчно:

СтрокаЧто происходитЗачем
--!strictStudio проверяет типы при набореМеньше ошибок «не тот тип»
local Players = ...Ссылка на сервис игроковНе писать длинный путь каждый раз
game:GetService("Players")Официальный способ взять APIРаботает после перезагрузки Place
gameКорень всего дерева ExplorerОтсюда доступен весь мир
print(...)Строка в OutputПервая отладка без UI

Разбор по смыслу:

  • В Luau local — переменная только в этом файле; так принято почти везде.
  • Комментарий -- — строка для человека, движок её пропускает.
  • Серверный скрипт не видит клавиатуру игрока — для WASD нужен LocalScript.

LocalScript на клиенте (StarterPlayerScripts)

--!strict

local Players = game:GetService("Players")
local player = Players.LocalPlayer

print("Клиент готов:", player.Name)
СтрокаЧто происходитЗачем
LocalPlayerОбъект вашего игрока на этом ПКUI, камера, «свой» ввод
StarterPlayerScriptsПри входе Studio копирует скрипт в игрокаОдин раз написали — у всех клиентов

Где создавать объекты:

ЗадачаExplorer → Insert Object
СерверServerScriptServiceScript
КлиентStarterPlayerStarterPlayerScriptsLocalScript
БиблиотекаReplicatedStorageModuleScript
Логика одного кубаPart → Script (сервер, если Part в Workspace)

Стартовые скрипты

Шаблон Baseplate: пол, SpawnLocation, один локальный игрок в Play.


Первый скрипт — print в Output

Запрос: roblox hello world script, roblox print example.

Задача: убедиться, что Script вообще запускается.

Настройка: ServerScriptServiceScript → имя HelloPrint.

print("Привет, Roblox!")
print("Скрипт работает")

Что увидите в Play: в Output две белые строки сразу после старта.

Разбор построчно:

СтрокаЧто происходитЗачем
print("...")Текст в OutputАналог console.log в JavaScript
Две строки подрядВыполняются сверху внизПорядок = порядок в файле

Что попробовать: print(2 + 2) → в Output будет 4.


Part красный при старте игры

Запрос: roblox change part color script.

Задача: куб на карте становится красным без ручной покраски в Properties.

Настройка:

  1. Workspace → Part (или используйте Baseplate).
  2. ПКМ на Part → Insert ObjectScript.
--!strict

local part = script.Parent :: BasePart
part.Color = Color3.fromRGB(255, 0, 0)
part.Material = Enum.Material.Neon

Что увидите в Play: Part светится красным (Neon).

Разбор построчно:

СтрокаЧто происходитЗачем
script.ParentОбъект-родитель Script (этот Part)Script лежит внутри Part
:: BasePartПодсказка типа для --!strictStudio знает, что есть .Color
Color3.fromRGB(255, 0, 0)Цвет из трёх чисел 0…255R=255, G=0, B=0 — красный
Material = NeonМатериал «неон»Ярче видно на уроке

Разбор по смыслу:

  • script — всегда «этот» Script, который выполняется.
  • Цвет можно менять и в Properties без кода; скрипт нужен, когда цвет зависит от события (касание, счёт).

Приветствие при входе игрока

Запрос: roblox PlayerAdded script, print player name when join.

Задача: при входе в Play в Output появляется ник игрока.

Настройка: ServerScriptServiceScript HelloServer.

--!strict

local Players = game:GetService("Players")

local function onPlayerAdded(player: Player)
print("Игрок на сервере:", player.Name)
end

Players.PlayerAdded:Connect(onPlayerAdded)

for _, player in Players:GetPlayers() do
onPlayerAdded(player)
end

Что увидите в Play: Игрок на сервере: ВашНик (локальный тестовый игрок).

Разбор построчно:

СтрокаЧто происходитЗачем
local function onPlayerAdded(player: Player)Именованная функция с типом аргументаУдобно передать в Connect
player.NameСтрока-никВ Tab и в чате
PlayerAdded:Connect(onPlayerAdded)«Когда игрок зашёл — вызови функцию»Основной паттерн Roblox
for _, player in GetPlayers()Перебор уже сидящих игроковScript мог загрузиться после вашего входа в Play
_ в for _, playerНомер в списке не нуженИдиома Luau

Разбор по смыслу:

  • Событие в Roblox — не if каждый кадр, а «вызови один раз, когда случилось».
  • Без цикла GetPlayers() в учебном Play иногда нет строки в Output — кажется, что скрипт сломан.

Что попробовать: print(player.UserId) — числовой ID аккаунта (для DataStore).


Вращающийся Part

Запрос: roblox spin part script, rotate part Heartbeat.

Задача: платформа на финише obby крутится — визуальный ориентир.

Настройка:

  1. Part Spinner, Anchored ✓.
  2. Script внутри Spinner.
--!strict

local RunService = game:GetService("RunService")
local part = script.Parent :: BasePart

local DEG_PER_SECOND = 90

RunService.Heartbeat:Connect(function(dt: number)
part.CFrame = part.CFrame * CFrame.Angles(0, math.rad(DEG_PER_SECOND) * dt, 0)
end)

Что увидите в Play: Part плавно крутится вокруг вертикали; полный оборот ~4 с при 90 град/с.

Разбор построчно:

СтрокаЧто происходитЗачем
RunServiceСервис «кадры» игрыЦиклы без while true вручную
Heartbeat:Connect(function(dt) ... end)Каждый кадр вызывается функцияdt — секунды с прошлого кадра
part.CFrameПозиция + поворотОдно свойство вместо Position + Rotation
CFrame.Angles(0, угол, 0)Поворот вокруг оси Y (вертикаль)«Карусель»
math.rad(...)Градусы → радианыAngles ждёт радианы
* dtУгол за этот кадрБез dt скорость зависит от FPS

Разбор по смыслу:

  • Аналог бесконечного цикла в Turtle, но движок сам вызывает функцию каждый кадр — не зависает весь сервер.
  • DEG_PER_SECOND = 180 — в два раза быстрее.

Кирпич-смерть (лава, Touched)

Запрос: roblox kill brick script, lava touched humanoid, kill part roblox.

Задача: красный Part убивает персонажа при касании — классика obby.

Настройка:

  1. Part Lava, красный цвет, Anchored ✓, размер достаточный (например 20×1×20).
  2. Script внутри Lava.
--!strict

local part = script.Parent :: BasePart

local function onTouched(other: BasePart)
local character = other.Parent
if not character then
return
end

local humanoid = character:FindFirstChildOfClass("Humanoid")
if humanoid then
humanoid.Health = 0
end
end

part.Touched:Connect(onTouched)

Что увидите в Play: зашли на красный Part — персонаж умер и появился у SpawnLocation.

Разбор построчно:

СтрокаЧто происходитЗачем
onTouched(other: BasePart)other — Part, который коснулся (часто нога/торс)Roblox передаёт «кто ударился»
other.ParentОбычно Model персонажаУ Part родитель — не Player, а модель
if not character then return endЗащита от мусорных касанийБез этого — ошибка на следующей строке
FindFirstChildOfClass("Humanoid")Ищет Humanoid в моделиУ декора в Workspace Humanoid нет
Health = 0СмертьДвижок сам респавнит
Touched:ConnectПодписка на касанияМного раз за одно падение — нормально

Разбор по смыслу:

  • Цепочка: нога (Part) → модель персонажа → Humanoid → Health.
  • Если лава «не убивает» — чаще всего касается не Humanoid, а пола; увеличьте Part по Y.

Чек-лист:

Проверка
Script внутри Part Lava
CanTouch включён
Персонаж реально касается (не пролетает сквозь тонкий слой)
В Output нет красных ошибок

Что попробовать: humanoid.Health = 50 — половина жизни вместо смерти.


Монетка и leaderstats

Запрос: roblox coin script, leaderstats coins, collect coin touched, IntValue roblox.

Задача: жёлтая сфера исчезает при касании; в Tab появляется Coins: 1.

Настройка (два скрипта):

  1. ServerScriptService → Script LeaderstatsSetup — код ниже первым.
  2. Workspace → Part, форма Ball, имя Coin, Anchored ✓, CanCollide выкл.
  3. Внутри Coin → Script CoinPickup.

Схема:

Игрок касается Coin
→ CoinPickup (Script на монетке)
→ находит Player по модели персонажа
→ coins.Value += 1 (сервер)
→ Tab показывает leaderstats
→ CoinUI (LocalScript) обновляет TextLabel

LeaderstatsSetup (ServerScriptService)

--!strict

local Players = game:GetService("Players")

local function setupLeaderstats(player: Player)
local folder = Instance.new("Folder")
folder.Name = "leaderstats"
folder.Parent = player

local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Value = 0
coins.Parent = folder
end

Players.PlayerAdded:Connect(setupLeaderstats)

Разбор построчно:

СтрокаЧто происходитЗачем
Instance.new("Folder")Создаёт пустую папку в памятиКонтейнер для счёта
folder.Name = "leaderstats"Имя строго leaderstatsИначе Tab Roblox не покажет таблицу
folder.Parent = playerПапка внутри объекта PlayerЖивёт на сервере, видна клиентам
Instance.new("IntValue")Целое числоМонеты, убийства, этап — всё IntValue
coins.Name = "Coins"Заголовок столбца в TabМожно Stage, Wins
Value = 0Старт с нуля
PlayerAdded:ConnectКаждому новому игроку — своя папка

CoinPickup (Script внутри Coin)

--!strict

local coin = script.Parent :: BasePart
local collected = false

local function onTouched(other: BasePart)
if collected then
return
end

local character = other.Parent
if not character then
return
end

local player = game:GetService("Players"):GetPlayerFromCharacter(character)
if not player then
return
end

local leaderstats = player:FindFirstChild("leaderstats")
local coins = leaderstats and leaderstats:FindFirstChild("Coins") :: IntValue?
if not coins then
return
end

collected = true
coins.Value += 1
coin.Transparency = 1
coin.CanTouch = false
end

coin.Touched:Connect(onTouched)

Разбор построчно:

СтрокаЧто происходитЗачем
collected = falseФлаг «уже подобрали»Touched срабатывает десятки раз за секунду
if collected then return endВторой раз не начислятьБез этого Coins +10 за одно касание
GetPlayerFromCharacter(character)Player из модели ног/торсаВ Touched приходит Part, не Player
FindFirstChild("leaderstats")Ищет папкуМожет ещё не создана — тогда nil
leaderstats and ... FindFirstChild("Coins")Два шага без ошибкиПаттерн «если есть папка — ищи Coins»
coins.Value += 1Увеличить счёт на сервереВсе игроки видят в Tab
Transparency = 1Полностью прозрачныйМонетка «исчезла», объект остался для отладки
CanTouch = falseБольше не ловит TouchedДополнительная защита

Что увидите в Play: коснулись шара — он пропал; TabCoins: 1.

Что попробовать:

task.delay(5, function()
collected = false
coin.Transparency = 0
coin.CanTouch = true
end)

Вставьте после сбора — монетка вернётся через 5 секунд.


Прыжковая платформа

Запрос: roblox jump pad script, JumpPower boost, jump boost part.

Задача: зелёный Part подбрасывает вверх — короткий obby-прыжок.

Настройка: Part JumpPad, зелёный, Anchored ✓, Script внутри.

--!strict

local pad = script.Parent :: BasePart
local BOOST = 80

local function onTouched(other: BasePart)
local character = other.Parent
if not character then
return
end
local humanoid = character:FindFirstChildOfClass("Humanoid")
if humanoid then
humanoid.JumpPower = BOOST
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
end

pad.Touched:Connect(onTouched)

Что увидите в Play: наступили на зелёный блок — персонаж подпрыгнул выше обычного.

Разбор построчно:

СтрокаЧто происходитЗачем
BOOST = 80Константа силы прыжкаМеняете одно число в Inspector-стиле
JumpPower = BOOSTЗадаёт силу прыжка HumanoidВ старых шаблонах
ChangeState(Jumping)Принудительный прыжокСрабатывает сразу при касании, не ждёт Space
JumpPower и JumpHeight

В новых шаблонах Roblox вместо JumpPower может быть JumpHeight. Откройте Humanoid персонажа в Play → Properties. Если JumpPower нет — замените строку на humanoid.JumpHeight = 50 (подберите число). Документация — create.roblox.com.


Спринт по Left Shift (LocalScript)

Запрос: roblox sprint script, WalkSpeed LocalScript, shift to run roblox.

Задача: зажали Shift — бег быстрее; отпустили — снова обычная ходьба.

Настройка: StarterPlayerStarterPlayerScriptsLocalScript SprintClient.

--!strict

local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")

local player = Players.LocalPlayer
local NORMAL = 16
local SPRINT = 28

local function getHumanoid(): Humanoid?
local character = player.Character
if not character then
return nil
end
return character:FindFirstChildOfClass("Humanoid")
end

UserInputService.InputBegan:Connect(function(input, processed)
if processed then
return
end
if input.KeyCode == Enum.KeyCode.LeftShift then
local hum = getHumanoid()
if hum then
hum.WalkSpeed = SPRINT
end
end
end)

UserInputService.InputEnded:Connect(function(input, _processed)
if input.KeyCode == Enum.KeyCode.LeftShift then
local hum = getHumanoid()
if hum then
hum.WalkSpeed = NORMAL
end
end
end)

player.CharacterAdded:Connect(function()
local hum = getHumanoid()
if hum then
hum.WalkSpeed = NORMAL
end
end)

Что увидите в Play: Shift — бег; отпустили — снова 16 studs/s (стандарт Roblox).

Разбор построчно:

СтрокаЧто происходитЗачем
UserInputServiceКлавиатура/мышь этого клиентаСервер не видит Shift
InputBeganКлавишу нажалиСтарт спринта
InputEndedКлавишу отпустилиВернуть скорость
processedtrue — ввод съел UI (чат)Не спринтовать при наборе в чате
Enum.KeyCode.LeftShiftКонстанта клавишиНе строка "LeftShift"
getHumanoid()Humanoid текущего персонажаПосле смерти модель новая
CharacterAddedСобытие «новый персонаж после респавна»Сброс WalkSpeed после лавы
NORMAL = 16Дефолт Roblox
SPRINT = 28~1.75× быстрееПодберите на вкус

Разбор по смыслу:

  • Это LocalScript — на сервере тот же код с LocalPlayer работает, на Script — нет.
  • В реальной игре читеры меняют WalkSpeed на клиенте; в продакшене скорость проверяют на сервере.

UI — надпись «Монеты: N»

Запрос: roblox TextLabel update, screen gui score script, leaderstats gui.

Задача: на экране текст обновляется при сборе монет (пример с leaderstats).

Настройка:

  1. StarterGuiScreenGuiTextLabel, имя CoinLabel, Text = Монеты: 0, Size в Properties.
  2. ПКМ на CoinLabelLocalScript CoinUI (родитель = TextLabel).
--!strict

local Players = game:GetService("Players")
local player = Players.LocalPlayer
local label = script.Parent :: TextLabel

local function updateCoins()
local leaderstats = player:FindFirstChild("leaderstats")
local coins = leaderstats and leaderstats:FindFirstChild("Coins") :: IntValue?
if coins then
label.Text = "Монеты: " .. tostring(coins.Value)
end
end

local function hookCoins()
local leaderstats = player:WaitForChild("leaderstats", 10)
if not leaderstats then
warn("leaderstats не найден за 10 с")
return
end
local coins = leaderstats:WaitForChild("Coins", 10) :: IntValue?
if not coins then
return
end
updateCoins()
coins.Changed:Connect(updateCoins)
end

player.CharacterAdded:Connect(hookCoins)
if player:FindFirstChild("leaderstats") then
hookCoins()
end

Что увидите в Play: собрали монетку — надпись Монеты: 1 без перезапуска.

Разбор построчно:

СтрокаЧто происходитЗачем
script.Parent :: TextLabelUI-элемент, внутри которого лежит скриптlabel.Text — свойство надписи
"Монеты: " .. tostring(coins.Value)Склейка строк.. — как + для строк в Python
WaitForChild("leaderstats", 10)Ждёт папку до 10 сСервер создаёт её чуть позже клиента
warn(...)Жёлтое предупреждение в OutputПонятнее, чем молчание
coins.Changed:ConnectПри каждом Value += 1 на сервереUI сам обновляется
CharacterAdded + hookCoinsПосле смерти переподпискаИначе UI «застынет»

Разбор по смыслу:

  • Сервер меняет число; клиент только показывает — правильное разделение.
  • Не пишите coins.Value += 1 в LocalScript для честной игры.

RemoteEvent — нажал E, сервер добавил монету

Запрос: roblox RemoteEvent tutorial, FireServer example, OnServerEvent.

Задача: игрок жмёт E; сервер добавляет +1 Coins (клиент не ворует счёт).

Настройка:

  1. ReplicatedStorageRemoteEvent → имя AddCoinRequest.
  2. ServerScriptService → Script CoinServer.
  3. StarterPlayerScripts → LocalScript CoinClient.
  4. Работает с LeaderstatsSetup.

CoinServer (сервер)

--!strict

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local event = ReplicatedStorage:WaitForChild("AddCoinRequest") :: RemoteEvent

local COOLDOWN = 1
local lastPress: { [Player]: number } = {}

event.OnServerEvent:Connect(function(player: Player)
local now = os.clock()
local prev = lastPress[player] or 0
if now - prev < COOLDOWN then
return
end
lastPress[player] = now

local leaderstats = player:FindFirstChild("leaderstats")
local coins = leaderstats and leaderstats:FindFirstChild("Coins") :: IntValue?
if coins then
coins.Value += 1
print(player.Name, "получил монету. Всего:", coins.Value)
end
end)

Разбор построчно (сервер):

СтрокаЧто происходитЗачем
WaitForChild("AddCoinRequest")Ждёт RemoteEvent в ReplicatedStorageИмя должно совпадать с Explorer
OnServerEvent:Connect(function(player) ...)Клиент вызвал FireServerplayerкто нажал E (не доверяйте аргументам клиента для identity)
lastPress[player]Таблица «последний раз нажал»У каждого игрока свой кулдаун
os.clock()Время в секундахДля антиспама
if now - prev < COOLDOWNЧаще 1 раз/с — игнорЗащита от макросов
coins.Value += 1 на сервереЕдинственное честное место

CoinClient (клиент)

--!strict

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local event = ReplicatedStorage:WaitForChild("AddCoinRequest") :: RemoteEvent

UserInputService.InputBegan:Connect(function(input, processed)
if processed then
return
end
if input.KeyCode == Enum.KeyCode.E then
event:FireServer()
end
end)

Разбор построчно (клиент):

СтрокаЧто происходитЗачем
FireServer()«Попроси сервер сделать действие»Без аргументов — просто сигнал «нажали E»
Только FireServer, без Value += 1Клиент не меняет счётИначе читеры

Что увидите в Play: E → +1 в Tab и строка в Output с именем и счётом.

Безопасность

Клиент может вызвать FireServer тысячу раз из эксплойта — сервер обязан проверять кулдаун, дистанцию, наличие предмета. В учебном obby достаточно COOLDOWN; в магазине — ещё цена и баланс на сервере.


ModuleScript — вынести код в модуль

Запрос: roblox require ModuleScript, return module table.

Задача: приветствие в одном файле, вызов из нескольких Script.

Настройка:

  1. ReplicatedStorageModuleScript HelloUtil.
  2. ServerScriptService → Script UseHello.

HelloUtil (ModuleScript):

--!strict

local HelloUtil = {}

function HelloUtil.greet(player: Player): string
return "Привет, " .. player.Name .. "!"
end

return HelloUtil

UseHello (Script):

--!strict

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local HelloUtil = require(ReplicatedStorage:WaitForChild("HelloUtil"))

Players.PlayerAdded:Connect(function(player)
print(HelloUtil.greet(player))
end)

Разбор ModuleScript:

СтрокаЧто происходитЗачем
local HelloUtil = {}Пустая таблица — «модуль»В неё кладут функции
function HelloUtil.greet(...)Метод модуляВызов: HelloUtil.greet(player)
return HelloUtilЧто вернёт requireБез returnrequire даст пустоту

Разбор Script:

СтрокаЧто происходитЗачем
require(...)Загрузить ModuleScript один разКэш — повторный require быстрый
WaitForChild("HelloUtil")Имя = имя объекта в ExplorerОпечатка → бесконечное ожидание

Разбор по смыслу:


Примеры посложнее

Случайный цвет при каждом касании

Запрос: roblox random color part touched.

--!strict

local part = script.Parent :: BasePart

part.Touched:Connect(function()
part.Color = Color3.fromRGB(
math.random(0, 255),
math.random(0, 255),
math.random(0, 255)
)
end)
СтрокаЧто происходитЗачем
Touched:Connect(function() ... end)Анонимная функция без otherЦвет меняется при любом касании
math.random(0, 255)Случайное целоеТри канала RGB
На сервереrandom честный для всехНа клиенте — только для себя

Таймер обратного отсчёта в Output

Запрос: roblox countdown script, task.wait loop.

--!strict

local SECONDS = 10

for t = SECONDS, 1, -1 do
print("Старт через", t)
task.wait(1)
end

print("Поехали!")
СтрокаЧто происходитЗачем
for t = SECONDS, 1, -1t = 10, 9, … 1Третье число — шаг −1
task.wait(1)Пауза 1 сНе блокирует весь сервер как старый wait()

Что увидите: десять строк в Output, затем Поехали!.


Спавн падающих кубов

Запрос: roblox spawn part script, Clone Instance.

--!strict

local ServerStorage = game:GetService("ServerStorage")
local template = ServerStorage:WaitForChild("FallingCube") :: BasePart

while true do
local clone = template:Clone()
clone.Position = Vector3.new(math.random(-20, 20), 30, math.random(-20, 20))
clone.Parent = workspace
task.delay(5, function()
clone:Destroy()
end)
task.wait(2)
end

Настройка: Part FallingCube в ServerStorage, Anchored выкл.

СтрокаЧто происходитЗачем
ServerStorageИгроки не видят шаблонХранилище «заготовок»
Clone()Копия PartОригинал остаётся
Vector3.new(x, y, z)Позиция в миреY=30 — высоко над картой
Parent = workspaceКлон появился в игре
task.delay(5, function() clone:Destroy() end)Удалить через 5 сНе копить мусор
while true + task.wait(2)Каждые 2 с новый кубБесконечный спавн

Частые ошибки новичка

СимптомЧто гуглятПричинаРешение
attempt to index nilroblox nil errorFindFirstChild не нашёл объектif obj then, WaitForChild, проверьте Explorer
LocalPlayer is nilLocalPlayer nil serverScript на сервереLocalScript в StarterPlayerScripts
Скрипт серыйscript won't runLocalScript не в том местеТолько StarterPlayerScripts / StarterGui / Tool
Touched молчитtouched not workingНет контакта, маленький PartУвеличить Part, CanTouch
Coins +10 за разcoin gives too manyМного TouchedФлаг collected
UI всегда 0textlabel not updatingНет Changed / нет leaderstatsUI пример
RemoteEvent ничегоFireServer not workingНе тот родитель / имяReplicatedStorage, имена совпадают
HelloUtil is not a valid memberrequire module errorНет return в ModuleScriptreturn HelloUtil в конце модуля
Output — главная отладка

View → Output. Красная строка: файл и номер — двойной клик откроет скрипт. Перед сдачей лабораторной сделайте скрин Output без ошибок в Play.


Мини-проект — obby за один вечер

Соберите на Baseplate (порядок важен):

ШагОбъектРаздел
1LeaderstatsSetup в ServerScriptServiceМонетка
25× Part CoinМонетка
3Part Lava между платформамиЛава
4Part JumpPadПрыжок
5SprintClient LocalScriptСпринт
6ScreenGui + CoinUIUI
7Spinner на финишеВращение

Что сказать на защите: «Счёт и сбор монет на сервере, UI и спринт на клиенте, лава через Touched и Humanoid».

Полный obby с чекпоинтами и DataStore — практикум 204.


Сравнение с Python Turtle

ИдеяTurtleRoblox Luau
Повторениеfor i in range(4)for t = 10, 1, -1
«Сделай что-то много раз»цикл + forwardHeartbeat:Connect
Реакция на действиередко (клик)Touched, PlayerAdded
Счёт очковпеременная в кодеleaderstats + Tab
Где запускPython на ПКF5 в Studio

Если вы прошли Turtle, в Roblox те же навыки: переменная → условие → цикл → функция → событие.


Куда дальше

  1. Roblox Studio — первая игра — Place, публикация.
  2. Разработка на Roblox — клиент–сервер, FilteringEnabled.
  3. Luau в Roblox — типы, task, API.
  4. Справочник по Roblox — Instance, DataStore.
  5. Unity C# — скрипты — другой движок, те же механики.
  6. Маршрут Roblox + Luau.

См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").