Overview and installation
What DashKart does, requirements, installation, commands and troubleshooting.
Quick-commerce (“10-minute grocery delivery”) job and business system for FiveM roleplay servers.
NPC customers order groceries from dark stores across Los Santos and Blaine County. Riders clock in, pick the items off the shelves, ride the order out on a rental scooter and hand it to a customer waiting at the door, racing a 10-minute promise. Players can buy the stores, set prices and payroll, hire riders and restock from a wholesale warehouse. Everything runs from an in-game tablet available in English, Hindi and Telugu.
Features
NPC order engine
- Demand follows the in-game clock: breakfast, lunch, evening and late-night peaks, scaled by how many riders are on duty at each store.
- Realistic baskets from weighted templates (breakfast, chai time, movie night, late-night noodles, monthly staples…), boosted at the right hours and filtered by the store’s real stock.
- 72 delivery doors (houses, apartments, offices) across the city and Blaine County, checked in game. Add your own doors in game with
/dk_dropadd(setup mode). - Customer peds wait at the door and only spawn when the rider is close; they are removed after the handover.
- Variety events revealed on arrival: big tip, nobody answers (wait, then call the customer), wrong gate, rude customer, bulk order (needs the van).
- Idle protection: riders waiting with an empty board get an order within seconds (configurable).
Rider job
- Clock in at the store counter, automatic uniform per gender (with hooks for illenium-appearance / EUP), outfit restored on clock-out.
- Rental scooter or van with a deposit, keys and fuel through your own scripts, damage deducted from the refund, penalties for abandoning it.
- Deliveries must be made on the DashKart rental (configurable).
- Shelf picking: a marker on every shelf that holds the order’s items, a grab-and-bag animation and a DashKart grocery bag in hand. Stores without a shelf layout use a single packing point.
- The packed order goes into the delivery bag on the scooter (or the back of the van) with the target, and comes out again at the customer’s door. Riding off with it in hand costs a star (configurable).
- Big orders on the van are packed into several bags (by basket weight). They wait on the store counter, the rider carries two per trip to the van, where they stay visible in the cargo area, and hands them to the customer trip by trip; the delivery target grows a minute per extra bag.
- Server-calculated rating (time vs. target, vehicle damage, events), streaks, on-time %, earnings history.
Stores, ownership and economy
- Stores are defined only by coordinates, so they work with vanilla shops or any MLO.
- Real stock: reserved when an order is created, consumed when it is packed. Out-of-stock items never appear in orders.
- Customers pay the basket plus a delivery fee into the store. The store pays the rider its payroll % and keeps the margin, so money is tied to goods that must be restocked.
- Players buy stores, set prices within limits, set payroll, hire and fire riders (staff get first pick on new orders, optional staff-only mode), deposit and withdraw, and sell the store back.
- Wholesale warehouse: restock by paid delivery (arrives later, survives restarts) or by driving the van yourself (no fee, timed). City-owned stores restock themselves.
Tablet app (React, bundled, no external requests)
- Rider app: shift overview, order slips, active order with the 10-minute dial, live map, shelf checklist, call customer, earnings.
- My store app for owners: overview with a revenue chart, live orders, stock and prices, restock, staff and payroll, ledger. Usable remotely with the tablet item (configurable); money moves only at the counter by default.
- Admin app: economy and daily NPC budget, stores (assign/remove owner, balance correction, prices, stock), live orders (force-cancel, compensate the rider), rider leaderboard, logs with search.
- Night and day themes, order sound, English / Hindi / Telugu with a font that renders all three natively.
Logging and anti-exploit
- Discord webhooks per channel (orders, payouts, stores, admin, exploits, daily economy summary), batched and rate-limit aware, with a test button in the admin panel.
- Server-authoritative design: the client only sends intents. Prices, amounts, distances and timers are computed on the server.
- Every network event and tablet call is rate-limited and type-checked. Violations are logged and can kick.
- AFK detection, minimum delivery distance, route-time validation (teleport / speed check), cooldown after suspicious deliveries, hourly earning caps, diminishing returns on long shifts, optional server-wide daily NPC budget.
Requirements
| Item | Details |
|---|---|
| FiveM server | artifact 7290 or newer, OneSync enabled |
| Dependencies | ox_lib, oxmysql |
| Database | MySQL 8 or MariaDB 10.x |
| Framework | QBox (qbx_core), QBCore (qb-core), ESX Legacy (es_extended), or any other through the custom template |
Supported integrations (auto-detected)
| Category | Supported resources (detection order) | Fallback when none is running |
|---|---|---|
| Framework | qbx_core, qb-core, es_extended | custom template |
| Inventory | ox_inventory, qs-inventory, codem-inventory, core_inventory, qb-inventory | framework built-in inventory |
| Target | ox_target, qb-target | ox_lib TextUI + E |
| Vehicle keys | qbx_vehiclekeys, qb-vehiclekeys, wasabi_carlock, MrNewbVehicleKeys | none (rental is left unlocked) |
| Fuel | ox_fuel, LegacyFuel, cdn-fuel, ps-fuel | GTA native fuel level |
| Emotes (rider animations) | rpemotes-reborn, scully_emotemenu | plain GTA animations from config/assets.lua |
| Notifications | ox_lib (default) | your framework’s notify |
The server console prints the adapter picked for each category on start. To force one, set it in config/main.lua → Config.Bridge (e.g. inventory = 'qs').
Installation
-
Copy both folders into your resources:
dashkart(keep that name, it is used for the tablet export) anddashkart_props(DashKart’s models: the delivery bag with its lid, the delivery boxes, the grocery bags and the rider tee).- Got DashKart through Cfx.re (escrow)? Download
dashkartfrom Keymaster → Granted Assets, signed in with the Cfx.re account that owns your server’s license key (it only runs on that key).dashkart_propscomes as its own zip (dashkart_props-<version>.zip) from MBTH Studios. - oxmysql must already be connected to your database (
set mysql_connection_string "..."inserver.cfg); most framework servers have this already.
- Got DashKart through Cfx.re (escrow)? Download
-
Start order in
server.cfg. DashKart must start after ox_lib, oxmysql, your framework and your inventory / target / keys / fuel scripts:ensure oxmysql ensure ox_lib ensure qbx_core # or qb-core / es_extended ensure ox_inventory # your inventory, target, keys, fuel ... ensure dashkart_props ensure dashkartYou can
restart dashkartat any time. Never restartdashkart_propson a live server: unloading streamed models crashes connected game clients, even when no bag is spawned. Changed or new models need a full server restart. -
Admin permission for
/dashkart admin:add_ace group.admin dashkart.admin allowOn ESX and QBCore the framework groups in
Config.Admin.groups(admin,god,superadmin) are accepted as well. -
Add the tablet item to your inventory. Copy-paste definitions for every inventory are in Inventory items. It is the only item DashKart uses. No icon ships with it: put any tablet image into your inventory’s image folder as
dashkart_tablet.png(or point the item at an existing image such astablet.png).Rider tee: the DashKart tee is add-on clothing. FiveM only streams it on servers with an Element Club Argentum (or higher) key or with 10 slots or fewer; anywhere else the rider’s torso is invisible. On such a server switch the uniform’s torso (component 11) in
config/rider.luato a vanilla shirt, see FAQ. -
Start the server. Database tables are created and updated automatically (migrations), and the console shows:
[DashKart] INFO Bridge framework -> qbox (detected) ... [DashKart] INFO DashKart v1.0.1 by MBTH Studios ready (...)If a line says
ERROR Config: ...orBridge ... is missing ..., fix that first: DashKart does not start with an invalid config. -
Optional: custom delivery scooter. Stream the model from its own resource and set it from
server.cfg(no config edit needed):ensure my_scooter_resource setr dashkart:scooter "my_scooter_model" ensure dashkartOn QBox / QBCore the model must also be registered in the framework’s vehicle list. See Models, props and clothing.
-
Optional: language. Set
Config.Locale = 'hi'(or'te','en') inconfig/main.lua, or leave itnilto follow ox_lib’s convar:setr ox:locale "hi".
How it plays
Rider: go to a DashKart store counter → Clock in → Rent scooter (deposit) → open the tablet (item or F6) → accept an order → pick the items from the marked shelves (or pack at the pickup point) → ride to the marker → hand over to the customer at the door → return the scooter for your deposit → Clock out. Riders without a tablet get one free when they clock in.
Owner: at the counter of an ownable store choose Store office to buy it. Then manage it from the office menu or the tablet’s My store app. Restock at the wholesale warehouse at the docks (blip DashKart Wholesale) or order a delivery from the tablet.
Admin: /dashkart admin opens the admin panel in the tablet, no item needed.
Configuration
All configuration is in config/ and is not escrowed. Every file is commented; the full key reference is in Configuration.
| File | What it controls | Sent to clients |
|---|---|---|
config/main.lua |
debug mode, language, currency symbol, bridge overrides, money accounts, admin command / ace / groups, rate limits, DB flush interval | yes |
config/stores.lua |
stores: counter, pickup point, rental spawns and return spot, zone, price, demand, payroll, optional shelf layout | yes |
config/catalog.lua |
products, prices, default stock, categories, owner price limits | yes |
config/rider.lua |
job settings, F6 key, rental deposits and penalties, packing / picking times, handover radius, uniforms, tablet item | yes |
config/wholesale.lua |
warehouse location, wholesale cost, van run, delivery fee and delay, city store auto-restock | yes |
config/assets.lua |
every vehicle, prop, animation, customer ped and blip | yes |
config/npc.lua |
demand curve, baskets, variety events, delivery points, timeouts | no (server only) |
config/economy.lua |
delivery fee, payroll range, bonuses and penalties, caps, anti-farm, store ownership, tablet remote access, admin panel limits | no (server only) |
config/webhooks.lua |
Discord webhook URLs, colours, role pings, which order outcomes are posted | no (server only) |
config/promos.lua |
reserved for player customers (coming in V2), not used in V1 | no (server only) |
Translations live in locales/en.json, hi.json and te.json (flat keys shared by the Lua side and the tablet). Product names can be translated by adding "item.<item name>": "..." keys.
The data/ folder holds layouts saved from in-game tools (shelves.json, dropoffs.json). Keep it writable and keep it when you update.
Commands and keys
| Command / key | Who | What |
|---|---|---|
| F6 | riders | open the tablet (needs the tablet item unless Config.Tablet.requireItem = false). Players can rebind it in Settings → Key Bindings → FiveM. |
use dashkart_tablet |
anyone holding it | open the tablet |
/dashkart admin |
admins | open the admin panel. The command name is Config.Admin.command. |
Setup and test commands (debug mode only)
These exist only while debug mode is on. It is off by default; turn it on for a setup session with setr dashkart:debug "true" in server.cfg (before ensure dashkart) and restart. With it off, none of the commands or their events are registered. The server commands check admin rights on the server; the client tuning commands only move props on your own screen and print config lines.
| Command | What |
|---|---|
/dk_bridgetest |
tests every detected integration live on your character (money, items, notify, target, fuel, keys) and prints PASS/FAIL plus X/Y passed to the server console and F8. Money and items end exactly as before. Config.DebugTest.item must exist in your inventory. |
/dk_tpstore <id> |
teleport to a store (wholesale for the warehouse). No id = list. |
/dk_tpdrop <index> |
teleport to a delivery point. No index = list the ranges. |
/dk_shelf add <category[,category]> [label] |
stand at a shelf, facing it, inside a store and record it. Categories: dairy, groceries, snacks, beverages, essentials or * (everything else). Also list, show, remove <n>, clear, export (prints a shelves = {...} block for config/stores.lua and copies it). Saved to data/shelves.json. |
/dk_dropaudit |
visits every delivery point and moves points that stand on a road onto the pavement (or disables them). Saved to data/dropoffs.json. Takes a few minutes. |
/dk_dropadd [type] [zone] |
adds your position (stand at a real door) as a delivery point. |
/dk_setowner <storeId> [serverId|none] |
give a store to a player or back to the city (testing). |
/dk_storecash <storeId> <amount> |
add or remove store balance (testing). |
/dk_bulkorder |
creates a bulk NPC order at your store right now (you must be on duty). Needs the van; falls back to a normal order if the store lacks stock for a bulk basket. |
/dk_setdeliveries <count> |
sets your lifetime completed deliveries, e.g. to test the van unlock (Config.Rider.rental.van.unlockDeliveries). |
/dk_mapdump |
captures the road network for the tablet map into data/roads_raw.json (takes a few minutes); node tools/build_roads.js turns it into the map data. |
/dk_boxpos x y z [rx ry rz] |
move the delivery bag on your rental scooter live and print the config line (Config.Assets.vehicleProps). |
/dk_lid [angle|close] |
open the delivery bag’s lid at angle degrees to tune openable.openAngle; close shuts it. |
/dk_cargopos <floor> [inset] |
place order bags in your rental van’s cargo area live and print the config line (Config.Assets.vanCargo). |
/dk_bagpos x y z [rx ry rz] |
move the hand-carried order bag live (Config.Assets.anims.carryBag). |
/dk_bagpos2 x y z [rx ry rz] |
move the second, left-hand bag of a big order live (carryBagFull.propLeft). |
/dk_anim <dict> <clip> [flag] [seconds] |
play any GTA animation on yourself to try alternatives for Config.Assets.anims. |
/dk_bagdebug |
prints why the “put order in the delivery bag” target does or does not show (order state, bag counts, rental, distance) |
/dk_clothcheck, /dk_clothtry <1|2|3|collection> |
diagnose the add-on rider tee (see the invisible tee FAQ below). |
Remove the dashkart:debug line (or set it to "false") before going live.
FAQ and troubleshooting
The tablet is a dark/grey screen covering the game, or screens stay blank.
You are running an old build of the UI. Make sure web/dist is the one from this release (re-download and replace the whole dashkart folder), then restart the resource and reconnect. If you edited web/src, rebuild it (see below). If it persists, press F8, type nui_devtools and send us a screenshot of the Console tab.
F6 does nothing.
With Config.Tablet.requireItem = true you need the dashkart_tablet item. Riders without one get it when they clock in. If the console says Could not give "dashkart_tablet" ... is the item defined in your inventory?, add the item (docs/ITEMS.md). Also check the key was not rebound in Settings → Key Bindings → FiveM.
Using the item does nothing (ox_inventory / QBox).
The ox_inventory item needs server = { export = 'dashkart.useTablet' }, and the resource folder must be named exactly dashkart.
No orders come in.
- Orders are only generated for stores where at least one rider is clocked in. A store nobody works at is idle.
- You need the rental out to accept orders (
Config.Rider.requireRental). - The store may be out of stock: check stock in My store or the admin panel. City stores restock themselves every
Config.Wholesale.autoRestock.checkIntervalseconds. - Riders who don’t move and do nothing for
Config.Economy.antiFarm.afkSecondsare paused until they move. - Caps:
Config.Economy.caps.maxNpcOrdersPerStorePerHouranddailyNpcBudget(0 = unlimited). - The console warns
Store "x" has no delivery points between ...if a store (for example one you added) has no delivery point insideConfig.Npc.minDistance/maxDistance.
The rental scooter does not spawn or the deposit is refunded immediately.
The console prints Could not spawn rental model "...". The model name is wrong or not streamed, or Config.Assets.vehicleTypes.scooter does not match the model (a scooter or motorbike is 'bike'). All spawn spots may also be blocked by other vehicles.
Custom scooter on QBox / QBCore: errors from qbx_vehiclekeys, or no keys.
Register the model in qbx_core/shared/vehicles.lua (QBCore: qb-core/shared/vehicles.lua) and restart the server. See docs/ASSETS.md.
/dashkart admin says no permission.
Add add_ace group.admin dashkart.admin allow and make sure your identifier is in group.admin, or that your framework group is listed in Config.Admin.groups.
Owners cannot withdraw from the tablet.
By design: money moves only at the store counter. Set Config.Ownership.tablet.remoteMoney = true to allow it remotely.
The uniform is not applied.
Only freemode peds (mp_m_freemode_01 / mp_f_freemode_01) can wear clothing components. For appearance resources or EUP use Config.Rider.uniform.onApply / onRestore.
The DashKart tee is invisible (the rider’s torso is missing).
FiveM streams add-on clothing only for server keys with the Element Club Argentum tier or higher, or servers with 10 slots or fewer (sv_maxclients 10). Upgrade the key, lower the slots, or switch the tee to a vanilla torso in Config.Rider.uniform. Details in Models, props and clothing.
Discord logs don’t arrive.
Fill the URLs in config/webhooks.lua and use the webhook test button in the admin panel (Economy tab). Expired orders are not posted by default (Config.Webhooks.orders.expired).
Can players order from the tablet as customers? Not in V1: all customers are NPCs. Player customers are planned for V2.
Customising
- Custom framework: fill in
bridge/framework/custom.lua. Guide: Custom framework. - Phone apps and other scripts: clock in / out from a phone (
Config.Rider.remoteDuty), read duty state, open the tablet. Exports, event and examples: Integration API. - Custom models, props, uniforms, MLOs: Models, props and clothing.
- Item definitions: Inventory items.
- All config keys: Configuration.
Rebuilding the tablet UI
The compiled UI ships in web/dist and is all the game needs. Only if you change the UI source in web/src (Node.js 18+):
cd web
npm install
npm run build
Escrow
DashKart is free. Its code is escrow-safe: when it is delivered through the Cfx.re asset escrow, these files stay open and editable:
config/*.lualocales/*.jsonbridge/framework/custom.luaserver/db/migrations/*.sqlanddata/*.json(read at runtime)
Everything else may be encrypted, and DashKart does not rely on reading its own source. The tablet UI in web/dist is a built (minified) bundle. dashkart_props (models and the tee) is not escrowed and ships as its own download.
DashKart is made by MBTH Studios.