diff --git a/.gitignore b/.gitignore
index eed1617f..119b6b2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,20 +46,29 @@ build2
 build-docs/
 bin
 
+# Ignore docs folders
 docs/**
 docs
 
+# Ignore codegenned files
 loader/src/internal/about.hpp
 loader/src/internal/resources.hpp
 loader/resources/mod.json
 loader/resources/version
 loader/resources/blanks/rename.js
+loader/resources/about.md
 loader/resources/changelog.md
+loader/resources/support.md
+
+# Ignore generated files
+installer/mac/*.pkg
+installer/windows/*.exe
+
+# Ignore fod's include directories which are stored in this funny file
 fods-catgirl-hideout.txt
+
+# Ignore I don't even know what that is probably fod's flash testing script
 test-docs.bat
 
-# krita files too because alk is funny
+# Ignore krita files too because we don't want our project files shaking my head
 **/*.kra
-
-installer/mac/*.pkg
-installer/windows/*.exe
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 180b2d85..f454003e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
 # Geode Changelog
 
+## v1.3.2
+ * Fix alignment of some textures (8f39c38)
+ * Bring back unknown problems (0663569)
+ * Fix some Windows 7 incompatibility (2d2bdd1)
+ * Remove enabled from the crashlogs (5b7d318)
+ * Make index unzipping async (7c582f1)
+ * Fix mods by developer crashing when mod was toggled (a6a47bf)
+ * Fix nested lists in the markdown (2723588)
+ * Fix search paths (8f39c38, aa55ebe)
+
 ## v1.3.1
  * Fix TulipHook not relocating RIP relative operands on MacOS (6cad19d)
 
diff --git a/VERSION b/VERSION
index e21e727f..88c5fb89 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.4.0
\ No newline at end of file
+1.4.0
diff --git a/bindings/Cocos2d.bro b/bindings/Cocos2d.bro
index 632ce503..4d1d2dab 100644
--- a/bindings/Cocos2d.bro
+++ b/bindings/Cocos2d.bro
@@ -360,6 +360,7 @@ class cocos2d::CCImage {
 class cocos2d::CCKeyboardDispatcher {
 	bool dispatchKeyboardMSG(cocos2d::enumKeyCodes, bool) = mac 0xe8190;
 	const char* keyToString(cocos2d::enumKeyCodes) = mac 0xe8450;
+	void updateModifierKeys(bool shft, bool ctrl, bool alt, bool cmd) = mac 0xe8430;
 }
 
 [[link(win)]]
diff --git a/bindings/GeometryDash.bro b/bindings/GeometryDash.bro
index ab336f38..d67e0028 100644
--- a/bindings/GeometryDash.bro
+++ b/bindings/GeometryDash.bro
@@ -4320,7 +4320,7 @@ class MoreOptionsLayer : FLAlertLayer, TextInputDelegate, GooglePlayDelegate {
     static MoreOptionsLayer* create() = win 0x1de850;
     virtual bool init() = mac 0x43f470, win 0x1DE8F0;
     void addToggle(const char* name, const char* key, const char* info) = mac 0x440430, win 0x1df6b0;
-    void onKeybindings(cocos2d::CCObject* sender) = win 0x749d0;
+    void onKeybindings(cocos2d::CCObject* sender) = mac 0x4410e0, win 0x749d0;
     void onToggle(cocos2d::CCObject* sender) = mac 0x441370;
 }
 
diff --git a/cmake/GeodeFile.cmake b/cmake/GeodeFile.cmake
index 4c7efaff..f44b7d26 100644
--- a/cmake/GeodeFile.cmake
+++ b/cmake/GeodeFile.cmake
@@ -307,6 +307,8 @@ function(package_geode_resources_now proname src dest header_dest)
         if (NOT FILE_NAME STREQUAL ".geode_cache" AND NOT FILE_SHOULD_HASH EQUAL -1)
             
             file(SHA256 ${file} COMPUTED_HASH)
+            file(SIZE ${file} FILE_SIZE)
+            message(STATUS "Hashed ${file} to ${COMPUTED_HASH} (${FILE_SIZE} bytes)")
             list(APPEND HEADER_FILE "\t{ \"${FILE_NAME}\", \"${COMPUTED_HASH}\" },\n")
 
             # list(APPEND HEADER_FILE "\t\"${FILE_NAME}\",\n")
diff --git a/codegen/src/BindingGen.cpp b/codegen/src/BindingGen.cpp
index eb4359c3..199e2555 100644
--- a/codegen/src/BindingGen.cpp
+++ b/codegen/src/BindingGen.cpp
@@ -185,7 +185,8 @@ std::string generateBindingHeader(Root const& root, ghc::filesystem::path const&
 
         single_output += fmt::format(::format_strings::class_start,
             fmt::arg("class_name", cls.name),
-            fmt::arg("base_classes", supers)
+            fmt::arg("base_classes", supers)//,
+            // fmt::arg("hidden", str_if("GEODE_HIDDEN ", (codegen::platform & (Platform::Mac | Platform::iOS)) != Platform::None))
         );
 
         // what.
diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt
index 4258f77a..422bf8d5 100644
--- a/loader/CMakeLists.txt
+++ b/loader/CMakeLists.txt
@@ -27,10 +27,13 @@ execute_process(
 )
 
 # Package info file for internal representation
+set(GEODE_RESOURCES_PATH ${CMAKE_CURRENT_SOURCE_DIR}/resources)
 configure_file(resources/mod.json.in ${CMAKE_CURRENT_SOURCE_DIR}/resources/mod.json)
 file(READ resources/mod.json LOADER_MOD_JSON)
-configure_file(${GEODE_ROOT_PATH}/VERSION ${CMAKE_CURRENT_SOURCE_DIR}/resources/version COPYONLY)
-configure_file(${GEODE_ROOT_PATH}/CHANGELOG.md ${CMAKE_CURRENT_SOURCE_DIR}/resources/changelog.md COPYONLY)
+configure_file(${GEODE_ROOT_PATH}/VERSION ${GEODE_RESOURCES_PATH}/version COPYONLY)
+configure_file(${GEODE_RESOURCES_PATH}/about.md.in ${GEODE_RESOURCES_PATH}/about.md NEWLINE_STYLE LF)
+configure_file(${GEODE_ROOT_PATH}/CHANGELOG.md ${GEODE_RESOURCES_PATH}/changelog.md NEWLINE_STYLE LF)
+configure_file(${GEODE_RESOURCES_PATH}/support.md.in ${GEODE_RESOURCES_PATH}/support.md NEWLINE_STYLE LF)
 configure_file(src/internal/about.hpp.in ${CMAKE_CURRENT_SOURCE_DIR}/src/internal/about.hpp)
 
 # Source files
diff --git a/loader/include/Geode/cocos/platform/android/CCPlatformDefine.h b/loader/include/Geode/cocos/platform/android/CCPlatformDefine.h
index 93fe1c46..3f9a88d1 100644
--- a/loader/include/Geode/cocos/platform/android/CCPlatformDefine.h
+++ b/loader/include/Geode/cocos/platform/android/CCPlatformDefine.h
@@ -3,12 +3,8 @@
 
 #include <android/log.h>
 
-#ifdef GEODE_EXPORTING
-    #define CC_DLL __attribute__((visibility("default")))
-#else
-    #define CC_DLL 
-#endif
-#define ACTUAL_CC_DLL CC_DLL
+#define CC_DLL 
+#define ACTUAL_CC_DLL
 
 #define CC_NO_MESSAGE_PSEUDOASSERT(cond)                        \
     if (!(cond)) {                                              \
diff --git a/loader/include/Geode/cocos/platform/ios/CCPlatformDefine.h b/loader/include/Geode/cocos/platform/ios/CCPlatformDefine.h
index 74bc5d07..df4e4242 100644
--- a/loader/include/Geode/cocos/platform/ios/CCPlatformDefine.h
+++ b/loader/include/Geode/cocos/platform/ios/CCPlatformDefine.h
@@ -3,12 +3,8 @@
 
 #include <assert.h>
 
-#ifdef GEODE_EXPORTING
-    #define CC_DLL __attribute__((visibility("default")))
-#else
-    #define CC_DLL 
-#endif
-#define ACTUAL_CC_DLL CC_DLL
+#define CC_DLL //__attribute__((visibility("hidden")))
+#define ACTUAL_CC_DLL
 
 #define CC_ASSERT(cond) assert(cond)
 
diff --git a/loader/include/Geode/cocos/platform/mac/CCPlatformDefine.h b/loader/include/Geode/cocos/platform/mac/CCPlatformDefine.h
index e542eecb..8ccb4edd 100644
--- a/loader/include/Geode/cocos/platform/mac/CCPlatformDefine.h
+++ b/loader/include/Geode/cocos/platform/mac/CCPlatformDefine.h
@@ -3,12 +3,8 @@
 
 #include <assert.h>
 
-#ifdef GEODE_EXPORTING
-    #define CC_DLL __attribute__((visibility("default")))
-#else
-    #define CC_DLL 
-#endif
-#define ACTUAL_CC_DLL CC_DLL
+#define CC_DLL //__attribute__((visibility("hidden")))
+#define ACTUAL_CC_DLL
 
 
 #if CC_DISABLE_ASSERT > 0
diff --git a/loader/resources/about.md b/loader/resources/about.md.in
similarity index 100%
rename from loader/resources/about.md
rename to loader/resources/about.md.in
diff --git a/loader/resources/support.md b/loader/resources/support.md.in
similarity index 100%
rename from loader/resources/support.md
rename to loader/resources/support.md.in
diff --git a/loader/src/loader/LoaderImpl.hpp b/loader/src/loader/LoaderImpl.hpp
index 24920413..ab6f4b1a 100644
--- a/loader/src/loader/LoaderImpl.hpp
+++ b/loader/src/loader/LoaderImpl.hpp
@@ -13,7 +13,6 @@
 #include <Geode/utils/ranges.hpp>
 #include <Geode/utils/MiniFunction.hpp>
 #include "ModImpl.hpp"
-#include <about.hpp>
 #include <crashlog.hpp>
 #include <mutex>
 #include <optional>
diff --git a/loader/src/ui/internal/info/DevProfilePopup.cpp b/loader/src/ui/internal/info/DevProfilePopup.cpp
index f5146e84..6571b078 100644
--- a/loader/src/ui/internal/info/DevProfilePopup.cpp
+++ b/loader/src/ui/internal/info/DevProfilePopup.cpp
@@ -5,8 +5,9 @@
 #include "../list/ModListCell.hpp"
 #include "../list/ModListLayer.hpp"
 
-bool DevProfilePopup::setup(std::string const& developer) {
+bool DevProfilePopup::setup(std::string const& developer, ModListLayer* list) {
     m_noElasticity = true;
+    m_layer = list;
 
     this->setTitle("Mods by " + developer);
 
@@ -18,7 +19,7 @@ bool DevProfilePopup::setup(std::string const& developer) {
     for (auto& mod : Loader::get()->getAllMods()) {
         if (mod->getDeveloper() == developer) {
             auto cell = ModCell::create(
-                mod, nullptr, ModListDisplay::Concise, { 358.f, 40.f }
+                mod, m_layer, ModListDisplay::Concise, { 358.f, 40.f }
             );
             cell->disableDeveloperButton();
             items->addObject(cell);
@@ -31,7 +32,7 @@ bool DevProfilePopup::setup(std::string const& developer) {
             continue;
         }
         auto cell = IndexItemCell::create(
-            item, nullptr, ModListDisplay::Concise, { 358.f, 40.f }
+            item, m_layer, ModListDisplay::Concise, { 358.f, 40.f }
         );
         cell->disableDeveloperButton();
         items->addObject(cell);
@@ -39,18 +40,18 @@ bool DevProfilePopup::setup(std::string const& developer) {
 
     // mods list
     auto listSize = CCSize { 358.f, 160.f };
-    auto list = ListView::create(items, 40.f, listSize.width, listSize.height);
-    list->setPosition(winSize / 2 - listSize / 2);
-    m_mainLayer->addChild(list);
+    auto cellList = ListView::create(items, 40.f, listSize.width, listSize.height);
+    cellList->setPosition(winSize / 2 - listSize / 2);
+    m_mainLayer->addChild(cellList);
 
     addListBorders(m_mainLayer, winSize / 2, listSize);
 
     return true;
 }
 
-DevProfilePopup* DevProfilePopup::create(std::string const& developer) {
+DevProfilePopup* DevProfilePopup::create(std::string const& developer, ModListLayer* list) {
     auto ret = new DevProfilePopup();
-    if (ret && ret->init(420.f, 260.f, developer)) {
+    if (ret && ret->init(420.f, 260.f, developer, list)) {
         ret->autorelease();
         return ret;
     }
diff --git a/loader/src/ui/internal/info/DevProfilePopup.hpp b/loader/src/ui/internal/info/DevProfilePopup.hpp
index af47a572..5ff3b631 100644
--- a/loader/src/ui/internal/info/DevProfilePopup.hpp
+++ b/loader/src/ui/internal/info/DevProfilePopup.hpp
@@ -4,10 +4,14 @@
 
 using namespace geode::prelude;
 
-class DevProfilePopup : public Popup<std::string const&> {
+class ModListLayer;
+
+class DevProfilePopup : public Popup<std::string const&, ModListLayer*> {
 protected:
-    bool setup(std::string const& developer) override;
+    ModListLayer* m_layer;
+
+    bool setup(std::string const& developer, ModListLayer* list) override;
 
 public:
-    static DevProfilePopup* create(std::string const& developer);
+    static DevProfilePopup* create(std::string const& developer, ModListLayer* list);
 };
diff --git a/loader/src/ui/internal/info/ModInfoPopup.cpp b/loader/src/ui/internal/info/ModInfoPopup.cpp
index 7b8902ca..945e5ec4 100644
--- a/loader/src/ui/internal/info/ModInfoPopup.cpp
+++ b/loader/src/ui/internal/info/ModInfoPopup.cpp
@@ -4,6 +4,7 @@
 #include "../list/ModListLayer.hpp"
 #include "../settings/ModSettingsPopup.hpp"
 #include <Geode/loader/Dirs.hpp>
+#include <about.hpp>
 
 #include <Geode/binding/ButtonSprite.hpp>
 #include <Geode/binding/CCTextInputNode.hpp>
diff --git a/loader/src/ui/internal/list/InstallListCell.cpp b/loader/src/ui/internal/list/InstallListCell.cpp
index 07daca20..352d8aaf 100644
--- a/loader/src/ui/internal/list/InstallListCell.cpp
+++ b/loader/src/ui/internal/list/InstallListCell.cpp
@@ -53,24 +53,21 @@ void InstallListCell::setupInfo(
     }
     this->addChild(m_titleLabel);
 
-    m_developerBtn = nullptr;
+    m_creatorLabel = nullptr;
     if (developer) {
         auto creatorStr = "by " + *developer;
-        auto creatorLabel = CCLabelBMFont::create(creatorStr.c_str(), "goldFont.fnt");
-        creatorLabel->setScale(.34f);
+        m_creatorLabel = CCLabelBMFont::create(creatorStr.c_str(), "goldFont.fnt");
+        m_creatorLabel->setScale(.34f);
         if (inactive) {
-            creatorLabel->setColor({ 163, 163, 163 });
+            m_creatorLabel->setColor({ 163, 163, 163 });
         }
 
-        m_developerBtn = CCMenuItemSpriteExtra::create(
-            creatorLabel, this, menu_selector(InstallListCell::onViewDev)
-        );
-        m_developerBtn->setPosition(
+        m_creatorLabel->setPosition(
             m_titleLabel->getPositionX() + m_titleLabel->getScaledContentSize().width + 3.f +
-                creatorLabel->getScaledContentSize().width / 2,
+                m_creatorLabel->getScaledContentSize().width / 2,
             m_height / 2
         );
-        m_menu->addChild(m_developerBtn);
+        m_menu->addChild(m_creatorLabel);
     }
 
     this->setupVersion(version);
@@ -96,7 +93,7 @@ void InstallListCell::setupVersion(std::variant<VersionInfo, ComparableVersionIn
     m_versionLabel->setScale(.2f);
     m_versionLabel->setPosition(
         m_titleLabel->getPositionX() + m_titleLabel->getScaledContentSize().width + 3.f +
-            (m_developerBtn ? m_developerBtn->getScaledContentSize().width + 3.f : 0.f),
+            (m_creatorLabel ? m_creatorLabel->getScaledContentSize().width + 3.f : 0.f),
         m_titleLabel->getPositionY() - 1.f
     );
     m_versionLabel->setColor({ 0, 255, 0 });
@@ -123,7 +120,7 @@ void InstallListCell::setupInfo(ModMetadata const& metadata, bool inactive) {
 }
 
 void InstallListCell::onViewDev(CCObject*) {
-    DevProfilePopup::create(getDeveloper())->show();
+    // DevProfilePopup::create(getDeveloper(), m_layer)->show();
 }
 
 bool InstallListCell::init(InstallListPopup* list, CCSize const& size) {
diff --git a/loader/src/ui/internal/list/InstallListCell.hpp b/loader/src/ui/internal/list/InstallListCell.hpp
index f2fd677c..ce5927ea 100644
--- a/loader/src/ui/internal/list/InstallListCell.hpp
+++ b/loader/src/ui/internal/list/InstallListCell.hpp
@@ -21,7 +21,7 @@ protected:
     float m_height;
     InstallListPopup* m_layer = nullptr;
     CCMenu* m_menu = nullptr;
-    CCMenuItemSpriteExtra* m_developerBtn = nullptr;
+    CCLabelBMFont* m_creatorLabel = nullptr;
     CCLabelBMFont* m_titleLabel = nullptr;
     CCLabelBMFont* m_versionLabel = nullptr;
     TagNode* m_tagLabel = nullptr;
diff --git a/loader/src/ui/internal/list/ModListCell.cpp b/loader/src/ui/internal/list/ModListCell.cpp
index 95e90386..061e6dcb 100644
--- a/loader/src/ui/internal/list/ModListCell.cpp
+++ b/loader/src/ui/internal/list/ModListCell.cpp
@@ -186,7 +186,7 @@ void ModListCell::updateCellLayout() {
 }
 
 void ModListCell::onViewDev(CCObject*) {
-    DevProfilePopup::create(this->getDeveloper())->show();
+    DevProfilePopup::create(this->getDeveloper(), m_layer)->show();
 }
 
 bool ModListCell::init(ModListLayer* list, CCSize const& size) {
@@ -233,7 +233,9 @@ void ModCell::onEnable(CCObject* sender) {
     else {
         tryOrAlert(m_mod->disable(), "Error disabling mod");
     }
-    m_layer->reloadList();
+    if (m_layer) {
+        m_layer->reloadList();   
+    }
 }
 
 void ModCell::onUnresolvedInfo(CCObject*) {
diff --git a/loader/src/utils/file.cpp b/loader/src/utils/file.cpp
index 8df76c0d..1f8a7ad6 100644
--- a/loader/src/utils/file.cpp
+++ b/loader/src/utils/file.cpp
@@ -21,48 +21,51 @@ using namespace geode::prelude;
 using namespace geode::utils::file;
 
 Result<std::string> utils::file::readString(ghc::filesystem::path const& path) {
+    if (!ghc::filesystem::exists(path))
+        return Err("File does not exist");
+
 #if _WIN32
     std::ifstream in(path.wstring(), std::ios::in | std::ios::binary);
 #else
     std::ifstream in(path.string(), std::ios::in | std::ios::binary);
 #endif
-    if (in) {
-        std::string contents;
-        in.seekg(0, std::ios::end);
-        contents.resize((const size_t)in.tellg());
-        in.seekg(0, std::ios::beg);
-        in.read(&contents[0], contents.size());
-        in.close();
-        return Ok(contents);
-    }
-    return Err("Unable to open file");
+    if (!in)
+        return Err("Unable to open file");
+
+    std::string contents;
+    in.seekg(0, std::ios::end);
+    contents.resize((const size_t)in.tellg());
+    in.seekg(0, std::ios::beg);
+    in.read(&contents[0], contents.size());
+    in.close();
+    return Ok(contents);
 }
 
 Result<json::Value> utils::file::readJson(ghc::filesystem::path const& path) {
-
     auto str = utils::file::readString(path);
-
-    if (str) {
-        try {
-            return Ok(json::parse(str.value()));
-        } catch(std::exception const& e) {
-            return Err("Unable to parse JSON: " + std::string(e.what()));
-        }
-    } else {
-        return Err("Unable to open file");
+    if (!str)
+        return Err(str.unwrapErr());
+    try {
+        return Ok(json::parse(str.value()));
+    }
+    catch(std::exception const& e) {
+        return Err("Unable to parse JSON: " + std::string(e.what()));
     }
 }
 
 Result<ByteVector> utils::file::readBinary(ghc::filesystem::path const& path) {
+    if (!ghc::filesystem::exists(path))
+        return Err("File does not exist");
+
 #if _WIN32
     std::ifstream in(path.wstring(), std::ios::in | std::ios::binary);
 #else
     std::ifstream in(path.string(), std::ios::in | std::ios::binary);
 #endif
-    if (in) {
-        return Ok(ByteVector(std::istreambuf_iterator<char>(in), {}));
-    }
-    return Err("Unable to open file");
+    if (!in)
+        return Err("Unable to open file");
+
+    return Ok(ByteVector(std::istreambuf_iterator<char>(in), {}));
 }
 
 Result<> utils::file::writeString(ghc::filesystem::path const& path, std::string const& data) {
@@ -72,14 +75,14 @@ Result<> utils::file::writeString(ghc::filesystem::path const& path, std::string
 #else
     file.open(path.string());
 #endif
-    if (file.is_open()) {
-        file << data;
+    if (!file.is_open()) {
         file.close();
-
-        return Ok();
+        return Err("Unable to open file");
     }
+
+    file << data;
     file.close();
-    return Err("Unable to open file");
+    return Ok();
 }
 
 Result<> utils::file::writeBinary(ghc::filesystem::path const& path, ByteVector const& data) {
@@ -89,14 +92,14 @@ Result<> utils::file::writeBinary(ghc::filesystem::path const& path, ByteVector
 #else
     file.open(path.string(), std::ios::out | std::ios::binary);
 #endif
-    if (file.is_open()) {
-        file.write(reinterpret_cast<char const*>(data.data()), data.size());
+    if (!file.is_open()) {
         file.close();
-
-        return Ok();
+        return Err("Unable to open file");
     }
+
+    file.write(reinterpret_cast<char const*>(data.data()), data.size());
     file.close();
-    return Err("Unable to open file");
+    return Ok();
 }
 
 Result<> utils::file::createDirectory(ghc::filesystem::path const& path) {