### Basic Installation Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/installation/automatic/linux.md Run the installer in the current directory to install EXILED with pre-release versions included. ```powershell .\Exiled.Installer-Linux --pre-releases ``` -------------------------------- ### Installation with Specific Paths and Version Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/installation/automatic/linux.md Installs EXILED by specifying the server path, appdata folder, and a target version. ```powershell .\Exiled.Installer-Linux -p /home/user/scpsl/server --appdata /home/user/scpsl --target-version 2.0.8 ``` -------------------------------- ### Exiled Installer Usage Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/installation/automatic/windows.md Displays the available command-line options for the Exiled installer. Use this to understand how to customize your installation. ```bash Usage: Exiled.Installer [options] [[--] ...]] Options: -p, --path (REQUIRED) Path to the folder with the SL server [default: YourWorkingFolder] --appdata (REQUIRED) Forces the folder to be the AppData folder (useful for containers when pterodactyl runs as root) [default: YourAppDataPath] --pre-releases Includes pre-releases [default: False] --target-version Target version for installation --github--token Uses a token for auth in case the rate limit is exceeded (no permissions required) --exit Automatically exits the application anyway --get-versions Gets all possible versions for installation --version Show version information -?, -h, --help Show help and usage information Additional Arguments: Arguments passed to the application that is being run. ``` -------------------------------- ### Basic EXILED Installation Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/installation/automatic/windows.md Installs EXILED, including pre-release versions, in the current directory. Ensure you are in your server directory before running. ```powershell .\Exiled.Installer-Win --pre-releases ``` -------------------------------- ### Example Event Argument Structure Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/plugins/events.md Illustrates the structure of an event argument class, highlighting properties like 'IsAllowed' for controlling event behavior. ```csharp public class EnragingEventArgs : IScp096Event, IDeniableEvent { // Note: Constructor omitted. public Scp096 Scp096 { get; } public Player Player { get; } public bool IsAllowed { get; set; } } ``` -------------------------------- ### Basic EXILED Installation Source: https://github.com/exmod-team/exiled/blob/master/EXILED/Exiled.Installer/README.md Installs EXILED in the current directory, including pre-release versions. This is the default behavior when no specific paths are provided. ```bash user@user:~/SCP# ./Exiled.Installer-Linux --pre-releases Exiled.Installer-Linux-3.2.3.0 AppData folder: YourAppDataPath Exiled folder: YourAppDataPath Receiving releases... Prereleases included - True Target release version - (null) Searching for the latest release that matches the parameters... Trying to find release.. Release found! PRE: True | ID: 87710626 | TAG: 6.0.0-beta.18 Asset found! ID: 90263995 | NAME: Exiled.tar.gz | SIZE: 1027928 | URL: https://api.github.com/repos/Exmod-Team/Exiled-EA/releases/assets/90263995 | DownloadURL: https://github.com/Exmod-Team/Exiled-EA/releases/download/6.0.0-beta.18/Exiled.tar.gz Processing 'EXILED/Plugins/dependencies/0Harmony.dll' Extracting '0Harmony.dll' into 'YourAppDataPath/EXILED/Plugins/dependencies/0Harmony.dll'... Processing 'EXILED/Plugins/dependencies/Exiled.API.dll' Extracting 'Exiled.API.dll' into 'YourAppDataPath/EXILED/Plugins/dependencies/Exiled.API.dll'... Processing 'EXILED/Plugins/dependencies/SemanticVersioning.dll' Extracting 'SemanticVersioning.dll' into 'YourAppDataPath/EXILED/Plugins/dependencies/SemanticVersioning.dll'... Processing 'EXILED/Plugins/dependencies/YamlDotNet.dll' Extracting 'YamlDotNet.dll' into 'YourAppDataPath/EXILED/Plugins/dependencies/YamlDotNet.dll'... Processing 'EXILED/Plugins/Exiled.CreditTags.dll' Extracting 'Exiled.CreditTags.dll' into 'YourAppDataPath/EXILED/Plugins/Exiled.CreditTags.dll'... Processing 'EXILED/Plugins/Exiled.CustomItems.dll' Extracting 'Exiled.CustomItems.dll' into 'YourAppDataPath/EXILED/Plugins/Exiled.CustomItems.dll'... Processing 'EXILED/Plugins/Exiled.CustomRoles.dll' Extracting 'Exiled.CustomRoles.dll' into 'YourAppDataPath/EXILED/Plugins/Exiled.CustomRoles.dll'... Processing 'EXILED/Plugins/Exiled.Events.dll' Extracting 'Exiled.Events.dll' into 'YourAppDataPath/EXILED/Plugins/Exiled.Events.dll'... Processing 'EXILED/Plugins/Exiled.Permissions.dll' Extracting 'Exiled.Permissions.dll' into 'YourAppDataPath/EXILED/Plugins/Exiled.Permissions.dll'... Processing 'EXILED/Plugins/Exiled.Updater.dll' Extracting 'Exiled.Updater.dll' into 'YourAppDataPath/EXILED/Plugins/Exiled.Updater.dll'... Processing 'SCP Secret Laboratory/PluginAPI/plugins/7777/dependencies/Exiled.API.dll' Extracting 'Exiled.API.dll' into 'YourAppDataPath/SCP Secret Laboratory/PluginAPI/plugins/7777/dependencies/Exiled.API.dll'... Processing 'SCP Secret Laboratory/PluginAPI/plugins/7777/dependencies/YamlDotNet.dll' Extracting 'YamlDotNet.dll' into 'YourAppDataPath/SCP Secret Laboratory/PluginAPI/plugins/7777/dependencies/YamlDotNet.dll'... Processing 'SCP Secret Laboratory/PluginAPI/plugins/7777/Exiled.Loader.dll' Extracting 'Exiled.Loader.dll' into 'YourAppDataPath/SCP Secret Laboratory/PluginAPI/plugins/7777/Exiled.Loader.dll'... Installation complete ``` -------------------------------- ### IConfig - Advanced Configuration Example Source: https://context7.com/exmod-team/exiled/llms.txt Demonstrates a sample configuration class implementing `IConfig` for a plugin. Properties are automatically serialized to/from YAML and can be documented using `System.ComponentModel.DescriptionAttribute`. The `IsEnabled` property is handled automatically to enable or disable plugin loading. ```APIDOC ## Configuration System — `IConfig` Configs are plain C# classes implementing `IConfig` that are automatically serialized to/from YAML by the loader. Every property is exposed to server operators. Use `System.ComponentModel.DescriptionAttribute` to document each option. EXILED handles `IsEnabled` automatically — if a server owner sets it to `false`, the plugin is never loaded. ```csharp using System.Collections.Generic; using System.ComponentModel; using Exiled.API.Features; // Broadcast using Exiled.API.Interfaces; using UnityEngine; public class AdvancedConfig : IConfig { [Description("Master enable/disable switch for this plugin.")] public bool IsEnabled { get; set; } = true; [Description("Output debug logs to the server console.")] public bool Debug { get; set; } = false; [Description("Maximum damage a Scientist can take per hit.")] public float ScientistMaxHitDamage { get; set; } = 1f; [Description("Roles that are immune to the Tesla gate.")] public List TeslaImmune { get; set; } = new() { PlayerRoles.RoleTypeId.NtfCaptain, PlayerRoles.RoleTypeId.Scientist, }; [Description("Broadcast sent to every joining player.")] public Broadcast JoinBroadcast { get; set; } = new("Welcome! Read the rules in #info.", 8); [Description("Spawn offset applied to tutorial players.")] public Vector3 TutorialSpawnOffset { get; set; } = new(0, 1, 0); // Nested dictionaries are supported [Description("Per-role friendly fire multipliers.")] public Dictionary RoleFFMultipliers { get; set; } = new() { { "ClassD", 0.5f }, { "Scientist", 0.0f }, }; } // Reading in OnEnabled: // Log.Info(Config.JoinBroadcast.Content); // "Welcome! Read the rules in #info." // Log.Info(Config.ScientistMaxHitDamage); // 1 ``` ``` -------------------------------- ### Custom EXILED Installation Source: https://github.com/exmod-team/exiled/blob/master/EXILED/Exiled.Installer/README.md Installs EXILED to a specific folder and appdata directory, without including pre-release versions. This allows for more control over the installation location. ```bash user@user:~/SCP# ./Exiled.Installer-Linux --appdata /user/SCP --exiled /user/SCP Exiled.Installer-Linux-3.2.3.0 AppData folder: /user/SCP Exiled folder: /user/SCP Receiving releases... Prereleases included - False Target release version - (null) Searching for the latest release that matches the parameters... Trying to find release.. Release found! PRE: False | ID: 87710626 | TAG: 6.0.0-beta.18 Asset found! ID: 90263995 | NAME: Exiled.tar.gz | SIZE: 1027928 | URL: https://api.github.com/repos/Exmod-Team/Exiled-EA/releases/assets/90263995 | DownloadURL: https://github.com/Exmod-Team/Exiled-EA/releases/download/6.0.0-beta.18/Exiled.tar.gz Processing 'EXILED/Plugins/dependencies/0Harmony.dll' Extracting '0Harmony.dll' into '/user/SCP/EXILED/Plugins/dependencies/0Harmony.dll'... Processing 'EXILED/Plugins/dependencies/Exiled.API.dll' Extracting 'Exiled.API.dll' into '/user/SCP/EXILED/Plugins/dependencies/Exiled.API.dll'... Processing 'EXILED/Plugins/dependencies/SemanticVersioning.dll' Extracting 'SemanticVersioning.dll' into '/user/SCP/EXILED/Plugins/dependencies/SemanticVersioning.dll'... Processing 'EXILED/Plugins/dependencies/YamlDotNet.dll' Extracting 'YamlDotNet.dll' into '/user/SCP/EXILED/Plugins/dependencies/YamlDotNet.dll'... Processing 'EXILED/Plugins/Exiled.CreditTags.dll' Extracting 'Exiled.CreditTags.dll' into '/user/SCP/EXILED/Plugins/Exiled.CreditTags.dll'... Processing 'EXILED/Plugins/Exiled.CustomItems.dll' Extracting 'Exiled.CustomItems.dll' into '/user/SCP/EXILED/Plugins/Exiled.CustomItems.dll'... Processing 'EXILED/Plugins/Exiled.CustomRoles.dll' Extracting 'Exiled.CustomRoles.dll' into '/user/SCP/EXILED/Plugins/Exiled.CustomRoles.dll'... Processing 'EXILED/Plugins/Exiled.Events.dll' Extracting 'Exiled.Events.dll' into '/user/SCP/EXILED/Plugins/Exiled.Events.dll'... Processing 'EXILED/Plugins/Exiled.Permissions.dll' Extracting 'Exiled.Permissions.dll' into '/user/SCP/EXILED/Plugins/Exiled.Permissions.dll'... Processing 'EXILED/Plugins/Exiled.Updater.dll' Extracting 'Exiled.Updater.dll' into '/user/SCP/EXILED/Plugins/Exiled.Updater.dll'... ``` -------------------------------- ### Implementing OnEnabled and OnDisabled Methods Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/plugins/structure.md This C# example shows how to add functionality to your EXILED plugin by overriding the `OnEnabled` and `OnDisabled` methods. These methods are called when the plugin is loaded and unloaded, respectively. Use `OnEnabled` for initialization and `OnDisabled` for cleanup. The example logs messages to the console. ```csharp namespace MyPluginNamespace { using Exiled.API.Features; public class Plugin : Plugin { public override void OnEnabled() { Log.Info("My plugin has been enabled!"); } public override void OnDisabled() { Log.Info("My plugin has been disabled!"); } } // Config.cs file using Exiled.API.Interfaces; public class Config : IConfig { public bool IsEnabled { get; set; } } } ``` -------------------------------- ### EXILED Plugin Base Class Example Source: https://context7.com/exmod-team/exiled/llms.txt Demonstrates the structure of an EXILED plugin, including configuration, event handling, and lifecycle methods. Ensure you inherit from Plugin and implement the required properties and methods. ```csharp using System; using Exiled.API.Enums; using Exiled.API.Features; using Exiled.API.Interfaces; using System.ComponentModel; // --- Config --- public class MyConfig : IConfig { [Description("Enable or disable the plugin.")] public bool IsEnabled { get; set; } = true; [Description("Show debug messages.")] public bool Debug { get; set; } = false; [Description("Welcome message shown to joining players.")] public string WelcomeMessage { get; set; } = "Welcome to the server!"; [Description("Duration of the welcome broadcast in seconds.")] public ushort WelcomeDuration { get; set; } = 5; } // --- Main Plugin Class --- public class MyPlugin : Plugin { // Singleton pattern keeps a single instance accessible private static readonly MyPlugin Singleton = new(); public static MyPlugin Instance => Singleton; private MyPlugin() { } public override string Name => "MyPlugin"; public override string Author => "YourName"; public override Version Version => new(1, 0, 0); // Lower priority loads after higher priority plugins public override PluginPriority Priority => PluginPriority.Default; private PlayerEventHandler playerHandler; public override void OnEnabled() { playerHandler = new PlayerEventHandler(); Exiled.Events.Handlers.Player.Verified += playerHandler.OnVerified; Log.Info($"WelcomeMessage config: {Config.WelcomeMessage}"); base.OnEnabled(); // prints "[MyPlugin] v1.0.0 by YourName has been enabled!" } public override void OnDisabled() { Exiled.Events.Handlers.Player.Verified -= playerHandler.OnVerified; playerHandler = null; base.OnDisabled(); } // OnReloaded carries over static variables across /exiled reload public override void OnReloaded() { } } ``` -------------------------------- ### Advanced EXILED Installation Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/installation/automatic/windows.md Installs EXILED to a specific server path and appdata folder, targeting a particular version. This is useful for managing installations in non-standard locations or for specific version requirements. ```powershell .\Exiled.Installer-Win -p D:\Games\SCPSL\Server --appdata C --target-version 2.0.8 ``` -------------------------------- ### Warhead.Starting Event Source: https://context7.com/exmod-team/exiled/llms.txt Fires when the nuke warhead sequence is initiated. Can be used to log who started the warhead or perform related actions. ```APIDOC ## Warhead.Starting ### Description Fires when the nuke warhead sequence is initiated. ### Method `Exiled.Events.Handlers.Warhead.Starting += YourHandlerMethod;` ### Event Arguments `StartingEventArgs` - **Player** (`Player?`): The player who initiated the warhead. Null if automated. - **IsSilent** (`bool`): Indicates if the warhead start was silent. ### Example Usage ```csharp public void OnWarheadStarting(StartingEventArgs ev) { Log.Warn($"{ev.Player?.Nickname ?? "AUTO"} started the warhead!"); } ``` ``` -------------------------------- ### Respawn API: Inspecting Wave State Source: https://context7.com/exmod-team/exiled/llms.txt Check the current respawn status using Respawn.IsSpawning, determine the next spawnable faction with Respawn.NextKnownSpawnableFaction, and get the current state with Respawn.CurrentState. ```csharp using Exiled.API.Features; using Exiled.API.Enums; using PlayerRoles; using Respawning; using Respawning.Waves; // --- Inspect wave state --- Log.Info(Respawn.IsSpawning.ToString()); // true while a wave is actively spawning Log.Info(Respawn.NextKnownSpawnableFaction.ToString()); // "NtfWave" or "ChaosWave" etc. Log.Info(Respawn.CurrentState.ToString()); // "Idle", "WaveSpawning", etc. ``` -------------------------------- ### Basic Plugin Structure with Config Inheritance Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/plugins/structure.md This C# snippet demonstrates the essential structure for an EXILED plugin. It shows how to inherit from `Plugin` and define a `Config` class that implements `IConfig` with an `IsEnabled` property. This setup is crucial for the EXILED framework to recognize and load the plugin. ```csharp namespace MyPluginNamespace { using Exiled.API.Features; public class Plugin : Plugin { // This plugin will now be recognized by the EXILED framework! } // It is strongly encouraged to create a separate file for your Config class. using Exiled.API.Interfaces; public class Config : IConfig { public bool IsEnabled { get; set; } } } ``` -------------------------------- ### EXILED Plugin Hot-Reload Pattern Example Source: https://context7.com/exmod-team/exiled/llms.txt This C# code demonstrates the hot-reloading pattern for an EXILED plugin. Ensure all subscriptions, coroutines, and mutable objects are managed in OnEnabled and OnDisabled. Static fields are preserved across reloads and should be updated in OnReloaded. ```csharp using Exiled.API.Features; using MEC; // Coroutines via More Effective Coroutines public class MyPlugin : Plugin { // --- Static data survives reload --- public static int TotalKillsEver = 0; // --- Instance data is reset on each enable --- private int killsThisSession = 0; private CoroutineHandle heartbeatCoroutine; private PlayerEventHandler handler; public override void OnEnabled() { // Restore from static (set in OnReloaded) killsThisSession = TotalKillsEver; handler = new PlayerEventHandler(this); Exiled.Events.Handlers.Player.Died += handler.OnDied; // Start a repeating coroutine heartbeatCoroutine = Timing.RunCoroutine(Heartbeat()); base.OnEnabled(); } public override void OnDisabled() { Exiled.Events.Handlers.Player.Died -= handler.OnDied; handler = null; Timing.KillCoroutines(heartbeatCoroutine); base.OnDisabled(); } public override void OnReloaded() { // Carry over instance state to static before OnEnabled runs again TotalKillsEver = killsThisSession; } public void RegisterKill() => killsThisSession++; private System.Collections.IEnumerator Heartbeat() { while (true) { yield return Timing.WaitForSeconds(60f); Log.Info($"[Heartbeat] Kills this session: {killsThisSession} | TPS: {Server.Tps:F1}"); } } } public class PlayerEventHandler { private readonly MyPlugin plugin; public PlayerEventHandler(MyPlugin plugin) => this.plugin = plugin; public void OnDied(Exiled.Events.EventArgs.Player.DiedEventArgs ev) { plugin.RegisterKill(); Log.Info($"{ev.Attacker?.Nickname ?? "?"} killed {ev.Player.Nickname}"); } } ``` -------------------------------- ### Opus Control Get Requests Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/SCPSLRessources/NW_Documentation.md Defines the types of requests that can be made to get Opus codec settings. This includes parameters like bitrate, complexity, and bandwidth. ```csharp [4001] = Application [4003] = Bitrate [4005] = MaxBandwidth [4007] = VBR [4009] = Bandwidth [4011] = Complexity [4013] = InbandFec [4015] = PacketLossPercentage [4017] = Dtx [4021] = VBRConstraint [4023] = ForceChannels [4025] = Signal [4027] = LookAhead [4029] = SampleRate [4031] = FinalRange [4033] = Pitch [4035] = Gain [4037] = LsbDepth ``` -------------------------------- ### Warhead API: State Queries Source: https://context7.com/exmod-team/exiled/llms.txt Query the current status of the Alpha Warhead, including whether it is in progress, detonated, or if it can be started. The detonation timer is also accessible. ```csharp using Exiled.API.Features; using Exiled.API.Enums; // --- State queries --- Log.Info(Warhead.Status.ToString()); // "NotArmed", "Armed", "InProgress", "Detonated" Log.Info(Warhead.IsInProgress.ToString()); // true during countdown Log.Info(Warhead.IsDetonated.ToString()); // true after detonation Log.Info(Warhead.DetonationTimer.ToString()); // remaining seconds Log.Info(Warhead.CanBeStarted.ToString()); // false if on cooldown or detonated ``` -------------------------------- ### Round API: State Checks and Statistics Source: https://context7.com/exmod-team/exiled/llms.txt Check the current state of the round (started, lobby, ended) and retrieve round statistics like total kills and escaped players. Elapsed time is also available. ```csharp using Exiled.API.Features; using RoundRestarting; // --- State checks --- Log.Info(Round.IsStarted.ToString()); // true during a round Log.Info(Round.IsLobby.ToString()); // true in pre-round lobby Log.Info(Round.IsEnded.ToString()); // true after round ends Log.Info(Round.ElapsedTime.ToString()); // "00:03:47.1234567" // --- Statistics --- Log.Info(Round.Kills.ToString()); // total kills this round Log.Info(Round.KillsByScp.ToString()); // SCP kills Log.Info(Round.EscapedScientists.ToString()); Log.Info(Round.EscapedDClasses.ToString()); Log.Info(Round.SurvivingSCPs.ToString()); ``` -------------------------------- ### Round API: Control and Player Ignoring Source: https://context7.com/exmod-team/exiled/llms.txt Control the round lifecycle by locking states, setting lobby timers, starting, ending, or restarting the round. Players can also be ignored for round-end calculations. ```csharp // --- Control --- Round.IsLocked = true; // prevents round end Round.IsLobbyLocked = true; // freezes lobby countdown Round.LobbyWaitingTime = 30; // set lobby timer (seconds) Round.Start(); // force-start round from lobby Round.EndRound(forceEnd: true); // force-end round immediately Round.Restart(fastRestart: true); // restart without reconnecting players Round.RestartSilently(); // equivalent to fast restart, no action // --- Alive-side query --- foreach (var side in Round.AliveSides) Log.Info($"Still alive: {side}"); // --- Ignore a player from round-end calculation --- Round.IgnoredPlayers.Add(player.ReferenceHub); ``` -------------------------------- ### SSPrimitiveSpawnerExample+ExampleId Enumeration Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/SCPSLRessources/NW_Documentation.md Lists identifiers for primitive spawning controls and properties. ```csharp [0] = ConfirmButton [1] = DestroyAllButton [2] = TypeDropdown [3] = ColorPresetDropdown [4] = ColorField [5] = ColorAlphaSlider [6] = CollisionsToggle [7] = RendererToggle [8] = ColorInfo [9] = ScaleSliderX [10] = ScaleSliderY [11] = ScaleSliderZ ``` -------------------------------- ### SSAbilitiesExample+ExampleId Enumeration Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/SCPSLRessources/NW_Documentation.md Identifies specific abilities used in the SSAbilitiesExample. ```csharp [0] = SpeedBoostKey [1] = SpeedBoostToggle [2] = HealAlly ``` -------------------------------- ### SSLightSpawnerExample+ExampleId Enumeration Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/SCPSLRessources/NW_Documentation.md Defines identifiers for various light spawning controls and properties. ```csharp [0] = IntensitySlider [1] = RangeSlider [2] = ColorPresetDropdown [3] = CustomColor [4] = ColorInfo [5] = ShadowType [6] = ShadowStrength [7] = LightType [8] = LightShape [9] = SpotAngle [10] = InnerSpotAngle [11] = ConfirmButton [12] = DestroyAllButton ``` -------------------------------- ### Spawn and Manage NPCs Source: https://context7.com/exmod-team/exiled/llms.txt Demonstrates spawning an NPC, interacting with its properties, making it follow a player, and destroying it. Ensure necessary using directives are present. ```csharp using Exiled.API.Features; using PlayerRoles; using UnityEngine; // --- Spawn an NPC --- Npc npc = Npc.Spawn( name: "Guard Bot", role: RoleTypeId.FacilityGuard, position: new Vector3(0, -5, 0)); Log.Info($ ``` -------------------------------- ### Server API - Inspection, Mutation, Command Execution, Restart, Shutdown, Session Variables Source: https://context7.com/exmod-team/exiled/llms.txt This snippet demonstrates how to inspect and control global server state, including name, player limits, friendly fire, TPS, and server-scope session variables. It also shows how to execute console commands and manage server restarts/shutdowns. ```csharp using Exiled.API.Features; // --- Inspection --- Log.Info(Server.Name); Log.Info(Server.Port.ToString()); Log.Info(Server.Version); Log.Info(Server.PlayerCount.ToString()); Log.Info(Server.Tps.ToString("F1")); Log.Info(Server.FriendlyFire.ToString()); // --- Mutate --- Server.Name = "My Server [MODDED]"; Server.MaxPlayerCount = 20; Server.FriendlyFire = true; Server.IsWhitelisted = false; // --- Execute a console command --- string result = Server.ExecuteCommand("bc 5 Hello from plugin!"); Log.Info(result); // --- Restart / Shutdown --- Server.Restart(); Server.Shutdown(); Server.RestartRedirect(7778); // --- Cross-plugin session variables --- Server.SessionVariables["event_active"] = true; if (Server.TryGetSessionVariable("event_active", out bool active) && active) Log.Info("An event is currently running."); ``` -------------------------------- ### Create a Simple Remote Admin Command Source: https://context7.com/exmod-team/exiled/llms.txt Implement ICommand to create a Remote Admin command. Ensure you have the necessary permissions and handle argument parsing correctly. Requires Exiled.Permissions.Extensions. ```csharp using System; using CommandSystem; using Exiled.API.Features; using Exiled.API.Features.Pickups; using Exiled.Permissions.Extensions; // CheckPermission // --- Simple Remote Admin command --- [CommandHandler(typeof(RemoteAdminCommandHandler))] public class InspectCommand : ICommand { public string Command { get; } = "inspect"; public string[] Aliases { get; } = new[] { "ins" }; public string Description { get; } = "Inspect a player's inventory and position."; public bool Execute(ArraySegment arguments, ICommandSender sender, out string response) { if (!sender.CheckPermission("myplugin.inspect")) { response = "You don't have permission to use this command."; return false; } if (arguments.Count < 1) { response = "Usage: inspect "; return false; } if (!int.TryParse(arguments.At(0), out int playerId)) { response = "Invalid player ID."; return false; } Player ply = Player.Get(playerId); if (ply is null) { response = $"No player with ID {playerId}."; return false; } response = $"{ply.Nickname} | Role: {ply.Role.Type} | HP: {ply.Health:F0} | " + $"Items: {string.Join(", ", ply.Items.Select(i => i.Type))} | " + $"Pos: {ply.Position}"; return true; } } ``` -------------------------------- ### Warhead API: Control Functions Source: https://context7.com/exmod-team/exiled/llms.txt Control the Alpha Warhead by starting, stopping, or detonating it. These actions can be customized with parameters like suppression of subtitles or specifying a trigger. ```csharp // --- Control --- Warhead.Start(); // begin countdown Warhead.Start(isAutomatic: false, suppressSubtitles: false, trigger: player); Warhead.Stop(); // cancel countdown Warhead.Stop(disabler: player); // cancel with specific disabler Warhead.Detonate(); // detonate immediately Warhead.Detonate(remaining: 10f); // detonate after 10 seconds ``` -------------------------------- ### Respawn API: Timer and Token Management Source: https://context7.com/exmod-team/exiled/llms.txt Accelerate respawn timers with Respawn.AdvanceTimer. Manage spawn tokens using Respawn.GrantTokens, Respawn.RemoveTokens, and check available tokens with Respawn.TryGetTokens. ```csharp // --- Advance respawn timer (makes wave spawn sooner) --- Respawn.AdvanceTimer(Faction.ChaosInsurgency, seconds: 30f); // --- Token management --- Respawn.GrantTokens(Faction.FoundationForces, amount: 5); Respawn.RemoveTokens(Faction.ChaosInsurgency, amount: 2); if (Respawn.TryGetTokens(SpawnableFaction.NtfWave, out int tokens)) Log.Info($"NTF tokens: {tokens}"); ``` -------------------------------- ### Config Class with Descriptions Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/plugins/structure.md Enhance configuration clarity by using `System.ComponentModel.DescriptionAttribute` to provide descriptions for each configuration option. ```csharp namespace MyPluginNamespace { using System.ComponentModel; using Exiled.API.Interfaces; public class Config : IConfig { [Description("Whether the plugin is enabled.")] public bool IsEnabled { get; set; } [Description("Whether debug messages should be shown in the console.")] bool Debug { get; set; } [Description("Config that must be true or false!")] public bool MyBoolConfig { get; set; } [Description("Config that must be a string!")] public string MyStringConfig { get; set; } [Description("Config that must be a number! Defaults to 5.")] public int MyIntConfig { get; set; } = 5; } } ``` -------------------------------- ### Player API - Lookup, Identity, Role, Health, Position, Inventory, Communication, Admin, Effects, Session Variables Source: https://context7.com/exmod-team/exiled/llms.txt Use Player.List to enumerate all players or Player.Get to fetch a specific one. This snippet covers managing player identity, roles, health, position, inventory, sending broadcasts/hints, administrative controls, applying/disabling effects, and using session variables. ```csharp using Exiled.API.Features; using Exiled.API.Features.Items; using PlayerRoles; using UnityEngine; // --- Lookup --- Player ply = Player.Get(2); // by player ID Player bySid = Player.Get("76561198000000000@steam"); // by UserId IReadOnlyCollection all = Player.List; // --- Identity --- Log.Info(ply.Nickname); Log.Info(ply.UserId); Log.Info(ply.Id.ToString()); Log.Info(ply.AuthenticationType.ToString()); Log.Info(ply.IsNPC.ToString()); // --- Role --- Log.Info(ply.Role.Type.ToString()); Log.Info(ply.IsScp.ToString()); ply.Role.Set(RoleTypeId.Tutorial); // --- Health --- Log.Info(ply.Health.ToString()); ply.Health = 100f; ply.MaxHealth = 150f; ply.IsGodModeEnabled = false; // --- Position & Movement --- ply.Position = new Vector3(0, -5, 0); ply.Teleport(RoleTypeId.ClassD.GetRandomSpawnLocation().Position); ply.Scale = new Vector3(1.5f, 1.5f, 1.5f); // --- Inventory --- ply.AddItem(ItemType.GunCOM18); ply.AddItem(ItemType.Medkit); ply.RemoveItem(ply.CurrentItem); ply.ClearInventory(); ply.ResetInventory(new[] { ItemType.Flashlight, ItemType.Radio }); ply.Ammo[ItemType.Ammo9x19] = 60; // --- Broadcasts & Hints --- ply.Broadcast(5, "Hello!", Broadcast.BroadcastFlags.Normal, false); ply.ShowHint("Press [E] to interact.", 3f); ply.ClearBroadcasts(); // --- Administrative --- ply.Kick("Rule violation."); ply.Ban(3600, "Cheating", "Admin"); ply.Mute(true); ply.IsMuted = true; ply.IsOverwatchEnabled = true; ply.IsBypassModeEnabled = true; ply.IsNoclipPermitted = true; // --- Effects --- ply.EnableEffect(duration: 10f, addDurationIfActive: true); ply.DisableEffect(); // --- Session Variables (temp per-player data, any type) --- ply.SessionVariables["kill_count"] = 0; if (ply.SessionVariables.TryGetValue("kill_count", out object val)) Log.Info($"Kills: {val}"); ``` -------------------------------- ### Respawn API: Pausing and Resuming Waves Source: https://context7.com/exmod-team/exiled/llms.txt Control respawn wave timers globally with Respawn.PauseWaves and Respawn.ResumeWaves, or individually for a specific faction using Respawn.PauseWave and Respawn.RestartWave. ```csharp // --- Pause / resume all waves --- Respawn.PauseWaves(); Respawn.ResumeWaves(); // --- Pause a specific faction's wave --- Respawn.PauseWave(SpawnableFaction.NtfWave); Respawn.RestartWave(SpawnableFaction.NtfWave); ``` -------------------------------- ### Basic Config Class Structure Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/plugins/structure.md Define a basic configuration class implementing `IConfig` with essential properties like `IsEnabled` and `Debug`. ```csharp namespace MyPluginNamespace { using Exiled.API.Interfaces; public class Config : IConfig { public bool IsEnabled { get; set; } public bool Debug { get; set; } } } ``` -------------------------------- ### Set EXILED_REFERENCES Environment Variable (Linux) Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/contributing/index.md Add this export command to your shell configuration file (e.g., ~/.bashrc) to set the EXILED_REFERENCES environment variable on Linux systems. This variable should point to the Managed directory of your SCP: Secret Laboratory Dedicated Server installation. ```bash export EXILED_REFERENCES="PATH" ``` -------------------------------- ### Checkout Development Branch Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/contributing/index.md Switch to the 'dev' branch for development. All pull requests should be submitted to this branch. ```bash git checkout dev ``` -------------------------------- ### Connecting and Disconnecting Event Handlers Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/plugins/events.md Demonstrates how to subscribe to and unsubscribe from events using the '+=' and '-=' operators within a plugin's lifecycle methods. ```csharp // Base plugin class // This example assumes a method called "OnEnraging" exists in this class. For best practice, you should create a new class to handle events. using Exiled.Events; public override void OnEnabled() { Scp096.Enraging += OnEnraging; // Scp096 is the event handler, while Enraging is the name of the event. The += operator connects this event to the provided method. } public override void OnDisabled() { Scp096.Enraging -= OnEnraging; // The -= operator disconnects this event from the provided method. } // Some other class using Exiled.Events.EventArgs; public void OnEnraging(EnragingEventArgs ev) // ev is the arguments for the event. Every event has a different argument class with different parameters, so make sure to check its documentation. { Log.Info(ev.Player.Nickname + " has just been enraged!"); } ``` -------------------------------- ### Respawn API: Forcing and Summoning Waves Source: https://context7.com/exmod-team/exiled/llms.txt Manually trigger respawn waves using Respawn.ForceWave with a Faction or SpawnableFaction. Use Respawn.SummonNtfChopper or Respawn.SummonChaosInsurgencyVan for specific vehicle effects. ```csharp // --- Force a respawn wave --- Respawn.ForceWave(Faction.FoundationForces); // force NTF wave Respawn.ForceWave(SpawnableFaction.ChaosWave); // force Chaos wave Respawn.SummonNtfChopper(); // trigger NTF chopper effect Respawn.SummonChaosInsurgencyVan(); // trigger Chaos van effect ``` -------------------------------- ### Hint Parameter Types Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/SCPSLRessources/NW_Documentation.md Lists the various data types that can be used as parameters for hints. ```csharp [0] = Text [1] = Timespan [2] = Ammo [3] = Item [4] = ItemCategory [5] = Byte [6] = SByte [7] = Short [8] = UShort [9] = Int [10] = UInt [11] = Long [12] = ULong [13] = Float [14] = Double [15] = PackedLong [16] = PackedULong [17] = Scp330Hint [18] = SSKeybind [19] = AnimationCurve ``` -------------------------------- ### Respawn API: Faction Influence and Spawn Protection Source: https://context7.com/exmod-team/exiled/llms.txt Adjust faction influence with Respawn.GrantInfluence, Respawn.GetInfluence, and Respawn.SetInfluence. Configure spawn protection using Respawn.ProtectionEnabled, Respawn.ProtectionTime, Respawn.ProtectedCanShoot, and Respawn.ProtectedTeams. ```csharp // --- Faction influence --- Respawn.GrantInfluence(Faction.FoundationForces, 10); float inf = Respawn.GetInfluence(Faction.FoundationForces); Respawn.SetInfluence(Faction.ChaosInsurgency, 50f); // --- Spawn protection --- Respawn.ProtectionEnabled = true; Respawn.ProtectionTime = 5f; // seconds Respawn.ProtectedCanShoot = false; Respawn.ProtectedTeams.Add(Team.ChaosInsurgency); ``` -------------------------------- ### Define Plugin Configuration with IConfig Source: https://context7.com/exmod-team/exiled/llms.txt Implement IConfig to create a configuration class for your EXILED plugin. Properties are automatically serialized to YAML and exposed to server operators. Use DescriptionAttribute for documentation. The IsEnabled property controls plugin loading. ```csharp using System.Collections.Generic; using System.ComponentModel; using Exiled.API.Features; using Exiled.API.Interfaces; using UnityEngine; public class AdvancedConfig : IConfig { [Description("Master enable/disable switch for this plugin.")] public bool IsEnabled { get; set; } = true; [Description("Output debug logs to the server console.")] public bool Debug { get; set; } = false; [Description("Maximum damage a Scientist can take per hit.")] public float ScientistMaxHitDamage { get; set; } = 1f; [Description("Roles that are immune to the Tesla gate.")] public List TeslaImmune { get; set; } = new() { PlayerRoles.RoleTypeId.NtfCaptain, PlayerRoles.RoleTypeId.Scientist, }; [Description("Broadcast sent to every joining player.")] public Broadcast JoinBroadcast { get; set; } = new("Welcome! Read the rules in #info.", 8); [Description("Spawn offset applied to tutorial players.")] public Vector3 TutorialSpawnOffset { get; set; } = new(0, 1, 0); // Nested dictionaries are supported [Description("Per-role friendly fire multipliers.")] public Dictionary RoleFFMultipliers { get; set; } = new() { { "ClassD", 0.5f }, { "Scientist", 0.0f }, }; } // Reading in OnEnabled: // Log.Info(Config.JoinBroadcast.Content); // "Welcome! Read the rules in #info." // Log.Info(Config.ScientistMaxHitDamage); // 1 ``` -------------------------------- ### Command Registration Source: https://context7.com/exmod-team/exiled/llms.txt Shows how to register custom commands for Remote Admin, Game Console, or the client by implementing `ICommand` and using the `[CommandHandler]` attribute. Parent commands can be used to group sub-commands. ```APIDOC ## Commands — `ICommand` and `ParentCommand` Register Remote Admin, Game Console, or Client (dot) commands by implementing `ICommand` and annotating with `[CommandHandler]`. Nest sub-commands under a `ParentCommand`. EXILED auto-discovers and registers all command types in your assembly. ```csharp using System; using CommandSystem; using Exiled.API.Features; using Exiled.API.Features.Pickups; using Exiled.Permissions.Extensions; // CheckPermission // --- Simple Remote Admin command --- [CommandHandler(typeof(RemoteAdminCommandHandler))] public class InspectCommand : ICommand { public string Command { get; } = "inspect"; public string[] Aliases { get; } = new[] { "ins" }; public string Description { get; } = "Inspect a player's inventory and position."; public bool Execute(ArraySegment arguments, ICommandSender sender, out string response) { if (!sender.CheckPermission("myplugin.inspect")) { response = "You don't have permission to use this command."; return false; } if (arguments.Count < 1) { response = "Usage: inspect "; return false; } if (!int.TryParse(arguments.At(0), out int playerId)) { response = "Invalid player ID."; return false; } Player ply = Player.Get(playerId); if (ply is null) { response = $"No player with ID {playerId}."; return false; } response = $"{ply.Nickname} | Role: {ply.Role.Type} | HP: {ply.Health:F0} | " + $ ``` -------------------------------- ### Map API: Spawn Pickup Source: https://context7.com/exmod-team/exiled/llms.txt Create and spawn a pickup item at a specified position and rotation on the map. The type and location of the spawned pickup are logged. ```csharp // --- Spawn a pickup on the map --- var pickup = Exiled.API.Features.Pickups.Pickup.CreateAndSpawn( ItemType.Medkit, new UnityEngine.Vector3(0, -5, 0), UnityEngine.Quaternion.identity); Log.Info($"Spawned {pickup.Type} at {pickup.Position}"); ``` -------------------------------- ### Cassie API: SCP Termination and Utilities Source: https://context7.com/exmod-team/exiled/llms.txt Handle SCP termination announcements using Cassie.ScpTermination, calculate spoken duration with Cassie.CalculateDuration, validate messages with Cassie.IsValid and Cassie.IsValidSentence, and clear the queue with Cassie.Clear. ```csharp // --- SCP termination (standard built-in) --- Player scpPlayer = Player.Get(p => p.IsScp).FirstOrDefault(); if (scpPlayer != null) Cassie.ScpTermination(scpPlayer, scpPlayer.ReferenceHub.playerStats.DealDamage(null)); ``` ```csharp // --- Calculate spoken duration --- float dur = Cassie.CalculateDuration("SCP 0 9 6 CONTAINEDSUCCESSFULLY"); Log.Info($"CASSIE will speak for ~{dur:F1}s"); ``` ```csharp // --- Validate words --- bool valid = Cassie.IsValid("CONTAINEDSUCCESSFULLY"); // true bool allOk = Cassie.IsValidSentence("SCP 0 9 6 CONTAINEDSUCCESSFULLY"); // true ``` ```csharp // --- Clear the CASSIE queue --- Cassie.Clear(); ``` -------------------------------- ### Cassie API: Send Announcements Source: https://context7.com/exmod-team/exiled/llms.txt Use Cassie.Message for plain text, Cassie.MessageTranslated for localized messages, Cassie.GlitchyMessage for distorted audio, and Cassie.DelayedMessage for timed announcements. Ensure necessary imports. ```csharp using Exiled.API.Features; // --- Plain message --- Cassie.Message("SCP 0 9 6 CONTAINEDSUCCESSFULLY", isHeld: false, isNoisy: true, isSubtitles: false); ``` ```csharp // --- With subtitle override --- Cassie.MessageTranslated( message: "ATTENTION ALL PERSONNEL SCP 0 7 3 HAS BREACHED CONTAINMENT", translation: "Attention all personnel: SCP-073 has breached containment.", isSubtitles: true); ``` ```csharp // --- Glitchy announcement --- Cassie.GlitchyMessage( "SCP 9 3 9 CONTAINEDSUCCESSFULLY", glitchChance: 0.1f, jamChance: 0.05f); ``` ```csharp // --- Delayed message (fires after 5 seconds) --- Cassie.DelayedMessage("RECONTAINMENTSEQUENCE INITIATED", delay: 5f); ``` -------------------------------- ### Create a Parent Command with Sub-commands Source: https://context7.com/exmod-team/exiled/llms.txt Define a ParentCommand to group related sub-commands. Ensure LoadGeneratedCommands is called and sub-commands are registered. The ExecuteParent method handles the base command logic. ```csharp // --- Parent command with sub-commands --- [CommandHandler(typeof(RemoteAdminCommandHandler))] public class EventCommand : ParentCommand { public EventCommand() => LoadGeneratedCommands(); public override string Command { get; } = "event"; public override string[] Aliases { get; } = new[] { "ev" }; public override string Description { get; } = "Event management commands."; public override void LoadGeneratedCommands() { RegisterCommand(new EventStartSubCommand()); RegisterCommand(new EventStopSubCommand()); } protected override bool ExecuteParent(ArraySegment arguments, ICommandSender sender, out string response) { response = "Usage: event "; return false; } } public class EventStartSubCommand : ICommand { public string Command { get; } = "start"; public string[] Aliases { get; } = Array.Empty(); public string Description { get; } = "Start the event."; public bool Execute(ArraySegment arguments, ICommandSender sender, out string response) { Server.SessionVariables["event_active"] = true; Cassie.Message("ATTENTION ALL PERSONNEL SPECIAL EVENT IS NOW ACTIVE"); response = "Event started."; return true; } } public class EventStopSubCommand : ICommand { public string Command { get; } = "stop"; public string[] Aliases { get; } = Array.Empty(); public string Description { get; } = "Stop the event."; public bool Execute(ArraySegment arguments, ICommandSender sender, out string response) { Server.SessionVariables["event_active"] = false; response = "Event stopped."; return true; } } ``` -------------------------------- ### LightingVideoSetting Enum Source: https://github.com/exmod-team/exiled/blob/master/EXILED/docs/articles/SCPSLRessources/NW_Documentation.md Defines video settings related to lighting and shadows. Used to control graphical fidelity and performance. ```csharp [0] = RenderShadows [1] = ShadowResolution [2] = RenderLights ```