public void onExiting(object sender, EventArgs args)
        {
            //Close world
            if (IsGameWorldloaded)
            {
                World.End();
            }

            ThreadManager.KillAllThreads();

            //Save the snooping data
            Snooper.Save();

            //Save the settings
            GameSettings.Save(Path.Combine(gameDirectory, "options.txt"));
#if DEBUG
            GameSettings.SaveDebug(Path.Combine(gameDirectory, "options.debug"));
#endif

            //Dispose of the discord hooks properly
            DiscordManager.ShutDown();

            //Save the logger
            Logger.Save();
        }
        /// <summary>
        /// This method is called ONCE per session, and is called from the Update() Loop the first time it is ever ran.
        /// Used for multithreaded initialization
        /// </summary>
        private void FirstUpdate()
        {
            //TODO: Loading screen, run this on a separate thread
#if !CONSOLE && CLIENT
            DiscordManager.InitialiseDiscord();
#endif

#if CLIENT
            OnTargetFPSChanged();
            Snooper.Initialise();

            InputManager.Initialise();

            //TODO: Rework for UI system
            font = Content.Load <SpriteFont>("MainFont");
#endif
            //TODO: Connect textures by string, and models are reloaded after textures are reloaded.
            TextureManager.Reload();

            //Initialise the Block & Item Managers
            blockRegistry = new BlockManager();
            itemRegistry  = new ItemManager();

            //Register the blocks and items
            BlockManager.RegisterBlocks();
            ItemManager.RegisterItems();

            GameSettings.Load(Path.Combine(gameDirectory, "options.txt"));
#if DEBUG
            GameSettings.LoadDebug(Path.Combine(gameDirectory, "options.debug"));
#endif

#if CLIENT
            //Register the UI Menus
            UiRegisterer.RegisterUiMenus();

            Window.TextInput += OnTextInput;
#endif
        }
        protected override void Update(GameTime gameTime)
        {
            //First tick initialization
            if (firstFrame == false)
            {
                firstFrame = true;
                FirstUpdate();
            }

            Time.GameTime = gameTime;
            InputManager.Update();

            base.Update(gameTime);

            if (quitOnEscape)
            {
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                {
                    Exit();
                }
            }
            else
            {
                //Handle pausing
                if (InputManager.Released("misc.pause"))
                {
                    TogglePause();
                }
            }

#if !CONSOLE && CLIENT
            //Screenshots
            if (InputManager.Released("misc.screenshot"))
            {
                CaptureScreenshot();
            }

#if DEBUG
            //Disable block rendering
            if (InputManager.IsPressed("debug.hotkey") && InputManager.Released("debug.renderchunks"))
            {
                GameSettings.RenderChunkBorders = !GameSettings.RenderChunkBorders;
            }

            //Show physics colliders
            if (InputManager.IsPressed("debug.hotkey") && InputManager.Released("debug.physicscolliders"))
            {
                GameSettings.Debug.RenderPhysicsTestLocations = !GameSettings.Debug.RenderPhysicsTestLocations;
            }

            //Show entity colliders
            if (InputManager.IsPressed("debug.hotkey") && InputManager.Released("debug.entitycolliders"))
            {
                GameSettings.DrawHitboxes = !GameSettings.DrawHitboxes;
            }

            //Respawn
            if (InputManager.IsPressed("debug.hotkey") && InputManager.Released("debug.respawn"))
            {
                if (IsGameWorldloaded)
                {
                    theWorld.player.position = new Vector3(theWorld.spawnX, theWorld.spawnY, theWorld.spawnZ);
                    theWorld.player.Velocity = Vector3.Zero;
                }
            }

            //Noclip
            if (InputManager.IsPressed("debug.hotkey") && InputManager.Released("debug.noclip"))
            {
                if (IsGameWorldloaded)
                {
                    theWorld.player.noClip = !theWorld.player.noClip;
                }
            }
#endif

            DiscordManager.OnUpdate();
#endif
            //Time logging
            Snooper.Snoop("time.totalplayed", gameTime.ElapsedGameTime.TotalSeconds);
            TimeSinceBoot += gameTime.ElapsedGameTime.TotalSeconds;

            Profiler.Start("UI Update", Color.LightCyan);
            foreach (GuiScreen ui in GUIs)
            {
                ui.Update();
            }
            Profiler.Stop("UI Update");

            IsMouseVisible = isPaused || IsGameWorldloaded == false;

            FinalUpdate();
        }