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.
SetHunger(source, value)¶
Sets the hunger value exactly (0–100). Updates the player object state and fires cv:client:SetHunger on the client.
SetThirst(source, value)¶
Same as SetHunger for thirst.
AddHunger(source, amount)¶
Adds amount to the current hunger (capped at maxHunger).
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.
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):
The schema is managed exclusively by the Docker init script
datenbank.sql.
cv_frameworkdoes not execute its ownCREATE TABLEstatements.