MAATRIX GAMES / Блог / FiveM: система голода и жажды для реализма

FiveM: система голода и жажды для реализма

MAATRIX GAMES

Голая механика «шкала бежит вниз, ешь бургер» на RP-сервере надоедает игрокам за неделю: либо она вообще не ощущается и превращается в фоновый цифровой шум, либо начинает раздражать так, что люди уходят с сервера, где им «не дают поиграть» из-за постоянной беготни по магазинам. Разберём, как настроить голод и жажду в ESX и QBCore так, чтобы механика работала на атмосферу и экономику сервера, а не против удержания игроков.

Как устроены голод и жажда в ESX и QBCore «из коробки»

В обоих популярных фреймворках для FiveM RP голод и жажда — это не отдельный плагин, а часть системы метаданных персонажа. В ESX Legacy значения хранятся в xPlayer.getMeta('hunger') и xPlayer.getMeta('thirst') (обычно диапазон 0–100 или 0–1000, в зависимости от версии core), а убывание задаётся серверным потоком в es_extended/server/main.lua либо в конфиге через Config.EnableDefaultInventory и связанные параметры — в старых сборках эту роль играл отдельный ресурс esx_status, который сейчас считается устаревшим и заменён встроенной системой метаданных.

В QBCore аналогично: QBCore.Player.PlayerData.metadata.hunger и .thirst живут в базе вместе с персонажем, а убывание крутится в qb-core/server/player.lua через периодический SetTimeout. HUD, который показывает игроку эти значения (обычно qb-hud или форк), просто подписывается на изменение метаданных через events — сам HUD голод и жажду не считает, только отображает.

Если сервер ещё не поднят или фреймворк не выбран — сначала пройди базовую установку ESX или QBCore, от этого выбора зависит, где именно искать конфиги ниже. Если сомневаешься, какое ядро вообще брать под новый сервер — есть отдельное сравнение ESX и QBCore.

Настройка скорости убывания и стартовых значений

Первый практический вопрос: с какой скоростью шкалы должны падать. Тут нет единственно верного числа — оно зависит от темпа игры на конкретном сервере (хардкорный выживач или лёгкий семейный RP) и от того, сколько в среднем длится игровая сессия. Дай ориентир, от которого можно оттолкнуться: если голод и жажда падают со 100 до 0 примерно за 2,5–4 часа реального времени активной игры, среднестатистический игрок успевает поесть 1–2 раза за сессию, не превращая это в основное занятие. Это именно ориентир, а не измеренное значение — подбирай под свой сервер тестами с реальными игроками.

Пример конфигурации в стиле QBCore (адаптируй имена переменных под свой форк qb-core):

Config.NeedsDecay = {
    hunger = 4,      -- сколько пунктов теряется за один тик
    thirst = 5,      -- жажда обычно падает чуть быстрее голода
    tickInterval = 300000, -- интервал тика в мс (5 минут)
}

В ESX Legacy похожая логика чаще задаётся прямо в потоке, который дергает xPlayer.setMeta:

-- server/main.lua, упрощённый пример потока убывания
CreateThread(function()
    while true do
        Wait(300000) -- 5 минут
        for _, xPlayer in pairs(ESX.GetExtendedPlayers()) do
            local hunger = math.max(xPlayer.getMeta('hunger') - 4, 0)
            local thirst = math.max(xPlayer.getMeta('thirst') - 5, 0)
            xPlayer.setMeta('hunger', hunger)
            xPlayer.setMeta('thirst', thirst)
        end
    end
end)

Стартовые значения при создании персонажа лучше выставлять не на максимум, а чуть ниже (например, 80–90 из 100) — это создаёт лёгкий стимул зайти в первый игровой магазин или закусочную в первые же минуты, что заодно знакомит новичка с этой механикой сразу, а не через час игры, когда шкала внезапно окажется в красной зоне.

Поднять сервер FiveM (GTA V) за пару минут

Готовый образ MAATRIX GAMES: NVMe, AMD EPYC, DDoS-защита, панель управления. Локации UK, US, RU. Оплата картой РФ, СБП или криптой.

Создать сервер

Как голод и жажда должны влиять на персонажа

