Station Types

Station Types

Station types define the different kinds of crafting stations available in your server. Each station type has its own recipes, props, upgrade paths, and visual appearance.

The configuration file is located at config/stationTypes.lua.

Structure Overview

Each station type is defined as a key in the stationTypes table:

local stationTypes = {
    ["general"] = {
        placeItem = 'crafting_bench',
        size = vec3(2, 1.05, 2),
        upgradeItems = { ... },
        stashSizes = { ... },
        sceneObjects = { ... },
        categories = { ... },
        recipes = { ... },
    },
    -- Add more station types here
}

Station Type Properties

placeItem

The inventory item used to place this station type. Each station type should have a unique placement item.

placeItem = 'crafting_bench'

size

The footprint dimensions of the station in meters (Length x Width x Height). Used for collision detection and placement validation.

size = vec3(2, 1.05, 2)

upgradeItems

A table of inventory items required to upgrade the station to each level. Keys must be sequential starting from 2 (level 1 is the base level).

upgradeItems = {
    [2] = "bench_upgrade_2",
    [3] = "bench_upgrade_3",
    [4] = "bench_upgrade_4"
}

stashSizes

Defines the storage capacity for each upgrade level of the station.

stashSizes = {
    [1] = { weight = 5000, slots = 3 },
    [2] = { weight = 10000, slots = 5 },
    [3] = { weight = 20000, slots = 7 },
    [4] = { weight = 50000, slots = 10 },
}

sceneObjects

Defines the props displayed for each upgrade level. The first prop in each level is the "anchor" prop where the camera and interactions attach.

sceneObjects = {
    [1] = { -- Level 1 props
        {
            model = `prop_tool_bench02_ld`,
            pos = vec3(0, 0, 0.0),
            rot = vec3(0, 0, 90),
            interactOffset = vec3(0, 0, 1),
            previewOffsets = {
                pos = vec3(0.1, 0, 1.1),
                rot = vec3(0, 0, -90)
            },
            camSettings = {
                posOffset = vec3(1, -0.25, 1.3),
                viewOffset = vec3(0, -0.25, 1),
                fov = 75
            }
        },
        -- Additional decorative props can be added here
    },
    [2] = { ... },
    [3] = { ... },
    [4] = { ... }
}

Prop Properties

PropertyTypeDescription
modelhashThe prop model hash (use backticks for hash)
posvec3Position offset relative to the station origin
rotvec3Rotation offset in degrees
interactOffsetvec3Offset for the interaction point
previewOffsetstablePosition and rotation for item preview
camSettingstableCamera position, view target, and FOV
activetable(Optional) Alternative model to show when crafting is active

Active Model Example

You can specify a different prop model to display when the station is actively crafting (e.g., a furnace with fire):

{
    model = `bzzz_prop_mine_furnace_a`,
    active = {
        model = `bzzz_prop_mine_furnace_b`, -- Model when active
    },
    pos = vec3(0, 0, 0.0),
    rot = vec3(0, 0, 180),
    -- ... other properties
}

categories

Categories are used for filtering recipes in the UI. Each category needs a unique ID, a display label, and a FontAwesome icon name.

categories = {
    {
        id = "weapons",
        label = "Weapons",
        icon = "gun"
    },
    {
        id = "healing",
        label = "Healing",
        icon = "band-aid"
    },
}

Icons use FontAwesome (opens in a new tab) icon names. Only use the icon name without the fa- prefix.

recipes

Recipes define what items can be crafted at each upgrade level. Recipes are organized by level, and all recipes from lower levels are automatically available at higher levels.

recipes = {
    [1] = {
        {
            name = "bandage",                -- Item name in inventory
            label = "Bandage",               -- Display name in UI
            previewModel = `prop_bandage`,   -- (Optional) 3D preview model
            category = "healing",            -- Category ID from above
            description = "A makeshift bandage for treating wounds.",
            time = 10,                       -- Crafting time in seconds
            materials = {
                { name = "scrapcloth", label = "Scrap Cloth", quantity = 5 },
                { name = "vodka", label = "Vodka", quantity = 1 }
            }
        },
    },
    [2] = {
        {
            name = "WEAPON_PISTOL",
            label = "Pistol",
            category = "weapons",
            description = "A standard issue pistol.",
            time = 60,
            materials = {
                { name = "metalscrap", label = "Metal Scrap", quantity = 30 },
                { name = "rubber", label = "Rubber", quantity = 15 },
                { name = "steel", label = "Steel", quantity = 10 }
            }
        },
    },
    -- Level 3 and 4 recipes...
}

Recipe Properties

PropertyTypeRequiredDescription
namestringYesThe item name in your inventory system
labelstringYesDisplay name shown in the UI
categorystringYesCategory ID to group the recipe
descriptionstringYesDescription shown in the UI
timenumberYesCrafting time in seconds
materialstableYesArray of required materials
previewModelhashNo3D model to preview (auto-detects weapons)

Material Properties

PropertyTypeDescription
namestringItem name in inventory
labelstringDisplay name in UI
quantitynumberAmount required

