public static void Update()
 {
     try {
         var gs = InterOp.get_game_state();
         if (gs == GameState.TitleScreen)
         {
             UberStateController.SkipListeners = true;
             if (TitleScreenCallback != null)
             {
                 OnTitleScreen();
             }
         }
         else if (gs == GameState.Game)
         {
             UberStateController.SkipListeners = false;
             UberStateController.Update();
             if (InputUnlockCallback != null && InterOp.player_can_move())
             {
                 OnInputUnlock();
             }
             SeedController.UpdateGoal();
             TrackFileController.Update();
         }
         AHK.Tick();
         BonusItemController.Update();
         DiscordController.Update();
         Client.Update();
     } catch (Exception e) {
         Log($"Update error: {e.Message}\n{e.StackTrace}");
     }
 }
        public static bool Initialize()
        {
            try {
                if (logThread == null)
                {
                    logThread = new Thread(() => {
                        while (true)
                        {
                            try {
                                var txt = logQueue.Take();
                                while (logQueue.TryTake(out var line))
                                {
                                    txt += line;
                                }
                                File.AppendAllText(LogFile, txt);
                            } catch (Exception e) {
                                if (Dev)
                                {
                                    AHK.Print($"error logging: {e}", toMessageLog: false);
                                }
                            }
                        }
                    });
                    logThread.Start();
                }

                BasePath = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(InterOp.get_base_path());
                Debug($"Init: set base path to {BasePath}");

                if (!Directory.Exists(SaveFolder))
                {
                    Directory.CreateDirectory(SaveFolder);
                }

                if (!File.Exists(SeedPathFile))
                {
                    File.WriteAllText(SeedPathFile, BasePath + ".currentseed");
                }

                foreach (var fileName in new string[] { LogFile, MessageLog })
                {
                    if (!File.Exists(fileName))
                    {
                        File.WriteAllText(fileName, "");
                        Log($"Wrote blank {fileName} (normal for first-time init)");
                    }
                }

                AHK.Init();
                SeedController.ReadSeed(true);

                Client.UberStateRegistered = UberStateController.RegisterSyncedUberState;
                DiscordController.Initialize();

                Debug("Init: Complete", false);
                return(true);
            } catch (Exception e) {
                Log($"init error: {e.Message}\n{e.StackTrace}");
                return(true);
            }
        }