Installation
Install Brewery
This page is a step-by-step install for bs_brewery on FiveM. Item definitions are large; you copy them from the resource files listed below and merge them into your inventory’s items file (or QBCore shared items). Small reference snippets are included here for merge shape, server.cfg order, and images.
Before you start (checklist)
| Requirement | Notes |
|---|---|
| MLO | Dolo Beer Factory — required; coordinates assume this interior |
| ox_lib | Notifications, inputs, callbacks |
| ox_inventory | Items, stashes, shop, searches — required for this script |
| ox_target | Brewery interactions |
| oxmysql | Database |
| Framework | One of: qbx_core (Qbox), qb-core (QBCore), es_extended (ESX) |
1) Add the resource
- Copy the
bs_breweryfolder into your server (for exampleresources/[standalone]/bs_brewery). - Do not rename the folder unless you know how to update every
nui:/// resource reference (default name isbs_brewery).
2) Database
- Open your MySQL tool (HeidiSQL, phpMyAdmin, CLI, etc.).
- Select the same database your
oxmysqlconnection uses. - Run the contents of:
bs_brewery/sql/install.sql
Optional (CLI example):
mysql -u YOUR_USER -p YOUR_DATABASE < /path/to/bs_brewery/sql/install.sql
The citizenid column stores QBCore/Qbox citizenid or ESX identifier, depending on Config.Framework.
3) Framework setting
Edit bs_brewery/shared/config.lua:
Config.Framework = 'qbx' -- 'qbx' | 'qb' | 'esx'
- Qbox:
'qbx' - QBCore:
'qb' - ESX:
'esx'
Set Config.Currency ('cash' or 'bank') to match how you want the shop and payouts to charge/pay.
4) Item installation (by framework)
This script expects all item names used in shared/config.lua / recipes to exist in ox_inventory (even on QBCore/ESX if you use ox_inventory for gameplay).
Source files in the resource
| File | Use when |
|---|---|
bs_brewery/items/ox_items.lua | ox_inventory (Qbox, QBCore+ox, ESX+ox) — full return { ... } ox item table |
bs_brewery/items/esx_items.lua | ESX + ox_inventory — same ox shape; keep in sync with ox_items.lua |
bs_brewery/items/qb_items.lua | QBCore QBShared.Items (qb-inventory style metadata) — not a full return file |
A) Qbox (QBX) — ox_inventory
Target file (typical): ox_inventory/data/items.lua
Here you will copy items in to your items.lua file in ox_inventory.
Steps
- Open
bs_brewery/items/ox_items.luain an editor. - Copy only the entries inside the main table: from the first
['pale_malt'](or first['...']afterreturn {) through the last item before the closing}of that file — do not paste a secondreturn {. - In
ox_inventory/data/items.lua, paste those lines inside your existingreturn { ... }, with a comma after the previous last item. - Ensure recipe books keep their
usecallbacks exactly as in the resource file (see snippet below). - Save, then restart
ox_inventory, thenbs_brewery.
Copy Items below and Append to Data > items.lua file:
-- ==========================================
-- BASE MALTS / GRAINS (sold by the pound)
-- ==========================================
['pale_malt'] = {
label = 'Pale Malt (2-Row)',
weight = 1000,
stack = true,
close = true,
description = 'Classic American 2-row pale malt. The foundation of most beers. Sold by the pound (lb).',
},
['pilsner_malt'] = {
label = 'Pilsner Malt',
weight = 1000,
stack = true,
close = true,
description = 'Light German pilsner malt for crisp lagers. Sold by the pound (lb).',
},
['wheat_malt'] = {
label = 'Wheat Malt',
weight = 1000,
stack = true,
close = true,
description = 'Malted wheat for hefeweizens and wheat beers. Sold by the pound (lb).',
},
['munich_malt'] = {
label = 'Munich Malt',
weight = 1000,
stack = true,
close = true,
description = 'Adds rich, bready, malty flavors. Sold by the pound (lb).',
},
['vienna_malt'] = {
label = 'Vienna Malt',
weight = 1000,
stack = true,
close = true,
description = 'Slightly darker base malt with toasty notes. Sold by the pound (lb).',
},
['maris_otter'] = {
label = 'Maris Otter',
weight = 1000,
stack = true,
close = true,
description = 'Premium English pale malt with biscuity character. Sold by the pound (lb).',
},
-- ==========================================
-- SPECIALTY GRAINS (sold by the pound)
-- ==========================================
['crystal_malt'] = {
label = 'Crystal Malt 60°L',
weight = 500,
stack = true,
close = true,
description = 'Adds caramel sweetness and body. 60°L refers to 60° Lovibond (color rating), not volume. Sold by the pound (lb).',
},
['chocolate_malt'] = {
label = 'Chocolate Malt',
weight = 500,
stack = true,
close = true,
description = 'Dark malt with chocolate and coffee notes. Sold by the pound (lb).',
},
['roasted_barley'] = {
label = 'Roasted Barley',
weight = 500,
stack = true,
close = true,
description = 'Unmalted barley, key for stouts. Sold by the pound (lb).',
},
['black_patent'] = {
label = 'Black Patent Malt',
weight = 500,
stack = true,
close = true,
description = 'Intensely roasted for color and bitter notes. Sold by the pound (lb).',
},
['carapils'] = {
label = 'Carapils/Dextrine',
weight = 500,
stack = true,
close = true,
description = 'Improves head retention and body. Sold by the pound (lb).',
},
['honey_malt'] = {
label = 'Honey Malt',
weight = 500,
stack = true,
close = true,
description = 'Sweet malt with honey-like flavors. Sold by the pound (lb).',
},
['smoked_malt'] = {
label = 'Smoked Malt',
weight = 500,
stack = true,
close = true,
description = 'Beechwood smoked malt for rauchbiers. Sold by the pound (lb).',
},
['oat_malt'] = {
label = 'Oat Malt',
weight = 500,
stack = true,
close = true,
description = 'Adds silky mouthfeel and body. Sold by the pound (lb).',
},
['rye_malt'] = {
label = 'Rye Malt',
weight = 500,
stack = true,
close = true,
description = 'Spicy grain character. Sold by the pound (lb).',
},
['acidulated_malt'] = {
label = 'Acidulated Malt',
weight = 500,
stack = true,
close = true,
description = 'Lowers mash pH naturally. Sold by the pound (lb).',
},
-- ==========================================
-- HOPS (sold by the ounce)
-- ==========================================
['cascade_hops'] = {
label = 'Cascade Hops',
weight = 100,
stack = true,
close = true,
description = 'Classic American hop with citrus and floral notes. Sold by the ounce (oz).',
},
['centennial_hops'] = {
label = 'Centennial Hops',
weight = 100,
stack = true,
close = true,
description = 'Balanced citrus and floral hop. Sold by the ounce (oz).',
},
['citra_hops'] = {
label = 'Citra Hops',
weight = 100,
stack = true,
close = true,
description = 'Intense tropical fruit and citrus. Sold by the ounce (oz).',
},
['mosaic_hops'] = {
label = 'Mosaic Hops',
weight = 100,
stack = true,
close = true,
description = 'Complex berry and tropical notes. Sold by the ounce (oz).',
},
['simcoe_hops'] = {
label = 'Simcoe Hops',
weight = 100,
stack = true,
close = true,
description = 'Pine, citrus, and earthy character. Sold by the ounce (oz).',
},
['amarillo_hops'] = {
label = 'Amarillo Hops',
weight = 100,
stack = true,
close = true,
description = 'Orange and floral aromatics. Sold by the ounce (oz).',
},
['saaz_hops'] = {
label = 'Saaz Hops',
weight = 100,
stack = true,
close = true,
description = 'Noble Czech hop with spicy, herbal notes. Sold by the ounce (oz).',
},
['hallertau_hops'] = {
label = 'Hallertau Hops',
weight = 100,
stack = true,
close = true,
description = 'Traditional German noble hop. Sold by the ounce (oz).',
},
['fuggle_hops'] = {
label = 'Fuggle Hops',
weight = 100,
stack = true,
close = true,
description = 'English hop with earthy, woody character. Sold by the ounce (oz).',
},
['ekg_hops'] = {
label = 'East Kent Goldings',
weight = 100,
stack = true,
close = true,
description = 'Classic English aroma hop. Sold by the ounce (oz).',
},
['galaxy_hops'] = {
label = 'Galaxy Hops',
weight = 100,
stack = true,
close = true,
description = 'Australian hop with passionfruit notes. Sold by the ounce (oz).',
},
['nelson_hops'] = {
label = 'Nelson Sauvin',
weight = 100,
stack = true,
close = true,
description = 'New Zealand hop with wine-like qualities. Sold by the ounce (oz).',
},
-- ==========================================
-- YEAST (sold by the packet)
-- ==========================================
['us05_yeast'] = {
label = 'US-05 Ale Yeast',
weight = 50,
stack = true,
close = true,
description = 'Clean American ale yeast. Sold by the packet.',
},
['s04_yeast'] = {
label = 'S-04 English Ale',
weight = 50,
stack = true,
close = true,
description = 'English ale yeast with fruity esters. Sold by the packet.',
},
['w34_yeast'] = {
label = 'W-34/70 Lager',
weight = 50,
stack = true,
close = true,
description = 'German lager yeast for clean fermentation. Sold by the packet.',
},
['belgian_yeast'] = {
label = 'Belgian Ale Yeast',
weight = 50,
stack = true,
close = true,
description = 'Produces spicy, fruity Belgian character. Sold by the packet.',
},
['hefeweizen_yeast'] = {
label = 'Hefeweizen Yeast',
weight = 50,
stack = true,
close = true,
description = 'Creates banana and clove flavors. Sold by the packet.',
},
['saison_yeast'] = {
label = 'Saison Yeast',
weight = 50,
stack = true,
close = true,
description = 'Farmhouse yeast with peppery notes. Sold by the packet.',
},
['brett_yeast'] = {
label = 'Brettanomyces',
weight = 50,
stack = true,
close = true,
description = 'Wild yeast for funky, complex beers. Sold by the packet.',
},
['lactobacillus'] = {
label = 'Lactobacillus',
weight = 50,
stack = true,
close = true,
description = 'Bacteria for sour beer production. Sold by the packet.',
},
-- ==========================================
-- ADJUNCTS & FLAVORS (units vary)
-- ==========================================
['cane_sugar'] = {
label = 'Cane Sugar',
weight = 500,
stack = true,
close = true,
description = 'Increases alcohol without adding body. Sold by the pound (lb).',
},
['honey'] = {
label = 'Honey',
weight = 500,
stack = true,
close = true,
description = 'Local wildflower honey. Sold by the pound (lb).',
},
['maple_syrup'] = {
label = 'Maple Syrup',
weight = 500,
stack = true,
close = true,
description = 'Grade A maple syrup. Sold by the pound (lb).',
},
['lactose'] = {
label = 'Lactose',
weight = 500,
stack = true,
close = true,
description = 'Unfermentable sugar for sweetness. Sold by the pound (lb).',
},
['coffee_beans'] = {
label = 'Coffee Beans',
weight = 250,
stack = true,
close = true,
description = 'Fresh roasted coffee beans. Sold in 4 ounce packages.',
},
['cocoa_nibs'] = {
label = 'Cocoa Nibs',
weight = 250,
stack = true,
close = true,
description = 'Raw cacao for chocolate flavor. Sold in 4 ounce packages.',
},
['vanilla_beans'] = {
label = 'Vanilla Beans',
weight = 100,
stack = true,
close = true,
description = 'Madagascar vanilla beans. Sold individually (each).',
},
['oak_chips'] = {
label = 'Oak Chips',
weight = 250,
stack = true,
close = true,
description = 'Medium toast French oak. Sold in 4 ounce packages.',
},
['fruit_puree'] = {
label = 'Fruit Puree',
weight = 500,
stack = true,
close = true,
description = 'Fresh fruit puree for brewing. Sold by the pound (lb).',
},
['pumpkin_spice'] = {
label = 'Pumpkin Spice',
weight = 100,
stack = true,
close = true,
description = 'Blend of cinnamon, nutmeg, and allspice. Sold by the ounce (oz).',
},
['coriander'] = {
label = 'Coriander',
weight = 100,
stack = true,
close = true,
description = 'Crushed coriander seeds. Sold by the ounce (oz).',
},
['orange_peel'] = {
label = 'Orange Peel',
weight = 100,
stack = true,
close = true,
description = 'Dried bitter orange peel. Sold by the ounce (oz).',
},
-- ==========================================
-- PACKAGING SUPPLIES
-- ==========================================
['beer_bottle'] = {
label = 'Beer Bottle (12oz)',
weight = 200,
stack = true,
close = true,
description = 'Empty amber glass bottle. 12 fluid ounces capacity. Sold in cases of 48.',
},
['bottle_cap'] = {
label = 'Bottle Cap',
weight = 5,
stack = true,
close = true,
description = 'Oxygen-absorbing crown cap.',
},
['bottle_cap_package'] = {
label = 'Bottle Cap Package',
weight = 250,
stack = true,
close = true,
description = 'A package containing 48 bottle caps. Use to unpack.',
},
['beer_label'] = {
label = 'Beer Label',
weight = 10,
stack = true,
close = true,
description = 'Waterproof adhesive label.',
},
['beer_keg'] = {
label = 'Empty Keg (5gal)',
weight = 5000,
stack = true,
close = true,
description = 'Cornelius-style keg. 5 gallon capacity.',
},
['keg_coupler'] = {
label = 'Keg Coupler',
weight = 500,
stack = true,
close = true,
description = 'Sankey D-style coupler.',
},
['beer_case'] = {
label = 'Beer Case (24-pack)',
weight = 500,
stack = true,
close = true,
description = 'Cardboard case for 24 bottles (12oz each).',
},
-- ==========================================
-- CLEANING & CHEMICALS
-- ==========================================
['pbw_cleaner'] = {
label = 'PBW Cleaner',
weight = 500,
stack = true,
close = true,
description = 'Powerful brewery wash cleaner. 16 fluid ounces.',
},
['starsan'] = {
label = 'Star San Sanitizer',
weight = 500,
stack = true,
close = true,
description = 'No-rinse sanitizer for brewing. 16 fluid ounces.',
},
-- ==========================================
-- EQUIPMENT & TOOLS
-- ==========================================
['hydrometer'] = {
label = 'Hydrometer',
weight = 100,
stack = false,
close = true,
description = 'Measures specific gravity for ABV calculation.',
},
['refractometer'] = {
label = 'Refractometer',
weight = 150,
stack = false,
close = true,
description = 'Measures sugar content quickly.',
},
['ph_meter'] = {
label = 'pH Meter',
weight = 200,
stack = false,
close = true,
description = 'Digital pH meter for water chemistry.',
},
['thermometer'] = {
label = 'Digital Thermometer',
weight = 100,
stack = false,
close = true,
description = 'Precise temperature measurement.',
},
['grain_scale'] = {
label = 'Grain Scale',
weight = 2000,
stack = false,
close = true,
description = 'Digital scale for weighing ingredients.',
},
-- ==========================================
-- RECIPE BOOKS (require `use` for bs_brewery UI)
-- ==========================================
['recipe_book_basic'] = {
label = 'Basic Brewing Guide',
weight = 500,
stack = false,
close = true,
description = 'Introduction to brewing basics. Right-click to use.',
use = function(event, item, inventory, slot, data)
TriggerServerEvent('bs_brewery:server:useRecipeBook', item.name)
end,
},
['recipe_book_intermediate'] = {
label = 'Intermediate Recipes',
weight = 500,
stack = false,
close = true,
description = 'Collection of intermediate beer recipes. Right-click to use.',
use = function(event, item, inventory, slot, data)
TriggerServerEvent('bs_brewery:server:useRecipeBook', item.name)
end,
},
['recipe_book_advanced'] = {
label = 'Advanced Techniques',
weight = 500,
stack = false,
close = true,
description = 'Advanced brewing methods and recipes. Right-click to use.',
use = function(event, item, inventory, slot, data)
TriggerServerEvent('bs_brewery:server:useRecipeBook', item.name)
end,
},
['recipe_book_master'] = {
label = "Master Brewer's Tome",
weight = 500,
stack = false,
close = true,
description = 'Expert-level brewing knowledge. Right-click to use.',
use = function(event, item, inventory, slot, data)
TriggerServerEvent('bs_brewery:server:useRecipeBook', item.name)
end,
},
['recipe_book_legendary'] = {
label = 'Legendary Brews',
weight = 500,
stack = false,
close = true,
description = 'The rarest and most complex recipes. Right-click to use.',
use = function(event, item, inventory, slot, data)
TriggerServerEvent('bs_brewery:server:useRecipeBook', item.name)
end,
},
-- ==========================================
-- FINISHED PRODUCTS (Generic, metadata determines type)
-- ==========================================
['craft_beer_bottle'] = {
label = 'Craft Beer Bottle',
weight = 350,
stack = true,
close = false,
description = 'A bottle of craft beer.',
consume = 1,
},
['craft_beer_keg'] = {
label = 'Craft Beer Keg',
weight = 20000,
stack = false,
close = true,
description = 'A 5-gallon keg of craft beer.',
},
['craft_beer_case'] = {
label = 'Craft Beer Case',
weight = 9000,
stack = false,
close = true,
description = 'A case of 24 craft beers.',
},
-- ==========================================
-- INTERMEDIATE BREWING ITEMS
-- ==========================================
['wort_sample'] = {
label = 'Wort Sample',
weight = 100,
stack = true,
close = true,
description = 'Sample of unfermented wort.',
},
['beer_sample'] = {
label = 'Beer Sample',
weight = 100,
stack = true,
close = true,
description = 'Sample of beer for quality testing.',
},
['milled_grain'] = {
label = 'Milled Grain',
weight = 1000,
stack = true,
close = true,
description = 'Crushed grain ready for mashing.',
},
}
Recipe books — use must call the server (copy as-is if missing):
['recipe_book_basic'] = {
label = 'Basic Brewing Guide',
weight = 500,
stack = false,
close = true,
description = 'Introduction to brewing basics. Right-click to use.',
use = function(event, item, inventory, slot, data)
TriggerServerEvent('bs_brewery:server:useRecipeBook', item.name)
end,
},
Repeat the same use pattern for: recipe_book_intermediate, recipe_book_advanced, recipe_book_master, recipe_book_legendary (full blocks are in items/ox_items.lua).
Item images (ox_inventory)
PNG files ship under bs_brewery/items/*.png. If icons do not show, add a client block per item (example):
['pale_malt'] = {
label = 'Pale Malt (2-Row)',
weight = 1000,
stack = true,
close = true,
description = '...',
client = {
image = 'nui://bs_brewery/items/pale_malt.png',
},
},
If your inventory already resolves images by item name + default path, you may not need client.image.
B) QBCore — ox_inventory (recommended)
If players use ox_inventory on QBCore:
- Set
Config.Framework = 'qb'inbs_brewery/shared/config.lua. - Merge
bs_brewery/items/ox_items.luaintoox_inventory/data/items.luausing the same steps as section A (ox format is identical).
You do not need qb_items.lua for ox_inventory-only setups.
C) QBCore — QBShared.Items (qb-inventory / classic QB item table)
Use this path if your stack still relies on qb-core/shared/items.lua (or a merged items file) with ['item'] = { ['name'] = ... } shape.
Target file (typical): qb-core/shared/items.lua inside QBShared.Items = { ... }.
Steps
- Open
bs_brewery/items/qb_items.lua. - Delete the template dummy block at the top (
['item_name'] = { ... },) — do not add that toQBShared.Items. - Copy all real entries from
['pale_malt']through the last brewery item. - Paste inside
QBShared.Items = { ... }with valid commas between entries. - Ensure images exist where your inventory expects them (often
qb-inventory/html/imagesor your inventory’s image folder); filenames in the resource useitemname.png. - Restart
qb-core(or your items resource) andbs_brewery.
Copy Items below and Append to Data > items.lua file:
['item_name'] = {
['name'] = 'item_name',
['label'] = "item_name",
['weight'] = 100,
['type'] = 'item',
['image'] = 'item_name.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "",
},
['pale_malt'] = {
['name'] = 'pale_malt',
['label'] = "Pale Malt (2-Row)",
['weight'] = 1000,
['type'] = 'item',
['image'] = 'pale_malt.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Classic American 2-row pale malt. The foundation of most beers. Sold by the pound (lb).",
},
['pilsner_malt'] = {
['name'] = 'pilsner_malt',
['label'] = "Pilsner Malt",
['weight'] = 1000,
['type'] = 'item',
['image'] = 'pilsner_malt.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Light German pilsner malt for crisp lagers. Sold by the pound (lb).",
},
['wheat_malt'] = {
['name'] = 'wheat_malt',
['label'] = "Wheat Malt",
['weight'] = 1000,
['type'] = 'item',
['image'] = 'wheat_malt.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Malted wheat for hefeweizens and wheat beers. Sold by the pound (lb).",
},
['munich_malt'] = {
['name'] = 'munich_malt',
['label'] = "Munich Malt",
['weight'] = 1000,
['type'] = 'item',
['image'] = 'munich_malt.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Adds rich, bready, malty flavors. Sold by the pound (lb).",
},
['vienna_malt'] = {
['name'] = 'vienna_malt',
['label'] = "Vienna Malt",
['weight'] = 1000,
['type'] = 'item',
['image'] = 'vienna_malt.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Slightly darker base malt with toasty notes. Sold by the pound (lb).",
},
['maris_otter'] = {
['name'] = 'maris_otter',
['label'] = "Maris Otter",
['weight'] = 1000,
['type'] = 'item',
['image'] = 'maris_otter.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Premium English pale malt with biscuity character. Sold by the pound (lb).",
},
['crystal_malt'] = {
['name'] = 'crystal_malt',
['label'] = "Crystal Malt 60°L",
['weight'] = 500,
['type'] = 'item',
['image'] = 'crystal_malt.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Adds caramel sweetness and body. 60°L refers to 60° Lovibond (color rating), not volume. Sold by the pound (lb).",
},
['chocolate_malt'] = {
['name'] = 'chocolate_malt',
['label'] = "Chocolate Malt",
['weight'] = 500,
['type'] = 'item',
['image'] = 'chocolate_malt.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Dark malt with chocolate and coffee notes. Sold by the pound (lb).",
},
['roasted_barley'] = {
['name'] = 'roasted_barley',
['label'] = "Roasted Barley",
['weight'] = 500,
['type'] = 'item',
['image'] = 'roasted_barley.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Unmalted barley, key for stouts. Sold by the pound (lb).",
},
['black_patent'] = {
['name'] = 'black_patent',
['label'] = "Black Patent Malt",
['weight'] = 500,
['type'] = 'item',
['image'] = 'black_patent.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Intensely roasted for color and bitter notes. Sold by the pound (lb).",
},
['carapils'] = {
['name'] = 'carapils',
['label'] = "Carapils/Dextrine",
['weight'] = 500,
['type'] = 'item',
['image'] = 'carapils.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Improves head retention and body. Sold by the pound (lb).",
},
['honey_malt'] = {
['name'] = 'honey_malt',
['label'] = "Honey Malt",
['weight'] = 500,
['type'] = 'item',
['image'] = 'honey_malt.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Sweet malt with honey-like flavors. Sold by the pound (lb).",
},
['smoked_malt'] = {
['name'] = 'smoked_malt',
['label'] = "Smoked Malt",
['weight'] = 500,
['type'] = 'item',
['image'] = 'smoked_malt.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Beechwood smoked malt for rauchbiers. Sold by the pound (lb).",
},
['oat_malt'] = {
['name'] = 'oat_malt',
['label'] = "Oat Malt",
['weight'] = 500,
['type'] = 'item',
['image'] = 'oat_malt.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Adds silky mouthfeel and body. Sold by the pound (lb).",
},
['rye_malt'] = {
['name'] = 'rye_malt',
['label'] = "Rye Malt",
['weight'] = 500,
['type'] = 'item',
['image'] = 'rye_malt.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Spicy grain character. Sold by the pound (lb).",
},
['acidulated_malt'] = {
['name'] = 'acidulated_malt',
['label'] = "Acidulated Malt",
['weight'] = 500,
['type'] = 'item',
['image'] = 'acidulated_malt.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Lowers mash pH naturally. Sold by the pound (lb).",
},
['cascade_hops'] = {
['name'] = 'cascade_hops',
['label'] = "Cascade Hops",
['weight'] = 100,
['type'] = 'item',
['image'] = 'cascade_hops.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Classic American hop with citrus and floral notes. Sold by the ounce (oz).",
},
['centennial_hops'] = {
['name'] = 'centennial_hops',
['label'] = "Centennial Hops",
['weight'] = 100,
['type'] = 'item',
['image'] = 'centennial_hops.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Balanced citrus and floral hop. Sold by the ounce (oz).",
},
['citra_hops'] = {
['name'] = 'citra_hops',
['label'] = "Citra Hops",
['weight'] = 100,
['type'] = 'item',
['image'] = 'citra_hops.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Intense tropical fruit and citrus. Sold by the ounce (oz).",
},
['mosaic_hops'] = {
['name'] = 'mosaic_hops',
['label'] = "Mosaic Hops",
['weight'] = 100,
['type'] = 'item',
['image'] = 'mosaic_hops.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Complex berry and tropical notes. Sold by the ounce (oz).",
},
['simcoe_hops'] = {
['name'] = 'simcoe_hops',
['label'] = "Simcoe Hops",
['weight'] = 100,
['type'] = 'item',
['image'] = 'simcoe_hops.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Pine, citrus, and earthy character. Sold by the ounce (oz).",
},
['amarillo_hops'] = {
['name'] = 'amarillo_hops',
['label'] = "Amarillo Hops",
['weight'] = 100,
['type'] = 'item',
['image'] = 'amarillo_hops.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Orange and floral aromatics. Sold by the ounce (oz).",
},
['saaz_hops'] = {
['name'] = 'saaz_hops',
['label'] = "Saaz Hops",
['weight'] = 100,
['type'] = 'item',
['image'] = 'saaz_hops.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Noble Czech hop with spicy, herbal notes. Sold by the ounce (oz).",
},
['hallertau_hops'] = {
['name'] = 'hallertau_hops',
['label'] = "Hallertau Hops",
['weight'] = 100,
['type'] = 'item',
['image'] = 'hallertau_hops.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Traditional German noble hop. Sold by the ounce (oz).",
},
['fuggle_hops'] = {
['name'] = 'fuggle_hops',
['label'] = "Fuggle Hops",
['weight'] = 100,
['type'] = 'item',
['image'] = 'fuggle_hops.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "English hop with earthy, woody character. Sold by the ounce (oz).",
},
['ekg_hops'] = {
['name'] = 'ekg_hops',
['label'] = "East Kent Goldings",
['weight'] = 100,
['type'] = 'item',
['image'] = 'ekg_hops.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Classic English aroma hop. Sold by the ounce (oz).",
},
['galaxy_hops'] = {
['name'] = 'galaxy_hops',
['label'] = "Galaxy Hops",
['weight'] = 100,
['type'] = 'item',
['image'] = 'galaxy_hops.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Australian hop with passionfruit notes. Sold by the ounce (oz).",
},
['nelson_hops'] = {
['name'] = 'nelson_hops',
['label'] = "Nelson Sauvin",
['weight'] = 100,
['type'] = 'item',
['image'] = 'nelson_hops.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "New Zealand hop with wine-like qualities. Sold by the ounce (oz).",
},
['us05_yeast'] = {
['name'] = 'us05_yeast',
['label'] = "US-05 Ale Yeast",
['weight'] = 50,
['type'] = 'item',
['image'] = 'us05_yeast.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Clean American ale yeast. Sold by the packet.",
},
['s04_yeast'] = {
['name'] = 's04_yeast',
['label'] = "S-04 English Ale",
['weight'] = 50,
['type'] = 'item',
['image'] = 's04_yeast.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "English ale yeast with fruity esters. Sold by the packet.",
},
['w34_yeast'] = {
['name'] = 'w34_yeast',
['label'] = "W-34/70 Lager",
['weight'] = 50,
['type'] = 'item',
['image'] = 'w34_yeast.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "German lager yeast for clean fermentation. Sold by the packet.",
},
['belgian_yeast'] = {
['name'] = 'belgian_yeast',
['label'] = "Belgian Ale Yeast",
['weight'] = 50,
['type'] = 'item',
['image'] = 'belgian_yeast.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Produces spicy, fruity Belgian character. Sold by the packet.",
},
['hefeweizen_yeast'] = {
['name'] = 'hefeweizen_yeast',
['label'] = "Hefeweizen Yeast",
['weight'] = 50,
['type'] = 'item',
['image'] = 'hefeweizen_yeast.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Creates banana and clove flavors. Sold by the packet.",
},
['saison_yeast'] = {
['name'] = 'saison_yeast',
['label'] = "Saison Yeast",
['weight'] = 50,
['type'] = 'item',
['image'] = 'saison_yeast.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Farmhouse yeast with peppery notes. Sold by the packet.",
},
['brett_yeast'] = {
['name'] = 'brett_yeast',
['label'] = "Brettanomyces",
['weight'] = 50,
['type'] = 'item',
['image'] = 'brett_yeast.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Wild yeast for funky, complex beers. Sold by the packet.",
},
['lactobacillus'] = {
['name'] = 'lactobacillus',
['label'] = "Lactobacillus",
['weight'] = 50,
['type'] = 'item',
['image'] = 'lactobacillus.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Bacteria for sour beer production. Sold by the packet.",
},
['cane_sugar'] = {
['name'] = 'cane_sugar',
['label'] = "Cane Sugar",
['weight'] = 500,
['type'] = 'item',
['image'] = 'cane_sugar.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Increases alcohol without adding body. Sold by the pound (lb).",
},
['honey'] = {
['name'] = 'honey',
['label'] = "Honey",
['weight'] = 500,
['type'] = 'item',
['image'] = 'honey.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Local wildflower honey. Sold by the pound (lb).",
},
['maple_syrup'] = {
['name'] = 'maple_syrup',
['label'] = "Maple Syrup",
['weight'] = 500,
['type'] = 'item',
['image'] = 'maple_syrup.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Grade A maple syrup. Sold by the pound (lb).",
},
['lactose'] = {
['name'] = 'lactose',
['label'] = "Lactose",
['weight'] = 500,
['type'] = 'item',
['image'] = 'lactose.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Unfermentable sugar for sweetness. Sold by the pound (lb).",
},
['coffee_beans'] = {
['name'] = 'coffee_beans',
['label'] = "Coffee Beans",
['weight'] = 250,
['type'] = 'item',
['image'] = 'coffee_beans.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Fresh roasted coffee beans. Sold in 4 ounce packages.",
},
['cocoa_nibs'] = {
['name'] = 'cocoa_nibs',
['label'] = "Cocoa Nibs",
['weight'] = 250,
['type'] = 'item',
['image'] = 'cocoa_nibs.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Raw cacao for chocolate flavor. Sold in 4 ounce packages.",
},
['vanilla_beans'] = {
['name'] = 'vanilla_beans',
['label'] = "Vanilla Beans",
['weight'] = 100,
['type'] = 'item',
['image'] = 'vanilla_beans.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Madagascar vanilla beans. Sold individually (each).",
},
['oak_chips'] = {
['name'] = 'oak_chips',
['label'] = "Oak Chips",
['weight'] = 250,
['type'] = 'item',
['image'] = 'oak_chips.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Medium toast French oak. Sold in 4 ounce packages.",
},
['fruit_puree'] = {
['name'] = 'fruit_puree',
['label'] = "Fruit Puree",
['weight'] = 500,
['type'] = 'item',
['image'] = 'fruit_puree.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Fresh fruit puree for brewing. Sold by the pound (lb).",
},
['pumpkin_spice'] = {
['name'] = 'pumpkin_spice',
['label'] = "Pumpkin Spice",
['weight'] = 100,
['type'] = 'item',
['image'] = 'pumpkin_spice.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Blend of cinnamon, nutmeg, and allspice. Sold by the ounce (oz).",
},
['coriander'] = {
['name'] = 'coriander',
['label'] = "Coriander",
['weight'] = 100,
['type'] = 'item',
['image'] = 'coriander.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Crushed coriander seeds. Sold by the ounce (oz).",
},
['orange_peel'] = {
['name'] = 'orange_peel',
['label'] = "Orange Peel",
['weight'] = 100,
['type'] = 'item',
['image'] = 'orange_peel.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Dried bitter orange peel. Sold by the ounce (oz).",
},
['beer_bottle'] = {
['name'] = 'beer_bottle',
['label'] = "Beer Bottle (12oz)",
['weight'] = 200,
['type'] = 'item',
['image'] = 'beer_bottle.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Empty amber glass bottle. 12 fluid ounces capacity. Sold in cases of 48.",
},
['bottle_cap'] = {
['name'] = 'bottle_cap',
['label'] = "Bottle Cap",
['weight'] = 5,
['type'] = 'item',
['image'] = 'bottle_cap.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Oxygen-absorbing crown cap.",
},
['bottle_cap_package'] = {
['name'] = 'bottle_cap_package',
['label'] = "Bottle Cap Package",
['weight'] = 250,
['type'] = 'item',
['image'] = 'bottle_cap_package.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "A package containing 48 bottle caps. Use to unpack.",
},
['beer_label'] = {
['name'] = 'beer_label',
['label'] = "Beer Label",
['weight'] = 10,
['type'] = 'item',
['image'] = 'beer_label.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Waterproof adhesive label.",
},
['beer_keg'] = {
['name'] = 'beer_keg',
['label'] = "Empty Keg (5gal)",
['weight'] = 5000,
['type'] = 'item',
['image'] = 'beer_keg.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Cornelius-style keg. 5 gallon capacity.",
},
['keg_coupler'] = {
['name'] = 'keg_coupler',
['label'] = "Keg Coupler",
['weight'] = 500,
['type'] = 'item',
['image'] = 'keg_coupler.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Sankey D-style coupler.",
},
['beer_case'] = {
['name'] = 'beer_case',
['label'] = "Beer Case (24-pack)",
['weight'] = 500,
['type'] = 'item',
['image'] = 'beer_case.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Cardboard case for 24 bottles (12oz each).",
},
['pbw_cleaner'] = {
['name'] = 'pbw_cleaner',
['label'] = "PBW Cleaner",
['weight'] = 500,
['type'] = 'item',
['image'] = 'pbw_cleaner.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Powerful brewery wash cleaner. 16 fluid ounces.",
},
['starsan'] = {
['name'] = 'starsan',
['label'] = "Star San Sanitizer",
['weight'] = 500,
['type'] = 'item',
['image'] = 'starsan.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "No-rinse sanitizer for brewing. 16 fluid ounces.",
},
['hydrometer'] = {
['name'] = 'hydrometer',
['label'] = "Hydrometer",
['weight'] = 100,
['type'] = 'item',
['image'] = 'hydrometer.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Measures specific gravity for ABV calculation.",
},
['refractometer'] = {
['name'] = 'refractometer',
['label'] = "Refractometer",
['weight'] = 150,
['type'] = 'item',
['image'] = 'refractometer.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Measures sugar content quickly.",
},
['ph_meter'] = {
['name'] = 'ph_meter',
['label'] = "pH Meter",
['weight'] = 200,
['type'] = 'item',
['image'] = 'ph_meter.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Digital pH meter for water chemistry.",
},
['thermometer'] = {
['name'] = 'thermometer',
['label'] = "Digital Thermometer",
['weight'] = 100,
['type'] = 'item',
['image'] = 'thermometer.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Precise temperature measurement.",
},
['grain_scale'] = {
['name'] = 'grain_scale',
['label'] = "Grain Scale",
['weight'] = 2000,
['type'] = 'item',
['image'] = 'grain_scale.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Digital scale for weighing ingredients.",
},
['recipe_book_basic'] = {
['name'] = 'recipe_book_basic',
['label'] = "Basic Brewing Guide",
['weight'] = 500,
['type'] = 'item',
['image'] = 'recipe_book_basic.png',
['unique'] = false,
['useable'] = true,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Introduction to brewing basics. Right-click to use.",
},
['recipe_book_intermediate'] = {
['name'] = 'recipe_book_intermediate',
['label'] = "Intermediate Recipes",
['weight'] = 500,
['type'] = 'item',
['image'] = 'recipe_book_intermediate.png',
['unique'] = false,
['useable'] = true,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Collection of intermediate beer recipes. Right-click to use.",
},
['recipe_book_advanced'] = {
['name'] = 'recipe_book_advanced',
['label'] = "Advanced Techniques",
['weight'] = 500,
['type'] = 'item',
['image'] = 'recipe_book_advanced.png',
['unique'] = false,
['useable'] = true,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Advanced brewing methods and recipes. Right-click to use.",
},
['recipe_book_master'] = {
['name'] = 'recipe_book_master',
['label'] = "Master Brewer's Tome",
['weight'] = 500,
['type'] = 'item',
['image'] = 'recipe_book_master.png',
['unique'] = false,
['useable'] = true,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Expert-level brewing knowledge. Right-click to use.",
},
['recipe_book_legendary'] = {
['name'] = 'recipe_book_legendary',
['label'] = "Legendary Brews",
['weight'] = 500,
['type'] = 'item',
['image'] = 'recipe_book_legendary.png',
['unique'] = false,
['useable'] = true,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "The rarest and most complex recipes. Right-click to use.",
},
['craft_beer_bottle'] = {
['name'] = 'craft_beer_bottle',
['label'] = "Craft Beer Bottle",
['weight'] = 350,
['type'] = 'item',
['image'] = 'craft_beer_bottle.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "A bottle of craft beer.",
},
['craft_beer_keg'] = {
['name'] = 'craft_beer_keg',
['label'] = "Craft Beer Keg",
['weight'] = 20000,
['type'] = 'item',
['image'] = 'craft_beer_keg.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "A 5-gallon keg of craft beer.",
},
['craft_beer_case'] = {
['name'] = 'craft_beer_case',
['label'] = "Craft Beer Case",
['weight'] = 9000,
['type'] = 'item',
['image'] = 'craft_beer_case.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "A case of 24 craft beers.",
},
['wort_sample'] = {
['name'] = 'wort_sample',
['label'] = "Wort Sample",
['weight'] = 100,
['type'] = 'item',
['image'] = 'wort_sample.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Sample of unfermented wort.",
},
['beer_sample'] = {
['name'] = 'beer_sample',
['label'] = "Beer Sample",
['weight'] = 100,
['type'] = 'item',
['image'] = 'beer_sample.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Sample of beer for quality testing.",
},
['milled_grain'] = {
['name'] = 'milled_grain',
['label'] = "Milled Grain",
['weight'] = 1000,
['type'] = 'item',
['image'] = 'milled_grain.png',
['unique'] = false,
['useable'] = false,
['shouldClose'] = true,
['combinable'] = nil,
['description'] = "Crushed grain ready for mashing.",
},**
}
Note: Recipe books in qb_items.lua may not include ox-style use functions. If you use ox_inventory for books, prefer merging ox_items.lua recipe book entries (with use) into ox_inventory instead.
D) ESX — ox_inventory
- Set
Config.Framework = 'esx'inbs_brewery/shared/config.lua. - Merge
bs_brewery/items/esx_items.lua(orox_items.lua— same ox table shape) intoox_inventory/data/items.luausing the same merge method as section A. - Restart
ox_inventory, thenbs_brewery.
Config.Currency = 'cash' maps to the ESX money account in the server bridge; 'bank' maps to bank.
-- ==========================================
-- BASE MALTS / GRAINS (sold by the pound)
-- ==========================================
['pale_malt'] = {
label = 'Pale Malt (2-Row)',
weight = 1000,
stack = true,
close = true,
description = 'Classic American 2-row pale malt. The foundation of most beers. Sold by the pound (lb).',
},
['pilsner_malt'] = {
label = 'Pilsner Malt',
weight = 1000,
stack = true,
close = true,
description = 'Light German pilsner malt for crisp lagers. Sold by the pound (lb).',
},
['wheat_malt'] = {
label = 'Wheat Malt',
weight = 1000,
stack = true,
close = true,
description = 'Malted wheat for hefeweizens and wheat beers. Sold by the pound (lb).',
},
['munich_malt'] = {
label = 'Munich Malt',
weight = 1000,
stack = true,
close = true,
description = 'Adds rich, bready, malty flavors. Sold by the pound (lb).',
},
['vienna_malt'] = {
label = 'Vienna Malt',
weight = 1000,
stack = true,
close = true,
description = 'Slightly darker base malt with toasty notes. Sold by the pound (lb).',
},
['maris_otter'] = {
label = 'Maris Otter',
weight = 1000,
stack = true,
close = true,
description = 'Premium English pale malt with biscuity character. Sold by the pound (lb).',
},
-- ==========================================
-- SPECIALTY GRAINS (sold by the pound)
-- ==========================================
['crystal_malt'] = {
label = 'Crystal Malt 60°L',
weight = 500,
stack = true,
close = true,
description = 'Adds caramel sweetness and body. 60°L refers to 60° Lovibond (color rating), not volume. Sold by the pound (lb).',
},
['chocolate_malt'] = {
label = 'Chocolate Malt',
weight = 500,
stack = true,
close = true,
description = 'Dark malt with chocolate and coffee notes. Sold by the pound (lb).',
},
['roasted_barley'] = {
label = 'Roasted Barley',
weight = 500,
stack = true,
close = true,
description = 'Unmalted barley, key for stouts. Sold by the pound (lb).',
},
['black_patent'] = {
label = 'Black Patent Malt',
weight = 500,
stack = true,
close = true,
description = 'Intensely roasted for color and bitter notes. Sold by the pound (lb).',
},
['carapils'] = {
label = 'Carapils/Dextrine',
weight = 500,
stack = true,
close = true,
description = 'Improves head retention and body. Sold by the pound (lb).',
},
['honey_malt'] = {
label = 'Honey Malt',
weight = 500,
stack = true,
close = true,
description = 'Sweet malt with honey-like flavors. Sold by the pound (lb).',
},
['smoked_malt'] = {
label = 'Smoked Malt',
weight = 500,
stack = true,
close = true,
description = 'Beechwood smoked malt for rauchbiers. Sold by the pound (lb).',
},
['oat_malt'] = {
label = 'Oat Malt',
weight = 500,
stack = true,
close = true,
description = 'Adds silky mouthfeel and body. Sold by the pound (lb).',
},
['rye_malt'] = {
label = 'Rye Malt',
weight = 500,
stack = true,
close = true,
description = 'Spicy grain character. Sold by the pound (lb).',
},
['acidulated_malt'] = {
label = 'Acidulated Malt',
weight = 500,
stack = true,
close = true,
description = 'Lowers mash pH naturally. Sold by the pound (lb).',
},
-- ==========================================
-- HOPS (sold by the ounce)
-- ==========================================
['cascade_hops'] = {
label = 'Cascade Hops',
weight = 100,
stack = true,
close = true,
description = 'Classic American hop with citrus and floral notes. Sold by the ounce (oz).',
},
['centennial_hops'] = {
label = 'Centennial Hops',
weight = 100,
stack = true,
close = true,
description = 'Balanced citrus and floral hop. Sold by the ounce (oz).',
},
['citra_hops'] = {
label = 'Citra Hops',
weight = 100,
stack = true,
close = true,
description = 'Intense tropical fruit and citrus. Sold by the ounce (oz).',
},
['mosaic_hops'] = {
label = 'Mosaic Hops',
weight = 100,
stack = true,
close = true,
description = 'Complex berry and tropical notes. Sold by the ounce (oz).',
},
['simcoe_hops'] = {
label = 'Simcoe Hops',
weight = 100,
stack = true,
close = true,
description = 'Pine, citrus, and earthy character. Sold by the ounce (oz).',
},
['amarillo_hops'] = {
label = 'Amarillo Hops',
weight = 100,
stack = true,
close = true,
description = 'Orange and floral aromatics. Sold by the ounce (oz).',
},
['saaz_hops'] = {
label = 'Saaz Hops',
weight = 100,
stack = true,
close = true,
description = 'Noble Czech hop with spicy, herbal notes. Sold by the ounce (oz).',
},
['hallertau_hops'] = {
label = 'Hallertau Hops',
weight = 100,
stack = true,
close = true,
description = 'Traditional German noble hop. Sold by the ounce (oz).',
},
['fuggle_hops'] = {
label = 'Fuggle Hops',
weight = 100,
stack = true,
close = true,
description = 'English hop with earthy, woody character. Sold by the ounce (oz).',
},
['ekg_hops'] = {
label = 'East Kent Goldings',
weight = 100,
stack = true,
close = true,
description = 'Classic English aroma hop. Sold by the ounce (oz).',
},
['galaxy_hops'] = {
label = 'Galaxy Hops',
weight = 100,
stack = true,
close = true,
description = 'Australian hop with passionfruit notes. Sold by the ounce (oz).',
},
['nelson_hops'] = {
label = 'Nelson Sauvin',
weight = 100,
stack = true,
close = true,
description = 'New Zealand hop with wine-like qualities. Sold by the ounce (oz).',
},
-- ==========================================
-- YEAST (sold by the packet)
-- ==========================================
['us05_yeast'] = {
label = 'US-05 Ale Yeast',
weight = 50,
stack = true,
close = true,
description = 'Clean American ale yeast. Sold by the packet.',
},
['s04_yeast'] = {
label = 'S-04 English Ale',
weight = 50,
stack = true,
close = true,
description = 'English ale yeast with fruity esters. Sold by the packet.',
},
['w34_yeast'] = {
label = 'W-34/70 Lager',
weight = 50,
stack = true,
close = true,
description = 'German lager yeast for clean fermentation. Sold by the packet.',
},
['belgian_yeast'] = {
label = 'Belgian Ale Yeast',
weight = 50,
stack = true,
close = true,
description = 'Produces spicy, fruity Belgian character. Sold by the packet.',
},
['hefeweizen_yeast'] = {
label = 'Hefeweizen Yeast',
weight = 50,
stack = true,
close = true,
description = 'Creates banana and clove flavors. Sold by the packet.',
},
['saison_yeast'] = {
label = 'Saison Yeast',
weight = 50,
stack = true,
close = true,
description = 'Farmhouse yeast with peppery notes. Sold by the packet.',
},
['brett_yeast'] = {
label = 'Brettanomyces',
weight = 50,
stack = true,
close = true,
description = 'Wild yeast for funky, complex beers. Sold by the packet.',
},
['lactobacillus'] = {
label = 'Lactobacillus',
weight = 50,
stack = true,
close = true,
description = 'Bacteria for sour beer production. Sold by the packet.',
},
-- ==========================================
-- ADJUNCTS & FLAVORS (units vary)
-- ==========================================
['cane_sugar'] = {
label = 'Cane Sugar',
weight = 500,
stack = true,
close = true,
description = 'Increases alcohol without adding body. Sold by the pound (lb).',
},
['honey'] = {
label = 'Honey',
weight = 500,
stack = true,
close = true,
description = 'Local wildflower honey. Sold by the pound (lb).',
},
['maple_syrup'] = {
label = 'Maple Syrup',
weight = 500,
stack = true,
close = true,
description = 'Grade A maple syrup. Sold by the pound (lb).',
},
['lactose'] = {
label = 'Lactose',
weight = 500,
stack = true,
close = true,
description = 'Unfermentable sugar for sweetness. Sold by the pound (lb).',
},
['coffee_beans'] = {
label = 'Coffee Beans',
weight = 250,
stack = true,
close = true,
description = 'Fresh roasted coffee beans. Sold in 4 ounce packages.',
},
['cocoa_nibs'] = {
label = 'Cocoa Nibs',
weight = 250,
stack = true,
close = true,
description = 'Raw cacao for chocolate flavor. Sold in 4 ounce packages.',
},
['vanilla_beans'] = {
label = 'Vanilla Beans',
weight = 100,
stack = true,
close = true,
description = 'Madagascar vanilla beans. Sold individually (each).',
},
['oak_chips'] = {
label = 'Oak Chips',
weight = 250,
stack = true,
close = true,
description = 'Medium toast French oak. Sold in 4 ounce packages.',
},
['fruit_puree'] = {
label = 'Fruit Puree',
weight = 500,
stack = true,
close = true,
description = 'Fresh fruit puree for brewing. Sold by the pound (lb).',
},
['pumpkin_spice'] = {
label = 'Pumpkin Spice',
weight = 100,
stack = true,
close = true,
description = 'Blend of cinnamon, nutmeg, and allspice. Sold by the ounce (oz).',
},
['coriander'] = {
label = 'Coriander',
weight = 100,
stack = true,
close = true,
description = 'Crushed coriander seeds. Sold by the ounce (oz).',
},
['orange_peel'] = {
label = 'Orange Peel',
weight = 100,
stack = true,
close = true,
description = 'Dried bitter orange peel. Sold by the ounce (oz).',
},
-- ==========================================
-- PACKAGING SUPPLIES
-- ==========================================
['beer_bottle'] = {
label = 'Beer Bottle (12oz)',
weight = 200,
stack = true,
close = true,
description = 'Empty amber glass bottle. 12 fluid ounces capacity. Sold in cases of 48.',
},
['bottle_cap'] = {
label = 'Bottle Cap',
weight = 5,
stack = true,
close = true,
description = 'Oxygen-absorbing crown cap.',
},
['bottle_cap_package'] = {
label = 'Bottle Cap Package',
weight = 250,
stack = true,
close = true,
description = 'A package containing 48 bottle caps. Use to unpack.',
},
['beer_label'] = {
label = 'Beer Label',
weight = 10,
stack = true,
close = true,
description = 'Waterproof adhesive label.',
},
['beer_keg'] = {
label = 'Empty Keg (5gal)',
weight = 5000,
stack = true,
close = true,
description = 'Cornelius-style keg. 5 gallon capacity.',
},
['keg_coupler'] = {
label = 'Keg Coupler',
weight = 500,
stack = true,
close = true,
description = 'Sankey D-style coupler.',
},
['beer_case'] = {
label = 'Beer Case (24-pack)',
weight = 500,
stack = true,
close = true,
description = 'Cardboard case for 24 bottles (12oz each).',
},
-- ==========================================
-- CLEANING & CHEMICALS
-- ==========================================
['pbw_cleaner'] = {
label = 'PBW Cleaner',
weight = 500,
stack = true,
close = true,
description = 'Powerful brewery wash cleaner. 16 fluid ounces.',
},
['starsan'] = {
label = 'Star San Sanitizer',
weight = 500,
stack = true,
close = true,
description = 'No-rinse sanitizer for brewing. 16 fluid ounces.',
},
-- ==========================================
-- EQUIPMENT & TOOLS
-- ==========================================
['hydrometer'] = {
label = 'Hydrometer',
weight = 100,
stack = false,
close = true,
description = 'Measures specific gravity for ABV calculation.',
},
['refractometer'] = {
label = 'Refractometer',
weight = 150,
stack = false,
close = true,
description = 'Measures sugar content quickly.',
},
['ph_meter'] = {
label = 'pH Meter',
weight = 200,
stack = false,
close = true,
description = 'Digital pH meter for water chemistry.',
},
['thermometer'] = {
label = 'Digital Thermometer',
weight = 100,
stack = false,
close = true,
description = 'Precise temperature measurement.',
},
['grain_scale'] = {
label = 'Grain Scale',
weight = 2000,
stack = false,
close = true,
description = 'Digital scale for weighing ingredients.',
},
-- ==========================================
-- RECIPE BOOKS (require `use` for bs_brewery UI)
-- ==========================================
['recipe_book_basic'] = {
label = 'Basic Brewing Guide',
weight = 500,
stack = false,
close = true,
description = 'Introduction to brewing basics. Right-click to use.',
use = function(event, item, inventory, slot, data)
TriggerServerEvent('bs_brewery:server:useRecipeBook', item.name)
end,
},
['recipe_book_intermediate'] = {
label = 'Intermediate Recipes',
weight = 500,
stack = false,
close = true,
description = 'Collection of intermediate beer recipes. Right-click to use.',
use = function(event, item, inventory, slot, data)
TriggerServerEvent('bs_brewery:server:useRecipeBook', item.name)
end,
},
['recipe_book_advanced'] = {
label = 'Advanced Techniques',
weight = 500,
stack = false,
close = true,
description = 'Advanced brewing methods and recipes. Right-click to use.',
use = function(event, item, inventory, slot, data)
TriggerServerEvent('bs_brewery:server:useRecipeBook', item.name)
end,
},
['recipe_book_master'] = {
label = "Master Brewer's Tome",
weight = 500,
stack = false,
close = true,
description = 'Expert-level brewing knowledge. Right-click to use.',
use = function(event, item, inventory, slot, data)
TriggerServerEvent('bs_brewery:server:useRecipeBook', item.name)
end,
},
['recipe_book_legendary'] = {
label = 'Legendary Brews',
weight = 500,
stack = false,
close = true,
description = 'The rarest and most complex recipes. Right-click to use.',
use = function(event, item, inventory, slot, data)
TriggerServerEvent('bs_brewery:server:useRecipeBook', item.name)
end,
},
-- ==========================================
-- FINISHED PRODUCTS (Generic, metadata determines type)
-- ==========================================
['craft_beer_bottle'] = {
label = 'Craft Beer Bottle',
weight = 350,
stack = true,
close = false,
description = 'A bottle of craft beer.',
consume = 1,
},
['craft_beer_keg'] = {
label = 'Craft Beer Keg',
weight = 20000,
stack = false,
close = true,
description = 'A 5-gallon keg of craft beer.',
},
['craft_beer_case'] = {
label = 'Craft Beer Case',
weight = 9000,
stack = false,
close = true,
description = 'A case of 24 craft beers.',
},
-- ==========================================
-- INTERMEDIATE BREWING ITEMS
-- ==========================================
['wort_sample'] = {
label = 'Wort Sample',
weight = 100,
stack = true,
close = true,
description = 'Sample of unfermented wort.',
},
['beer_sample'] = {
label = 'Beer Sample',
weight = 100,
stack = true,
close = true,
description = 'Sample of beer for quality testing.',
},
['milled_grain'] = {
label = 'Milled Grain',
weight = 1000,
stack = true,
close = true,
description = 'Crushed grain ready for mashing.',
},
5) server.cfg load order
Start dependencies before bs_brewery. Example:
ensure oxmysql
ensure ox_lib
ensure ox_inventory
ensure ox_target
# Framework (pick one ecosystem)
ensure qbx_core
# OR: ensure qb-core
# OR: ensure es_extended
# MLO (example — use your map resource name)
ensure dolo_beer_factory
ensure bs_brewery
Adjust names to match your actual resource folder names.
6) Verify
- Join the server, go to the brewery MLO.
- Open brewery storage / shop — if items are missing, ox_inventory will error or refuse; fix merges.
- Use a recipe book from inventory — the UI should open; if not, confirm
use→bs_brewery:server:useRecipeBookon those items in ox_inventory. - Start a short mash/boil test to confirm callbacks and DB tables respond.
7) Troubleshooting
| Symptom | Things to check |
|---|---|
| Shop / stash “cannot open” | Item names in ox_inventory/data/items.lua missing or typo’d vs shared/config.lua |
| Recipe book does nothing | use missing on book items in ox_inventory; event must be bs_brewery:server:useRecipeBook |
| Wrong framework errors | Config.Framework matches your core; core starts before bs_brewery |
| No images | Add client.image with nui://bs_brewery/items/<name>.png, or match your inventory’s image convention |
| DB errors | Re-run sql/install.sql; confirm oxmysql points at that DB |