Why?
There’s something fascinating about looking beneath a game’s surface. Figuring out how it works, and finding ways to change things that weren’t supposed to be changed.
Here’s a little example on how it all works.
Loading plugins
[BepInPlugin("minimal.eft.plugin", "Minimal", "1.0.0")]
public class Loader : BaseUnityPlugin
{
public static GameObject gameObject;
public static ManualLogSource logger;
void Awake()
{
logger = Logger;
gameObject = new GameObject();
DontDestroyOnLoad(gameObject);
gameObject.AddComponent<Manager>();
}
} Global manager
public class Manager : MonoBehaviour
{
public static bool bLoaderQuestion = true;
public static Manager instance;
int flLoaderWidth = 200f;
void Start()
{
instance = this;
G.IsMenuFrozen = true;
T.SetupFolders();
T.PopulateAssets();
T.SetupShaders();
AttributeUtilities.LinkAttributes();
Colors.AddColors();
StartCoroutine(UpdateObjects());
}
void Update()
{
bLoaderQuestion = false;
G.IsMenuFrozen = false;
if (bLoaderQuestion)
{
if (Input.GetKeyDown(KeyCode.Y) || Input.GetKeyDown(KeyCode.N))
{
bLoaderQuestion = false;
G.IsMenuFrozen = false;
if (Input.GetKeyDown(KeyCode.N))
{
Loader.gameObject.DestroyAllChildren();
DestroyObject(Loader.gameObject);
}
}
}
}
void OnGUI()
{
Styles.Setup();
Colors.Interpolate(out Colors.RainbowColor, 0);
if (bLoaderQuestion)
{
GUI.Box(new Rect(G.Settings.MenuSettings.X - (flLoaderWidth / 2) - 2, G.Settings.MenuSettings.Y - 2, (flLoaderWidth + 4), 59), "", Styles.MenuPrimary); // border
GUI.Box(new Rect(G.Settings.MenuSettings.X - (flLoaderWidth / 2), G.Settings.MenuSettings.Y + 0, flLoaderWidth, 55), "", Styles.MenuBackground); // background
GUI.Label(new Rect(G.Settings.MenuSettings.X - (flLoaderWidth / 2), G.Settings.MenuSettings.Y + -5, flLoaderWidth, 35), "Load Avalon?", Styles.MenuTitle); // question
GUI.Label(new Rect(G.Settings.MenuSettings.X - (flLoaderWidth / 2) + 5, G.Settings.MenuSettings.Y + 25, flLoaderWidth, 35), "Yes (Y)", Styles.MenuTextColorLeft); // yes
GUI.Label(new Rect(G.Settings.MenuSettings.X - (flLoaderWidth / 2) - 5, G.Settings.MenuSettings.Y + 25, flLoaderWidth, 35), "No (N)", Styles.MenuTextColorRight); // no
}
if (G.MainCamera == null)
G.MainCamera = Camera.main;
}
} Backend structure
public class structure
{
public static bool keyCooldown = false;
public static IEnumerator KeyboardEventCooldown()
{
keyCooldown = true;
yield return new WaitForSeconds(0.2f);
keyCooldown = false;
}
public static void SetupMenu(string menuName, string title, int maxSize)
{
if (G.Submenu != title || G.MaxMenuSize != maxSize)
{
G.Submenu = title;
G.MaxMenuSize = maxSize;
G.MenuSize = 0;
var result = G.SavedCursors.SingleOrDefault(x => x.Key == G.CurrentMenu);
G.Cursor = (result.Value != null) ? result.Value : 0;
G.Dividers = new bool[maxSize + 1];
for (int i = 0; i < maxSize; i++)
G.Dividers[i] = false;
}
}
public static void AddOpt(string text, int index, string desc = "", bool enabled = true)
{
if (G.Cursor == index)
{
GUI.Box(new Rect(G.Settings.MenuSettings.X - (G.Settings.MenuSettings.Width / 2), G.Settings.MenuSettings.Y + (70 + index * 35), G.Settings.MenuSettings.Width, 35), "", Styles.MenuScrollbar);
GUI.Label(new Rect(G.Settings.MenuSettings.X - (G.Settings.MenuSettings.Width / 2) + 10, G.Settings.MenuSettings.Y + (105 + G.MaxMenuSize * 35), G.Settings.MenuSettings.Width, 35), desc, (G.Settings.MenuSettings.DesignIndex == 0 ? Styles.MenuTextColorLeft : Styles.MenuTextLeft));
if (Event.current.Equals(Event.KeyboardEvent("F")) && !keyCooldown && enabled)
{
Manager.ExecuteOptions();
Manager.instance.StartCoroutine(KeyboardEventCooldown());
}
}
GUI.Label(new Rect(G.Settings.MenuSettings.X - (G.Settings.MenuSettings.Width / 2) + 10, G.Settings.MenuSettings.Y + (70 + index * 35), G.Settings.MenuSettings.Width, 35), (!enabled ? string.Format("<color=#ffffff40>{0}</color>", text) : text), Styles.MenuTextLeft);
if (G.MenuSize != G.MaxMenuSize)
G.MenuSize++;
}
} 
Frontend structure
[Comp]
public class MainMenu : MonoBehaviour
{
void OnGUI()
{
if (G.IsMenuOpen)
{
switch (G.Settings.MenuSettings.DesignIndex)
{
case 0:
GUI.Box(new Rect(G.Settings.MenuSettings.X - (G.Settings.MenuSettings.Width / 2) - 2, G.Settings.MenuSettings.Y - 2, G.Settings.MenuSettings.Width + 4, (140 + G.MaxMenuSize * 35) + 4), "", Styles.MenuPrimary); // border
GUI.Box(new Rect(G.Settings.MenuSettings.X - (G.Settings.MenuSettings.Width / 2), G.Settings.MenuSettings.Y + 0, G.Settings.MenuSettings.Width, (140 + G.MaxMenuSize * 35)), "", Styles.MenuBackground); // background
GUI.Box(new Rect(G.Settings.MenuSettings.X - (G.Settings.MenuSettings.Width / 2), G.Settings.MenuSettings.Y + 35, G.Settings.MenuSettings.Width, 35), "", Styles.MenuSecondary); // top bar
GUI.Box(new Rect(G.Settings.MenuSettings.X - (G.Settings.MenuSettings.Width / 2), G.Settings.MenuSettings.Y + (105 + G.MaxMenuSize * 35), G.Settings.MenuSettings.Width, 35), "", Styles.MenuSecondary); // bottom bar
GUI.Label(new Rect(G.Settings.MenuSettings.X - (G.Settings.MenuSettings.Width / 2), G.Settings.MenuSettings.Y + 0, G.Settings.MenuSettings.Width, 35), G.MenuName, Styles.MenuTitle); // title
GUI.Label(new Rect(G.Settings.MenuSettings.X - (G.Settings.MenuSettings.Width / 2) + 10, G.Settings.MenuSettings.Y + 35, G.Settings.MenuSettings.Width, 35), G.Submenu, Styles.MenuTextColorLeft); // subtitle
GUI.Label(new Rect(G.Settings.MenuSettings.X - (G.Settings.MenuSettings.Width / 2) - 10, G.Settings.MenuSettings.Y + 35, G.Settings.MenuSettings.Width, 35), $"{(G.Cursor + 1)} / {(G.MaxMenuSize + 1)}", Styles.MenuTextColorRight); // optcount
break;
}
switch (G.CurrentMenu)
{
case "main":
Structure.SetupMenu("main", "Main Menu", 0);
Structure.AddOpt("Hello World", 0, "This is a description.");
break;
}
}
}
} 


Monitoring controls
[Comp]
public class Controls : MonoBehaviour
{
void Update()
{
if (!G.IsMenuFrozen)
{
if (Input.GetKeyDown(KeyCode.LeftAlt))
G.IsMenuOpen = !G.IsMenuOpen;
if (G.IsMenuOpen)
{
if (Input.GetKeyDown(KeyCode.UpArrow))
{
G.Cursor--;
if (G.Cursor < 0)
G.Cursor = G.MenuSize;
}
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
G.Cursor++;
if (G.Cursor > G.MenuSize)
G.Cursor = 0;
}
else if (Input.GetKeyDown(KeyCode.Backspace))
{
var result = G.SavedCursors.SingleOrDefault(x => x.Key == G.CurrentMenu);
if (result.Value != null)
G.SavedCursors.Remove(result);
}
}
}
}
}