OnPowergridStageChange
OnPowergridStageChange is called during PowergridManager.ServerTick when the calculated power grid stage differs from the stored stage, or on the first tick after a server start.
object OnPowergridStageChange(PowergridManager powergridManager, int stage)Parameters
| Parameter | Type | Description |
|---|---|---|
powergridManager | PowergridManager | The PowergridManager instance being ticked. Use it to read the current stage via CurrentStage, the inserted fuse count, or to inspect its configuration before the stage is committed. |
stage | int | The grid stage the manager is about to switch to, as calculated by PowergridManager.CalculateCurrentStage(). It is the new value, not the one currently stored in CurrentStage. |
Return value
Return null to let the tick continue: analytics are recorded and CurrentStage is set to the new stage. Return any non-null value to stop the block early, so the analytics call and the CurrentStage assignment are skipped and the grid keeps its previous stage.
How it works
The hook fires from PowergridManager.ServerTick after the manager recalculates the stage from the fuses inserted in the power grid. It runs when the newly calculated stage differs from CurrentStage, and also on the first tick after loading because hasTickedOnce is still false. Two parameters matter: powergridManager is the live manager, and stage is the value the server is about to write into CurrentStage.
Returning a non-null value from this hook aborts the rest of the stage-change block, so the analytics event is not sent and CurrentStage keeps its old value. That makes the hook a veto: the server will keep thinking the grid is at the previous stage until the next tick where the calculated stage differs again.
You cannot narrow dispatch by declaring a more specific parameter type here in a useful way: both PowergridManager and int are already the concrete types the game passes in. Because the hook fires on a server tick (once per grid manager, not per player), keep the body cheap. It is a good place to record stage transitions, announce a grid upgrade in chat, or block a transition you consider unwanted.
Example plugin: Announce power grid stage upgrades in chat
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Powergrid Stage Announcer", "RustPluginGenerator", "1.0.0")]
[Description("Announces power grid stage changes in chat and throttles repeated messages")]
public class PowergridStageAnnouncer : RustPlugin
{
private const string PermAnnounce = "powergridstageannouncer.announce";
private PluginConfig config;
private readonly Dictionary<ulong, int> lastStage = new Dictionary<ulong, int>();
private readonly Dictionary<ulong, float> lastAnnounce = new Dictionary<ulong, float>();
private class PluginConfig
{
[JsonProperty("Announce upgrades")]
public bool AnnounceUpgrades { get; set; } = true;
[JsonProperty("Announce downgrades")]
public bool AnnounceDowngrades { get; set; } = true;
[JsonProperty("Minimum seconds between messages per grid")]
public float CooldownSeconds { get; set; } = 30f;
}
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>
{
["Upgrade"] = "Power grid stage increased to {0}.",
["Downgrade"] = "Power grid stage dropped to {0}."
}, 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(PermAnnounce, this);
}
private object OnPowergridStageChange(PowergridManager powergridManager, int stage)
{
if (powergridManager == null || !config.AnnounceUpgrades && !config.AnnounceDowngrades) return null;
ulong gridId = powergridManager.net != null ? powergridManager.net.ID.Value : 0UL;
int oldStage;
if (!lastStage.TryGetValue(gridId, out oldStage))
{
lastStage[gridId] = stage;
return null;
}
if (oldStage == stage) return null;
lastStage[gridId] = stage;
bool upgrade = stage > oldStage;
if (upgrade && !config.AnnounceUpgrades) return null;
if (!upgrade && !config.AnnounceDowngrades) return null;
float now = Time.realtimeSinceStartup;
float previous;
if (lastAnnounce.TryGetValue(gridId, out previous) && now - previous < config.CooldownSeconds) return null;
lastAnnounce[gridId] = now;
string message = Msg(upgrade ? "Upgrade" : "Downgrade", null, stage);
foreach (BasePlayer player in BasePlayer.activePlayerList)
{
if (player == null || !player.IsConnected) continue;
if (!permission.UserHasPermission(player.UserIDString, PermAnnounce)) continue;
player.ChatMessage(message);
}
return null;
}
}
}The plugin tracks the last announced stage per PowergridManager in a dictionary keyed by the manager's network ID. On every OnPowergridStageChange call it reads the new stage and the manager's CurrentStage (the old value), sends a server-wide chat line when the stage went up, and stores the new value. Config controls whether downgrades are reported too and the cooldown that prevents repeated messages if the grid oscillates. All player-facing text goes through the language file so admins can reword it.
Common use cases
Alert the server when the grid is upgraded
Broadcast a chat message when the stage increases so players know a bigger reactor or more fuses went online.
Log grid transitions for admins
Write stage changes with a timestamp into a data file so admins can correlate outages with player activity.
Block unwanted stage changes
Return a non-null value to keep the grid on its old stage, for example while a scheduled maintenance window is active.
Pitfalls
Non-null return silently freezes the stage
Returning anything other than null skips the assignment to CurrentStage, so the server's view of the grid stage never updates and the hook can fire on every later tick.
Fires on the first tick after start
Because hasTickedOnce starts false, the hook runs once per manager shortly after server load even without a real change. Do not treat the first call as an actual upgrade.
Tick-frequency cost
The hook sits on a server tick path. Avoid chat spam, file writes or heavy loops in the handler; buffer data and flush with a timer instead.
Build a plugin with OnPowergridStageChange
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 OnPowergridStageChange
Generate