Geode provides utilities for mods to depend on other mods, to make sharing code easy. Note that Geode only manages dependencies that are mods. Normal C++ dependencies, like a JSON parsing library, ZIP library, or some networking utilities, should just be installed like they are in any other C++ project. Use CPM, Git submodules, copy the code to your project, whatever you prefer. If the library is dynamic, include theDocumentation 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.
.dll with your mod through the files key in resources.
However, sometimes you want to depend on code that can’t just be used as a normal library; for example, custom keybinds. Geode does not provide any custom keybinds utilities out-of-the-box, so you need to use a library. However, it would not make much sense if every mod bundled their own incompatible systems for dealing with custom keybinds. Instead, there should be one mod that just adds the functionality, and then other mods can depend on that mod and call its functions to add keybinds.
How dependencies work
Dependency mods are like any other mods, except that they include their headers and linkable files in their .geode package. Usually the headers are located in aninclude directory inside the package, but they may also be anywhere. The linkable file is mod.id.lib on Windows and the normal mod binary on other platforms, located at the root of the package.
Otherwise, dependency mods are just like normal mods; they may place hooks, patches, add features to the game, and be published on the mods index. However, dependency mods should keep the features they add to a minimum, and be focused on the specific features they’re meant to add. For example, a custom keybinds dependency should only add the necessities for working with custom keybinds; it shouldn’t also add a bunch of other features, like adding more icons or customizing menus.
If a dependency is required, it is linked to; this means that for the mod that depends on it to run, the dependency must be present. However, as sometimes you may want to only use a dependency if it is loaded, dependencies may also be marked optional. In this case, the dependency is not linked to, which means that you can’t use any of the dependency’s functions, but have to use Geode’s functions for working with optional dependencies. See Optional dependencies for more info.
Adding dependencies
Dependencies can be added to your mod by simply adding it to thedependencies key in mod.json:
version field of a dependency may be written as >=version, =version, or <=version. The comparisons work as expected, with the addition that if the major versions are different, the comparison is always false. This means that if you depend on version >=1.2.5 of a mod, version v1.8.0 will be considered acceptable but v2.0.0 will not. For this reason, if you make a mod that is depended upon, you should follow strict semver.
Once you have added a dependency to your mod.json, if you have Geode CLI v1.4.0 or higher, it’s headers are automatically added to your project. If you have the mod installed, the headers from the installed version will be used. If you don’t have the mod installed, Geode will install it from the mods index. The added dependency files for your project can be found in build/geode-deps/<dep.id>. Geode automatically add build/geode-deps to your project’s include path, and links whatever binaries are found in dependencies, meaning you most likely don’t have to configure anything.
Example
The modhjfod.gmd-api contains utilities for working with .GMD files. You can add it to your mod by adding the following to your mod.json:
hjfod.gmd-api in your installed mods. If the mods index, and install it for you.
Importance
Dependency must be installed for this mod to work
recommended
Dependency is not required, but is recommended and will be downloaded by default.
suggested
Dependency is not required, and will not be downloaded by default.
Events
The key system Geode provides for optional mod interop are events. For example, a mod that adds support for drag-and-dropping files on the GD window could define a drag-and-drop event that other mods can then listen to. Usually however, events are defined in code in a way that requires linking by inheriting from theEvent class. To avoid this, mods that want to support being used optionally should also provide events that are specializations of the DispatchEvent class:
DispatchEvents have an associated ID, which is specific for each DispatchEvent specialization. This can be used to differentiate between events; for example, the drag drop API might use this to let dependencies determine which file types they listen to.
Mods that use the dependency can now listen for drag-and-drop events:
User Objects
One way for mods to communicate with optional dependencies is through user objects, which may contain any data. These are like thesetUserData and setUserObject functions native to CCNodes, except that these objects have a string key associated with them. For example, a mod that adds scrollbars to layers might use the following check to see if a scrollbar should be added to a layer:
CCNode::setUserObject function:
CCObjects, a mod can store any piece of information within a user object. This can range from objects as simple as a CCBool to more complicated, mod-specific ones that store multiple pieces of data.
Mods can also add an event listener to listen for when attributes are added/changed:
Event Macro
Included in Geode v4.3.0 is a macro to automate the process of exporting functions from API mods, in a way that works for optional dependencies. This makes use of events to grab a function pointer from the API mod, and call it from the dependent mod, hence the name. The exported functions must return ageode::Result, considering the API mod may not be available, and thus the function cannot be called.
Two versions of the macro are available: