OnFireBallSpread
OnFireBallSpread is called inside FireBall.TryToSpread right after a child fireball entity is spawned and before its spread velocity is applied.
void OnFireBallSpread(FireBall fireBall, BaseEntity entity)Parameters
| Parameter | Type | Description |
|---|---|---|
fireBall | FireBall | The FireBall entity that is spawning a new child fireball during its spread step. Use it to read the parent position, creator, generation and other state inherited by the new ball. |
entity | BaseEntity | The freshly created child BaseEntity that has already been positioned, spawned and given its creator. It gets its velocity immediately after the hook returns. |
Return value
This hook is invoked purely for notification; the return value is ignored. The original code continues regardless and always applies the random velocity and increments the generation of the child entity.
How it works
FireBall.TryToSpread runs while a fireball is alive and decides to spawn offspring. The game creates a child entity, moves it to the parent's position plus a quarter unit up, spawns it, and copies the creator reference. Oxide then fires OnFireBallSpread with the parent FireBall and the new child BaseEntity. Immediately after the hook returns, the original code assigns the child a random upward-biased velocity (45 degree aim cone, 5-8 speed) and sets its generation so it can continue spreading.
This is called per spawned child, so a single parent can produce multiple calls. Both parameters can be filtered by declaration: declare FireBall as-is, but you can narrow entity to a more specific type such as BaseEntity subclasses; Oxide skips your method when the argument does not match. Fireballs ignore DamageType conventions, so do not confuse them with thrown explosives. Use the hook for balancing, cleanup, or attaching markers to offspring; do not return a value, it is ignored.
Example plugin: Limit fireball spread depth and tag spawned children
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("FireBall Spread Limiter", "RustPluginGenerator", "1.0.0")]
[Description("Limits how deep fireballs can spread and caps the total number of active fireballs")]
public class FireBallSpreadLimiter : RustPlugin
{
private const string PermAdmin = "fireballspreadlimiter.admin";
private PluginConfig config;
public class PluginConfig
{
[JsonProperty("Maximum generation depth")]
public int MaxGeneration { get; set; } = 3;
[JsonProperty("Maximum active fireballs on the server")]
public int MaxActiveFireBalls { get; set; } = 200;
[JsonProperty("Give admins spread notifications")]
public bool NotifyAdmins { 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);
private void Init()
{
permission.RegisterPermission(PermAdmin, this);
}
private void OnFireBallSpread(FireBall fireBall, BaseEntity entity)
{
if (entity == null || entity.IsDestroyed) return;
if (entity is FireBall child == false) return;
if (child.generation >= config.MaxGeneration)
{
entity.Kill();
NotifyAdmins(fireBall, "Fireball blocked: depth limit reached");
return;
}
if (CountActive() > config.MaxActiveFireBalls)
{
entity.Kill();
NotifyAdmins(fireBall, "Fireball blocked: server fireball cap reached");
}
}
private int CountActive()
{
int count = 0;
foreach (var networkable in BaseNetworkable.serverEntities)
{
if (networkable is FireBall && !networkable.IsDestroyed) count++;
}
return count;
}
private void NotifyAdmins(FireBall parent, string message)
{
if (!config.NotifyAdmins) return;
foreach (var player in BasePlayer.activePlayerList)
{
if (player == null || !player.IsConnected) continue;
if (!permission.UserHasPermission(player.UserIDString, PermAdmin)) continue;
player.ChatMessage($"{message} (parent gen {parent?.generation})");
}
}
}
}The plugin reads a maximum allowed generation from its config. In OnFireBallSpread it inspects the child entity; if its generation exceeds the limit it kills the entity so the fire never reaches deeper layers. Otherwise it applies a stack limit by checking how many fireballs are already active, killing new ones when the total exceeds a configured cap. Because SetGeneration is called after the hook, the plugin reads the parent's generation off the FireBall parameter combined with the current generation value on the parent to decide. Messages are sent only to admins via a permission when verbose mode is on, avoiding chat spam during large fires.
Common use cases
Cap fireball spread depth
Kill or neuter child fireballs once the parent generation reaches a configurable limit so large fires on bases do not snowball.
Track and clean up offspring
Record spawned child entity IDs so a timer can remove fireballs after a few seconds or on Unload, avoiding orphaned entities after plugin reloads.
Debug fire spread
Log the parent/child pair for admins testing custom fireball behavior or tuning spread numbers on a test server.
Pitfalls
Velocity is applied after you return
Killing the child inside the hook is fine because Spawn already ran, but any velocity changes you make are overwritten by the game right after; do not rely on setting velocity you want to keep.
Called many times per parent
A single fireball can call this hook repeatedly as it spreads. Keep the body cheap and avoid Puts/PrintWarning, which would flood the log.
Both entity and parent can be destroyed
The child may already be destroyed by other plugins or by a clearup pass between Spawn and this hook; always null-check and check IsDestroyed before acting.
Build a plugin with OnFireBallSpread
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 OnFireBallSpread
Generate