Skip to content
RustPluginGenerator

OnItemCraft

OnItemCraft is called when a player starts crafting an item in a workbench or crafting queue, and again when an industrial crafter begins running a job.

Signature
object OnItemCraft(ItemCraftTask itemCraftTask, BasePlayer owner, Item fromTempBlueprint)

Parameters

Hook parameters
ParameterTypeDescription
itemCraftTaskItemCraftTaskThe craft task being started. Use its blueprint (itemCraftTask.blueprint) to read the item definition, and itemCraftTask.amount for the requested quantity. On the industrial path this argument is the IndustrialCrafter entity instead.
ownerBasePlayerThe player who started the craft. Null on the industrial overload, where the crafter entity is passed as the first argument instead. Use it for permission checks and feedback.
fromTempBlueprintItemThe temporary blueprint item created from a reusable blueprint, or null when the player crafts from a normal learned blueprint. Available only in the ItemCrafter.CraftItem call.

Return value

Return null to let crafting proceed normally. Returning true (any bool) on the player path aborts the craft before it is queued. On the industrial path, any non-null return stops that job loop.

How it works

The hook fires from two places. The first is ItemCrafter.CraftItem, run when a player submits a craft task: the arguments are the ItemCraftTask (blueprint, amount, takenItems), the crafting owner, and fromTempBlueprint when the player used a temporary blueprint item. The second is IndustrialCrafter.RunJob, where the first argument is the IndustrialCrafter entity and the second is the ItemBlueprint it is about to run.

To scope your code, declare parameters as a narrower type. owner typed as BasePlayer is safe on the player path but the industrial call passes an IndustrialCrafter there, so Oxide skips it. Declaring the first parameter as ItemCraftTask limits your method to player crafts; declaring it as IndustrialCrafter limits it to industrial jobs.

Cancelling a craft prevents the task from being queued, but do not assume items were already consumed when the hook runs. Check itemCraftTask.blueprint?.targetItem?.displayName.english before comparing names.

Other signatures

Oxide also calls OnItemCraft from other places in the game with these parameter types. Declare the overload you need, or several:

  • object OnItemCraft(IndustrialCrafter industrialCrafter, ItemBlueprint blueprint)

Example plugin: Restrict crafting by permission and blueprint

CraftPermissionGate.cs
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;

namespace Oxide.Plugins
{
    [Info("Craft Permission Gate", "RustPluginGenerator", "1.0.0")]
    [Description("Blocks configured blueprints from being crafted unless the player has a bypass permission.")]
    public class CraftPermissionGate : RustPlugin
    {
        private const string PermBypass = "craftpermissiongate.bypass";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Blocked blueprint names (display names)")]
            public List<string> BlockedBlueprints { get; set; } = new List<string> { "Timed Explosive Charge", "Rocket" };
        }

        protected override void LoadDefaultConfig() => config = new PluginConfig();

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<PluginConfig>();
                if (config == null) throw new Exception();
            }
            catch
            {
                PrintWarning("Configuration file is invalid, using defaults");
                LoadDefaultConfig();
            }
            SaveConfig();
        }

        protected override void SaveConfig() => Config.WriteObject(config);

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["Blocked"] = "You are not allowed to craft {0} on this server."
            }, this);
        }

        private string Msg(string key, string userId = null, params object[] args) =>
            string.Format(lang.GetMessage(key, this, userId), args);

        private void Init()
        {
            permission.RegisterPermission(PermBypass, this);
        }

        private object OnItemCraft(ItemCraftTask itemCraftTask, BasePlayer owner, Item fromTempBlueprint)
        {
            if (itemCraftTask == null || owner == null) return null;

            ItemDefinition target = itemCraftTask.blueprint?.targetItem;
            if (target == null) return null;

            if (permission.UserHasPermission(owner.UserIDString, PermBypass)) return null;

            string name = target.displayName?.english;
            if (string.IsNullOrEmpty(name)) return null;

            foreach (string blocked in config.BlockedBlueprints)
            {
                if (string.IsNullOrEmpty(blocked)) continue;
                if (!string.Equals(blocked.Trim(), name, StringComparison.OrdinalIgnoreCase)) continue;

                owner.ChatMessage(Msg("Blocked", owner.UserIDString, name));
                return true;
            }

            return null;
        }
    }
}

The plugin reads BlockedBlueprints from the config and refuses player crafts of those items unless the player holds craftpermissiongate.bypass. The hook declares ItemCraftTask as its first parameter, so industrial crafters are ignored. When a match is found it sends a lang message to the owner and returns true, which stops the task from being queued. Comparisons are done case-insensitively on the blueprint target's displayName.english, and list entries are normalised at startup so admins can write names freely in oxide/config.

Common use cases

  • Lock expensive items behind permissions

    Return true for rockets, C4 or turrets when the player lacks a VIP permission so only paying groups can craft them. Players get a chat message explaining why the craft was refused.

  • Disable a craft while a plugin is busy

    Pair the hook with a cooldown or team limit: refuse the craft if the player already has too many queued tasks of that type, keeping workbench queues sane during raids.

  • Log what players craft

    Record blueprint name, amount and owner into oxide/data for economy or audit plugins. Do not call Puts here; it fires on every craft submission and would spam the console.

Pitfalls

  • Two different signatures share the hook name

    On the industrial path the first argument is an IndustrialCrafter and owner is null. If you read owner.UserIDString without narrowing the signature, an industrial job will throw a null reference. Declare ItemCraftTask to stay on the player path.

  • Returning false still aborts the craft

    The patcher only checks that the return value is a bool. Returning false does not mean allow; it stops the craft exactly like true. Use null to allow.

  • The hook runs before the queue confirms

    It fires when the task is submitted, which can include items the player later removes or when the queue is full. Do not deduct currency or items in a way that cannot be rolled back if the craft fails.

Plugin recipes that use OnItemCraft

Build a plugin with OnItemCraft

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Lock expensive items behind permissions using the OnItemCraft hook, with a config file and a permission
Generate this plugin

Edit the prompt on the next screen. 2 free plugins a month, no card.

Last updated Oct 26, 2026. Found a mistake? Email support@rustplugingenerator.com.

Build a plugin with OnItemCraft

Generate