SWEPs в Garry's Mod: создание оружия и инструментов на Lua
Полный гайд по созданию SWEP для Garry's Mod в 2026: структура аддона, SWEP-таблица, хуки PrimaryAttack/Reload, базы TFA/M9K, упаковка в .gma, Workshop.
Кратко: SWEP (Scripted Weapon ENTity) - это скриптовое оружие на Lua для Garry’s Mod, создаваемое в
addons/myaddon/lua/weapons/swep_name/. Минимальный SWEP - это файлshared.luaс таблицейSWEP(полями Base, PrintName, ViewModel, Primary) и хукомSWEP:PrimaryAttack(). Готовый аддон упаковывается в .gma черезgmad.exe createи публикуется в Workshop черезgmpublish.exe.
Создание SWEP - это база для разработчиков Garry’s Mod-серверов. Через SWEPs делают всё от реалистичных AK-47 до магических посохов и медицинских аптечек. В этом гайде - полная разработка с нуля: структура аддона, разбор каждого поля SWEP-таблицы, описание всех хуков, рабочий пример пистолета, упаковка в .gma и публикация в Steam Workshop в 2026 году.
Что такое SWEP и как он работает?
SWEP (Scripted Weapon ENTity) - это скриптовое оружие или инструмент на Lua для Garry’s Mod. В отличие от стандартного оружия движка Source (которое hardcoded в C++), SWEPs полностью описываются Lua-таблицей и могут реализовать любое поведение: огнестрел, медикаменты, телепорты, гранаты, лазерные указки. Все встроенные инструменты GMod (Physgun, Tool Gun, Gravity Gun) - это тоже SWEPs.
Сервер при старте сканирует все папки lua/weapons/ в активных аддонах и автоматически регистрирует найденные SWEPs. Имя папки (или файла, если SWEP однофайловый) становится класс-именем оружия. Например, файл lua/weapons/my_pistol.lua создаст оружие класса my_pistol, которое выдаётся командой give my_pistol.
Какая структура папок у SWEP-аддона?
Стандартная структура аддона с SWEP в 2026 году:
addons/myweapon/
├── addon.json # метаданные для Workshop
├── lua/
│ └── weapons/
│ └── my_pistol/
│ ├── shared.lua # общая часть (клиент + сервер)
│ ├── cl_init.lua # только клиент (HUD, эффекты)
│ └── init.lua # только сервер (логика урона)
├── models/ # модель оружия .mdl
│ └── weapons/
│ └── my_pistol/
│ ├── v_pistol.mdl # view model (от первого лица)
│ ├── v_pistol.vvd
│ ├── v_pistol.dx90.vtx
│ ├── v_pistol.phy
│ ├── w_pistol.mdl # world model (вид со стороны)
│ └── w_pistol.dx90.vtx
├── materials/ # текстуры
│ └── models/weapons/my_pistol/
│ ├── pistol.vmt
│ └── pistol.vtf
└── sound/ # звуки
└── weapons/my_pistol/
├── shoot.wav
└── reload.wav
Для простых SWEP без эффектов и серверной логики можно ограничиться одним файлом lua/weapons/my_pistol.lua - GMod автоматически распознает и его, и трёхфайловую структуру.
Pterohost - игровой хостинг с DDoS-защитой L4+L7, NVMe SSD и круглосуточной поддержкой. Промокод 4START даёт -20% на первый заказ. Заказать сервер Garry’s Mod
Какие поля у SWEP-таблицы?
SWEP - это глобальная Lua-таблица с десятками настраиваемых полей. Полный референс самых важных:
Метаданные
SWEP.Base = "weapon_base" -- база (weapon_base, TFA, M9K)
SWEP.PrintName = "My Pistol" -- отображаемое имя в Q-меню
SWEP.Category = "My Weapons" -- категория в Q-меню
SWEP.Author = "Your Nickname" -- автор
SWEP.Contact = "" -- контакт (Steam, email)
SWEP.Purpose = "Standard pistol" -- назначение
SWEP.Instructions = "Left click to fire" -- инструкция игроку
SWEP.Spawnable = true -- появляется в Q-меню
SWEP.AdminOnly = false -- только для админов
SWEP.UseHands = true -- показывать руки игрока на view-модели
Модели и анимации
SWEP.ViewModel = "models/weapons/my_pistol/v_pistol.mdl" -- от первого лица
SWEP.WorldModel = "models/weapons/my_pistol/w_pistol.mdl" -- со стороны
SWEP.ViewModelFOV = 60 -- FOV view-модели (обычно 55-70)
SWEP.ViewModelFlip = false -- зеркалить view-модель
SWEP.HoldType = "pistol" -- pistol, smg, ar2, shotgun, rpg, melee
SWEP.DrawCrosshair = true -- показывать прицел
SWEP.Slot = 1 -- слот инвентаря (0-5)
SWEP.SlotPos = 0 -- позиция в слоте
Первичная атака (Primary)
SWEP.Primary.ClipSize = 12 -- размер магазина
SWEP.Primary.DefaultClip = 36 -- стартовый запас патронов
SWEP.Primary.Automatic = false -- false = одиночный, true = автоогонь
SWEP.Primary.Ammo = "pistol" -- тип патронов (pistol, smg1, ar2, buckshot, 357, slam)
SWEP.Primary.Damage = 25 -- урон за выстрел
SWEP.Primary.NumShots = 1 -- количество пуль за выстрел (для дробовика)
SWEP.Primary.Cone = 0.02 -- разброс (0 = идеальная точность)
SWEP.Primary.Delay = 0.15 -- задержка между выстрелами (секунды)
SWEP.Primary.Recoil = 1.5 -- отдача
SWEP.Primary.Force = 5 -- сила импульса по врагу
SWEP.Primary.Sound = Sound("Weapon_Pistol.Single") -- звук выстрела
Вторичная атака (Secondary)
SWEP.Secondary.ClipSize = -1 -- -1 = не использует магазин
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"
Какие хуки есть у SWEP?
Хуки SWEP - это методы, которые движок вызывает в определённые моменты. Полный список самых используемых:
| Хук | Когда вызывается | Сторона |
|---|---|---|
SWEP:Initialize() | При спавне оружия | shared |
SWEP:Deploy() | Когда игрок достал оружие | shared |
SWEP:Holster() | Перед сменой оружия | shared |
SWEP:PrimaryAttack() | Нажата ЛКМ | shared |
SWEP:SecondaryAttack() | Нажата ПКМ | shared |
SWEP:Reload() | Нажата R | shared |
SWEP:Think() | Каждый тик | shared |
SWEP:OnRemove() | При удалении | shared |
SWEP:DrawHUD() | Отрисовка HUD | client |
SWEP:DrawWorldModel() | Отрисовка модели в мире | client |
SWEP:OnDrop() | Когда игрок бросил оружие | server |
Главное правило: чем меньше кода в SWEP:Think(), тем лучше для производительности. Think вызывается 33-66 раз в секунду на каждом игроке - 30 игроков с тяжёлым Think кладут сервер. Подробнее в гайде по оптимизации сервера GMod.
Полный пример SWEP-пистолета
Рабочий код простого пистолета с одиночной стрельбой и перезарядкой. Файл addons/my_pistol/lua/weapons/my_pistol/shared.lua:
-- Метаданные
SWEP.PrintName = "Custom Pistol"
SWEP.Author = "Pterohost Docs"
SWEP.Purpose = "Demonstration SWEP for GMod tutorial"
SWEP.Instructions = "Left click to shoot, R to reload"
SWEP.Category = "Pterohost Tutorial"
SWEP.Spawnable = true
SWEP.AdminOnly = false
SWEP.UseHands = true
-- Модели (Half-Life 2 default - заменить на свои)
SWEP.ViewModel = "models/weapons/c_pistol.mdl"
SWEP.WorldModel = "models/weapons/w_pistol.mdl"
SWEP.ViewModelFOV = 54
SWEP.HoldType = "pistol"
-- База
SWEP.Base = "weapon_base"
SWEP.Slot = 1
SWEP.SlotPos = 1
SWEP.DrawAmmo = true
SWEP.DrawCrosshair = true
-- Первичная атака
SWEP.Primary.ClipSize = 17
SWEP.Primary.DefaultClip = 51
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = "pistol"
SWEP.Primary.Damage = 25
SWEP.Primary.NumShots = 1
SWEP.Primary.Cone = 0.015
SWEP.Primary.Delay = 0.2
SWEP.Primary.Recoil = 1.2
SWEP.Primary.Force = 5
SWEP.Primary.Sound = Sound("Weapon_Pistol.Single")
-- Вторичная (не используется)
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"
-- Хук инициализации
function SWEP:Initialize()
self:SetHoldType(self.HoldType)
end
-- Хук первичной атаки
function SWEP:PrimaryAttack()
if not self:CanPrimaryAttack() then return end
self:EmitSound(self.Primary.Sound)
self:SendWeaponAnim(ACT_VM_PRIMARYATTACK)
self.Owner:SetAnimation(PLAYER_ATTACK1)
local bullet = {
Num = self.Primary.NumShots,
Src = self.Owner:GetShootPos(),
Dir = self.Owner:GetAimVector(),
Spread = Vector(self.Primary.Cone, self.Primary.Cone, 0),
Tracer = 1,
TracerName = "Tracer",
Force = self.Primary.Force,
Damage = self.Primary.Damage,
Ammo = self.Primary.Ammo,
}
self.Owner:FireBullets(bullet)
self:TakePrimaryAmmo(1)
-- Отдача (только на клиенте)
if SERVER then
self.Owner:ViewPunch(Angle(-self.Primary.Recoil, 0, 0))
end
self:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
end
-- Хук вторичной (пусто)
function SWEP:SecondaryAttack()
return false
end
-- Хук перезарядки
function SWEP:Reload()
self:DefaultReload(ACT_VM_RELOAD)
end
-- Хук деплоя
function SWEP:Deploy()
self:SendWeaponAnim(ACT_VM_DRAW)
return true
end
Этот код кладётся в addons/my_pistol/lua/weapons/my_pistol/shared.lua (или в lua/weapons/my_pistol.lua для однофайлового варианта). После перезапуска сервера оружие появится в Q-меню в категории “Pterohost Tutorial” и будет доступно командой give my_pistol.
Как создать addon.json?
Файл addons/my_pistol/addon.json нужен для упаковки в .gma и публикации в Workshop:
{
"title": "My Pistol - Custom SWEP",
"type": "weapon",
"tags": ["weapon", "roleplay"],
"ignore": [
"*.psd",
"*.txt",
"*.bak",
".git/*"
]
}
Допустимые type: gamemode, map, weapon, vehicle, npc, entity, tool, effects, model, servercontent. Тегов можно указать до двух из списка: fun, roleplay, scenic, movie, realism, cartoon, water, comic, build.
Как упаковать SWEP в .gma?
Утилита gmad.exe входит в дистрибутив GMod (папка bin/). Команда упаковки на Windows:
"C:\Program Files (x86)\Steam\steamapps\common\GarrysMod\bin\gmad.exe" create ^
-folder "C:\Users\You\Desktop\my_pistol" ^
-out "C:\Users\You\Desktop\my_pistol.gma"
На Linux (через Proton или нативно):
~/.steam/steam/steamapps/common/GarrysMod/bin/linux64/gmad_linux create \
-folder ~/my_pistol \
-out ~/my_pistol.gma
Полученный .gma можно положить в garrysmod/addons/ любого сервера - он автоматически загрузится при старте.
Как опубликовать SWEP в Workshop?
После создания .gma нужна иконка 512x512 пикселей в формате .jpg - например icon.jpg рядом с .gma. Команда публикации:
gmpublish.exe create -addon my_pistol.gma -icon icon.jpg
Steam запросит описание - заполните markdown-текст с описанием SWEP. После публикации аддон появится в вашем профиле Workshop через 10-30 минут. Для обновления уже опубликованного аддона:
gmpublish.exe update -id 123456789 -addon my_pistol.gma -changes "Fixed reload animation"
ID берётся из URL Workshop-страницы: steamcommunity.com/sharedfiles/filedetails/?id=123456789.
Какие базы SWEP использовать?
Базы (Base) - это родительские SWEPs, от которых наследуется ваш. Они дают готовую функциональность (баллистика, ADS-прицел, кастомные анимации) - не нужно писать всё с нуля. Топ-3 базы в 2026 году:
TFA Base 4.0 (Workshop ID 1466459888) - самая популярная и активно поддерживаемая. Поддерживает ADS-прицеливание, attachments (глушители, прицелы), реалистичную баллистику с дальностью и penetration, кастомные звуки и анимации, customизация через TFA-customization. Используется в 70% русских MilitaryRP-серверов.
SWEP.Base = "tfa_gun_base"
SWEP.Category = "TFA - Pistols"
SWEP.Primary.Damage = 30
-- TFA-специфичные поля
SWEP.IronSightsPos = Vector(-6, 0, 1.5) -- позиция при ADS
SWEP.IronSightsAng = Vector(0, 0, 0)
M9K Base (Workshop ID 130518333) - старая (2014-2017), но стабильная. Не поддерживает ADS-attachments TFA, но проще в освоении. Подходит для классических Sandbox и DarkRP без претензий на реализм.
Customizable Weaponry 2.0 (CW 2.0) (Workshop ID 220336977) - тактический реализм с детальным обмундированием (прицелы, тактические рукоятки, фонари). Тяжёлая база для серверов с фокусом на milsim.
weapon_base - встроенная база GMod. Без зависимостей от Workshop, но без удобств TFA/CW. Для новичков и простых SWEPs - оптимальный выбор.
Как протестировать SWEP?
Локальное тестирование - быстрейший способ проверить SWEP перед публикацией:
- Положить аддон в
garrysmod/addons/my_pistol/(распакованный, не .gma). - Запустить GMod, создать одиночную игру на
gm_construct. - В консоли:
sv_cheats 1(обычно уже включено в singleplayer). - Получить оружие:
give my_pistol(имя файла без расширения). - Включить дебаг:
developer 1- ошибки покажутся прямо на экране.
Для multiplayer-тестирования (проверка работы по сети, синхронизации хуков):
- Запустить слушающий сервер: “Создать” -> “Несколько игроков”.
- Подключиться вторым игроком (например с другого компьютера или через VPN).
- Проверить отображение world-модели и звуки на стороне второго игрока.
Если SWEP крашит клиент - смотреть garrysmod/console.log после краша. Если не появляется в Q-меню - проверить SWEP.Spawnable = true и наличие SWEP.Category.
Связанные материалы
После создания SWEP полезно настроить серверную инфраструктуру: настройка DarkRP-сервера для использования оружия в роли работ, админ-панель ULX для тестирования с правами админа, и удаление лишних Workshop-аддонов для очистки коллекции.
Pterohost - игровой хостинг с DDoS-защитой L4+L7, NVMe SSD и круглосуточной поддержкой. Промокод 4START даёт -20% на первый заказ. Заказать сервер Garry’s Mod
FAQ: создание SWEP в Garry’s Mod
Можно ли создавать SWEP без знания Lua? Технически да - редактирование существующего SWEP с заменой моделей, звуков и значений урона не требует программирования. Но создание оригинального поведения (новые механики, эффекты, взаимодействия) без понимания Lua-синтаксиса невозможно. Базовый Lua осваивается за 5-10 часов.
Как сделать автоматический огонь? Установить SWEP.Primary.Automatic = true. С этим флагом движок сам обрабатывает удержание ЛКМ и вызывает PrimaryAttack каждые SWEP.Primary.Delay секунд, пока кнопка зажата. Не нужно писать ничего в Think.
Можно ли использовать модели из CS:GO/CS:S? Да, если они есть в mounted-играх (Counter-Strike: Source, Counter-Strike 2). Путь в SWEP: models/weapons/cstrike/c_pist_glock18.mdl. Игроки без подключённого CS:S увидят ERROR-модель - решается через FastDL с раздачей нужных моделей.
Как добавить кастомную перезарядку с анимацией? Заменить self:DefaultReload(ACT_VM_RELOAD) на ручную логику с проверкой времени и SWEP:SendWeaponAnim(). Нужно знать ACT-константы анимаций модели (можно посмотреть в Hammer Editor или через mdldecompiler).
Сколько SWEPs можно загрузить на сервер? Технически лимита нет - встречаются серверы с 500+ SWEPs из TFA-паков. Но каждый SWEP занимает 1-5 МБ RAM сервера и удлиняет время загрузки клиента на 0.1-0.5 секунды. Рекомендуется не более 100-150 активных SWEPs на публичном сервере.
Можно ли продавать собственные SWEPs? В Steam Workshop - нет, Workshop запрещает любую монетизацию контента для GMod. Но продавать SWEPs как часть приватных серверных сборок (например через ScriptFodder/CoderHire) - можно и легально. Многие топовые DarkRP-сервера именно так и зарабатывают.
Где найти готовые модели для SWEP? Workshop GMod (тег “model”), Models Resource (бесплатные риги), Sketchfab (часть моделей под CC0), CS:GO/CS2 модели через VPK-extraction. Для коммерческого использования всегда проверять лицензию - многие модели на Workshop под “Personal Use Only”.