This guide covers how Exilebuddy runs. It's meant to help devs understand what goes on behind the scenes, and the order their code will execute.

There are 4 main phases of Exilebuddy.

The [Startup] phase is from when Exilebuddy is launched until the GUI fully loads.
The [Idle] phase is after the [Startup] phase when there is no bot running.
The [Running] phase is after the [Startup] phase when there is a bot running.
The [Shutdown] phase is when Exilebuddy is being closed.

[Startup]
- When you start Exilebuddy, you go through a series of startup setup steps.
- These include choosing the default language (currently only English is supported), the configuration to use, which is used to handle settings, and then choosing the Path of Exile process to attach to.
- When a process is attached to, Exilebuddy will setup some internal game related data for caching and API purposes.
- Once that has completed, 3rdparty code is processed, compiled, and then loaded.
- After loading has been completed, specific interface functions are called.
-- ContentManager is initialized first. This means the IBase.Initialize functions are called for any IContent objects loaded.
-- BotManager is initialized second. This means the IBase.Initialize functions are called for any IBot objects loaded.
-- RoutineManager is initialized thrid. This means the IBase.Initialize functions are called for any IRoutine objects loaded.
-- PluginManager is initialized last. This means the IBase.Initialize functions are called for any IPlugin objects loaded.
--- PluginManager will also enable all plugins that are configured to be enabled after initialization. This means the IEnableable.Enable function is called for all enabled IPlugin objects loaded.
- Next, final internal setup logic runs. This includes some additional GUI setup and registering global hotkeys.
- At this point, LokiPoe.IsBotFullyLoaded is set to true, and one last group of logic is executed.
- The message 'core_bot_fully_loaded_event' will be broadcast (inside the framelock) to inform all IContent, the current IBot, the current IRoutine, and all enabled IPlugins that everything is ready to go.
- Lastly, command line arguments and settings are checked for auto-starting and auto-minimizing the bot GUI.

[Idle]
- Assuming the bot is not auto-started, Exilebuddy will next enter the [Idle] phase.
- LokiPoe.OnGuiTick will be running on the GUI thread (outside the framelock) to provide the means to interact with Exilebuddy when it is not running.
- Otherwise, this is an idle phase, which means:
-- ProcessHookManager will not be enabled. Call LokiPoe.ProcessHookManager.Enable() to enable it.
-- LokiPoe.Input.Binding might not reflect current game settings. Call LokiPoe.Input.Binding.Update() to update them.
-- Not all game data might be cached yet, or might reflect old data until it is accessed again.

[Running]
- When BotManager.Start is called, Exilebuddy transitions into the [Running] phase.
- LokiPoe.OnGuiTick will be running on the GUI thread (outside the framelock).
- A new thread is created to run the bot. This is the "BotThread".
- The BotThread will disable and clear memory caching for GreyMagic.
- First, the current IBot object is started.
-- BotManager.PreStart is invoked inside the framelock.
-- IStartStopEvents.Start is called for the current IBot inside the framelock.
-- BotManager.PostStart is invoked inside the framelock.
- The BotThread will then enter it's main loop.
-- BotManager.MsBeforeNextTick is checked to see if a delay is needed before running again. If non-zero, a Sleep will run and the value cleared.
-- TimeOfLastTick is set to the current time.
-- The current IBot is ticked.
--- BotManager.PreTick is invoked inside the framelock.
--- ITickEvents.Tick is called for the current IBot inside the framelock.
--- BotManager.PostTick is invoked inside the framelock.
-- MsBetweenTicks is then used to sleep before the next BotThread loop cycle (which runs until an exit is signaled).
- When an exit signal is processed, the current IBot is stopped.
-- BotManager.PreStop is invoked inside the framelock.
-- IStartStopEvents.Stop is called for the current IBot inside the framelock.
-- BotManager.PostStop is invoked inside the framelock.
- The BotThread has now completed execution and is cleaned up.
- Exilebuddy transitions back into the [Idle] phase.

[Shutdown]
- When Exilebuddy is existing, it will be in the [Shutdown] phase.
- Specific interface functions are called.
-- PluginManager.Deinitialize is called first. This means the IBase.Deinitialize functions are called for any IPlugin objects loaded.
-- RoutineManager.Deinitialize is called second. This means the IBase.Deinitialize functions are called for any IRoutine objects loaded.
-- BotManager.Deinitialize is called third. This means the IBase.Deinitialize functions are called for any IBot objects loaded.
-- ContentManager.Deinitialize is called last. This means the IBase.Deinitialize functions are called for any IContent objects loaded.
- Various additional internal cleanup code executes and Exilebuddy exits.

As a whole, most of what Exilebuddy does is determined by the bot base (IBot) used. There are not any limitations on what a bot base can or can't do in terms of big picture designs. Currently, most bot bases make use of routines through the RoutineManager, plugins through the PluginManager, then divide logic into tasks via the TaskManager and coroutine logic. However, there's a lot of flexibility possible, some of which is already shown.

More discussion about designs and putting things together will be covered in another thread. For now, this concludes Exilebuddy's execution flow.