Сама по себе падающая шкала — не геймплей, а раздражитель, если она ни на что не влияет. Стандартный набор эффектов, который использует большинство RP-серверов:

  • Стамина и скорость бега. При голоде/жажде ниже определённого порога (например, 20 из 100) снижается регенерация стамины или сама доступная стамина — персонаж быстрее выдыхается при беге. Реализуется через SetPlayerSprintStaminaLimits или изменение SetRunSprintMultiplierForPlayer в клиентском скрипте, который слушает изменения метаданных.
  • Здоровье при полном истощении. Если шкала держится на нуле дольше N минут, персонаж начинает терять здоровье небольшими порциями (SetEntityHealth с шагом вниз раз в минуту). Это должно быть медленным и заметным заранее через HUD и экранные подсказки, а не внезапной смертью — иначе игроки воспримут это как баг, а не фичу.
  • Визуальные и звуковые сигналы. Лёгкое покачивание камеры, звук урчания в животе или сухого кашля при низких значениях — многие сборки используют для этого анимации персонажа (TaskPlayAnim с анимацией «шатает») в дополнение к HUD-индикатору.
  • Ограничение действий. Некоторые серверы блокируют тяжёлую физическую работу (грузчик, механик) при критически низком голоде — это скорее опциональная фича для хардкорных RP-серверов, чем стандарт, и легко переусердствовать, сделав механику навязчивой.

Важно не мешать в один порог сразу все эффекты — плавная деградация (лёгкое неудобство → заметное неудобство → серьёзные последствия) воспринимается игроками честнее, чем резкий переход «всё нормально» → «персонаж падает».

Еда и напитки: предметы, приготовление, торговые точки

Механика без источников еды бессмысленна, поэтому вторая половина настройки — это предметы и точки, где их можно получить. В QBCore предметы описываются в qb-core/shared/items.lua, а логика использования — через QBCore.Functions.CreateUseableItem:

QBCore.Functions.CreateUseableItem('sandwich', function(source, item)
    local Player = QBCore.Functions.GetPlayer(source)
    if not Player then return end
    TriggerClientEvent('QBCore:Notify', source, 'Вы съели сэндвич', 'success')
    Player.Functions.RemoveItem('sandwich', 1)
    TriggerClientEvent('inventory:client:ItemBox', source, QBCore.Shared.Items['sandwich'], 'remove')
    Player.Functions.SetMetaData('hunger', math.min(Player.PlayerData.metadata.hunger + 25, 100))
end)

В ESX похожий паттерн через ESX.RegisterUsableItem, где вместо метаданных QBCore используется xPlayer.setMeta. Логика та же: удалить предмет, проиграть анимацию (TaskPlayAnim на еде/питье занимает пару секунд — это заодно создаёт небольшое временное окно уязвимости, что многие RP-сообщества считают фичей, а не багом), поднять нужную шкалу.

Точки получения еды и напитков стоит разнести по разным механикам, чтобы не превращать всё в один магазин у спавна:

ИсточникЧто даётОсобенность
24/7 магазины (qb-shops, esx_shops)базовая еда/вода недороговсегда доступны, минимум RP
Vending-машины по городу (ps-vending и аналоги)снеки, водатребуют мелочи в кармане, добавляют жизни в локации
Рестораны/закусочные (job-скрипты типа burgershot)готовая еда с бонусом к насыщениютребует работы NPC/игрока-повара, больше RP-контекста
Крафт/готовка на кухне домасамодельная едадолгий путь, но дешевле и даёт геймплей фермерам/поварам

Разнообразие источников — это ещё и часть экономики сервера: если ты уже настраивал деньги и зарплаты, см. базовую настройку экономики RP-сервера — цены на еду и напитки логично привязывать к тем же принципам money sink, что и остальные бытовые траты.

HUD: отображение шкал голода и жажды

Игрок должен видеть текущее состояние без необходимости открывать инвентарь или спрашивать в чате. Большинство HUD-ресурсов (qb-hud, форки esx_hud / кастомные NUI) подписываются на события изменения метаданных и обновляют полосы в интерфейсе:

-- клиентский обработчик обновления HUD (пример под QBCore)
RegisterNetEvent('hud:client:UpdateNeeds', function(hunger, thirst)
    SendNUIMessage({
        action = 'updateNeeds',
        hunger = hunger,
        thirst = thirst
    })
end)

