Транспортные моды и апгрейды для FiveM
Голый ванильный автопарк GTA V закрывает RP-сервер месяца на два, а дальше игроки начинают спрашивать про конкретные модели, которых в игре нет, и про тюнинг серьёзнее стандартного Los Santos Customs. Add-on транспорт и апгрейды — это уже не «накинуть архив в resources», а работа с несколькими meta-файлами, которые должны совпадать друг с другом по именам и хешам, плюс интеграция с экономикой фреймворка. Разберём путь машины от архива с моделью до пункта в гараже игрока — и почему сотня add-on тачек ощущается новичками не как плюс, а как долгая загрузка при первом коннекте.
Содержание
- Add-on против replace: почему для RP это разные истории
- Из чего состоит ресурс с машиной
- vehicles.meta: паспорт машины
- carvariations.meta и carcols.meta: цвета и тюнинг-киты
- Тюнинг «под капотом»: handling.meta и тормозной путь
- Регистрация в фреймворке: автосалон, гараж и деньги
- Сколько add-on машин выдержит клиент: цена стрима
Add-on против replace: почему для RP это разные истории
Есть два разных способа добавить машину. Replace-пакет подменяет существующую ванильную модель (например, «превращает» sultan в тюнингованный кастом) — просто, но модель исчезает из игры и ломается везде, где использовалась (NPC-трафик, миссии, другие ресурсы, вызывающие её по имени). Для RP-сервера это редко подходит: слишком много непредсказуемых побочных эффектов.
Add-on транспорт добавляет новую модель под уникальным именем рядом с ванильными, ничего не подменяя. Именно так работают почти все платные и бесплатные тачки, которые продаются под FiveM — с собственным modelName, текстурами и хендлингом. Дальше в статье речь только про add-on: это стандарт для живого RP-сервера.
Если сервер ещё не поднят или ты только начинаешь разбираться со структурой ресурсов — сначала пройди установку FiveM-сервера и общий принцип установки кастомных скриптов: add-on машина технически тоже ресурс, просто без Lua-логики внутри, а из data-файлов и стрим-ассетов.
Из чего состоит ресурс с машиной
Типовая структура папки для одной или нескольких add-on машин:
[vehicles]/
└── mycar/
├── fxmanifest.lua
├── data/
│ ├── vehicles.meta
│ ├── carvariations.meta
│ ├── carcols.meta
│ └── handling.meta
└── stream/
├── mycar.yft — основная модель (high detail)
├── mycar_hi.yft — опциональная модель повышенной детализации
└── mycar.ytd — текстуры
Файлы из stream/ FXServer подхватывает автоматически по расширению (.yft, .ytd, .ydr) без перечисления в files{} — достаточно, чтобы папка называлась stream. А data-файлы нужно явно объявить директивами data_file, иначе движок их не прочитает:
fx_version 'cerulean'
game 'gta5'
this_is_a_map 'yes'
data_file 'VEHICLE_METADATA_FILE' 'data/vehicles.meta'
data_file 'CARVARIATIONS_FILE' 'data/carvariations.meta'
data_file 'CARCOLS_FILE' 'data/carcols.meta'
data_file 'HANDLING_FILE' 'data/handling.meta'
files {
'data/vehicles.meta',
'data/carvariations.meta',
'data/carcols.meta',
'data/handling.meta',
}
Директива this_is_a_map 'yes' тут не про карту-локацию — она говорит движку, что ресурс поставляет игровые data-файлы (мета для транспорта, оружия и т.д.), а не только код.
Нужен игровой сервер?
MAATRIX GAMES — 45+ игр, деплой за минуты, DDoS-защита, автобэкапы. Тарифы от 399 ₽/мес.
Создать серверvehicles.meta: паспорт машины
Это ключевой файл — он объявляет саму модель и связывает её с остальными файлами по имени. Минимальный <Item> внутри <InitDatas>:
<Item>
<modelName>mycar</modelName>
<txdName>mycar</txdName>
<handlingId>MYCAR</handlingId>
<gameName>MYCAR</gameName>
<vehicleMakeName>CUSTOM</vehicleMakeName>
<audioNameHash>sultan</audioNameHash>
<layout>LAYOUT_STANDARD</layout>
<plateType>VPT_FRONT_AND_BACK_PLATES</plateType>
<vehicleClass>VC_SPORT</vehicleClass>
<wheelType>WT_SPORT</wheelType>
</Item>
Это упрощённый ориентир, а не полный набор тегов — у реального vehicles.meta их несколько десятков, и точный список зависит от версии игры. Практический совет: не пиши файл с нуля, а бери за основу vehicles.meta из скачанного мода (почти все продавцы кастомных тачек кладут его готовым) и правь только то, что нужно.
Три поля здесь — источник большинства ошибок при установке чужой машины:
modelName— уникальное имя модели, указывается при спавне (/car mycar). Если два мода на сервере используют одинаковыйmodelName, выигрывает загруженный последним — вторая машина либо не спавнится, либо визуально подменяется первой.handlingId— связывает модель с записью вhandling.meta(см. ниже про апгрейды), должен буквально совпадать сidв файле хендлинга.audioNameHash— часто ставят на звук существующей ванильной машины (sultan,elegy2), если у мода нет своего звукового пакета — иначе двигатель будет немой.
carvariations.meta и carcols.meta: цвета и тюнинг-киты
carvariations.meta объявляет, какие «киты» и цвета доступны для модели — без записи здесь машина заспавнится, но не будет открываться в Los Santos Customs как редактируемая:
<Item>
<modelName>mycar</modelName>
<colors>
<Item>
<indices content="char_array">0 0 0 0</indices>
</Item>
</colors>
<kits>
<Item>mycar_kit</Item>
</kits>
</Item>
Сам список визуальных апгрейдов — бамперы, юбки, спойлеры, решётка радиатора, выхлоп, диски, ливреи — описывается в carcols.meta внутри <Kits>:
<Item kitName="mycar_kit">
<visibleMods>
<Item>
<modelName>mycar_bumper_f_1</modelName>
<type>VMT_BUMPER_F</type>
<bone>bumper_f</bone>
</Item>
<Item>
<modelName>mycar_spoiler_1</modelName>
<type>VMT_SPOILER</type>
<bone>chassis</bone>
</Item>
</visibleMods>
</Item>
Каждый <Item> — деталь в одном слоте (VMT_BUMPER_F/VMT_BUMPER_R, VMT_SKIRT, VMT_SPOILER, VMT_EXHAUST, VMT_GRILL, VMT_HOOD, VMT_ROOF и другие), которая появится в Los Santos Customs как опция для покупки. Покраска (цвет, перламутр, диски) в carcols напрямую не задаётся — она выставляется в рантайме нативкой SetVehicleColours из тюнинг-меню, а carcols лишь определяет, какие детали кузова вообще доступны для смены.
Тюнинг «под капотом»: handling.meta и тормозной путь
Визуальный тюнинг — это карcols, а вот физику (разгон, управляемость, тормозной путь) правит handling.meta, привязанный к машине через тот самый handlingId. Параметры, с которыми чаще всего работают при настройке апгрейдов производительности:
<Item type="CHandlingData">
<handlingName>MYCAR</handlingName>
<fMass value="1500.000000" />
<fInitialDriveForce value="0.270000" />
<fBrakeForce value="1.150000" />
<fBrakeBiasFront value="0.550000" />
<fHandBrakeForce value="0.700000" />
</Item>
fBrakeForce и fBrakeBiasFront напрямую влияют на тормозной путь: чем выше fBrakeForce, тем короче дистанция торможения, а баланс между осями (fBrakeBiasFront) определяет, не будет ли машину заносить при резком торможении. Многие тюнинг-скрипты для ESX/QBCore (уровни апгрейда тормозов, двигателя, турбо) просто подменяют часть этих значений через отдельный ресурс-оверрайд или временно нативкой SetVehicleHandlingFloat — без правки исходного XML мода. Второй способ безопаснее: не трогаешь оригинальный handling.meta автора, а накладываешь апгрейды поверх скриптом.
Точных «эталонных» значений для конкретного уровня тюнинга называть не будем — они подбираются вручную под баланс сервера, любые цифры без контекста мода будут условностью.
Регистрация в фреймворке: автосалон, гараж и деньги
Мало положить ресурс в resources/ и прописать ensure в server.cfg — движок увидит модель и она заспавнится по команде, но в магазине (Los Santos Customs, автосалон, гараж) игрок её не увидит, пока она не зарегистрирована в списке фреймворка.
В QBCore это qb-core/shared/vehicles.lua — общая таблица, из которой берут название, цену и категорию сразу и автосалон (qb-vehicleshop), и гараж (qb-garages), и меню спавна для админов:
['mycar'] = {
['name'] = 'MyCar GT',
['brand'] = 'Custom',
['model'] = 'mycar',
['price'] = 85000,
['category'] = 'sports',
['hash'] = `mycar`,
['shop'] = 'pdm',
},
В ESX ситуация менее однородная: в старых сборках список машин лежал в es_extended/data/vehicles.lua, а в актуальном ESX Legacy каталог автосалона чаще хранится в базе — таблица vehicles с полями model, price, category. Открой конфиг именно того автосалон-ресурса, который стоит на сервере — принцип один, конкретный файл или SQL-таблица зависят от версии.
Отдельный слой — хранение купленной машины: гараж плюс база. В QBCore это таблица player_vehicles (plate, garage, state), в ESX — owned_vehicles. Оба пишут запись при покупке через qb-vehicleshop/esx_vehicleshop (списание денег — Player.Functions.RemoveMoney/ESX.Functions.MinusCharacterMoney) и читают её обратно при заходе в гараж, чтобы заспавнить ту же модель с сохранённым plate.
Для add-on машины здесь нет ничего специфичного — гараж работает с modelName как со строкой, ему всё равно, ванильная это модель или кастомная. Единственное условие: modelName из vehicles.meta должен буквально совпадать со значением model в записи фреймворка и в базе — опечатка в любом из трёх мест даёт пустой слот в гараже или ошибку спавна «invalid model». Если на сервере уже настроена связка ESX или QBCore — добавление машины в существующий гараж занимает одну строку в конфиге.
Сколько add-on машин выдержит клиент: цена стрима
Это многие владельцы серверов недооценивают. Каждая add-on машина — минимум одна модель (.yft) и один текстурный пакет (.ytd), и вес пакета обычно измеряется единицами-десятками мегабайт: львиную долю веса дают текстуры (диффуз, нормали, спекуляр в высоком разрешении), а не полигоны модели.
Две проблемы, которые стоит разделять:
- Первый коннект нового игрока. FiveM скачивает и кэширует ресурсы сервера при первом заходе и при каждом обновлении контента. Библиотека из пары сотен add-on машин легко тянет на несколько гигабайт суммарно — при слабом канале это долгие минуты на экране загрузки, и часть новичков просто не досидит до входа.
- Стриминг в рантайме. Даже после кэширования игра подгружает модели и текстуры по мере необходимости в ограниченный бюджет памяти. Если на карте одновременно много тяжёлых add-on моделей — например, на автовыставке или сборе RP-фракции — возможны просадки FPS, «попкорн»-эффект прорисовки текстур и на слабых клиентах риск вылета по нехватке видеопамяти. Точных цифр «сколько машин можно» не существует — это ориентир, а не гарантия, слишком многое зависит от железа игроков.
Практические меры вместо погони за количеством:
- Сжимай текстуры в DXT5/BC7 при экспорте, а не оставляй несжатый TGA/PNG — разница в весе может быть кратной без заметной потери качества.
- Проверяй, есть ли у мода
_hi.yft— если сервер не про фото-режим и близкие кат-сцены, часто можно убрать_hi-версию и сэкономить объём без визуальной потери для рядового игрока. - Курируй библиотеку осознанно: 40–60 аккуратно подобранных машин с разумным весом ощущаются лучше, чем 300 «для количества», среди которых половина дублирует друг друга по классу.
Похожая логика — про то, что каждый добавленный ассет ест бюджет стриминга клиента, — разбиралась в статье про карты и MLO-интерьеры для FiveM: принцип общий для любого крупного ассета, будь то интерьер или машина.
Нужен игровой сервер?
MAATRIX GAMES — 45+ игр, деплой за минуты, DDoS-защита, автобэкапы. Тарифы от 399 ₽/мес.
Создать серверЧастые вопросы
Машина заспавнилась серым силуэтом без текстур — в чём проблема?
Почти всегда несовпадение txdName в vehicles.meta с реальным именем текстурного словаря внутри .ytd, либо файл текстур не попал в stream/. Проверь оба имени и путь.
Можно ли добавить сотню add-on машин одним общим ресурсом вместо сотни отдельных папок?
Да, так даже удобнее для порядка в server.cfg — один fxmanifest.lua может объявлять сколько угодно data_file/files записей на несколько моделей сразу. Главное — уникальные имена моделей и текстур внутри пакета.
Машина спавнится, но не открывается в Los Santos Customs для тюнинга.
Проверь, что модель прописана в carvariations.meta с привязкой к kitName из carcols.meta, и что этот kitName не совпадает по написанию с чужим китом на сервере — конфликтует так же, как и modelName.
Нужно ли перезапускать весь сервер после добавления новой машины?
Нет, обычно достаточно refresh и ensure через консоль/RCON, как с обычным скриптом. Полный рестарт нужен, только если правишь server.cfg вручную.
Как понять, что модель конфликтует с другой по хешу, а не просто сломан файл?
В консоли сервера обычно видно предупреждение о дублирующемся modelName/archetype при старте ресурса. Если предупреждения нет, а машина ведёт себя странно (не тот звук, не та физика) — сверь handlingId и audioNameHash.