ATY Scripts Logo
ATY Scripts/Docs/Inventory/Crafting

Crafting

Crafting

Drop one ingredient onto another and the recipe lights up.

The gesture

Crafting has no menu. You drag an item onto another item in your own inventory; if the pair names a recipe, the interface shows what it would make, what it costs, which tools are needed and the chance of failure. Confirm and the hands get busy for time milliseconds.

Two constraints follow from making it a gesture rather than a menu:

A drag names two items. A recipe can need any number of ingredients, but a drag has two ends, so any two of a recipe's ingredients start it — scrap onto plastic or plastic onto scrap, the same recipe answers. What else it needs is taken from the rest of the bag, and the confirm window lists every line with what you have beside it.

A pair belongs to one recipe. If scrap onto plastic could make either a lockpick or a crowbar, the drag would have to ask which — and then it is a menu again. The admin panel refuses to save a recipe that shares a pair with another one, and names the recipe it clashes with. data/recipes.lua is not checked the same way, so keep the pairs in the file distinct.

Anything larger than this — multi-step production, blueprints, timed queues — is a crafting resource's job. This inventory hands it items through the same API every other resource uses.

Defining a recipe

data/recipes.lua:

Recipes = {
    {
        id          = 'lockpick',
        ingredients = {
            { item = 'scrap',   count = 2 },
            { item = 'plastic', count = 1 },
        },
        results = { { item = 'lockpick', count = 1 } },
        time    = 2500,
    },
}
Field Meaning
id Unique name
ingredients Each { item, count }. Add consume = false to make it a tool — needed, not spent
results What comes out. More than one entry is allowed
time Milliseconds the hands are busy. Left out, it is 3000, as in ox_inventory. 0 is instant (see below)
chance Percent success. Below 100, failure costs the materials
keepOnFail Return the ingredients when it fails
label The name shown for it; defaults to the first result's label
job / grade Only that job, at that grade or above
licence A licence the player must hold
skill / level A skill level, answered by whichever resource registered RegisterSkillProvider; with none registered the recipe is refused
bench true = only at a Config.Workbench location
enabled false turns it off without deleting it

The shipped first-aid recipe demonstrates the long form: three ingredients, one of which is a tool, a failure chance, and waste out the other end.

The time it takes

A recipe with a time is a timed action, as it is in ox_inventory. Confirming it closes the inventory and runs a progress bar with ox's crafting animation (Config.Anim.craft), on the same bar a meal or a body search uses, so Config.Consume.progress picks it too. Nothing is spent while the bar runs. The cancel key (X) or dying stops it, and the materials stay where they were.

The server keeps the clock. When the bar reports it has finished, the server checks that the full time has passed, then asks every rule again: the pair must still make the same recipe, the materials must still be there, the bench must still be in reach and the result must still fit. A bar that finished early, or a bag that changed underneath it, crafts nothing.

Carrying the result

A craft that would put you over weight is refused before the materials are spent, and so is one whose result your job may not hold (restrictJobs). Free slots are not reserved ahead: if the bag runs out of slots while the results go in, what was spent stays spent, what was made stays made, and the ledger records exactly that.

Two places a recipe can live

Source Where it is stored Who edits it
data/recipes.lua The file A developer
Admin panel → Recipes aty_recipes table An admin, live, no restart

Panel recipes are never written back to the file. The file stays the developer's copy; the table is the layer on top. Both are read by the same loader, so a recipe behaves identically whichever it came from.

invrecipes          list what is loaded, and where each came from
invcraft            SELF-TEST — crafts the shipped recipes in a throwaway
                    stash and checks every way a craft must refuse
invrecipewrite      SELF-TEST — exercises the editor through the panel's
                    own endpoint. It writes nothing to disk.
`invrecipewrite` is a test, not an exporter, despite the name. It creates and deletes throwaway recipes to prove the panel's endpoint actually works — a form that posts perfectly to an endpoint that refuses is a form that looks fine and does nothing.
ATY Scripts LogoATY SCRIPTS

Crafting highly optimized FiveM scripts for QBCore & ESX. Maximum performance, precision code, zero lag.

Join Community

Partner

Official partners with Tebex. Secure checkout and Cfx.re Keymaster integration.

Legal

Not affiliated with Rockstar Games, Cfx.re, FiveM, or Take-Two Interactive. Purchases bound by Tebex Terms of Service.

© 2026 ATY SCRIPTS. All rights reserved.