diff --git a/bindings/GeometryDash.bro b/bindings/GeometryDash.bro
index 241b5eb9..ba7c1f37 100644
--- a/bindings/GeometryDash.bro
+++ b/bindings/GeometryDash.bro
@@ -1,4 +1,5 @@
 // geode additions to make stl containers easier
+// clang-format off
 class GDString {
     void winDtor() = win 0xf6e0;
     char const* winCStr() = win 0xf710;
@@ -2104,6 +2105,14 @@ class GJGameLevel : cocos2d::CCNode {
     GJDifficulty getAverageDifficulty() = win 0xbd9b0;
     gd::string getUnpackedLevelDescription() = win 0xbf890;
 
+    static GJGameLevel* getCurrent() {
+        auto playLayer = PlayLayer::get();
+        if (playLayer) return playLayer->m_level;
+        auto editorLayer = LevelEditorLayer::get();
+        if (editorLayer) return editorLayer->m_level;
+        return nullptr;
+    }
+
     cocos2d::CCDictionary* m_lastBuildSave;
     int m_levelIDRand;
     int m_levelIDSeed;
@@ -3547,10 +3556,10 @@ class LevelCell : TableViewCell {
 }
 
 class LevelCommentDelegate {
-    virtual void loadCommentsFinished(cocos2d::CCArray *, const char*)  {}
-    virtual void loadCommentsFailed(const char*)  {}
+    virtual void loadCommentsFinished(cocos2d::CCArray*, char const*)  {}
+    virtual void loadCommentsFailed(char const*)  {}
     virtual void updateUserScoreFinished()  {}
-    virtual void setupPageInfo(gd::string, const char*)  {}
+    virtual void setupPageInfo(gd::string, char const*)  {}
 }
 
 class LevelDeleteDelegate {
@@ -3852,6 +3861,12 @@ class LevelSettingsObject : cocos2d::CCNode {
     static LevelSettingsObject* objectFromString(gd::string) = mac 0x945a0, win 0x16f440;
     void setupColorsFromLegacyMode(cocos2d::CCDictionary*) = mac 0xa6a30, win 0x170050;
 
+    static LevelSettingsObject* get() {
+        auto baseLayer = GJBaseGameLayer::get();
+        if (baseLayer) return baseLayer->m_levelSettings;
+        return nullptr;
+    }
+
     gd::string getSaveString() = mac 0x979c0, win 0x16ebf0;
 
     GJEffectManager* m_effectManager;
@@ -4032,7 +4047,7 @@ class MusicDownloadManager : cocos2d::CCNode, PlatformDownloadDelegate {
     cocos2d::CCDictionary* m_unknownDict;
     cocos2d::CCArray* m_handlers;
     cocos2d::CCDictionary* m_songsDict;
-    int m_unknown;
+    int m_priority;
 }
 
 class NumberInputDelegate {
@@ -5369,4 +5384,4 @@ class VideoOptionsLayer : FLAlertLayer {
 class LevelTools {
     static gd::string base64DecodeString(gd::string) = mac 0x294510, win 0x18b3b0;
 }
-
+// clang-format on
diff --git a/loader/include/Geode/utils/casts.hpp b/loader/include/Geode/utils/casts.hpp
index a98ee800..d49fcd41 100644
--- a/loader/include/Geode/utils/casts.hpp
+++ b/loader/include/Geode/utils/casts.hpp
@@ -9,7 +9,7 @@ namespace geode::cast {
     /**
      * Alias for static_cast
      */
-    template <typename T, typename F>
+    template <class T, class F>
     static constexpr T as(F const v) {
         return static_cast<T>(v);
     }
@@ -18,8 +18,8 @@ namespace geode::cast {
      * Cast from anything to anything else,
      * provided they are the same size
      */
-    template <typename T, typename F>
-    static constexpr T union_cast(F v) {
+    template <class T, class F>
+    static constexpr T union_cast(F const v) {
         static_assert(sizeof(F) == sizeof(T), "union_cast: R and T don't match in size!");
 
         union {
@@ -36,27 +36,40 @@ namespace geode::cast {
      * cast but uses reference syntactic sugar to
      * look cleaner.
      */
-    template <typename T, typename F>
+    template <class T, class F>
     static constexpr T reference_cast(F v) {
         return reinterpret_cast<T&>(v);
     }
 
     /**
-     * Cast an adjusted this pointer to it's base pointer
+     * Cast based on RTTI. Casts an adjusted this pointer
+     * to it's non offset form.
      */
-    template <typename T, typename F>
-    static constexpr T base_cast(F obj) {
-        return reinterpret_cast<T>(dynamic_cast<void*>(obj));
+    template <class T, class F>
+    static constexpr T base_cast(F const obj) {
+        return static_cast<T>(dynamic_cast<void*>(obj));
     }
 
     /**
-     * Cast based on RTTI. This is a replacement for
-     * dynamic_cast, since it doesn't work for gd.
+     * Cast based on RTTI. This is used to check
+     * if an object is exactly the class needed. Returns
+     * nullptr on failure.
      */
-    template <typename T, typename F>
-    static T typeid_cast(F obj) {
-        if (std::string(typeid(*obj).name()) == typeid(std::remove_pointer_t<T>).name())
-            return reinterpret_cast<T>(obj);
-        else return nullptr;
+    template <class T, class F>
+    static T exact_cast(F const obj) {
+        if (std::strcmp(typeid(*obj).name(), typeid(std::remove_pointer_t<T>).name()) == 0) {
+            return base_cast<T>(obj);
+        }
+        return nullptr;
+    }
+
+    /**
+     * Cast based on RTTI. This behaves as a replacement
+     * of dynamic_cast for cocos and gd classes,
+     * and must be used for expected results.
+     */
+    template <class T, class F>
+    static T safe_cast(F const obj) {
+        return typeinfo_cast<T>(obj);
     }
 }