Zum Inhalt

Hunger & Thirst System

The hunger and thirst system tracks the nutritional status of every player. Values are persisted to the database, managed server-side through the Player object state, and displayed in real time by the cv_hud React UI.


Files

File Purpose
modules/hunger/config.lua Configuration parameters (depletion rates, damage thresholds …)
modules/hunger/server/hunger.lua Server logic, exports, events
modules/hunger/server/items.lua Food/drink item definitions + usable callbacks
modules/hunger/client/hunger.lua Client depletion loop, statebag push, 60 s sync
resources/[char]/cv_hud/…/PlayerHud.tsx React component rendering the hunger/thirst bars

Configuration

All parameters live in modules/hunger/config.lua under Config.Hunger:

Config.Hunger = {
    maxHunger           = 100,   -- Maximum hunger value
    maxThirst           = 100,   -- Maximum thirst value
    startHunger         = 75,    -- Fallback start value on login
    startThirst         = 75,

    hungerDepletion     = 0.05,  -- Points lost per second (walking)
    thirstDepletion     = 0.08,

    runningMultiplier   = 2.0,   -- Depletion multiplier while running
    sprintingMultiplier = 3.5,   -- Depletion multiplier while sprinting

    damageThreshold     = 10,    -- Take damage when value drops below this
    damageAmount        = 1,     -- HP damage per tick

    saveInterval        = 300000, -- DB save interval in ms (5 min)
}

Data Flow

sequenceDiagram
    participant DB as Database
    participant SRV as Server (hunger.lua)
    participant PLY as Player Object
    participant CLT as Client (hunger.lua)
    participant HUD as cv_hud (React)

    DB->>SRV: Character loaded (hunger, thirst)
    SRV->>PLY: player:setHunger(db_value)<br/>player:setThirst(db_value)
    PLY-->>SRV: Statebag replicated (player:<id>)
    SRV->>CLT: TriggerClientEvent cv:client:SetHunger

    loop Every second
        CLT->>CLT: Calculate depletion
        CLT->>HUD: LocalPlayer.state:set('hunger', …)
        HUD->>HUD: AddStateBagChangeHandler → React update
    end

    loop Every 60 seconds
        CLT->>SRV: TriggerServerEvent cv:server:SyncHunger
        SRV->>PLY: Update player.hunger / player.thirst
        Note over SRV,PLY: Next saveCharacter() persists the real values
    end

Server API

Exports

All exports are called from other resources via exports.cv_framework:…().

GetPlayerHunger(source)

Returns the player's current hunger and thirst values.

local data = exports.cv_framework:GetPlayerHunger(source)
-- data = { hunger = 82, thirst = 67 }

SetHunger(source, value)

Sets the hunger value exactly (0–100). Updates the player object state and fires cv:client:SetHunger on the client.

exports.cv_framework:SetHunger(source, 100)

SetThirst(source, value)

Same as SetHunger for thirst.

AddHunger(source, amount)

Adds amount to the current hunger (capped at maxHunger).

exports.cv_framework:AddHunger(source, 40) -- player ate a burger

AddThirst(source, amount)

Same as AddHunger for thirst.

InitializePlayer(source, hunger, thirst)

Called internally after a character is loaded. Sets hunger/thirst from the database and bootstraps the client depletion loop with the correct values.


Server Events

cv:server:DrinkWater (NetEvent)

Convenience wrapper for the client: adds thirst and shows a notification.

TriggerServerEvent('cv:server:DrinkWater', 20)

cv:server:EatFood (NetEvent)

Same as above for hunger.

cv:server:SyncHunger (NetEvent)

Fired by the client every 60 seconds to keep server-side values current between DB saves.

-- called internally — do not trigger manually
TriggerServerEvent('cv:server:SyncHunger', currentHunger, currentThirst)

Client API

Namespace: cv.hunger

cv.hunger.getHunger()number

Returns the locally cached hunger value (0–100).

cv.hunger.getThirst()number

Returns the locally cached thirst value.

cv.hunger.eat(amount?)

Sends cv:server:EatFood with amount (default: 20).

cv.hunger.drink(amount?)

Sends cv:server:DrinkWater with amount (default: 20).


Client Events

cv:client:SetHunger(hunger, thirst) (NetEvent)

Fired by the server after character load, eating/drinking, or a SetHunger/SetThirst call. Updates local variables and immediately pushes them to the statebag, triggering a HUD update.


HUD Integration

cv_hud reads hunger and thirst from the local player statebag (LocalPlayer.state) via AddStateBagChangeHandler.

-- cv_hud/client/main.lua (simplified)
AddStateBagChangeHandler('hunger', 'player:<id>', function()
    updatePlayerDataFromState()  -- → SendNUIMessage → React
end)

The StatusBar React component in PlayerHud.tsx rounds the value to a whole number before rendering:

const rounded = Math.round(value);
// bar width:  style={{ width: `${rounded}%` }}
// label:      {rounded}%

Food Items

All food and drink items are defined in modules/hunger/server/items.lua and inserted into item_definitions on every server start via INSERT IGNORE (type: consumable).

Name Label Thirst
water Water +30
drink_sprunk Sprunk +25
drink_junk Junk Energy +20
coffee Coffee +20
bubble_tea Bubble Tea +25
burgershot_cola BurgerShot Cola +25
beer_dignity Dignity Beer +20
beer_jackey Jackey Beer +20
beer_stronzo Stronzo Beer +20
beer_thaw Thaw Beer +20
bourbon Bourbon +10
whisky Whisky +10
wine Wine +15
whitewine_rockfordhill White Wine (Rockford Hills) +15
champagne_bleuterd Champagne Bleuterd +15
champagne_le_cocteau Champagne Le Cocteau +15
cuba_libre Cuba Libre +12
gin_tonic Gin Tonic +12
tequila_sunrise Tequila Sunrise +12
Name Label Hunger
pancakes Pancakes +45
burgershot_baconlover Bacon Lover Burger +40
burgershot_burrito BurgerShot Burrito +35
burgershot_chickenwings Chicken Wings +30
burgershot_fries French Fries +25
burgershot_hotdog Hotdog +30
burgershot_sandwich_tomate_mozzarella Tomato Mozzarella Sandwich +35
chicken_bucket Chicken Bucket +50
chips Chips +15
sandwich Sandwich +35
sushi Sushi +40
dino_nugget Dino Nuggets +25
banh_bao Bánh Bao +35
Name Label Hunger
cake_apple Apple Cake +30
cake_chocolate Chocolate Cake +30
cake_lemon Lemon Cake +30
cake_strawberry Strawberry Cake +30
cupcake Cupcake +20

Depletion Rates

Idle consumption over time (example values at hungerDepletion = 0.05, thirstDepletion = 0.08):

Time Hunger lost Thirst lost
1 minute −3 −4.8
10 minutes −30 −48
1 hour −180 (floor: 0) −288 (floor: 0)

Running (×2.0) and sprinting (×3.5) scale all values accordingly.

Damage at critical values

If hunger or thirst drops below 10, the player takes 1 HP of damage every tick.


Database Schema

Hunger and thirst are stored in the characters table (defined in datenbank.sql):

`hunger` INT NOT NULL DEFAULT 100,
`thirst` INT NOT NULL DEFAULT 100,

The schema is managed exclusively by the Docker init script datenbank.sql.
cv_framework does not execute its own CREATE TABLE statements.