OnEntityGroundMissing
OnEntityGroundMissing is called when a DestroyOnGroundMissing component notices that the entity lost the ground or foundation supporting it, right before the game kills or drops that entity.
object OnEntityGroundMissing(BaseEntity entity)Parameters
| Parameter | Type | Description |
|---|---|---|
entity | BaseEntity | The BaseEntity whose supporting ground has disappeared, rebuilt from the object reference of the DestroyOnGroundMissing MonoBehaviour. Cast it to a more specific type (BuildingBlock, DroppedItemContainer, BaseCombatEntity) before reading component-specific data. |
Return value
Returning null (or nothing, in a void method) lets the original OnGroundMissing body run, which kills the entity or otherwise handles the missing support with the standard stability and logging logic. Returning any non-null value skips that body entirely, so the entity is left untouched and you become responsible for it (killing it, dropping its contents, moving it, or letting stability handle it later).
How it works
The hook fires from DestroyOnGroundMissing.OnGroundMissing, the routine the game runs when the block, foundation or terrain beneath an entity is gone. The component is common on deployables, dropped items and structures, so the call typically follows a building block being destroyed or decaying away. The only argument is the affected BaseEntity, which is resolved from the GameObject and can be null-checked and cast: as BuildingBlock for structures, as DroppedItemContainer or as BaseCombatEntity for loot and combat entities. Declaring the parameter as a narrower type such as BaseCombatEntity works with Oxide's dispatch: calls where the entity is a different type are skipped, but you then lose visibility of plain structures. Because the same hook fires for every entity losing its base, guard on entity.IsDestroyed and filter by prefab or owner when you only care about a specific kind of object. You cannot stop the ground from being missing; you can only decide what happens to the entity instead of the default kill or fall handling.
Example plugin: Save dropped loot boxes when their ground vanishes
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Ground Missing Loot Saver", "RustPluginGenerator", "1.0.0")]
[Description("Drops contained loot on the ground when a dropped container loses its support instead of letting it be destroyed.")]
public class GroundMissingLootSaver : RustPlugin
{
private const string PermUse = "groundmissinglootsaver.use";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Only rescue for permitted players")]
public bool RequirePermission { get; set; } = true;
[JsonProperty("Notify owner on rescue")]
public bool NotifyOwner { get; set; } = 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>
{
["Rescued"] = "Your ground loot at {0} was saved from collapsing ground.",
["RescuedMany"] = "{0} ground loot containers were rescued from collapsing ground."
}, 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 object OnEntityGroundMissing(BaseEntity entity)
{
if (entity == null || entity.IsDestroyed) return null;
DroppedItemContainer container = entity as DroppedItemContainer;
if (container == null || container.inventory == null) return null;
if (config.RequirePermission && container.OwnerID != 0UL)
{
string id = container.OwnerID.ToString();
if (!permission.UserHasPermission(id, PermUse)) return null;
}
Vector3 position = entity.transform.position;
List<Item> items = container.inventory.itemList;
if (items != null)
{
for (int i = items.Count - 1; i >= 0; i--)
{
Item item = items[i];
if (item == null) continue;
item.RemoveFromContainer();
item.Drop(position + new Vector3(0f, 0.25f, 0f), Vector3.up * 0.1f);
}
}
NotifyOwner(container.OwnerID, position);
entity.Kill();
return true;
}
private void NotifyOwner(ulong ownerId, Vector3 position)
{
if (!config.NotifyOwner || ownerId == 0UL) return;
BasePlayer owner = BasePlayer.FindByID(ownerId);
if (owner == null || !owner.IsConnected) return;
owner.ChatMessage(Msg("Rescued", owner.UserIDString, position.ToString("0")));
}
}
}The plugin watches OnEntityGroundMissing and only acts on DroppedItemContainer entities. Instead of letting the default path destroy the bag, it cancels the routine by returning true, then reads entity.OwnerID, the entity position and the serialized container inventory. The items are re-created on the ground with Drop at the entity position, so the loot survives the collapse for players to pick up, and the original container is removed with Kill(). A config flag toggles the behaviour, a permission restricts it to specific players and a chat message notifies the owner when they are online and connected.
Common use cases
Preserve loot from collapsing ground
Turn lost supports into a second chance for owners: move contained items to the ground instead of letting the normal destruction path remove the container outright.
Relocate deployables instead of killing them
When a deployable's foundation decays, teleport it to a safe height or to a stored position before returning non-null to suppress the default missing-ground kill.
Audit stability failures
Track which entity types most often lose their ground and store counts in the Oxide data folder, so admins can tune decay or foundation rules on their map.
Pitfalls
Returning non-null for everything
Cancelling the routine for every entity disables the game's own stability cleanup, so orphaned structures, bags and items accumulate. Always filter by type or prefab before suppressing the default path.
Forgetting entity can be null or destroyed
The call originates from a Unity message and the entity resolved from the GameObject can already be null or marked destroyed. Null-check
entityand its members before reading position or inventory.Assuming the hook fires only for player structures
Any object with a DestroyOnGroundMissing component triggers it, including NPC-related and world-spawned entities. Check
OwnerID, category or prefab name if your logic is meant for player buildings only.
Build a plugin with OnEntityGroundMissing
Describe what should happen and get a compiled plugin that uses this hook.
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 OnEntityGroundMissing
Generate