ModEasy, a c++ library, is an easy to add modding system that is functional out of the box, but also designed to be extendable for whatever you may need.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DomtronVox ec9f669bcb Added basic stuff for a testing system along with partial test code for ConfigStore and ConfigLoaderINI code. 1 year ago
examples/1_minimal Removed the ini parser dep and just wrote my own. While I wanted to avoid it (avoid NIH sydrom), I couldn't find a lib that matched my needs and didn't crash. 2 years ago
src Added ability to change file open mode in the writeToTextFile function. Also added turnicate mode to the openFile function. 1 year ago
tests Added basic stuff for a testing system along with partial test code for ConfigStore and ConfigLoaderINI code. 1 year ago
.gitignore Initial commit. Basic implementation of the Configuration sub-system. Build system in place with one example partly implemented. 2 years ago
CMakeLists.txt Added basic stuff for a testing system along with partial test code for ConfigStore and ConfigLoaderINI code. 1 year ago Tweaked some things, added build instructions section and a usage section. 1 year ago


ModEasy is a small, customizable library that provides easy modding support to any project. A Mod can stand for module or modification and is a package of data and/or code that adds onto or overrides the original data and/or code.


  • Support Linux, Windows, and MacOS.
  • Functional out of the box.
    • Mod configuration via simple ini files.
    • Mod types of: configuration files (no code), pre-compiled library (dll, so, etc), and Lua.
  • Mod dependency handling. Automatically builds a dependency tree that loads mods in a certain order allowing mod inter-dependency with the option for load order overrides.
  • API registration for both the core project and mods that allows calling those registered functions from each supported mod type.
  • Customizable
    • Custom configuration file type(s). Add additional configuration file loaders and/or override the default.
    • Custom Mod handlers to add additional modding languages.
  • TODO: single header?

Build Instructions

Install prerequisites

To build you need cmake, and a c++ 11 capable compiler.


sudo apt install build-essential cmake


mkdir build && cd build && cmake .. && make -j2

You can make the -j# be "number of core" - 1 for faster build times.

If you want to run the unit tests, after the above commands run: make test


As stated above the library tries to function out of the box. Once you install the library using it in your code is fairly simple.

#include <ModEasy.h>

std::unique_ptr modding; modding = std::make_unique("mods"); //the modding folder relative to your executable.

//register your core API functions modding->regiserAPI("MyFunction", funct_ptr); //etc

//initiate all mods modding->initiateMods();

API Reference


  • Constructor(mods_path)
    • mods_path: string. a path, either absolute or relative to the binary, that points to a location to load mods from.

High-level Design and Extending Functionality

Library is broken into 6 parts:

  • Configuration: Focused on loading configuration formats.
  • Dependency: Builds a loading order based on required and optional dependencies.
  • Implementation: Handles loading different mod types (lua/configuration/etc).
  • API: Holds API objects from each mod and the core program.
  • WebMediator: Handles http post and get requests to online mod repositories.
  • ModFrameworkCore: Core class that organizes and mediates everything.


The Configuration sub-system is based around recursive key/value objects and file parsers. These two aspects are handled by the ConfigStore and ConfigLoader classes respectively.


The ConfigLoader base class forces derivatives to implement the validate, parse, and serialize functions. By default we include a ConfigLoaderINI class that loads .ini style config files.

  • Validate checks a given file is the right format.
  • Parse takes a file path and populates a ConfigStore object with the data therein.
  • Serialize converts a ConfigStore into the configuration file format and saves it to the given path.

In the ModFrameworkCore, you can set the default ConfigLoader. There is also a function to register new formates and associate them with a ConfigLoader child class.


The ConfigStore class allows storing string values and nested ConfigStore objects in key/value pairs. ConfigStore has the getStr, getNested, and set functions that return and take string and ConfigStore variables. There are no customizable parts to the ConfigStore.

Just a note, ConfigStore uses unordered_maps for the two type of data stored. You can get their iterators with the beginStr, endStr, beginNested, and endNested functions. Unordered_maps use forward iterators so you can only test equivalence (==) and non-equivalence (!=) when using them in a for loop. Trying to use less then greater then or the variants will fail.


The Dependency sub-system makes sure that mods will be loaded in the correct order. This is a self-contained sub-system and doesn't need any user extensions.


The Implementation sub-system deals with actually loading the meat of the Mod. By default there are 3 implementation mod types:

  • config: Mods just used to load up collection's of configuration files.
  • pre-compiled: Mods that load pre-compiled libraries.
  • Lua: Mods in the Lua language.

New mod types are defined by creating a new derivative of the ModHandler. ModHandler derivatives need to implement the load function.

The load function is given the directory path and ConfigStore object for the mod and is supposed to do everything needed to get a mod loaded and working.