ConsumablesNewFree

Consumables: Configuration

Every option in config/config.lua and config/foods.lua, from keys, bite timing and spoil times to giving food, ground drops and adding your own food.

v1.0.0Open sourceFreeQBox · QBCore · ESX · Standalone

Tip

After editing, restart only the resource with ensure hype-consumables; a full server restart is not needed.

General options live in config/config.lua, the food definitions in config/foods.lua. Both files return one table; the sections below follow their order.

General

config/config.lua
Debug = false,
Framework = 'auto',
Inventory = 'auto',
Notifications = 'auto',

Prop

Type

Controls

Keys used while eating and while picking a player. They are GTA controls: during that time they are disabled every frame and read with IsDisabledControlJustPressed, so game actions on the same key (cover, horn, headlights) and other scripts cannot interfere. While you are not eating they belong to the game.

config/config.lua
Controls = {
    bite = { label = 'E', controls = { 38, 51, 86 } },
    give = { label = 'H', controls = { 74, 104 } },
    drop = { label = 'Q', controls = { 44, 85 } },
    stop = { label = 'X', controls = { 73, 105 } },
},

Prop

Type

The full list of control ids is in the FiveM documentation.

Keys

Offer keys. They are also needed while you are not eating (incoming offers), so they are registered as key bindings that players can change under Settings → Key Bindings → FiveM. They are only active while you pick a player or have an incoming offer.

config/config.lua
Keys = {
    accept = 'Y',
    decline = 'N',
},

Prop

Type

Default keys only apply once

FiveM stores a player's key bindings the first time they join. Changing Keys later only affects players who never had the binding; others keep their current key until they change it in the settings.

Consume

config/config.lua
Consume = {
    biteTime = 2600,
    biteOnStart = true,
    minBiteRatio = 0.7,
    allowInVehicle = true,
    allowSprint = false,
    cancelOnRagdoll = true,
},

Prop

Type

Categories

Default unit, perishability and spoil time per category. A field set on the food itself overrides the category value. spoilTime is in seconds of real time, so food keeps spoiling while the server is off.

config/config.lua
Categories = {
    basic_drink = { perishable = false, unit = 'ml' },
    fresh_food = { perishable = true, spoilTime = 48 * 60 * 60, unit = 'g' },
    packaged_food = { perishable = true, spoilTime = 72 * 60 * 60, unit = 'g' },
    fresh_drink = { perishable = true, spoilTime = 24 * 60 * 60, unit = 'ml' },
    special_food = { perishable = true, spoilTime = 36 * 60 * 60, unit = 'g' },
},
CategorySpoils afterUnitUsed by
basic_drinkNevermlwater
fresh_food48 hoursgburger, sandwich, hotdog, taco, fries
packaged_food72 hoursgdonut, chips, egobar, sprunk and ecola (ml)
fresh_drink24 hoursmlcoffee, grapejuice
special_food36 hoursgNot used by the included foods

Prop

Type

The panel shows the category name for single portion foods (foods without defaultWeight), translated from ui.category in the locale files. If you add a category, add its name there too.

Spoilage

config/config.lua
Spoilage = {
    checkInterval = 5 * 60,
    allowConsume = false,
    nutritionMultiplier = 0.25,
    healthLossPerBite = 4,
    spoiledItem = false,
    labelSuffix = true,
},

Prop

Type

Food in offline players' inventories and in stashes is not walked by the periodic check. The expiry is stored as a timestamp, so it is applied on the next use or when the player joins.

Transfer

Giving food to a nearby player.

config/config.lua
Transfer = {
    distance = 3.0,
    timeout = 20,
    cooldown = 3,
    showNames = false,
},

Prop

Type

A player can have one outgoing offer at a time, and a player who already has an incoming offer cannot receive another.

Drops

Food put on the ground. Props are only spawned for players within renderDistance, and expired drops are cleaned up once a minute.

