Skip to content

Configuration

Everything lives in config.lua, which stays editable in both the Open and Encrypted variant. There are no framework, inventory, target or image-path options - those are handled by vns-core.

General options

Option Default What it does
Config.HideWhenCantCraft true Hide recipes the player's level is too low for. With false they are shown, but the server still refuses to craft them.
Config.DistanceToCraft 3.5 The crafting timer only counts down while the player is within this distance of the bench. Walk away and the timer pauses until you come back.
Config.PauseWhenDoorLocked false On container benches, also pause the timer while the container door is locked.
Config.DurabilityKeys false false, or a number: every lock/unlock of a container door removes that much durability from the key. See Key durability.
Config.ContainerProps 12 props The props spawned on every container bench (workbenches, toolboxes, doors). Positions are offsets from the container. Entry [11] must stay the door.
Config.Lang English All player-facing strings.

Unused options

Config.CraftingStopWithDistance exists in the config but is not read - the distance pause via Config.DistanceToCraft is always active. The blip field on workbenches is also not used; no blips are created.

Defining a recipe

Recipes live in Config.Recipes. The key is the item name the craft produces:

Config.Recipes = {
    ['lockpick'] = {
        XPRequired = 0,         -- From what level this item will be craftable
        Amount = 1,             -- The amount that will be crafted
        ExperiancePerCraft = 0, -- XP added to the character for crafting
        Time = 10,              -- Time in seconds to make the craft
        Ingredients = {
            ['iron'] = 2,
            ['steel'] = 2,
            ['metalscrap'] = 9,
        }
    },
}
Field What it does
XPRequired Minimum crafting XP to craft the recipe. Checked on the server.
Amount How many of the item one craft produces.
ExperiancePerCraft XP added when the craft completes. Note the spelling - the code uses ExperiancePerCraft.
Time Craft duration in seconds (only counts down near the bench).
Ingredients ['item_name'] = amount pairs. All must be present; they are removed when the craft starts.
TimeBlockFrom / TimeBlockTo Optional, set both or neither. With numbers (server hours, 0-23) the recipe is only available when the server clock is at or before TimeBlockFrom or at or after TimeBlockTo. TimeBlockFrom = 2, TimeBlockTo = 18 makes it night-only (18:00-02:59). false/false or leaving them out means always available.

A recipe does nothing until its name is in the recipes list of at least one workbench. If the player's inventory can't hold the result when the timer ends, they get notenoughspace and the script retries a few seconds later.

Defining a workbench

Workbenches live in Config.Workbenches as a numbered list:

Config.Workbenches = {
    [1] = {
        coords = vector3(101.51, 6616.3, 32.44),  -- vector3 for a bench, vector4 for a container
        blip = false,
        bench = 1,                                -- must be unique
        isContainer = false,
        isUnlocked = true,
        recipes = {
            "handcuffs",
            "lockpick",
        }
    },
    [2] = {
        coords = vector4(865.27, 2170.265, 52.286, 154.648),
        blip = false,
        bench = 2,
        isContainer = true,
        isUnlocked = false,   -- containers start locked - leave this false
        key = "key1",         -- item that locks/unlocks the door
        recipes = {
            "weapon_pistol",
            "grip",
        }
    },
}
Field What it does
coords Bench position. Plain benches use vector3; containers need a vector4 (w is the container heading).
bench A unique number per bench.
isContainer true spawns a shipping container with the props from Config.ContainerProps and a working door.
isUnlocked Containers: whether the door starts unlocked. Keep it false - the state toggles at runtime and resets on resource restart.
key Containers: the item required for the Lock/Unlock door target option. The option is only shown while the player carries it.
recipes Recipe names (keys from Config.Recipes) this bench offers.

Players open a bench by pressing E within 1 m of coords. A locked container has to be unlocked through the door first; the server also refuses crafts at a locked container.

Crafting levels

Crafting XP is stored per character in the vns_crafting_levels table. It only goes up through ExperiancePerCraft (all 0 in the default config) or the admin command:

/setxp [server id] [amount]

/setxp requires the vns-core admin permission (Config.AdminAce in vns-core/config.lua, command by default) and also works from the server console. With the default config the basic recipes are level 0 and the weapon tiers unlock at 100-350 XP.

GetCraftingLevel, SetCraftingLevel and AddCraftingExperience in server/server_open.lua handle the storage. Replace them if you want to use an existing XP or skill system.

Key durability

With Config.DurabilityKeys set to a number, each door toggle removes that much durability from the key. Once a toggle would take it below zero, the key item is removed.

Limitation

vns-core has no cross-inventory way to read item metadata, so durability is tracked by the script per character and item in memory: every key starts at 100, and the values reset when the resource restarts. When the player carries exactly one key, it is re-issued with quality/durability metadata so inventories that display it show the current value. With several keys of the same item that step is skipped.

To use your inventory's real item metadata instead, replace GetToolDurability and SetToolDurability in server/server_open.lua.

Texts

Config.Lang = {
    craft3dmessage = '[~b~E~w~] Craft',
    alreadycrafting = "You already crafting something",
    notenoughmaterials = "You dont have enough materials",
    craftingsuccess = "Successful assembly",
    notenoughspace = "Not enough space",
    craftabuse = "Crafting abuse detected",
    notenoughlevel = "Your crafting level is too low",
    cannotcraftnow = "You can not craft this right now",
}

The Lock/Unlock door target label is set in AddTargetEntity in client/client_open.lua.

Open files

File Functions
client/client_open.lua DrawText3D, ClientNotification, GetItemImagePath, PlayerHasKey, AddTargetEntity (container door option), character load/unload events
server/server_open.lua GetPlayerIdentifier, GetSourceFromIdentifier, ServerNotification, PlayerHasItem, RemoveInventoryItem, AddInventoryItem, GetItemLabel, crafting level functions, /setxp, GetToolDurability, SetToolDurability