diff --git a/EXILED/Exiled.Events/EventArgs/Interfaces/ISnakeEvent.cs b/EXILED/Exiled.Events/EventArgs/Interfaces/ISnakeEvent.cs
new file mode 100644
index 0000000000..b2a3cda8ca
--- /dev/null
+++ b/EXILED/Exiled.Events/EventArgs/Interfaces/ISnakeEvent.cs
@@ -0,0 +1,28 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Events.EventArgs.Interfaces
+{
+ using Exiled.API.Features.Items;
+ using InventorySystem.Items.Keycards.Snake;
+
+ ///
+ /// Event args used for all related events.
+ ///
+ public interface ISnakeEvent : IPlayerEvent
+ {
+ ///
+ /// Gets the Snake game controller.
+ ///
+ public SnakeEngine Engine { get; }
+
+ ///
+ /// Gets the keycard that triggered this event.
+ ///
+ public Keycard Keycard { get; }
+ }
+}
\ No newline at end of file
diff --git a/EXILED/Exiled.Events/EventArgs/Snake/GainedScoreEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Snake/GainedScoreEventArgs.cs
new file mode 100644
index 0000000000..d1ac92e0ee
--- /dev/null
+++ b/EXILED/Exiled.Events/EventArgs/Snake/GainedScoreEventArgs.cs
@@ -0,0 +1,49 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Events.EventArgs.Snake
+{
+ using Exiled.API.Features.Items;
+ using Interfaces;
+ using InventorySystem.Items.Keycards.Snake;
+
+ ///
+ /// Contains all information after a player gains score in the Snake minigame.
+ ///
+ public class GainedScoreEventArgs : ISnakeEvent
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The instance.
+ /// The who triggered this event.
+ /// The triggering this event.
+ public GainedScoreEventArgs(SnakeEngine engine, API.Features.Player player, Keycard keycard)
+ {
+ Engine = engine;
+ Player = player;
+ Score = engine.Score;
+ Keycard = keycard;
+ }
+
+ ///
+ public SnakeEngine Engine { get; }
+
+ ///
+ /// Gets the person playing the game.
+ ///
+ public API.Features.Player Player { get; }
+
+ ///
+ public Keycard Keycard { get; }
+
+ ///
+ /// Gets the newly obtained score.
+ ///
+ public int Score { get; }
+ }
+}
\ No newline at end of file
diff --git a/EXILED/Exiled.Events/EventArgs/Snake/GameOverEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Snake/GameOverEventArgs.cs
new file mode 100644
index 0000000000..fe9498324e
--- /dev/null
+++ b/EXILED/Exiled.Events/EventArgs/Snake/GameOverEventArgs.cs
@@ -0,0 +1,55 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Events.EventArgs.Snake
+{
+ using Exiled.API.Features.Items;
+ using Interfaces;
+ using InventorySystem.Items.Keycards.Snake;
+
+ ///
+ /// Contains all information after a player loses at Snake.
+ ///
+ public class GameOverEventArgs : ISnakeEvent
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The instance.
+ /// The who triggered this event.
+ /// The triggering this event.
+ public GameOverEventArgs(SnakeEngine engine, API.Features.Player player, Keycard keycard)
+ {
+ Engine = engine;
+ Player = player;
+ FinalScore = engine.Score;
+ Length = engine.CurLength;
+ Keycard = keycard;
+ }
+
+ ///
+ public SnakeEngine Engine { get; }
+
+ ///
+ /// Gets the person playing the game.
+ ///
+ public API.Features.Player Player { get; }
+
+ ///
+ public Keycard Keycard { get; }
+
+ ///
+ /// Gets the final score.
+ ///
+ public int FinalScore { get; }
+
+ ///
+ /// Gets the final length of the snake.
+ ///
+ public int Length { get; }
+ }
+}
\ No newline at end of file
diff --git a/EXILED/Exiled.Events/EventArgs/Snake/NewGameEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Snake/NewGameEventArgs.cs
new file mode 100644
index 0000000000..4a96c0df1e
--- /dev/null
+++ b/EXILED/Exiled.Events/EventArgs/Snake/NewGameEventArgs.cs
@@ -0,0 +1,43 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Events.EventArgs.Snake
+{
+ using Exiled.API.Features.Items;
+ using Interfaces;
+ using InventorySystem.Items.Keycards.Snake;
+
+ ///
+ /// Contains all information when a player starts a new snake game.
+ ///
+ public class NewGameEventArgs : ISnakeEvent
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The instance.
+ /// The who triggered this event.
+ /// The triggering this event.
+ public NewGameEventArgs(SnakeEngine engine, API.Features.Player player, Keycard keycard)
+ {
+ Engine = engine;
+ Player = player;
+ Keycard = keycard;
+ }
+
+ ///
+ public SnakeEngine Engine { get; }
+
+ ///
+ /// Gets the person playing the game.
+ ///
+ public API.Features.Player Player { get; }
+
+ ///
+ public Keycard Keycard { get; }
+ }
+}
\ No newline at end of file
diff --git a/EXILED/Exiled.Events/Exiled.Events.csproj b/EXILED/Exiled.Events/Exiled.Events.csproj
index 620625057d..528d035ba6 100644
--- a/EXILED/Exiled.Events/Exiled.Events.csproj
+++ b/EXILED/Exiled.Events/Exiled.Events.csproj
@@ -37,6 +37,7 @@
+
diff --git a/EXILED/Exiled.Events/Handlers/Snake.cs b/EXILED/Exiled.Events/Handlers/Snake.cs
new file mode 100644
index 0000000000..8b2d3e2e89
--- /dev/null
+++ b/EXILED/Exiled.Events/Handlers/Snake.cs
@@ -0,0 +1,62 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Events.Handlers
+{
+#pragma warning disable SA1623 // Property summary documentation should match accessors
+
+ using Exiled.Events.EventArgs.Snake;
+ using Features;
+
+ ///
+ /// Handles Snake related events.
+ ///
+ public class Snake
+ {
+ ///
+ /// Invoked when gaining score in Snake.
+ ///
+ public static Event GainedScore { get; set; } = new();
+
+ ///
+ /// Invoked when a player loses in Snake.
+ ///
+ public static Event GameOver { get; set; } = new();
+
+ ///
+ /// Invoked when a player starts a new game.
+ ///
+ public static Event NewGame { get; set; } = new();
+
+ ///
+ /// Called when a player gains score in Snake.
+ ///
+ /// The instance.
+ public static void OnGainedScore(GainedScoreEventArgs ev)
+ {
+ GainedScore.InvokeSafely(ev);
+ }
+
+ ///
+ /// Called when a player loses in Snake.
+ ///
+ /// The instance.
+ public static void OnGameOver(GameOverEventArgs ev)
+ {
+ GameOver.InvokeSafely(ev);
+ }
+
+ ///
+ /// Called when a player starts a new game in Snake.
+ ///
+ /// The instance.
+ public static void OnNewGame(NewGameEventArgs ev)
+ {
+ NewGame.InvokeSafely(ev);
+ }
+ }
+}
\ No newline at end of file
diff --git a/EXILED/Exiled.Events/Patches/Events/Snake/ChaosKeycard.cs b/EXILED/Exiled.Events/Patches/Events/Snake/ChaosKeycard.cs
new file mode 100644
index 0000000000..f17b99c056
--- /dev/null
+++ b/EXILED/Exiled.Events/Patches/Events/Snake/ChaosKeycard.cs
@@ -0,0 +1,61 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Events.Patches.Events.Snake
+{
+ using System.Collections.Generic;
+ using System.Reflection.Emit;
+
+ using Attributes;
+ using Exiled.API.Features.Items;
+ using HarmonyLib;
+ using InventorySystem.Items.Keycards;
+ using InventorySystem.Items.Keycards.Snake;
+
+ using static HarmonyLib.AccessTools;
+
+ ///
+ /// Patches .
+ ///
+ [EventPatch(typeof(Handlers.Snake), nameof(Handlers.Snake.GainedScore))]
+ [EventPatch(typeof(Handlers.Snake), nameof(Handlers.Snake.GameOver))]
+ [EventPatch(typeof(Handlers.Snake), nameof(Handlers.Snake.NewGame))]
+ [HarmonyPatch(typeof(ChaosKeycardItem), nameof(ChaosKeycardItem.ServerProcessCustomCmd))]
+ internal static class ChaosKeycard
+ {
+ private static IEnumerable Transpiler(IEnumerable instructions)
+ {
+ CodeMatcher matcher = new CodeMatcher(instructions)
+ .MatchEndForward(new CodeMatch(OpCodes.Ldc_I4_1))
+ .Advance(-1)
+ .Insert(
+ new(OpCodes.Ldarg_0),
+ new(OpCodes.Ldloc_1),
+ new(OpCodes.Call, Method(typeof(ChaosKeycard), nameof(OnCardUse))));
+
+ return matcher.InstructionEnumeration();
+ }
+
+ private static void OnCardUse(ChaosKeycardItem itemBase, SnakeNetworkMessage message)
+ {
+ Keycard item = Item.Get(itemBase);
+ API.Features.Player player = item.Owner;
+
+ if (!ChaosKeycardItem.SnakeSessions.TryGetValue(item.Serial, out SnakeEngine engine))
+ return;
+
+ bool isNewGame = message.HasFlag(SnakeNetworkMessage.SyncFlags.GameReset);
+
+ if(message.HasFlag(SnakeNetworkMessage.SyncFlags.HasNewFood) && !isNewGame)
+ Handlers.Snake.OnGainedScore(new (engine, player, item));
+ else if (message.HasFlag(SnakeNetworkMessage.SyncFlags.GameOver))
+ Handlers.Snake.OnGameOver(new(engine, player, item));
+ else if (isNewGame)
+ Handlers.Snake.OnNewGame(new(engine, player, item));
+ }
+ }
+}
\ No newline at end of file