Skip to content
RustPluginGenerator

CanChangeGrade

CanChangeGrade is called when a player tries to change the grade of a building block with a hammer, before the upgrade cost and permission checks run.

Signature
object CanChangeGrade(BasePlayer player, BuildingBlock buildingBlock, BuildingGrade.Enum iGrade, ulong iSkin)

Parameters

Hook parameters
ParameterTypeDescription
playerBasePlayerThe BasePlayer requesting the grade change. Always the player who owns the hammer action, so use it for permission and admin checks.
buildingBlockBuildingBlockThe BuildingBlock whose grade is about to change. Use buildingBlock.grade for the current grade and buildingBlock.buildingID or GetBuildingPrivilege() to key rules per structure.
iGradeBuildingGrade.EnumThe BuildingGrade.Enum the player is trying to change to (Twigs, Wood, Stone, Metal, TopTier). Declare it as BuildingGrade.Enum so Oxide can match it.
iSkinulongThe skin id applied to the resulting building grade. 0 means the default appearance; non-zero values come from grade skins.

Return value

Return false to deny the grade change outright; the game never runs its own permission and cost checks. Return true to allow the change without running those vanilla checks, and return null (or nothing that is a bool) to let the game handle it normally. Any non-bool return value is ignored.

How it works

Oxide fires this hook from BuildingBlock.CanChangeToGrade, which the game calls when a player uses a building hammer (or the grade picker) to turn a block into another grade or skin. Because the call happens inside the grade check, it runs before the game decides whether the player can afford the upgrade, so blocking here prevents the whole upgrade flow including resource consumption.

The parameters cover everything you need for rules: player is the requester, buildingBlock is the target, iGrade is the destination grade and iSkin the destination skin id. Compare iGrade against buildingBlock.grade to tell upgrades from downgrades, and check buildingBlock.GetBuildingPrivilege() or buildingBlock.buildingID to apply rules per base or team.

Declaring player as a more specific type does not help here since it is already BasePlayer. The returned boolean controls the outcome, so always return a real value when you want to decide, and null to fall through to vanilla checks. Running cost checks, chat messages or effect spawns from this hook is fine; it only fires on player grade actions, not per tick.

Example plugin: Restrict grade skins to a permission

GradeSkinPermission.cs
using System.Collections.Generic;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Grade Skin Permission", "RustPluginGenerator", "1.0.0")]
    [Description("Requires a permission for non-default building grade skins")]
    public class GradeSkinPermission : RustPlugin
    {
        private const string PermUse = "gradeskinpermission.use";

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

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["NoSkinPermission"] = "You do not have permission to use that building skin."
            }, this);
        }

        private string Msg(string key, string userId = null) => lang.GetMessage(key, this, userId);

        private object CanChangeGrade(BasePlayer player, BuildingBlock buildingBlock, BuildingGrade.Enum grade, ulong skin)
        {
            if (player == null || buildingBlock == null)
                return null;

            if (skin == 0)
                return null;

            if (permission.UserHasPermission(player.UserIDString, PermUse))
                return null;

            player.ChatMessage(Msg("NoSkinPermission", player.UserIDString));
            return false;
        }
    }
}

The plugin adds a gradeskinpermission.use permission and intercepts every grade change attempt. If the requested skin id is not zero and the player lacks the permission, the hook returns false and the player receives the NoSkinPermission message; all other attempts return null so vanilla upgrade rules stay intact. The destination skin and grade are read straight from the hook arguments, so no extra lookups are needed, and the permission is registered in Init before any player can use a hammer.

Common use cases

  • Paid or permission-gated skins

    Block skin ids the player did not unlock while allowing the default skin. Combine with an economy plugin call to charge for premium skins before approving the change.

  • No downgrades in raid zones

    Compare the requested grade with buildingBlock.grade and deny downgrades while a raid or event is active, forcing players to keep the current protection level.

  • Grade lock per privilege

    Check buildingBlock.GetBuildingPrivilege() and only let players who are authorized on the cupboard change grades, even if they have hammer build permission.

Pitfalls

  • Returning true skips vanilla checks

    Returning true bypasses the game's own affordability and permission test, so a player low on resources could still upgrade. Return null when you only want to add a rule on top of the defaults.

  • Fires for every block of a multi-block structure

    A large base upgrade invokes the hook once per block. Keep the body cheap and avoid sending chat messages unless a rule actually denies the change.

  • Skin and grade are separate arguments

    A block can be upgraded to the same grade with a different skin. Do not assume iGrade differs from buildingBlock.grade just because the hook fired.

Build a plugin with CanChangeGrade

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

Prompt: Paid or permission-gated skins using the CanChangeGrade 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 CanChangeGrade

Generate