FiveM farming and crops script

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_lib and oxmysql.
  • 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

  1. Put rolo_cultivos in your resources folder.

  2. Make sure ox_lib and oxmysql start before it.

  3. Add ensure rolo_cultivos to your server.cfg.

  4. Items: add the example items from items/ to your inventory.

    • ox_origen_items.lua for ox_inventory / origen_inventory (seeds and the watering can use the client exports rolo_cultivos.useSeed and rolo_cultivos.useCan);
    • qb_items.lua for 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 for weed_seed or fertilizer, keep yours.
  5. Give admins access, either with an ace or with one of Config.AdminGroups:

    add_ace group.admin rolo_cultivos.admin allow
    
  6. In game, open /cultivotablet → Zones. Stand in the field and create the zone at your position.

  7. 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.lua and config_server.lua (Discord webhooks, server only);
  • locales/*.lua: every text;
  • bridge/*.lua: bridge/client.lua (notify / text / progress systems, target, character) and bridge/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.
Stuck?

Write to us in the Discord support channel with the script, your framework and the console error.