OnBoatPathGenerate
OnBoatPathGenerate is called when the game builds the default ocean patrol path used by AI-driven boats, before the vanilla path points are generated. Returning a list of Vector3 replaces the generated route.
object OnBoatPathGenerate()Return value
Return null to let the vanilla path generator run normally. Return a List<UnityEngine.Vector3> and the method returns that list immediately, skipping the built-in shore distance and water depth logic. Any other return type is ignored and vanilla generation proceeds.
How it works
The hook fires inside BaseBoat.GenerateOceanPatrolPath, the static method Rust uses to produce a patrol route for boats that wander the ocean (for example the tugboat/cargo-style AI boats that roam open water). The call happens at the very top of the method, before any shore-distance or water-depth sampling runs, so it effectively asks whether a plugin wants to supply its own route.
There are no parameters. The method is a static factory with default arguments (minDistanceFromShore = 50f, minWaterDepth = 8f) that shape the vanilla path; those values are not exposed to the hook, so a replacement path must do its own placement reasoning.
Anything returned must be a List<UnityEngine.Vector3>. Returning null lets the vanilla generator run and produce the standard path. Returning a list skips the vanilla generation entirely and uses your points, so keep every point above water and inside terrain bounds to avoid boats driving onto land or under the map.
Because the path is regenerated per boat, keep the returned list small and cheap to build. Do not do heavy terrain queries or allocate large collections here on every call.
Example plugin: Send AI boats along a custom patrol route
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Boat Patrol Route", "RustPluginGenerator", "1.0.0")]
[Description("Replaces the vanilla AI boat patrol path with a configurable waypoint route")]
public class BoatPatrolRoute : RustPlugin
{
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Enable custom route")]
public bool Enabled = true;
[JsonProperty("Minimum clearance above water (meters)")]
public float WaterClearance = 2f;
[JsonProperty("Waypoints (x, y, z)")]
public List<Vector3> Waypoints = new List<Vector3>
{
new Vector3(-400f, 0f, -400f),
new Vector3(400f, 0f, -400f),
new Vector3(400f, 0f, 400f),
new Vector3(-400f, 0f, 400f)
};
}
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);
private object OnBoatPathGenerate()
{
if (config == null || !config.Enabled || config.Waypoints == null || config.Waypoints.Count < 2)
return null;
var path = new List<Vector3>(config.Waypoints.Count);
foreach (var point in config.Waypoints)
{
float ground = TerrainMeta.HeightMap != null ? TerrainMeta.HeightMap.GetHeight(point) : 0f;
if (point.y < ground + config.WaterClearance)
return null; // fall back to vanilla so we never drive boats onto land
path.Add(point);
}
return path;
}
[ConsoleCommand("boatroute.show")]
private void CmdShowRoute(ConsoleSystem.Arg arg)
{
if (config == null || config.Waypoints == null)
{
arg.ReplyWith("No route configured.");
return;
}
arg.ReplyWith($"Route enabled: {config.Enabled}, points: {config.Waypoints.Count}");
for (int i = 0; i < config.Waypoints.Count; i++)
arg.ReplyWith($" #{i}: {config.Waypoints[i]}");
}
}
}The plugin builds a configurable list of waypoints from config and returns it from OnBoatPathGenerate, replacing the vanilla ocean patrol path with a fixed circuit. LoadDefaultConfig provides a default square route so the plugin works without configuration, and the config loader can be edited to place points in your map's water. Each point is validated against the terrain height map; if any point sits below sea level plus a small margin, the hook returns null so the boat falls back to the vanilla generator instead of being driven onto shore. A console command prints the current route so admins can confirm what is being handed to AI boats.
Common use cases
Fixed patrol circuits around monuments
Define waypoint rings around offshore monuments or islands so AI boats roam areas you want watched, rather than drifting across the whole ocean.
Keep AI boats away from player shorelines
Return routes placed far from beaches so patrol boats stop wandering into coastal bases and causing noise or collisions.
Themed event routes
Swap the default generator for a scripted loop during an event, then remove the plugin or return null afterwards to restore vanilla behaviour.
Pitfalls
Bad points drive boats onto land
The hook skips vanilla shore-distance and water-depth checks, so every returned point must be verified against
TerrainMeta.HeightMap.GetHeight. A point under the map or on a beach will strand the boat.Called per boat generation
The route is generated whenever a boat needs a path, which can happen repeatedly during a wipe. Keep the list allocation light and avoid rebuilding large structures on every call.
Returning the wrong type silently fails
Only a
List<Vector3>is honoured. Returning an array or another collection type is ignored and the vanilla path is used, which can look like your hook is not firing at all.
Build a plugin with OnBoatPathGenerate
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 OnBoatPathGenerate
Generate