Практический нюанс, который часто упускают: не обновляй NUI на каждое минимальное изменение шкалы (например, раз в секунду) — это лишняя нагрузка на клиент без пользы, раз убывание и так идёт тиками в несколько минут. Обновляй HUD событием именно тогда, когда меняются метаданные, а не по отдельному постоянному таймеру.

Цветовую индикацию стоит делать постепенной (зелёный → жёлтый → красный по мере падения шкалы), а не бинарной — это интуитивно подсказывает игроку, что пора зайти в магазин, ещё до того, как начнутся штрафы к характеристикам.

Баланс между реализмом и играбельностью — частые ошибки

Здесь чаще всего ломают удержание игроков, даже не осознавая этого:

  • Слишком быстрое убывание. Если шкалы падают за 30–40 минут, игроки тратят заметную часть сессии на беготню за едой вместо основного RP — это быстро вызывает усталость от механики, а не погружение.
  • Штраф к здоровью без предупреждения. Резкая потеря HP без визуальных сигналов заранее выглядит как баг сервера, а не осознанное последствие — жалобы в тикеты почти гарантированы.
  • Единственная точка еды на всю карту. Если весь сервер завязан на один магазин у спавна, это создаёт толпу и убивает смысл вариативных источников (готовка, рестораны, вендинги по районам).
  • Отсутствие исключений для афк/загрузки. Если игрок вылетел или завис на загрузке карты, а таймер продолжает тикать — при возврате он получает штраф не по своей вине. Стоит ставить убывание на паузу, пока NetworkIsPlayerActive возвращает false, либо не начислять декей за время, пока игрок был offline.
  • Игнорирование мультиплеера семей/групп. Если у тебя на сервере есть общие дома и готовка, полезно позволить готовить впрок (стак еды на несколько применений), а не заставлять есть по одному предмету за раз — это меньше раздражает при активной игре с фракциями, о которых можно почитать в статье про систему фракций и банд.

Универсального «правильного» баланса не существует — на харкорных выживальческих RP-серверах агрессивный голод/жажда воспринимается как часть атмосферы, на более казуальных семейных проектах та же настройка станет причиной оттока. Ориентируйся на фидбек своего конкретного комьюнити и меняй параметры небольшими шагами, а не резкими скачками.

Поднять сервер FiveM (GTA V) за пару минут

Готовый образ MAATRIX GAMES: NVMe, AMD EPYC, DDoS-защита, панель управления. Локации UK, US, RU. Оплата картой РФ, СБП или криптой.

Создать сервер

Частые вопросы

Нужен ли отдельный ресурс для голода и жажды, или хватает встроенной системы ESX/QBCore?

Для большинства серверов встроенной системы метаданных достаточно — она уже интегрирована с HUD и инвентарём. Отдельные ресурсы (вроде исторического esx_status) чаще используют старые сборки или серверы, где нужна кастомная логика (например, отдельная шкала «энергии» помимо голода и жажды).

Как синхронизировать голод/жажду между инвентарём и HUD, если они из разных ресурсов?

Через события (TriggerEvent/TriggerClientEvent) и общий источник правды — метаданные игрока в базе. HUD и инвентарь не должны хранить свою копию значений, только подписываться на изменения от core-ресурса, иначе они рано или поздно разойдутся.

Стоит ли делать голод/жажду одинаковыми по скорости или жажда должна падать быстрее?

Логичнее, чтобы жажда убывала немного быстрее голода — это ближе к тому, как игроки интуитивно ожидают механику работать, и создаёт более частые, но мелкие поводы взаимодействовать с окружением (вода почти везде дешевле и доступнее еды).

Как протестировать баланс скорости убывания перед тем, как выкатывать на живой сервер?

Прогони механику на тестовой ветке с несколькими добровольцами из комьюнити на протяжении пары обычных игровых сессий и спроси прямо: мешало ли это RP или ощущалось естественно. Метрики вроде среднего времени между визитами в магазин полезны, но субъективный фидбек игроков в этом вопросе важнее голых цифр.

Можно ли отключить урон от голода/жажды, оставив только визуальные эффекты?

Да, это частый компромисс — оставить шкалы и лёгкие штрафы к стамине как атмосферный элемент, но убрать урон здоровью полностью. Так механика напоминает о себе, но не становится источником случайных смертей персонажа не по вине игрока.