Skip to content
RustPluginGenerator

OnEngineLoadoutRefresh

OnEngineLoadoutRefresh is called when an EngineStorage module recalculates its loadout stats (usable state, acceleration, top speed and fuel economy boosts) after its inventory changes. Returning a non-null value skips the game's default recalculation.

Signature
object OnEngineLoadoutRefresh(Rust.Modular.EngineStorage engineStorage)

Parameters

Hook parameters
ParameterTypeDescription
engineStorageRust.Modular.EngineStorageThe EngineStorage module whose loadout data is being recalculated. Use it to inspect the module's inventory (container items, slots, broken items) and the modular car it is attached to via GetParentEntity().

Return value

Return null to let the game run its normal recalculation of isUsable and the acceleration, top speed and fuel economy boost percentages. Return any non-null object to skip that default block entirely; the module is left with whatever values it currently holds.

How it works

This hook fires inside Rust.Modular.EngineStorage.RefreshLoadoutData, the method that derives an engine module's stats from the items in its container. The engine layout typically refreshes when parts are inserted or removed, when an item inside breaks, or when the module is moved onto a car. The hook runs before the vanilla computation, so it sees the current container contents but not the freshly computed results.

The only parameter is the EngineStorage. Read engineStorage.inventory to inspect itemList and capacity, check item.isBroken and each item's info, and walk to the parent vehicle with GetParentEntity() when you need to know which car owns the engine. There is no narrower type to declare here; EngineStorage is already specific.

Because the return value is checked for validity, returning a non-null object prevents isUsable and the three boost percentages from being recalculated by the game. This is a deliberate override, not a way to edit values in place: the vanilla fields are simply left as they were. Use it only when you fully manage those fields yourself, otherwise return null.

Example plugin: Log engine loadout changes and warn on broken parts

EngineLoadoutMonitor.cs
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Engine Loadout Monitor", "RustPluginGenerator", "1.0.0")]
    [Description("Reports engine module loadout refreshes and warns drivers about broken parts")]
    public class EngineLoadoutMonitor : RustPlugin
    {
        private const string PermAdmin = "engineloadoutmonitor.admin";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Broken parts warning threshold")]
            public int BrokenThreshold = 2;

            [JsonProperty("Broadcast refresh summary to admins")]
            public bool LogToAdmins = true;
        }

        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>
            {
                ["BrokenWarning"] = "Your engine has {0} broken part(s) and may stop working. Repair them soon.",
                ["AdminSummary"] = "[Engine] {0} items, {1} broken, usable: {2}"
            }, 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(PermAdmin, this);
        }

        private object OnEngineLoadoutRefresh(Rust.Modular.EngineStorage engineStorage)
        {
            if (engineStorage == null) return null;

            var inventory = engineStorage.inventory;
            if (inventory == null || inventory.itemList == null) return null;

            int total = inventory.itemList.Count;
            int broken = 0;
            foreach (var item in inventory.itemList)
            {
                if (item != null && item.isBroken) broken++;
            }

            bool usable = broken == 0;

            var car = engineStorage.GetParentEntity() as ModularCar;
            var driver = car?.GetDriver();

            if (config.LogToAdmins)
            {
                string summary = Msg("AdminSummary", null, total, broken, usable);
                foreach (var player in BasePlayer.activePlayerList)
                {
                    if (player != null && permission.UserHasPermission(player.UserIDString, PermAdmin))
                        player.ChatMessage(summary);
                }
            }

            if (driver != null && config.BrokenThreshold > 0 && broken >= config.BrokenThreshold)
                driver.ChatMessage(Msg("BrokenWarning", driver.UserIDString, broken));

            return null;
        }
    }
}

The plugin watches engine module loadout refreshes and reports a summary to online players with the engineloadoutmonitor.admin permission. On each call it reads the module's inventory, counts the items in itemList, counts how many are broken and computes whether the module is usable. It also resolves the parent vehicle and its driver, and if the configurable BrokenThreshold is greater than zero and the broken count meets or exceeds it, it sends a chat warning to the driver. All messages go through the language file, and the hook always returns null so vanilla stat calculation is untouched. This is useful for admins tracking engine failures or building a diagnostics feed without changing gameplay.

Common use cases

  • Admin diagnostics

    Print a short summary of every engine refresh to the console so admins can see why a modular car lost performance.

  • Broken-part alerts

    Detect when too many engine parts are broken and notify the driver before the module becomes unusable.

  • Custom stat override

    Return non-null after setting your own boost values so your server rules replace the stock engine calculations for tuned modules.

Pitfalls

  • Returning non-null skips vanilla stats

    Any object you return stops the default recalculation, so unless you set isUsable and the boost fields yourself the module keeps its old values.

  • Fires frequently

    The layout can refresh repeatedly as items change, so avoid heavy work or chat spam inside the hook and gate any messaging behind a cooldown or config.

  • Container may be empty or null

    Always null-check engineStorage, its inventory and itemList before iterating, since a module can be freshly spawned without items.

Build a plugin with OnEngineLoadoutRefresh

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

Prompt: Admin diagnostics using the OnEngineLoadoutRefresh 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 OnEngineLoadoutRefresh

Generate