Repository navigation
Modules
A module is a class deriving from FhModule. They are the basic unit of functionality and organization in Fahrenheit mods.
Mods, unless purely file-based, consist of anywhere from one to an unlimited number of modules. They allow you to split the combined functionality of your mods into smaller, legible, reusable pieces.
Modules may retrieve instances of each other at runtime and interact with each other.
Beyond being organizational scopes, modules possess the following properties:
- Each gets its own global and local state.
- Each gets its own log file.
- Each gets to specify the games it supports.
A valid module has only two basic requirements.
- It must have exactly one, public, parameterless constructor.
- It must implement the
initmethod. See Initialization.
For example:
// A perfectly valid, minimal module that does nothing.
[FhLoad(FhGameId.FFX | FhGameId.FFX2 | FhGameId.FFX2LM)]
public sealed class ExampleModule : FhModule {
public override bool init(FhModContext mod_context, FileStream global_state_file) {
return true;
}
}For a module to be loaded, apply the FhLoad attribute specifying which games it supports. For example:
// Will be loaded in all three games.
[FhLoad(FhGameId.FFX | FhGameId.FFX2 | FhGameId.FFX2LM)]
public sealed class ModuleThatDoesThings : FhModule { }
// Will be loaded only in FF X.
[FhLoad(FhGameId.FFX)]
public sealed class ModuleThatAlsoDoesThings : FhModule { }If the appropriate game is launched, Fahrenheit will instantiate the module.
To retrieve an instance of another module at runtime safely, use a FhModuleHandle<T>. For example:
FhModuleHandle<ModuleThatDoesThings> h_one = new(this);
FhModuleHandle<ModuleThatAlsoDoesThings> h_two = new(this);
if (h_one.try_get_module(out ModuleThatDoesThings? m_imgui) &&
h_two.try_get_module(out ModuleThatAlsoDoesThings? m_resload))
{
// If the call succeeds, you may store the returned
// modules and use them as you see fit.
}Important
Always use handles to refer to other modules. They allow you to deal with their potential absence gracefully.
Never construct your own instances of modules.
From Fahrenheit's perspective, such modules do not exist, thus none of their callbacks execute.