Pterohost docs

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()Нажата Rshared
SWEP:Think()Каждый тикshared
SWEP:OnRemove()При удаленииshared
SWEP:DrawHUD()Отрисовка HUDclient
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 перед публикацией:

  1. Положить аддон в garrysmod/addons/my_pistol/ (распакованный, не .gma).
  2. Запустить GMod, создать одиночную игру на gm_construct.
  3. В консоли: sv_cheats 1 (обычно уже включено в singleplayer).
  4. Получить оружие: give my_pistol (имя файла без расширения).
  5. Включить дебаг: developer 1 - ошибки покажутся прямо на экране.

Для multiplayer-тестирования (проверка работы по сети, синхронизации хуков):

  1. Запустить слушающий сервер: “Создать” -> “Несколько игроков”.
  2. Подключиться вторым игроком (например с другого компьютера или через VPN).
  3. Проверить отображение 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”.