Cultivos documentation
A complete crop system. Admins create zones and crop types in game from a tablet. Players plant, water and take care of their plants, harvest by quality, process the harvest and sell it on a market whose prices move. Illegal crops alert the police, who can burn them in raids.
- Version 3.0.2
- Requirements: FXServer build 35245+, OneSync (the manifest declares
/onesync),ox_libandoxmysql. - Frameworks: QBCore · Qbox Legacy · standalone ·
'custom'(see Integrations / Custom) - Languages: es · en
- No lock-in: rolo_notify and every other ROLO SCRIPT resource are optional. Without rolo_notify the script uses ox_lib, your framework's notifications or the base game.
- No tickets needed: everything you may want to adapt is in open files (see Escrow: what is open).
What's new in 3.0.2: a plant's progress is retried when a save fails instead of being lost; money functions reject invalid amounts (NaN, infinity, <= 0); Qbox usable items work (CreateUseableItem); item counts are validated and a full ox_inventory counts as "cannot carry"; a picture for each of the 16 crop items (items/images/); Config.Target = 'custom'; 'custom' framework (money, permissions, usable items) and police alerts from the open bridge files; clearer docs for owner alerts and police alert systems.
Features
Growing
- Zones and crop types from a tablet (
/cultivotablet). You can create them, edit them, move a zone to your position, and delete them.- Zone options: max plants, restricted to certain jobs, greenhouse, map blip.
- Growth stages: sprout → medium → ready, using 3 models, or one model that rises out of the ground.
- Water: it decays smoothly, and rain refills outdoor plants (works with any weather script). A plant left dry too long dies.
- Quality 0–100%: it drops when the plant lacks water, has pests or rots, meaning it was left ready without being harvested. Quality sets the yield and is written into the harvested item's metadata.
- Pests: they appear at random and are removed with the pesticide item.
- Fertilizers: several types (faster growth, bigger yield). Press K to cycle which one you'll use on the next plant.
- Watering can with charges: refill it standing in water (river, lake, sea, pool).
- Greenhouses: no rain, slower drying, fewer pests.
- Seeds back: a % chance to get seeds when harvesting.
- Free planting (optional): use a seed on real soil (grass, dirt, sand), with a limit per player.
Economy
- Processing tables: turn the harvest into products (dry and bag, pack into boxes...). Recipes are configurable, and the quality carries over.
- NPC buyers with a dynamic market: every sale lowers the price, which recovers over time. Quality affects the price.
Police
- Illegal crops: a % chance of a police alert when planting, harvesting or selling.
- Supported dispatch scripts: origen_police, ps-dispatch, cd_dispatch, qs-dispatch, core_dispatch and rcore_dispatch.
- Without any of them, the police on duty get a notification and a blip.
- Raids: the police burn illegal plants (animation and fire). The owner is warned.
Tablet
- "My crops" (
/cultivos): each plant's status, time left, quality and GPS. - Owner alerts (notifications while the owner is in the city, once per problem): ready to harvest, needs water (below 25 % by default), pests, rotting, dead (dry or rotten) and burned by the police. Ready / water / pests / dead can be turned off in
Config.OwnerAlerts. - Statistics: top growers, harvests per crop, and actions (sown, harvested, sold, destroyed, burned).
- Market: live buyer prices.
Integration
- Notifications, "[E]" texts and progress bars through rolo_notify when it runs (optional), or ox_lib / qb-core / okok / your own (
Config.Notify,Config.TextUI,Config.Progress). - ox_target / qb-target / your own on the buyers and processing tables, with the E key as a fallback (
Config.Target). - Inventories: ox_inventory, origen_inventory, qs-inventory, codem-inventory, core_inventory, qb-inventory (and ps / lj / tgiann through QBCore), ESX.
- Discord logs per category: plants, harvest, police, market, admin.
- The database is created and upgraded automatically, including the v2 tables. 4 example crops are created on the first start.
Installation
Put
rolo_cultivosin your resources folder.Make sure
ox_libandoxmysqlstart before it.Add
ensure rolo_cultivosto yourserver.cfg.Items: add the example items from
items/to your inventory.ox_origen_items.luafor ox_inventory / origen_inventory (seeds and the watering can use the client exportsrolo_cultivos.useSeedandrolo_cultivos.useCan);qb_items.luafor qb-core / Qbox / qs-inventory (registered as usable by the script);
Skip any you already have (for example
water_bottle).- Item images:
items/images/has a PNG for every crop item (512×512, transparent): the weed seeds and the fertilizer, the seeds, harvests and boxes of corn, pumpkin and cabbage, the raw and bagged weed, the premium fertilizer, the pesticide and the watering can. Copy them to your inventory's image folder (ox_inventory/web/images,origen_inventory/ui/images,qb-inventory/html/images...). If your inventory already has an image forweed_seedorfertilizer, keep yours.
Give admins access, either with an ace or with one of
Config.AdminGroups:add_ace group.admin rolo_cultivos.admin allowIn game, open
/cultivotablet→ Zones. Stand in the field and create the zone at your position.Move the buyers and processing tables in
config.lua(Config.Buyers,Config.Processing) to wherever you want them on your map.
Configuration
Everything is in config.lua.
| Option | What it does |
|---|---|
Config.Locale |
'es' / 'en' |
Config.Framework / Config.Inventory |
'auto' detects them; 'custom' = your own (bridge/ / compat/, see Integrations / Custom) |
Config.Notify / TextUI / Progress / Target |
UI systems ('auto' = rolo_notify when running; also 'rolo_notify', 'ox_lib', 'qbcore', 'esx', 'okok' for Notify, 'kit' for TextUI; 'custom' in bridge/client.lua) |
Config.PoliceJobs |
jobs that burn plants and receive the alerts |
Config.Raid |
fireFx (asset, name, scale): the fire effect on a plant the police burn |
Config.Dispatch |
police system ('auto' = origen_police first, 'custom' in bridge/server.lua) and alert chances |
Config.Quality / Death / Rot / Pests |
how plants lose quality or die |
Config.Fertilizers |
fertilizer types (useCrop = values of each crop type) |
Config.WateringCan |
item and charges |
Config.FreePlanting |
planting outside zones, limit per player, soil materials |
Config.Processing |
tables, props and recipes |
Config.Buyers / Config.Market |
buyers, base prices and how the market moves |
Config.OwnerAlerts |
which alerts the owner gets |
Config.ExampleCrops |
crops created on the first start |
config_server.lua |
Discord webhooks per category (server only) |
Integrations / Custom
Everything you may want to adapt is in open files (config.lua, locales/, bridge/, compat/, items/): you never need the escrowed code.
Item exports (ox_inventory / origen_inventory, client side, in the item definition): client = { export = 'rolo_cultivos.useSeed' } on every seed item (used for free planting) and client = { export = 'rolo_cultivos.useCan' } on the watering can. Other inventories use the framework's usable item, which the script registers (Bridge.RegisterUsableItem). If you rename a seed or the can in config.lua, rename it in your item definition too.
Events: the script has no public server events or exports of its own; the client events rolo_cultivos:client:useSeed and rolo_cultivos:client:useCan are what the usable items trigger, and you can fire them from your own item code:
TriggerClientEvent('rolo_cultivos:client:useSeed', source, 'weed_seed') -- plant that seed (free planting must be on)
TriggerClientEvent('rolo_cultivos:client:useCan', source) -- refill the watering can (in water)
Where to plug in your own system ('custom')
| System | config.lua |
Open file and function |
|---|---|---|
| Framework: character, online lookup, money, admin check, usable items | Config.Framework = 'custom' |
bridge/server.lua: Bridge.GetChar(src) (return { id, name, job, grade, onDuty }), Bridge.SourceOf(charId), Bridge.GetMoney / AddMoney / RemoveMoney(src, account, amount), Bridge.IsAdmin(src), Bridge.RegisterUsableItem(item, cb). Fill CustomOnCharLoaded (call cb(src) from your framework's loaded event). Client, bridge/client.lua: Bridge.PlayerInfo() (return { name, citizenid, job }), CustomOnLoaded / CustomOnUnloaded (call cb() from your events) |
| Inventory (items, metadata, carry check) | Config.Inventory = 'custom' |
Compat.CustomInventory (count, add, remove, canCarry) in compat/server.lua; item metadata (quality) in Bridge.SetItemMetadata of bridge/server.lua |
| Police alerts | Config.Dispatch.system = 'custom' |
Bridge.PoliceAlert(src, { coords, title, message }) in bridge/server.lua; dispatch scripts that need the client use the rolo_cultivos:client:dispatch handler in bridge/client.lua |
| Notifications, "[E]" texts, progress bars | Config.Notify / TextUI / Progress = 'custom' |
Bridge.Notify, Bridge.ShowText / Bridge.HideText and Bridge.Progress in bridge/client.lua |
| Target (buyers, processing tables) | Config.Target = 'custom' |
Bridge.AddEntityTarget(entity, name, label, icon, onSelect) in bridge/client.lua (return true when your target took it) |
| Discord logs | config_server.lua |
Bridge.Log(category, title, description, fields) in bridge/server.lua |
| Crops, fertilizers, recipes, buyers, prices, alerts, texts | config.lua (Config.Fertilizers, Processing, Buyers, Market, OwnerAlerts, PoliceJobs...), locales/*.lua |
Examples:
-- bridge/server.lua (Config.Framework = 'custom')
function Bridge.AddMoney(src, account, amount, reason) return MyFramework.AddMoney(src, account, amount) == true end
-- bridge/server.lua (Config.Dispatch.system = 'custom')
function Bridge.PoliceAlert(src, data)
exports['my_dispatch']:Send({ coords = data.coords, title = data.title, message = data.message })
end
-- bridge/client.lua (Config.Target = 'custom')
function Bridge.AddEntityTarget(entity, name, label, icon, onSelect)
exports['my_target']:AddEntity(entity, { label = label, onSelect = function() onSelect(entity) end })
return true
end
Anything you leave empty is skipped and the script keeps working without that part.
Escrow: what is open
These files stay open (editable) when the resource is escrowed, exactly as escrow_ignore in fxmanifest.lua says:
config.luaandconfig_server.lua(Discord webhooks, server only);locales/*.lua: every text;bridge/*.lua:bridge/client.lua(notify / text / progress systems, target, character) andbridge/server.lua(framework, money, usable items, item metadata, police dispatch, logs). Each has'custom'branches;compat/*.lua: inventories (and vehicle keys / fuel helpers shared by every ROLO SCRIPT resource);items/*: item definitions for every inventory and the 16 item images.
The rest of the Lua code (client/, server/, shared/) is encrypted. Everything a buyer may need to adapt has a 'custom' hook in the open files above.
Controls
| Key | Action |
|---|---|
| E | Plant (inside a zone) · water · treat pests · harvest · remove a dead plant |
| G | Destroy your own plant · burn an illegal plant (police) |
| K | Change the fertilizer for the next plant (rebindable in Settings → Key Bindings → FiveM) |
Tablet look (Config.TabletCase)
The tablet comes in a rugged case: rubber bumpers in the job's colour, a riveted nameplate on the top, screws, side buttons, status LEDs and the ROLO SCRIPT logo on the bottom bezel (the only logo), and the job's emblem (icon in the case colour + name) on the top-left of the screen. Change the colour, the nameplate text, its icon and the wear ('grease' stains, 'dust'), or use style = 'classic' for the thin frame. How it opens (Config.TabletView): 'hands' = the character takes a real tablet out (everyone sees it), the camera goes first person and the screen rises from below over it, with the game still visible around; closing puts it away and gives the camera back. 'screen' = only the screen.
Upgrading from v2
v3 migrates the old tables automatically, adding the new columns and the log table. Your zones, crop types and plants are kept. Old fertilized plants use the first fertilizer in Config.Fertilizers.
© ROLO SCRIPT
Secrets: config_server.lua
Discord webhooks and API keys go in config_server.lua, not in config.lua. config.lua is sent to every player's game (FiveM shares it), so anything in it can be read by a cheater; config_server.lua is loaded only by the server. Paste your webhooks there and leave config.lua without secrets.
Compatibility
The shared compatibility core (compat/server.lua + compat/client.lua, open files) detects your systems on start and prints them in the server console, e.g. compat: framework qbcore · inventory ox_inventory · garages qb-garages · society qb-banking.
- Frameworks: QBCore, Qbox, ESX Legacy, standalone,
'custom'. - Inventories: ox_inventory, origen_inventory, qs-inventory, codem-inventory, core_inventory, qb-inventory, ps-inventory / lj-inventory / tgiann-inventory (through the QBCore player functions).
Config.Inventory = 'custom'+Compat.CustomInventory. Item counts are validated and a full ox_inventory counts as "cannot carry". - Police dispatch: origen_police, ps-dispatch, cd_dispatch, qs-dispatch, core_dispatch, rcore_dispatch,
'jobs'(notification + blip to police on duty),'custom','none'. - Target: ox_target, qb-target,
'key'(E),'custom'. - Optional ROLO SCRIPT resources (rolo_notify): used when they run, never required.
- Errors are printed in the console with the system's name, never silent.
- Names and columns follow each script's public documentation. Test once after installing with your own setup.
Write to us in the Discord support channel with the script, your framework and the console error.
