Physgun Wiki

Реалмы и разделение кода

В Garry's Mod один и тот же Lua-код может выполняться на сервере, на клиенте или на обоих сторонах. Геймод разделяет эти три случая именем файла:

Префикс Где выполняется Что туда кладут
sv_ только сервер изменение состояния, net.Receive сервера, чат-команды, выдача денег
cl_ только клиент отрисовка, панели VGUI, HUD
sh_ обе стороны геттеры, чтение сетевых переменных, чистые функции, константы

Зачем это строго

Всё, что попало под AddCSLuaFile, скачивает каждый игрок при входе. Серверная логика клиенту не нужна и только удлиняет загрузку, а заодно раскрывает устройство сервера.

Поэтому правило простое: в sh_ попадает только то, что действительно нужно обеим сторонам. Если функция нужна одной — она не sh_.

Геттер и сеттер врозь

Базовый приём проекта — читающий метод в sh_, изменяющий в sv_:

-- economy/sh_money.lua, доступно везде function PLAYER:Money() return self:GetNetVar('money', 0) end
-- economy/sv_money.lua, только сервер function PLAYER:SetMoney(count) self:SetNetVar('money', count) end

Клиент читает баланс для HUD, но изменить его не может — на клиенте SetMoney просто не существует.

Не заворачивайте в if SERVER

Ветку if SERVER then ... end внутри геймода писать не нужно: для этого есть файл нужного реалма. Такие проверки уместны только в библиотеках из lua/autorun/, которые по своей природе общие.

-- Плохо: серверная логика уезжает клиенту -- sh_something.lua if SERVER then function PLAYER:GiveReward() ... end end
-- Хорошо: файл сам определяет реалм -- sv_something.lua function PLAYER:GiveReward() ... end

Подключение

Автозагрузки по папкам нет. Файл начинает работать только после того, как его прописали вручную:

  • init.luainclude для sv_ и sh_, плюс AddCSLuaFile для cl_ и sh_
  • cl_init.luainclude для cl_ и sh_

Забытый AddCSLuaFile даёт самую частую ошибку: на сервере всё работает, а на клиенте функции «не существует». Подробнее — Как подключить свой модуль.