Documentation Index
Fetch the complete documentation index at: https://mintlify.com/geode-sdk/docs/llms.txt
Use this file to discover all available pages before exploring further.
Migrating from Geode v4.x to v5.0
C++ Standard
Geode now requires C++23 to build. The mod template has been updated a while ago, but for older mods you might need to openCMakeLists.txt and edit this line:
23 instead of 20.
Changes to Event
The entire event system has been reworked. There are now multiple event classes for different purposes, and filters are far more performant, though a lot less dynamic. Events now also have priority ordering, for defining the order in which listeners are handled.
Usage migration
Migration for Event subclasses
Migration for DispatchEvent
Renamed to geode::Dispatch, but DispatchEvent is kept as an alias for easier migration. Its a thread-safe event with one filter arg for the id:
Thread safety
Thread safety is now opt-in for events, meaning that if you want to send/listen to an event from different threads you should use theThreadSafe variants.
This has nothing to do with GD’s main thread, event listeners will always get triggered on the same thread that sent the event.
GlobalEvent
If you have an Event with filter args, it’s not possible to have an unfiltered listener (aka a listener that receives every event, regardless of the args). In those cases, you should use GlobalEvent.
listen:
Changes to settings change listeners
geode::listenForSettingChanges() no longer infers the setting type. Aside from that, usage remains exactly the same:
geode::listenForAllSettingChanges() has recieved a new std::string_view argument representing the key of the setting whose value changed. Aside from that, usage remains mostly the same:
Changes to Popup
geode::Popup is no longer templated, and instead accepts its own arguments in Popup::init (which also replaces initAnchored). It now uses the pattern similar to any other node. For example the following code:
Async changes (web, file picker, etc.)
geode::Task has been replaced by an asynchronous system that utilizes C++ coroutines. This makes it much easier to write performant, concurrent code, but it also means there’s a lot to change to port to the new system.
Functions like geode::utils::file::pick or web::WebRequest::get now return a Future that can be awaited or spawned to run in parallel. For example, to launch a global file picker in v4, you would use this code:
file::pick() on the async runtime, and once completed, call the provided callback on the main thread. If you want more control over what happens (such as not calling your function on main thread), you can use the Runtime directly:
async::TaskHolder class was added which has a similar API. For example, the following v4 code that makes requests:
Async cancellation
Thegeode::Task class allowed tasks to be cancelled externally, or even by the task itself. The new futures are cancelled simply by destroying them, and tasks are cancelled by calling abort() on the handle. The aforementioned TaskHolder class automatically will call abort on the held task when destroyed, replaced by another .spawn call, or when you manually call listener.cancel(). For example, this code below will never actually complete the request:
Task, you can forget about checking for cancellation and leverage the power of coroutines - your task can be cancelled at any co_await point.
fmt::localtime
We updated our fmt dependency to v12, which removed the fmt::localtime function. Now Geode provides a drop-in replacement for it:
Changes to std::function arguments
Almost all parts of geode that accepted a std::function (such as queueInMainThread, TextInput::setCallback, etc.) have been changed to use geode::Function instead. The primary difference is that a geode::Function cannot be copied, only moved. Most proper usages should still compile and work properly, but if you have errors that are related to std::function, try adding std::moves or making sure to explicitly use geode::Function everywhere.
Changes to string arguments
A ton of functions that acceptedstd::string_view, std::string or std::string const& have been written uncarefully and inefficiently before, which v5 aimed to fix. For many cases, you don’t need to change anything, but conversion between string types isn’t always possible, so this might break some code. This applies to return values as well, certain commonly used functions like CCNode::getID have been changed to return geode::ZStringView, which is a type that attempts to be API-compatible with string_view, while keeping a guarantee of null termination.
Changes to dependencies and incompatibilities
Dependencies and incompatibilites have received some breaking changes. The first is that the old array syntax has now been fully removed, and the second is that the old"importance" keys have been replaced by "required": boolean for dependencies and "breaking": boolean for incompatibilities. Suggestions and recommendations have been removed, but will be added back in a later update as a separate key.
For example, the following v4 code:
Changes to mod error reporting
Mod::isEnabledhas been renamed toMod::isLoadedto better describe its purposeMod::isOrWillBeEnablednow reports whether the user has tried to enable the mod and does not consider if it succesfully loaded or not- The
LoadProblemclass now has significantly fewer variants.- All of the different functions related to checking different problems in
Modhave been reduced to justMod::failedToLoad(for major issues) andMod::getLoadProblem(for all potential issues)
- All of the different functions related to checking different problems in
ModMetadataparsing has been reduced to just thecreateandcreateFromGeodeFilefunctions, which now always return aModMetadatainstead of a result. The returnedModMetadatarepresents a best-effort parse, and any errors are reported in theModMetadataitself that you can check viahasErrors()andgetErrors().
getChild deprecation
getChild in the global namespace has been removed, use CCNode::getChildByIndex instead, the behavior is identical.
”path” setting removal
path setting type has been removed, use file instead, the behavior is identical.