Roblox GuidebookБаза знаний
Русский ⌄
Все руководства

Разработка / ROBLOX

Куда помещать Script, LocalScript и ModuleScript в Roblox Studio

Пошаговая проверка расположения и RunContext: серверный и клиентский запуск, копии LocalScript, подключение модуля и таблица контейнеров.

Обновлено:

Сначала определите, кто выполняет действие #

Для каждого небольшого фрагмента кода сформулируйте задачу. Правило начисления награды должно проверяться сервером, а локальное отображение интерфейса относится к клиенту. Общая функция может быть вынесена в модуль, который вызывается подходящей стороной. Это помогает выбрать точку запуска ещё до добавления объекта в Explorer.

На выполнение влияют тип объекта, его расположение и, для обычного Script, RunContext. Одинаковый текст в разных контейнерах может дать разный результат. В этом упражнении мы создадим независимые сообщения сервера и клиента, затем подключим простой модуль. Используйте отдельный учебный проект: так проще видеть, какое сообщение относится к какому примеру.

Точки запуска сервера, клиента и общая библиотека
Схема учебной структуры: Script выбирает контекст, ModuleScript подключается через require().

1. Запустите обычный Script на сервере #

В Explorer откройте ServerScriptService и добавьте обычный Script с именем ServerStart. Выберите его, откройте Properties и установите RunContext в Server. Стандартный Legacy тоже работает для обычного серверного Script в этом контейнере, но явный Server делает назначение упражнения заметным. Убедитесь, что скрипт включён.

Замените содержимое первым примером ниже. Откройте Output и запустите Test с игроком. Ожидается SERVER: ready в серверном контексте. Сообщение подтверждает, что выполнение дошло до print(), а не то, что уже готова система наград. Если строки нет, проверьте фильтры Output и место объекта до изменения кода.

print("SERVER: ready")

2. Запустите клиентский Script #

В ReplicatedStorage добавьте обычный Script с именем ClientStart. В Properties обязательно установите RunContext в Client. Затем вставьте второй пример ниже. Само помещение обычного Script в ReplicatedStorage со стандартным Legacy не заменяет настройку клиентского контекста.

Начните новый Test. Найдите CLIENT: ready в клиентском контексте, а SERVER: ready — в серверном. Это две стороны тестовой игры. Для такого клиентского входа текущая документация рекомендует ReplicatedStorage. Не переносите этот Script с RunContext Client в StarterPlayerScripts ради эксперимента: исходник и его копия могут запускаться, создавая нежелательное дублирование.

print("CLIENT: ready")

3. Когда нужен LocalScript, учитывайте копирование #

LocalScript выполняется на клиенте и не имеет RunContext. Для отдельного упражнения остановите тест, временно отключите ClientStart и создайте LocalScript в StarterPlayer → StarterPlayerScripts. Дайте ему другое имя, например LocalStart, и выведите print("LOCAL: ready").

После Test найдите сообщение клиента. Во время игры содержимое стартового контейнера копируется к игроку, поэтому источник сообщения может вести в Players → имя игрока → PlayerScripts. Это объясняет, почему путь отличается от места, куда вы добавляли исходник. LocalScript, просто лежащий в ReplicatedStorage, не запускается от одного своего присутствия там.

4. Подключите ModuleScript из точки запуска #

Остановите тест и добавьте в ReplicatedStorage ModuleScript с точным именем PracticeModule. Вставьте в него первый из двух примеров этого раздела. Он возвращает таблицу с функцией start(). Добавление ModuleScript само по себе не вызывает эту функцию; для подключения нужен выполняющийся код.

В ServerStart вставьте второй пример раздела: он находит модуль, получает возвращённое значение через require() и затем вызывает start(). При новом Test ожидается MODULE: started в серверном контексте. WaitForChild ждёт объект с указанным именем: при опечатке ожидание не создаёт недостающий модуль. Сравните имя в Explorer и строку PracticeModule.

Точка запуска получает модуль и вызывает start()
Первый код раздела помещается в PracticeModule, второй — в ServerStart.
local PracticeModule = {}

function PracticeModule.start()
    print("MODULE: started")
end

return PracticeModule
print("SERVER: ready")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local practice = require(ReplicatedStorage:WaitForChild("PracticeModule"))
practice.start()

5. Выбирайте контейнер по назначению #

Используйте таблицу как отправную точку для структуры проекта. ServerScriptService подходит для серверного запуска; ReplicatedStorage — для рекомендованного клиентского Script с RunContext Client и общих модулей. Серверный модуль можно держать в ServerScriptService, если клиенту он не нужен.

Размещение и доступность — разные вопросы. Объекты ReplicatedStorage передаются клиентам, поэтому общие модули не должны содержать секреты или заменять серверную проверку покупок и наград. ServerStorage предназначен для серверных объектов; обычный Script там не запускается автоматически. Переместите точку запуска в предназначенный для выполнения контейнер, а не скрывайте её среди хранимых моделей.

Тип и контекстРасположениеНазначение
Script · ServerServerScriptServiceСерверный запуск
Script · ClientReplicatedStorageКлиентский запуск
LocalScriptStarterPlayer → StarterPlayerScriptsКлиентская копия
ModuleScriptReplicatedStorageОбщий модуль
ScriptServerStorageХранение; Script не стартует

6. Если запуска нет, проверьте четыре вещи #

Сначала проверьте точный тип: обычный Script, LocalScript или ModuleScript. Затем путь в Explorer, RunContext там, где он есть, и состояние включения. Для модуля дополнительно найдите вызывающий require() скрипт. Несколько похожих значков или одинаковые имена не подтверждают одинаковое окружение.

Добавьте короткий print в начало точки запуска, откройте Output без текстового фильтра и проверьте нужный контекст. Если первая метка появилась, но следующая нет, исследуйте код между ними. Если отсутствуют обе, начните с запуска и отображения сообщений. Ошибку выполнения читайте по её источнику; переносить все файлы наугад обычно мешает установить причину.

7. Сохраните исходник и повторите проверку #

Остановите Test перед окончательным редактированием. Если вы меняли скопированный LocalScript внутри PlayerScripts во время игры, перенесите нужное исправление в исходный LocalScript в StarterPlayerScripts. Объекты тестовой сессии сбрасываются после остановки, поэтому исправление только в временной копии может не пережить следующий запуск.

Для основной пары примеров снова включите ClientStart и отключите отдельный LocalStart, если он больше не нужен. Запустите свежий Test: проверьте SERVER: ready, CLIENT: ready и MODULE: started из серверного вызова. Сохраните проект. Успешная проверка означает, что вы понимаете тип, путь, контекст и вызывающий код каждого сообщения; дальше переносите реальные функции по одной.

Первоисточники

Roblox Creator Hub
Roblox Creator Hub · ModuleScript
Roblox Creator Hub · Output
Roblox Creator Hub · Testing modes