A good QBCore drug system is more than a collection of client events. The important work—inventory checks, rewards, cooldowns, permissions and transaction logging—belongs on the server. That structure makes the resource easier to debug and much harder to abuse.
1. Start with a server-authoritative architecture
Split the resource into clear responsibilities. The client should handle targets, menus, animations and progress feedback. The server should decide whether an action is valid and apply every inventory or money change. Keep item names and configurable locations in a shared config so they are not duplicated across files.
- Client: interaction zones, prompts and visual feedback.
- Server: inventory validation, rewards, cooldowns and logging.
- Shared config: item names, processing recipes, locations and timings.
- Database: only the persistent state and audit data your server actually needs.
2. Define the processing flow before writing UI
For each activity, write down the complete state change. A processing step might require a specific input item, a minimum quantity, an allowed location and a cooldown. The server verifies those conditions, removes the input and only then adds the output. If any validation fails, nothing should be awarded.
RegisterNetEvent('stellar-drugs:server:process', function(recipeId, amount)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local recipe = Config.Recipes[recipeId]
if not recipe or amount < 1 or amount > recipe.maxBatch then return end
if not IsPlayerNearProcess(src, recipeId) then return end
if IsOnCooldown(src, recipeId) then return end
local item = Player.Functions.GetItemByName(recipe.input)
if not item or item.amount < amount then return end
if Player.Functions.RemoveItem(recipe.input, amount) then
Player.Functions.AddItem(recipe.output, amount * recipe.outputAmount)
SetCooldown(src, recipeId)
LogProcess(src, recipeId, amount)
end
end)
The exact QBCore inventory method depends on the version and inventory resource your server uses, so verify the current documentation for your stack before shipping generated code.
3. Validate every client request
Treat a client event as a request, not proof that an action happened legitimately. Re-check the player, recipe, amount, location, inventory and cooldown on the server. If jobs or permissions are involved, verify them from server-side player data rather than accepting a client-supplied role.
- Reject unknown recipe IDs and unexpected payload shapes.
- Clamp or reject unreasonable quantities.
- Rate-limit repeated events.
- Check server-known location before processing.
- Log rejected high-risk actions so staff can investigate patterns.
4. Keep item and recipe definitions consistent
Most deployment problems come from mismatched item names or dependencies. Before starting the resource, confirm that every configured input and output exists in your inventory system, images are present where required, and the resource start order loads QBCore and any target/menu library first.
| Check | Why it matters |
|---|---|
| Item names | Prevents silent add/remove failures |
| Dependency order | Stops exports from being called before a resource is ready |
| Recipe limits | Prevents accidental huge batches |
| Server logs | Makes failed transactions easier to trace |
5. Add cooldowns and concurrency protection
A button cooldown in the UI is not enough because a modified client can skip it. Store the authoritative cooldown on the server. For valuable processing steps, also prevent the same player from starting overlapping transactions before the first one finishes.
6. Test the resource like a hostile client would
Use a private development server and test both the normal route and failure paths. Try missing items, excessive quantities, repeated events, reconnects during a process, invalid recipe IDs and interaction from outside the allowed zone. Confirm that every rejected request leaves inventory and money unchanged.
- Test as a normal player, not only an admin.
- Use two players to expose shared-state mistakes.
- Restart the resource and server to verify state recovery.
- Check console and database logs after each failed case.
- Keep a rollback copy before updating a live server.
7. Deploy in small, reversible steps
Ship the minimal working loop first, observe it, and only then add more recipes, sellers or UI. Keep configuration separate from core logic so balancing changes do not require rewriting the resource. For database changes, back up production data and test migrations against a copy first.
8. Using an AI script generator effectively
AI is most useful when the prompt describes the framework version, inventory system, target/menu dependency, exact files required and acceptance tests. Ask for one system at a time, then run it on a private server and bring the actual errors back for revision. Avoid pasting generated code directly into production without review.
For a broader workflow, see the AI game script generator guide, the Roblox AI script generator guide, and the FiveM AI script generator guide.