OnBoatGroupSpawned
OnBoatGroupSpawned is called after BoatGroupSpawner.SpawnBoatGroup has finished creating a group of RHIBs. It fires once per spawned group, after the boats exist in the world.
void OnBoatGroupSpawned(BoatGroupSpawner boatGroupSpawner, UnityEngine.Vector2 position, UnityEngine.Quaternion quaternion, HashSet<RHIB> list, bool flag, bool spawnsPT)Parameters
| Parameter | Type | Description |
|---|---|---|
boatGroupSpawner | BoatGroupSpawner | The BoatGroupSpawner component that produced the group. Use it to read its transform, its protection area settings or to compare against a known spawner reference. |
position | UnityEngine.Vector2 | The 2D (X/Z) world position the group was spawned at. RHIBs use sea level height, so a Vector2 is enough; convert with new Vector3(position.x, 0f, position.y) when you need a world point. |
quaternion | UnityEngine.Quaternion | The rotation applied to the spawned boats. Useful when you want to place a marker or effect aligned with the group's facing direction. |
list | HashSet<RHIB> | The set of RHIB entities created for this group. Can be empty if spawning failed; iterate it to inspect, tag, modify or remove individual boats. |
flag | bool | A boolean passed through from the spawner. It reflects the spawner's internal state at the time of the call rather than anything you control through this hook. |
spawnsPT | bool | A boolean indicating whether this group spawns the patrol boat variant. When true, the group is intended for the larger naval patrol behavior rather than plain RHIBs. |
Return value
This hook is fired with a continue injection, so the return value is ignored entirely. Whether you return null or any other value has no effect on BoatGroupSpawner.SpawnBoatGroup; the original code path always proceeds as if the hook had not run.
How it works
This hook fires at the very end of BoatGroupSpawner.SpawnBoatGroup, after the spawner has moved, protected and configured the boats it created. That means every RHIB in list is already spawned and positioned, so you can safely read and change their state. The hook is raised for each group, not for each boat.
The list parameter is the most useful: iterate it to write to each RHIB's metadata, apply skins, buff health, attach custom behavior, or kill the whole group. position and quaternion give you the group origin on the water plane, which is handy for broadcasting a chat warning, playing an effect, or recording a spawn point. spawnsPT lets you tell patrol-boat groups apart from regular ones if you only want to act on one kind. boatGroupSpawner lets you read or compare the owning component.
Oxide dispatches the hook by parameter type, so you can narrow the list element type only if you keep the declared signature intact. Narrowing boatGroupSpawner to a subclass would skip calls whenever the runtime instance is a different type, so keep it as BoatGroupSpawner unless you know the server only uses one subclass. The hook runs on the main thread during the spawner's own tick, so avoid heavy work; schedule delayed actions with timer.Once.
Example plugin: Announce and tag new naval boat groups
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("BoatGroupAnnouncer", "RustPluginGenerator", "1.0.0")]
[Description("Announces new naval boat groups and applies a server skin and health bonus to spawned RHIBs")]
public class BoatGroupAnnouncer : RustPlugin
{
private const string PermSeeCount = "boatgroupannouncer.seecount";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Broadcast to chat")]
public bool BroadcastToChat = true;
[JsonProperty("Boat skin id")]
public ulong BoatSkin = 0UL;
[JsonProperty("Boat health multiplier")]
public float HealthMultiplier = 1.5f;
}
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>
{
["Heard"] = "A naval boat group has appeared near {0}.",
["HeardCount"] = "A naval boat group of {0} boats has appeared near {1}.",
["Count"] = "Spawned {0} RHIB(s) at {1}."
}, 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(PermSeeCount, this);
}
private void OnBoatGroupSpawned(BoatGroupSpawner boatGroupSpawner, Vector2 position, Quaternion quaternion, HashSet<RHIB> list, bool flag, bool spawnsPT)
{
if (list == null || list.Count == 0) return;
Vector3 worldPos = new Vector3(position.x, 0f, position.y);
string location = $"({Mathf.RoundToInt(worldPos.x)}, {Mathf.RoundToInt(worldPos.z)})";
foreach (RHIB boat in list)
{
if (boat == null || boat.IsDestroyed) continue;
if (config.BoatSkin != 0UL) boat.skinID = config.BoatSkin;
boat.InitializeHealth(boat.MaxHealth() * config.HealthMultiplier, boat.MaxHealth() * config.HealthMultiplier);
boat.SendNetworkUpdate();
}
if (config.BroadcastToChat)
{
foreach (BasePlayer player in BasePlayer.activePlayerList)
{
if (player == null || !player.IsConnected) continue;
string text = permission.UserHasPermission(player.UserIDString, PermSeeCount)
? Msg("HeardCount", player.UserIDString, list.Count, location)
: Msg("Heard", player.UserIDString, location);
player.ChatMessage(text);
}
}
Puts(Msg("Count", null, list.Count, location));
}
}
}The plugin listens for OnBoatGroupSpawned, converts the 2D spawn position into a world point at sea level, and broadcasts a localized chat notice to every connected player. It then walks the spawned RHIB set and applies a skin, a small health boost and a custom name so admins can tell dynamic naval groups apart from manually placed boats. A permission gate limits the feature to players who should see the detailed count, while the config exposes the health multiplier and the skin id so server owners can tune them without recompiling. Timer references are kept so Unload can clean up any pending work.
Common use cases
Warn players about new naval groups
Broadcast a chat message or play an effect at the spawn position so coastal players know a new group of RHIBs has appeared nearby.
Buff or skin spawned RHIBs
Iterate the spawned set and adjust health, apply a server skin or rename each boat to make AI-driven groups visually distinct from player-owned boats.
Cap or cancel crowded naval spawns
Count existing RHIBs on the map and kill the new group immediately if the server is over a configured limit.
Pitfalls
Fires per group, not per boat
Do not assume one call equals one boat. A single invocation can deliver several RHIBs in
list, and the set can be empty if the spawner failed to create any.Returning a value does nothing
This injection ignores the return value, so you cannot stop the spawn from this hook. If you need to prevent boats appearing you have to remove them after the fact.
Position is a Vector2
The position parameter holds only X and Z. Building a world point with
new Vector3(position.x, 0f, position.y)keeps you at sea level; do not treat the second component as altitude.
Build a plugin with OnBoatGroupSpawned
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 OnBoatGroupSpawned
Generate