For weapons (items starting with WEAPON_), the preview model is automatically set to the weapon model if not specified.

Complete Example

Here's a complete example of a station type configuration:

["general"] = {
    placeItem = 'crafting_bench',
    size = vec3(2, 1.05, 2),
    upgradeItems = {
        [2] = "bench_upgrade_2",
        [3] = "bench_upgrade_3",
        [4] = "bench_upgrade_4"
    },
    stashSizes = {
        [1] = { weight = 5000, slots = 3 },
        [2] = { weight = 10000, slots = 5 },
        [3] = { weight = 20000, slots = 7 },
        [4] = { weight = 50000, slots = 10 },
    },
    sceneObjects = {
        [1] = {
            {
                model = `prop_tool_bench02_ld`,
                pos = vec3(0, 0, 0.0),
                rot = vec3(0, 0, 90),
                interactOffset = vec3(0, 0, 1),
                previewOffsets = {
                    pos = vec3(0.1, 0, 1.1),
                    rot = vec3(0, 0, -90)
                },
                camSettings = {
                    posOffset = vec3(1, -0.25, 1.3),
                    viewOffset = vec3(0, -0.25, 1),
                    fov = 75
                }
            },
        },
        [2] = {
            {
                model = `prop_tool_bench02`,
                pos = vec3(0, 0, 0.0),
                rot = vec3(0, 0, 90),
                interactOffset = vec3(0, 0, 1),
                previewOffsets = {
                    pos = vec3(0.1, 0, 1.1),
                    rot = vec3(0, 0, -90)
                },
                camSettings = {
                    posOffset = vec3(1, -0.25, 1.3),
                    viewOffset = vec3(0, -0.25, 1),
                    fov = 75
                }
            },
        },
        -- ... levels 3 and 4
    },
    categories = {
        {
            id = "weapons",
            label = "Weapons",
            icon = "gun"
        },
        {
            id = "healing",
            label = "Healing",
            icon = "band-aid"
        },
    },
    recipes = {
        [1] = {
            {
                name = "bandage",
                label = "Bandage",
                category = "healing",
                description = "A makeshift bandage for treating wounds.",
                time = 10,
                materials = {
                    { name = "scrapcloth", label = "Scrap Cloth", quantity = 5 },
                    { name = "vodka", label = "Vodka", quantity = 1 }
                }
            },
        },
        [2] = {
            {
                name = "WEAPON_PISTOL",
                label = "Pistol",
                category = "weapons",
                description = "A standard issue pistol.",
                time = 60,
                materials = {
                    { name = "metalscrap", label = "Metal Scrap", quantity = 30 },
                    { name = "rubber", label = "Rubber", quantity = 15 },
                    { name = "steel", label = "Steel", quantity = 10 }
                }
            },
        },
        [3] = {
            {
                name = "WEAPON_SMG",
                label = "Submachine Gun",
                category = "weapons",
                description = "A compact submachine gun.",
                time = 60,
                materials = {
                    { name = "metalscrap", label = "Metal Scrap", quantity = 50 },
                    { name = "rubber", label = "Rubber", quantity = 25 },
                    { name = "steel", label = "Steel", quantity = 20 }
                }
            },
        },
        [4] = {
            {
                name = "WEAPON_ASSAULTRIFLE",
                label = "Assault Rifle",
                category = "weapons",
                description = "A standard issue assault rifle.",
                time = 60,
                materials = {
                    { name = "metalscrap", label = "Metal Scrap", quantity = 50 },
                    { name = "rubber", label = "Rubber", quantity = 25 },
                    { name = "steel", label = "Steel", quantity = 20 }
                }
            },
        }
    }
}

Adding a New Station Type

To add a new station type:

  1. Add a new key to the stationTypes table with a unique identifier
  2. Define all required properties (placeItem, size, sceneObjects, categories, recipes)
  3. Create the corresponding inventory items (see Items Setup)
  4. Optionally add upgrade items and stash sizes for upgradable stations
["cooking"] = {
    placeItem = 'cooking_station',
    size = vec3(1.5, 1.5, 1.5),
    stashSizes = {
        [1] = { weight = 10000, slots = 5 },
    },
    sceneObjects = {
        [1] = {
            {
                model = `prop_bbq_2`,
                pos = vec3(0, 0, 0.0),
                rot = vec3(0, 0, 0),
                interactOffset = vec3(0, 0, 1),
                previewOffsets = {
                    pos = vec3(0, 0, 1),
                    rot = vec3(0, 0, 0)
                },
                camSettings = {
                    posOffset = vec3(1, 0, 1),
                    viewOffset = vec3(0, 0, 0.5),
                    fov = 60
                }
            },
        },
    },
    categories = {
        {
            id = "food",
            label = "Food",
            icon = "utensils"
        },
    },
    recipes = {
        [1] = {
            {
                name = "burger",
                label = "Burger",
                category = "food",
                description = "A delicious grilled burger.",
                time = 15,
                materials = {
                    { name = "raw_meat", label = "Raw Meat", quantity = 1 },
                    { name = "bread", label = "Bread", quantity = 1 }
                }
            },
        },
    }
}