en-crafting lets survivors turn scavenged junk into useful gear. Every recipe belongs to a station:
- By hand: anywhere, default key
J. - Workbench: any world prop with a workbench model, plus benches this resource spawns.
- Campfire: fire props. Standing near one also warms you.
The crafting page lists the station's recipes. For each one it shows the ingredients (and how many you have), tools you need but keep, blueprint requirements, skill or level locks, and how many you can afford. Crafting runs a progress bar with the station's animation. Ingredients are only taken when it finishes, and skill bonuses make crafting faster and sometimes save materials.
At a glance
| Depends on | en-core, en-ui, en-inventory |
| Start after | All of the above |
| Database tables | None (recipes are config; placed benches are stored by the content system) |
| Config files | config/shared.lua |
| Key binds | en_crafting_hand (J) |
| In-game builder | Content kind bench in en-admin |
How it works
Stations and benches
A station is defined in Config.stations. Any prop whose model is in a station's models list acts as that station, targeted through encore.target.addModel. Benches listed in Config.benches, or placed with en-admin, are spawned client-side as frozen props within 60 m.
When a station has heat = true, standing within 4 m of one of its props sets LocalPlayer.state.nearHeat, which en-weathersync uses to warm you.
Crafting time
duration = recipe.time * amount * (1 - math.min(0.6, craftSpeedBonus))Material refunds
When a craft finishes, each ingredient unit has a min(0.9, craftRefund bonus) chance of being saved.
Server checks
On finish, the server checks everything again: you're still within distance + 2 of the station, at least 90% of the time has passed, and you have the ingredients, tools, blueprint and room to carry the result. If you drop ingredients mid-craft, the craft fails.
Bonuses and XP come from en-skills.
Configuration
| Key | Default | What it does |
|---|---|---|
Config.keys.hand | 'J' | Hand-crafting key bind |
Config.stations | hand, workbench, campfire | Station definitions: label, icon, models (props that act as this station), anim = { dict, clip, flag }, heat (bool) |
Config.benches | 2 workbenches | Props this resource spawns: { id?, station, model, coords = vec4 }. id defaults to config:<index> |
Config.distance | 2.5 | Reach to a station |
Config.maxBatch | 10 | Most of one recipe per craft |
Config.recipes | 9 recipes | Recipe definitions |
Recipe fields
| Field | What it does |
|---|---|
id | Unique id |
station | Key in Config.stations |
result | { item, count } |
ingredients | { { item, count }, ... }, taken on finish |
tools | { 'item', ... }, needed but kept |
blueprint | Item that must be carried; kept |
time | Milliseconds for one, before the speed bonus |
requires | { skill = 'name', level = n } or { level = n } (character level) |
xp | { [skill] = amount } per craft, multiplied by the amount crafted |
category | List grouping; defaults to the result item's category |
Adding a station and recipes
Config.stations.stove = {
label = 'Camp Stove', icon = 'temperature', heat = true,
models = { 'prop_cooker_03' },
anim = { dict = 'amb@prop_human_bbq@male@idle_a', clip = 'idle_b', flag = 1 },
}
Config.recipes[#Config.recipes + 1] = {
id = 'cook_beans', station = 'campfire', result = { item = 'canned_beans', count = 1 },
ingredients = { { item = 'garbage', count = 1 } }, time = 6000, xp = { crafting = 1 },
}
Config.recipes[#Config.recipes + 1] = {
id = 'ammo_shotgun', station = 'workbench', result = { item = 'ammo_shotgun', count = 6 },
ingredients = { { item = 'scrapmetal', count = 4 }, { item = 'garbage', count = 2 } },
tools = { 'WEAPON_CROWBAR' }, blueprint = 'blueprint_ammo',
time = 11000, requires = { skill = 'crafting', level = 4 }, xp = { crafting = 10 },
}Every item a recipe uses must exist in en-inventory's item list; see Add an item.
A placed bench's model must be one of its station's models. A blank model uses the first one, and anything else is rejected. Stations with no models, such as hand, can't be placed.
Exports
All exports are server-side. There are no client exports.
| Export | Arguments | Returns |
|---|---|---|
GetRecipe | id | The recipe table from config, or nil |
IsCrafting | source | boolean |
BuilderList | kind | For 'bench': { id, label, subtitle, coords, placed, inConfig }[] (label is the station label, subtitle the model) |
BuilderGet | kind, id | { station, model, coords } |
BuilderValidate | kind, id, data | ok, err |
BuilderSchema | kind | Fields station, model, coords |
BuilderTemplate | kind | { station = 'workbench', model = 'prop_tool_bench02' } |
Events
| Event | Side | Payload |
|---|---|---|
en-crafting:server:crafted | Server-local | source, recipeId, amount |
en-quests uses this event for craft objectives.
State bags
| Key | Meaning |
|---|---|
nearHeat | Player state, replicated. true within 4 m of a prop of a heat = true station |
Examples
Reward a milestone for crafting ammunition:
AddEventHandler('en-crafting:server:crafted', function(source, recipeId, amount)
local recipe = exports['en-crafting']:GetRecipe(recipeId)
if recipe and recipe.result.item == 'ammo_shotgun' then
exports['en-core']:AddXP(source, amount * 5)
end
end)Don't let a player teleport or start a job while crafting:
if exports['en-crafting']:IsCrafting(source) then
return false, 'Finish crafting first.'
endRelated
- en-skills
- en-properties (workbench and campfire pieces work as stations)
- en-weathersync
- Add an item