> For the complete documentation index, see [llms.txt](https://cactus-code.gitbook.io/cactus-code-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cactus-code.gitbook.io/cactus-code-docs/documentation/scripts/advanced-crafting-v2/config.md).

# Config

```lua
-- Clean, documented config for cactus-craft
-- This file is intended to be friendly for server owners who will pick up
-- the script. Each option is documented. Keep keys stable to maintain
-- compatibility with the resource code.

Config = {}
Config.Framework = 'VORP' -- Options: 'VORP' | 'RSG' | 'RedEM' | 'CUSTOM'
Config.devmode = false    -- true = prints debug information to server/client console

Config.NotificationSystem = 'vorp' -- 'vorp' | 'redem' | 'custom' | 'none' | 'bln' | 'rsg' and more 

Config.InventoryImgPath = "vorp_inventory/html/img/items" --- RSG "rsg_inventory/html/images/"
Config.PendingPersistence = true
Config.DisplayXP = true

Config.NameIcon = 'craft.png'
Config.NameIconSize = { width = 36, height = 36, borderRadius = 6 }

Config.BackgroundCrafting = {
    Enabled = true,
    AllowUIClose = true,
    Persistence = true,
    TickSeconds = 5
}

Config.IllegalDefaultCraftTime = 15

Config.EnableXP = true
Config.XPPerCraft = 5
Config.XPLevelThreshold = 100

Config.OpenKey = "INPUT_CUT_FREE"
-- Refer to https://github.com/femga/rdr3_discoveries/tree/a63669efcfea34915c53dbd29724a2a7103f822f/Controls for key mapping ids.


----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------

-- Crafting stations: each entry describes a station visible on the map
-- id: unique internal id (string)
-- name: human-friendly station name (displayed in UI)
-- coords: vector3 position where the prompt is shown
-- blip: optional table { enabled = bool, sprite = string, scale = number }
-- categories: list of category ids this station exposes
-- jobs: optional list of allowed jobs (empty = accessible to everyone)
-- showXP: toggle XP UI elements for this station
-- logo: filename under html/img/ used as station icon
-- logoSize: { width = px, height = px, borderRadius = px }
-- illegal: true marks this station as illegal (only illegal recipes & experimentation)

Config.CraftingStations = {
    {
        id = "valentine_forge",
        name = "Valentine Forge",
        coords = vector3(-280.7818, 778.3886, 119.5539),
        blip = { enabled = true, sprite = 'blip_shop_blacksmith', scale = 0.2 },
        categories = { "weapons", "tools" },
        jobs = {},
        showXP = true,
        logo = 'forge.png',
        logoSize = { width = 48, height = 48, borderRadius = 6 },
        PromptTexte = "Work the anvil",
        illegal = false
    },
    {
        id = "saintdenis_tailor",
        name = "Saint Denis Tailor",
        coords = vector3(2650.7429, -1181.9304, 53.2787),
        blip = { enabled = true, sprite = 'blip_shop_tailor', scale = 0.18 },
        categories = { "outfitting", "provisions" },
        jobs = {},
        showXP = true,
        logo = 'tailor.png',
        logoSize = { width = 46, height = 46, borderRadius = 8 },
        PromptTexte = "Lay out the patterns",
        illegal = false
    },
    {
        id = "emerald_distillery",
        name = "Emerald Distillery",
        coords = vector3(1414.9310, 367.2047, 90.5797),
        blip = { enabled = true, sprite = 'blip_campfire_full', scale = 0.2 },
        categories = { "provisions", "alchemy" },
        jobs = {},
        showXP = true,
        logo = 'distillery.png',
        logoSize = { width = 44, height = 44, borderRadius = 8 },
        PromptTexte = "Prepare the still",
        illegal = false
    },
    {
        id = "bleaktower_hideout",
        name = "Bleak Tower Hideout",
        coords = vector3(-2074.2190, -1723.0585, 126.8657),
        blip = { enabled = false },
        categories = { "smuggling", "alchemy" },
        jobs = {},
        showXP = false,
        logo = 'skull.png',
        logoSize = { width = 52, height = 52, borderRadius = 10 },
        PromptTexte = "Experiment in secret",
        illegal = true
    }
}


-- Categories shown in the UI
Config.Categories = {
    { id = "weapons", label = "Weapons" },
    { id = "tools", label = "Tools" },
    { id = "outfitting", label = "Outfitting" },
    { id = "provisions", label = "Provisions" },
    { id = "alchemy", label = "Alchemy" },
    { id = "smuggling", label = "Smuggling" }
}

-- ==========================================================================
-- Recipes
-- Each recipe is a table with the following keys:
-- id         : unique string identifier (required)
-- label      : display name shown in UI (required)
-- category   : category id (required)
-- craftTime  : time in seconds to craft one item (required)
-- requiredLevel: level required to craft (optional, default 0)
-- xpGain     : XP granted on success (optional, default Config.XPPerCraft, use false to disable XP display)
-- CategoryIllegal: true to hide recipe until the player discovers it through experimentation
-- Animations : string key to an animation defined in animations.lua or false to skip
-- ingredients: array of { item = '<itemName>', label = '<display label>', amount = <number> }
-- result     : { item = '<itemName>', amount = <number>, Itsweapon = <bool> }
-- stations   : optional list of station ids where this recipe is available (empty/nil = all stations matching category/legality)
-- Note: the legacy field `name` is optional and not required by the script; use
--       `id` and `label` for identification and display. The code will fall back
--       to `label` if `name` is missing.
-- ==========================================================================

Config.Recipes = {
    {
        id = "steel_longknife",
        label = "Steel Longknife",
        category = "weapons",
        craftTime = 18,
        requiredLevel = 2,
        xpGain = 16,
        Animations = "knifecooking",
        CategoryIllegal = false,
        stations = { "valentine_forge" },
        ingredients = {
            { item = "iron_ore", label = "Iron Ore", amount = 4 },
            { item = "coal_chunk", label = "Coal Chunk", amount = 2 },
            { item = "oak_handle", label = "Oak Handle", amount = 1 }
        },
        result = { item = "weapon_melee_longknife", amount = 1, Itsweapon = true }
    },

    {
        id = "reinforced_pickaxe",
        label = "Reinforced Pickaxe",
        category = "tools",
        craftTime = 22,
        requiredLevel = 3,
        xpGain = 18,
        Animations = "craft",
        CategoryIllegal = false,
        stations = { "valentine_forge" },
        ingredients = {
            { item = "steel_ingot", label = "Steel Ingot", amount = 3 },
            { item = "hickory_plank", label = "Hickory Plank", amount = 1 },
            { item = "rivets", label = "Box of Rivets", amount = 1 }
        },
        result = { item = "reinforced_pickaxe", amount = 1, Itsweapon = false }
    },

    {
        id = "tailored_duster",
        label = "Tailored Duster Coat",
        category = "outfitting",
        craftTime = 26,
        requiredLevel = 2,
        xpGain = 20,
        Animations = "crafting",
        CategoryIllegal = false,
        stations = { "saintdenis_tailor" },
        ingredients = {
            { item = "fine_cloth", label = "Fine Cloth", amount = 3 },
            { item = "leather_strip", label = "Leather Trim", amount = 2 },
            { item = "tailor_thread", label = "Tailor Thread", amount = 1 }
        },
        result = { item = "duster_coat_black", amount = 1, Itsweapon = false }
    },

    {
        id = "hunting_satchel",
        label = "Hunting Satchel",
        category = "outfitting",
        craftTime = 20,
        requiredLevel = 1,
        xpGain = 14,
        Animations = "crafting",
        CategoryIllegal = false,
        stations = { "saintdenis_tailor" },
        ingredients = {
            { item = "tanned_hide", label = "Tanned Hide", amount = 2 },
            { item = "bronze_buckle", label = "Bronze Buckle", amount = 1 },
            { item = "linen_roll", label = "Linen Roll", amount = 1 }
        },
        result = { item = "hunting_satchel", amount = 1, Itsweapon = false }
    },

    {
        id = "spiced_venison",
        label = "Spiced Venison Jerky",
        category = "provisions",
        craftTime = 12,
        requiredLevel = 0,
        xpGain = 8,
        Animations = "craft",
        CategoryIllegal = false,
        stations = { "emerald_distillery", "saintdenis_tailor" },
        ingredients = {
            { item = "raw_venison", label = "Raw Venison", amount = 2 },
            { item = "salt_pouch", label = "Salt Pouch", amount = 1 },
            { item = "herb_bundle", label = "Herb Bundle", amount = 1 }
        },
        result = { item = "spiced_venison", amount = 3, Itsweapon = false }
    },

    {
        id = "frontier_tonic",
        label = "Frontier Tonic",
        category = "alchemy",
        craftTime = 16,
        requiredLevel = 1,
        xpGain = 12,
        Animations = "craft",
        CategoryIllegal = false,
        stations = { "emerald_distillery" },
        ingredients = {
            { item = "canis_root", label = "Canis Root", amount = 1 },
            { item = "prairie_flower", label = "Prairie Flower", amount = 2 },
            { item = "glass_bottle", label = "Glass Bottle", amount = 1 }
        },
        result = { item = "frontier_tonic", amount = 1, Itsweapon = false }
    },

    {
        id = "moonshine_crate",
        label = "Crate of Moonshine",
        category = "smuggling",
        craftTime = 28,
        requiredLevel = 0,
        xpGain = false,
        Animations = "craft",
        CategoryIllegal = true,
        stations = { "bleaktower_hideout" },
        ingredients = {
            { item = "corn_mash", label = "Corn Mash", amount = 4 },
            { item = "sugar_sack", label = "Sugar Sack", amount = 2 },
            { item = "oak_barrel", label = "Aged Barrel", amount = 1 }
        },
        result = { item = "moonshine_crate", amount = 1, Itsweapon = false }
    },

    {
        id = "poachers_tonic",
        label = "Poacher's Tonic",
        category = "alchemy",
        craftTime = 24,
        requiredLevel = 0,
        xpGain = false,
        Animations = "craft",
        CategoryIllegal = true,
        stations = { "bleaktower_hideout" },
        ingredients = {
            { item = "ravens_claw", label = "Raven's Claw", amount = 2 },
            { item = "nightshade", label = "Nightshade", amount = 2 },
            { item = "glass_bottle", label = "Glass Bottle", amount = 1 }
        },
        result = { item = "poachers_tonic", amount = 1, Itsweapon = false }
    }
}

-- ==========================================================================
-- Localization (messages shown to players). Keep keys stable if you translate.
-- ==========================================================================
Config.Lang = {
    ['open_crafting'] = 'Open crafting',
    ['open_prompt'] = 'Open',
    ['prompt_hold_label'] = 'Hold to open',

    ['tab_recipes'] = 'Recipes',
    ['tab_inventory'] = 'Inventory',
    ['tab_crafting'] = 'In Progress',
    ['tab_pending'] = 'Pending',

    ['title_available_recipes'] = 'Available recipes',
    ['title_your_inventory'] = 'Your inventory',
    ['title_crafting_queue'] = 'Crafting queue',

    ['btn_add_to_craft'] = 'Add to craft',
    ['btn_start'] = 'Start',
    ['lbl_qty'] = 'Qty',
    ['lbl_recipe_count'] = 'Total: %s',
    ['search_placeholder'] = 'Search recipes...',

    ['pending_claim'] = 'Claim',
    ['pending_none'] = 'No crafts waiting',

    ['craft_progress_text'] = 'Crafting...',
    ['confirm_title'] = 'Confirm craft',
    ['confirm_cancel'] = 'Cancel',
    ['confirm_ok'] = 'Craft',

    ['crafting_started'] = 'Craft started...',
    ['crafting_complete'] = 'Craft complete!',
    ['crafting_pending_ready'] = 'Your craft is ready in the IN PROGRESS tab.',
    ['crafting_failed'] = 'Craft failed!',
    ['not_enough_items'] = 'Not enough materials',
    ['inventory_full'] = 'Inventory is full',
    ['level_required'] = 'Requires level %s',
    ['xp_gained'] = '+%s XP gained',
    ['job_required'] = 'You do not have the required job',

    ['no_recipes'] = 'No recipes available',
    ['no_inventory_items'] = 'No items in inventory',
    ['insufficient_level'] = 'Your level is too low',

    ['weapon_crafted_desc'] = 'Crafted weapon - Serial: %s'
}
----/!\ Dont TOUCH if you dont understand ----
-- Performance optimization: limit full inventory scan to prevent server hitches
-- Set to false to disable full inventory scanning (only recipe ingredients will be checked)
Config.EnableFullInventoryScan = true
Config.MaxInventoryItems = 500 -- Maximum items to process to prevent hitches
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://cactus-code.gitbook.io/cactus-code-docs/documentation/scripts/advanced-crafting-v2/config.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