config/config.lua
Drops = {
    enabled = true,
    persist = true,
    maxTotal = 150,
    maxPerPlayer = 5,
    lifetime = 60 * 60,
    removeSpoiled = false,
    renderDistance = 40.0,
    interactDistance = 2.0,
    placeDistance = 3.0,
    fallbackProp = 'prop_cs_burger_01',
},

Prop

Type

Rate limit

Prop

Type

Some actions use their own fixed delays: placing a drop 1 second, picking one up 0.75 seconds, and offers use Transfer.cooldown.

Foods

config/foods.lua holds one entry per food. The key is the inventory item name, so it must match the item you added during installation.

config/foods.lua
local eat = { dict = 'mp_player_inteat@burger', clip = 'mp_player_int_eat_burger', flag = 49 }

return {
    burger = {
        label = 'Burger',
        category = 'fresh_food',
        defaultWeight = 200,
        biteSize = 20,
        hungerPerBite = 5,
        animation = eat,
        prop = { model = 'prop_cs_burger_01', bone = 18905, pos = vec3(0.13, 0.05, 0.02), rot = vec3(-50.0, 16.0, 60.0) },
    },
}

Prop

Type

Included foods

ItemLabelCategoryAmountPer biteBitesValue per bite
burgerBurgerfresh_food200 g20 g105 hunger
sandwichSandwichfresh_food180 g30 g66 hunger
hotdogHot Dogfresh_food150 g25 g66 hunger
tacoTacofresh_food120 g20 g65 hunger
friesFriesfresh_food150 g15 g103 hunger
donutDonutpackaged_food80 g20 g44 hunger
chipsChipspackaged_food90 g10 g92 hunger
egobarEgo Barpackaged_food50 g10 g53 hunger
waterWaterbasic_drink500 ml100 ml55 thirst (25 total)
sprunkSprunkpackaged_food330 ml55 ml66 thirst
ecolaeColapackaged_food330 ml55 ml66 thirst
coffeeCoffeefresh_drink250 ml50 ml55 thirst
grapejuiceGrape Juicefresh_drink300 ml60 ml56 thirst

Coffee has a longer bite (biteTime = 3200). Water uses thirstPerUse = 25, the others set a value per bite.

Adding a food

Add an entry to config/foods.lua:

config/foods.lua
pizza_slice = {
    label = 'Pizza Slice',
    category = 'fresh_food',      -- spoil time and unit come from the category
    defaultWeight = 140,          -- starting amount
    biteSize = 35,                -- per bite (or bites = 4)
    hungerPerBite = 6,            -- or hungerPerUse = 24 (value of the whole item)
    spoilTime = 24 * 60 * 60,     -- optional: overrides the category
    animation = { dict = 'mp_player_inteat@burger', clip = 'mp_player_int_eat_burger' },
    prop = { model = 'prop_cs_burger_01', bone = 18905, pos = vec3(0.13, 0.05, 0.02), rot = vec3(-50.0, 16.0, 60.0) },
},

Add an item with the same name to your inventory. Copy an entry from INSTALL/ox_inventory.md or INSTALL/qb_inventory.md and change the name, label and image.

Restart the resource. If the item is missing from the inventory, the console lists it on start.

When the last bite is smaller than biteSize, only the rest is eaten and its hunger and thirst value is applied proportionally. Missing prop models are detected with IsModelInCdimage: no prop is shown in the hand and Drops.fallbackProp is used on the ground.

Locales

The language comes from ox_lib, so it is set in server.cfg rather than in the config:

server.cfg
setr ox:locale "en"

en and tr are included. The Lua side and the panel share the same files. To add a language, copy locales/en.json, translate it, save it with the language code as its name (e.g. de.json) and set ox:locale to that code.

The amount, expiry and (Spoiled) lines in the inventory are written into the item metadata on the server, in the server's language, whenever the item changes. The expiry date uses the DD.MM.YYYY HH:MM format and the server's clock. Item labels and the ox_inventory button texts come from your item definitions, not from the locales.

config.lua
foods.lua
en.json
tr.json
fxmanifest.lua

On this page