OnFindSpawnPoint
OnFindSpawnPoint is called when the server resolves a spawn position for a player (or team) and lets a plugin override it. Returning a BasePlayer.SpawnPoint replaces the vanilla result.
object OnFindSpawnPoint(BasePlayer forPlayer, ulong teamId)Parameters
| Parameter | Type | Description |
|---|---|---|
forPlayer | BasePlayer | The BasePlayer who needs a spawn point. May be null in rare cases where the server resolves a spawn without a specific player. |
teamId | ulong | The relationship team id the player belongs to (0 when the player is not on a team). Useful for picking team-aware spawn positions. |
Return value
Return null (or any value that is not a BasePlayer.SpawnPoint) to continue with the game's own spawn resolution. Return a BasePlayer.SpawnPoint and the method returns it directly, so the server uses your position and rotation instead of computing one.
How it works
This hook fires inside ServerMgr.FindSpawnPoint before the server runs its own logic for choosing where a player appears. That method is the shared entry point for player spawning, so the hook runs for ordinary respawns and any other code path that asks the server for a spawn point, including team-based resolution when teamId is non-zero.
forPlayer is the player being placed; you can read forPlayer.userID, forPlayer.currentTeam or their position to make a decision. teamId gives you the team context without looking it up, which matters for team respawn rules. Because Oxide dispatches hooks by argument type, declaring the first parameter as BasePlayer is what the signature already requires; there is no narrower type to use here since the argument is a player.
Return null to let the game choose the spawn normally. Return a BasePlayer.SpawnPoint you construct (new BasePlayer.SpawnPoint { pos = ..., rot = ... }) to force a location. Only that type is accepted; returning anything else is ignored. Keep the work cheap: this hook runs per spawn request, not per frame.
Example plugin: Force spawns at a configured point with permission bypass
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Fixed Spawn Point", "RustPluginGenerator", "1.0.0")]
[Description("Forces players without a bypass permission to spawn at a configured position.")]
public class FixedSpawnPoint : RustPlugin
{
private const string PermBypass = "fixedspawnpoint.bypass";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Spawn position (x y z)")]
public string Position = "0 2 0";
[JsonProperty("Spawn rotation (x y z)")]
public string Rotation = "0 0 0";
[JsonProperty("Permission that keeps vanilla spawns")]
public bool AllowBypassPermission = 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>
{
["Set"] = "Spawn point set to {0}.",
["NoPerm"] = "You do not have permission to use this command."
}, 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(PermBypass, this);
}
[ChatCommand("setspawn")]
private void CmdSetSpawn(BasePlayer player, string command, string[] args)
{
if (player == null || !player.IsAdmin) return;
Vector3 pos = player.transform.position + Vector3.up * 0.5f;
config.Position = $"{pos.x} {pos.y} {pos.z}";
config.Rotation = $"{player.transform.rotation.eulerAngles.x} {player.transform.rotation.eulerAngles.y} {player.transform.rotation.eulerAngles.z}";
SaveConfig();
player.ChatMessage(Msg("Set", player.UserIDString, config.Position));
}
private object OnFindSpawnPoint(BasePlayer forPlayer, ulong teamId)
{
if (forPlayer == null) return null;
if (config.AllowBypassPermission && permission.UserHasPermission(forPlayer.UserIDString, PermBypass))
return null;
Vector3 pos;
Vector3 rot;
if (!TryParseVector(config.Position, out pos) || !TryParseVector(config.Rotation, out rot))
return null;
return new BasePlayer.SpawnPoint
{
pos = pos,
rot = Quaternion.Euler(rot)
};
}
private static bool TryParseVector(string value, out Vector3 result)
{
result = Vector3.zero;
if (string.IsNullOrEmpty(value)) return false;
string[] parts = value.Split(' ');
if (parts.Length != 3) return false;
float x, y, z;
if (!float.TryParse(parts[0], out x) || !float.TryParse(parts[1], out y) || !float.TryParse(parts[2], out z))
return false;
result = new Vector3(x, y, z);
return true;
}
}
}The plugin stores a spawn position, rotation and an optional permission and minimum team id in its config. OnFindSpawnPoint checks whether the incoming player is null or has the bypass permission; if not, it builds a BasePlayer.SpawnPoint from the configured pos and rot and returns it, so the server places the player there. LoadDefaultConfig seeds a sensible origin so the plugin works out of the box, and a chat command lets admins record their current position as the spawn point, saving the config immediately. Returning null on disallowed paths keeps vanilla behavior.
Common use cases
Custom beach or arena spawn
Point all fresh spawns at a fixed coordinate, for example a custom lobby or fair-play arena on a minigame server.
Team-aware spawn placement
Use
teamIdto send players to their team's base area or a shared staging zone when they respawn.VIP spawn bypass
Give players with a permission the vanilla spawn choice while routing everyone else to a controlled location.
Pitfalls
Return type is strict
Only a
BasePlayer.SpawnPointinstance is accepted. Returning aVector3or a bare position does nothing and the game spawns normally.Not the same as OnPlayerSpawn
This hook decides where a player appears;
OnPlayerSpawn/OnPlayerRespawnreport that a spawn happened. Use those for post-spawn effects like kits or messages.Ignore the position at your peril
A configured point that sits inside terrain or a monument build zone can trap players. Verify coordinates and keep a safe fallback.
Build a plugin with OnFindSpawnPoint
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 OnFindSpawnPoint
Generate