Loaded
Loaded is called once on your plugin instance right after Oxide finishes adding the plugin to the plugin manager and injecting plugin references. It is the earliest point where the plugin is fully registered and plugin references are available.
void Loaded()Return value
The return value is ignored. The hook is called as a plain method with no arguments and whatever you return has no effect on Oxide or on plugin loading.
How it works
Oxide invokes Loaded from CSharpPlugin.HandleAddedToManager, after the plugin has been registered with the manager, added to the watcher for file changes, and after every [PluginReference] field or property has been resolved against the currently loaded plugins. It runs on every load of the plugin: server start, oxide.reload, and hot reload when the source file changes. No game world state is guaranteed yet — the server may still be initializing, so world entities, players and save data are not reliable here. Use Loaded for setup that depends on other plugins already being wired up, for reading a referenced plugin's API surface, or for one-time state that must exist before any gameplay hook fires. Parameterless and void; it is called exactly once per instance. Unlike Init, which runs during Oxide's plugin initialization before references are injected, Loaded runs after reference injection, so [PluginReference] members are non-null (or null only because the target plugin is not loaded).
Example plugin: Warn when optional companion plugins are missing
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Loaded Dependency Check", "RustPluginGenerator", "1.0.0")]
[Description("Verifies that optional and required plugin references are present when this plugin loads.")]
public class LoadedDependencyCheck : RustPlugin
{
private const string PermCheck = "loadeddependencycheck.check";
[PluginReference] private Plugin Economics;
private PluginConfig config;
private Timer checkTimer;
private List<string> missingAtLoad = new List<string>();
private class PluginConfig
{
[JsonProperty("Require Economics plugin")]
public bool RequireEconomics { get; set; } = true;
[JsonProperty("Warn on server initialization")]
public bool WarnOnStartup { 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);
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Missing"] = "Missing plugin reference: {0}",
["AllPresent"] = "All required plugin references are present.",
["CheckSummary"] = "Loaded at {0}. Missing references: {1}",
["NoMissing"] = "No missing references recorded.",
["StartupOk"] = "{0} is ready and its dependencies are satisfied."
}, 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(PermCheck, this);
}
private void Loaded()
{
missingAtLoad.Clear();
if (Economics == null && config.RequireEconomics)
{
missingAtLoad.Add("Economics");
PrintWarning(Msg("Missing", null, "Economics"));
}
if (missingAtLoad.Count == 0)
{
Puts(Msg("AllPresent"));
}
}
private void OnServerInitialized()
{
if (!config.WarnOnStartup) return;
checkTimer = timer.Once(3f, () =>
{
if (missingAtLoad.Count == 0)
{
Puts(Msg("StartupOk", null, Name));
}
});
}
[ChatCommand("loaded.check")]
private void CmdCheck(BasePlayer player, string command, string[] args)
{
if (player == null) return;
if (!permission.UserHasPermission(player.UserIDString, PermCheck))
{
player.ChatMessage("You do not have permission to run this command.");
return;
}
string missing = missingAtLoad.Count == 0
? Msg("NoMissing", player.UserIDString)
: string.Join(", ", missingAtLoad.ToArray());
player.ChatMessage(Msg("CheckSummary", player.UserIDString, DateTime.UtcNow.ToString("u"), missing));
if (Economics == null)
{
player.ChatMessage(Msg("Missing", player.UserIDString, "Economics"));
}
else
{
player.ChatMessage(Msg("AllPresent", player.UserIDString));
}
}
private void Unload()
{
checkTimer?.Destroy();
checkTimer = null;
}
}
}The plugin declares an optional [PluginReference] to an economy plugin and a required reference to an imaginary helper plugin. Loaded runs after Oxide has injected those references, so the example checks each one: if it is null it records a startup warning through PrintWarning and keeps a summary for admins who later run loaded.check. The loaded.check chat command is permission-gated and can be run later to re-verify references, which is useful after a live reload. A short OnServerInitialized message confirms the plugin is ready to the console. All text goes through the language file, and Unload clears the timer reference to follow plugin hygiene.
Common use cases
Verify injected plugin references
Check each
[PluginReference]member inLoadedand print a warning naming the missing plugin, so admins see the problem at load time instead of when a player first triggers a feature.Prime in-memory caches tied to other plugins
Query a referenced plugin's API via
CallduringLoadedto snapshot its version or configuration, before any gameplay hook can invoke your code.Run setup that must not run before references exist
Anything that calls
Economics,Kitsor similar plugins belongs here rather than inInit, sinceLoadedruns after Oxide has resolved those fields.
Pitfalls
World is not ready yet
Loadedfires during plugin registration and may run before the save loads.BasePlayer.activePlayerList, entity lookups and world data can be empty or incomplete; useOnServerInitializedfor world-dependent setup.Null references are expected, not errors
A
[PluginReference]is null when the target plugin is not loaded at that moment. Treat it as a soft condition: warn or degrade gracefully rather than throwing, since Oxide logs an exception and records the plugin as failed.Fires again on every reload
Loadedruns onoxide.reloadand on hot reload, so avoid allocating long-lived resources or schedulingtimer.Everywithout also destroying them inUnload.
Build a plugin with Loaded
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 Loaded
Generate