public override void Initialize()
        {
            // Because of `Celeste.Tags.Initialize` of all things
            // We create a static CrystalStaticSpinner which needs to access Tags.TransitionUpdate
            // Which wouldn't be loaded in time for EverestModule.Load
            TimedTriggerSpikes.LoadDelayed();

            // Register CustomCassetteBlock types
            CustomCassetteBlock.Initialize();

            // We may hook methods in other mods, so this needs to be done after they're loaded
            AbstractPanel.LoadDelayed();
        }
        public override void Load()
        {
            Everest.Events.Level.OnLoadEntity += Level_OnLoadEntity;
            Everest.Events.CustomBirdTutorial.OnParseCommand += CustomBirdTutorial_OnParseCommand;

            RegisterOptionalDependencies();
            Everest.Events.Everest.OnRegisterModule += OnRegisterModule;

            DashStateRefill.Load();
            DreamTunnelDash.Load();
            SeekerDash.Load();

            DreamBlockDummy.Load();

            CustomDreamBlock.Load();
            // Individual Dream Blocks hooked in CustomDreamBlock.Load

            DreamDashCollider.Load();

            AbstractPanel.Load();
            // Panel-specific hooks loaded from AbstractPanel.Load

            ConnectedSwapBlockHooks.Hook();
            CustomCassetteBlock.Hook();

            AttachedWallBooster.Hook();
            MoveBlockRedirect.Load();
            MoveBlockRedirectable.Load();
            MoveSwapBlock.Load();

            AbstractInputController.Load();
            // Controller-specific hooks loaded from AbstractInputController.Load
            CassetteJumpFixController.Load();
            // TimedTriggerSpikes hooked in Initialize

            UnderwaterMusicController.Load();

            HeartGemShard.Load();
            CustomSummitGem.Load();

            CustomBooster.Load();

            DreamJellyfish.Load();
            DreamJellyfishRenderer.Load();

            ChainedKevin.Load();
        }
        public override void Unload()
        {
            Everest.Events.Level.OnLoadEntity -= Level_OnLoadEntity;
            Everest.Events.CustomBirdTutorial.OnParseCommand -= CustomBirdTutorial_OnParseCommand;

            Everest.Events.Everest.OnRegisterModule -= OnRegisterModule;

            DashStateRefill.Unload();
            DreamTunnelDash.Unload();
            SeekerDash.Unload();

            DreamBlockDummy.Unload();

            CustomDreamBlock.Unload();
            // Individual Dream Blocks unhooked in CustomDreamBlock.Unload

            AbstractPanel.Unload();
            DreamDashCollider.Unload();

            ConnectedSwapBlockHooks.Unhook();
            CustomCassetteBlock.Unhook();

            AttachedWallBooster.Unhook();
            MoveBlockRedirect.Unload();
            MoveBlockRedirectable.Unload();
            MoveSwapBlock.Unload();
            AbstractInputController.Unload();
            CassetteJumpFixController.Unload();
            TimedTriggerSpikes.Unload();

            UnderwaterMusicController.Unload();

            HeartGemShard.Unload();
            CustomSummitGem.Unload();

            CustomBooster.Unload();

            DreamJellyfish.Unload();
            DreamJellyfishRenderer.Unload();

            ChainedKevin.Unload();
        }