Skip to content
RustPluginGenerator

OnFireworkStarted

OnFireworkStarted is called on the server right after a BaseFirework entity is lit and switches on its On/OnFire flags, before its exhaustion timer is scheduled. It marks the moment the rocket begins its upward flight.

Signature
void OnFireworkStarted(BaseFirework firework)

Parameters

Hook parameters
ParameterTypeDescription
fireworkBaseFireworkThe BaseFirework entity that just transitioned into its active flight state. Use it to read position, OwnerID, or to attach follow-up logic such as timers keyed to net.ID.Value.

Return value

The return value is ignored. The original code continues and always schedules the exhaustion timer via Invoke(OnExhausted, activityLength), regardless of what the hook returns. Return nothing (or null) and rely on other hooks such as OnFireworkExhausted or OnFireworkDamage to alter behavior.

How it works

The hook fires inside BaseFirework.Begin, after the entity's flags are updated to On and OnFire (with a network update queued) and just before Invoke(OnExhausted, activityLength) schedules the end of the flight. Anything that puts a firework into its active phase runs through Begin, so this covers a player igniting a placed firework with a held ignition source as well as anything else that calls the same method on the server.

The only parameter is the firework entity itself. Read firework.net.ID.Value to correlate the start and the later exhaustion, firework.transform.position for the launch point, or firework.OwnerID to find the player who placed it. If you only care about fireworks (not every BaseFirework subclass), declaring BaseFirework is already as specific as it gets here; declaring anything narrower would never match.

Because the hook runs synchronously inside Begin, keep the body cheap: record state, start a timer.Once, or send an effect. Do not call Kill() on the firework here unless you deliberately want the scheduled exhaustion to fire against a dead entity.

Example plugin: Broadcast and track firework launches per player

FireworkLaunchAnnouncer.cs
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Firework Launch Announcer", "RustPluginGenerator", "1.0.0")]
    [Description("Tracks firework launches per player and broadcasts permitted launches to the server.")]
    public class FireworkLaunchAnnouncer : RustPlugin
    {
        private const string PermAnnounce = "fireworklaunchannouncer.announce";

        private PluginConfig config;
        private readonly Dictionary<ulong, int> launchesByPlayer = new Dictionary<ulong, int>();

        private class PluginConfig
        {
            [JsonProperty("Broadcast launched fireworks to all players")]
            public bool Broadcast { get; set; } = true;

            [JsonProperty("Broadcast format ({0} = player name, {1} = absolute position)")]
            public string BroadcastFormat { get; set; } = "{0} lit a firework at {1}";
        }

        private void Init()
        {
            permission.RegisterPermission(PermAnnounce, this);
        }

        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 OnFireworkStarted(BaseFirework firework)
        {
            if (firework == null) return;

            ulong ownerId = firework.OwnerID;
            BasePlayer owner = ownerId != 0 ? BasePlayer.FindByID(ownerId) : null;

            if (owner == null || !permission.UserHasPermission(owner.UserIDString, PermAnnounce)) return;

            launchesByPlayer.TryGetValue(ownerId, out int count);
            launchesByPlayer[ownerId] = count + 1;

            if (!config.Broadcast) return;

            Vector3 pos = firework.transform.position;
            string coords = $"{Mathf.RoundToInt(pos.x)}, {Mathf.RoundToInt(pos.z)}";
            Server.Broadcast(string.Format(config.BroadcastFormat, owner.displayName, coords));
        }

        private void Unload()
        {
            launchesByPlayer.Clear();
        }
    }
}

The plugin keeps a small in-memory counter of how many fireworks each player has launched during the current server session and stores the launch time keyed by the firework's network ID. When OnFireworkStarted fires, it reads firework.OwnerID, resolves the player with BasePlayer.FindByID, and checks the fireworklaunchannouncer.announce permission. Authorized players get a broadcast to the whole server and a counter update. The in-memory dictionary is cleared in Unload so a reload starts fresh, which keeps the example free of disk I/O while still demonstrating the hook's natural data flow.

Common use cases

  • Zone-based restrictions

    Cancel or counteract launches inside no-build zones by killing the firework in OnFireworkStarted when its position falls within a monitored area, then informing the owner via chat.

  • Event signaling

    Use launched fireworks as a trigger for server events: start a countdown, spawn a supply drop nearby, or sound a siren for all connected players.

  • Statistics tracking

    Log how many fireworks each player launches per wipe by incrementing a counter keyed on OwnerID and persisting it with Interface.Oxide.DataFileSystem on save.

Pitfalls

  • OwnerID is zero for non-player sources

    Fireworks spawned by plugins or admin commands may carry OwnerID 0. Always guard against BasePlayer.FindByID(0) == null before using the player object.

  • Killing here leaves a dangling invoke

    The exhaustion timer is already scheduled at the time the hook runs, so destroying the entity does not cancel that invoke. Expect OnFireworkExhausted to still fire and code defensively there.

  • Fires once per firework, not per volley

    A multi-shot firework still invokes Begin once when lit. Do not design logic that assumes one hook call per visible burst; use OnFireworkExhausted for the flight completion.

Build a plugin with OnFireworkStarted

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Zone-based restrictions using the OnFireworkStarted hook, with a config file and a permission
Generate this plugin

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 OnFireworkStarted

Generate