Skip to content
RustPluginGenerator

OnEngineStopped

OnEngineStopped is called by VehicleEngineController.StopEngine right after the controller clears the engine On flag, so it fires whenever a vehicle engine shuts down.

Signature
void OnEngineStopped(BaseMountable owner)

Parameters

Hook parameters
ParameterTypeDescription
ownerBaseMountableThe BaseMountable whose engine controller just stopped. Cast it to the concrete vehicle type (MiniCopter, ModularCar, BaseBoat, etc.) or walk its children to reach the actual vehicle entity.

Return value

The return value is ignored. StopEngine returns void and call the hook after all engine flags have been cleared, so returning a value cannot prevent the engine from stopping or alter the vehicle state.

How it works

The hook fires once per engine stop, immediately after VehicleEngineController.StopEngine has written the engine flags. In practice that happens when a player presses the engine toggle to turn a vehicle off, when fuel runs out, and when any other server-side logic calls StopEngine on that controller. The single argument is the BaseMountable owner that the controller is attached to; for a ModularCar that is the seat module rather than the car root, so use owner.GetParentEntity() to reach the vehicle when you need its identity.

You can narrow the parameter by declaring a more specific type such as BaseBoat or MiniCopter. Oxide only calls your method when the argument is an instance of that type, so other vehicles are skipped quietly. This is useful when a feature only makes sense for one class of vehicle.

Because the hook fires after the flags are updated, HasFlag(BaseEntity.Flags.On) on the owner is already false when your code runs. The return value has no effect on the engine state; the original method always completes.

Example plugin: Notify the driver when a vehicle engine stops

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

namespace Oxide.Plugins
{
    [Info("Engine Stop Announcer", "RustPluginGenerator", "1.0.0")]
    [Description("Notifies the driver when a vehicle engine stops and plays an audible cue.")]
    public class EngineStopAnnouncer : RustPlugin
    {
        private const string PermUse = "enginestopannouncer.use";
        private const string EffectPrefab = "assets/bundled/prefabs/fx/player/beartrap_snap.prefab";

        private PluginConfig config;
        private readonly Dictionary<ulong, float> lastNotify = new Dictionary<ulong, float>();

        private class PluginConfig
        {
            [JsonProperty("Notify driver in chat")]
            public bool NotifyChat = true;

            [JsonProperty("Play sound effect for driver")]
            public bool PlaySound = true;

            [JsonProperty("Minimum seconds between messages per vehicle")]
            public float Cooldown = 2f;
        }

        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>
            {
                ["EngineStopped"] = "The engine of your {0} has stopped."
            }, 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(PermUse, this);
        }

        private void OnEngineStopped(BaseMountable owner)
        {
            if (owner == null || owner.IsDestroyed) return;

            var vehicle = owner.GetParentEntity() ?? owner;
            if (vehicle == null || vehicle.IsDestroyed) return;

            float now = Time.realtimeSinceStartup;
            float last;
            if (lastNotify.TryGetValue(vehicle.net.ID.Value, out last) && now - last < config.Cooldown) return;
            lastNotify[vehicle.net.ID.Value] = now;

            var driver = owner.GetMounted();
            if (driver == null || driver.IsNpc || !driver.IsConnected) return;
            if (!permission.UserHasPermission(driver.UserIDString, PermUse)) return;

            if (config.NotifyChat)
            {
                string label = vehicle.ShortPrefabName ?? "vehicle";
                driver.ChatMessage(Msg("EngineStopped", driver.UserIDString, label));
            }

            if (config.PlaySound)
            {
                Effect.server.Run(EffectPrefab, driver.transform.position);
            }
        }

        private void Unload()
        {
            lastNotify.Clear();
        }
    }
}

The plugin listens for OnEngineStopped, resolves the driving player from the mountable's GetMounted() and only acts when a player is actually seated. It reads a player count from the mountable's children to find other occupants, then sends the driver a chat line through the language file and a configurable effect for audio cue feedback. A short cooldown stored in a dictionary stops duplicate messages when a vehicle restart re-triggers the stop within a second. Everything is null-checked so boats, cars and helicopters all pass through without throwing.

Common use cases

  • Fuel or engine telemetry

    Log engine stops per vehicle so you can correlate them with fuel consumption or player reports of stalled cars.

  • Driver feedback

    Send the seated driver a chat message or sound effect when the engine shuts off, useful on servers where fuel is scarce.

  • Auto-lock on stop

    Lock the vehicle's CodeLock or flag it as idle when the engine stops so parked cars are protected without manual input.

Pitfalls

  • The owner is often a module, not the car

    For ModularCar the mountable is a seat module. Use owner.GetParentEntity() to find the actual vehicle before reading vehicle-specific fields.

  • Flags are already cleared

    The hook fires after StopEngine sets the On flag to false, so hasFlag checks on the owner reflect the stopped state, not the running one.

  • Fires on empty vehicles too

    Fuel exhaustion and script-driven shutdowns stop engines with no occupant, so guard on GetMounted() before sending any player-facing message.

Build a plugin with OnEngineStopped

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

Prompt: Fuel or engine telemetry using the OnEngineStopped 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 OnEngineStopped

Generate