MAATRIX GAMES / Блог / Транспортные моды и апгрейды для FiveM

Транспортные моды и апгрейды для FiveM

MAATRIX GAMES

Голый ванильный автопарк GTA V закрывает RP-сервер месяца на два, а дальше игроки начинают спрашивать про конкретные модели, которых в игре нет, и про тюнинг серьёзнее стандартного Los Santos Customs. Add-on транспорт и апгрейды — это уже не «накинуть архив в resources», а работа с несколькими 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.