Modular Architecture
The entire HUD system is orchestrated by HudModuleManager. On initialization it registers the 7 built-in modules. Via the eymistaken_hud Fabric entrypoint, third-party addons can register additional modules that are loaded and managed alongside the core ones automatically.
Each module extends HudModule, which handles render position injection, rainbow color cycling, and the context menu settings contract. Every frame, HudModuleManager calls tickAll(Minecraft) and renderAll(GuiGraphicsExtractor, float). The render pipeline runs through the client-side HUD registry — modules receive a GuiGraphicsExtractor context and implement extractRenderState(GuiGraphicsExtractor, float) to draw their content. Automatic stacking layout per screen quadrant (TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, CENTER) is handled entirely by the manager before calling each module.
Adding the Dependency
Use JitPack to compile your addon mod against Eymistaken's HUD 26.1. Add the following to your build.gradle:
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
modImplementation 'com.github.Eymistaken:Eymistaken-s-HUD:-SNAPSHOT'
}
After reloading your Gradle project, all 26.1 API classes — including HudModule, HudModuleSetting, and all six setting types — will be available in your development environment.
Creating a Custom Module
Every HUD element must extend HudModule and implement its abstract methods. Below is the minimum required implementation:
import com.eymistaken.simplecps.api.HudModule;
import com.eymistaken.simplecps.SimpleCPSConfig;
import net.minecraft.client.gui.GuiGraphicsExtractor;
public class MyCustomModule extends HudModule {
@Override
public String getName() {
return "My Custom Tracker";
}
@Override
public SimpleCPSConfig.Position getPositionType() {
return SimpleCPSConfig.Position.TOP_LEFT; // Default corner alignment
}
@Override
public int getXOffset() { return 0; }
@Override
public int getYOffset() { return 0; }
@Override
public boolean isEnabled() {
return true; // Tie to your own config
}
@Override
public int getWidth() {
return 100; // Required for stacking layout
}
@Override
public int getHeight() {
return 20;
}
@Override
public void extractRenderState(GuiGraphicsExtractor context, float tickDelta) {
// this.x and this.y are injected by HudModuleManager before extractRenderState() is called.
context.drawString(this.client.font, "Hello World", this.x, this.y, 0xFFFFFF, true);
}
@Override
public void tick(net.minecraft.client.Minecraft client) {
// Optional: runs every client tick (timers, click tracking, etc.)
super.tick(client);
}
}
Important: Always return accurate values from getWidth() and getHeight(). Returning 0 removes your module from the stacking layout and makes it invisible.
HUD Editor Integration (Drag & Drop)
Override the optional setter methods to allow players to move, scale, and reset your module in the HUD Editor. Important: save all values to your own mod's config — never to SimpleCPSConfig.
// Inside your MyCustomModule class:
@Override
public void setPositionType(SimpleCPSConfig.Position pos) {
MyAddonConfig.anchor = pos; // Save to YOUR config
}
@Override
public void setXOffset(int x) { MyAddonConfig.xOffset = x; }
@Override
public void setYOffset(int y) { MyAddonConfig.yOffset = y; }
@Override
public void setScale(int scale) { MyAddonConfig.scale = scale; }
@Override
public int getScale() { return MyAddonConfig.scale; }
@Override
public void resetToDefaults() {
// Called by "Reset Position" in the context menu
MyAddonConfig.anchor = SimpleCPSConfig.Position.TOP_LEFT;
MyAddonConfig.xOffset = 0;
MyAddonConfig.yOffset = 0;
MyAddonConfig.scale = 100;
}
If you skip these overrides, your module will still render correctly — but players will not be able to move or scale it via the HUD Editor.
Registering the Plugin
Declare an entrypoint implementing EymistakenHudPlugin in your fabric.mod.json. Your modules will be passed to HudModuleManager#registerModule() and managed alongside the built-in ones from that point forward — no core modification required.
Implementation class:
import com.eymistaken.simplecps.api.EymistakenHudPlugin;
import com.eymistaken.simplecps.HudModuleManager;
public class MyPluginInit implements EymistakenHudPlugin {
@Override
public void registerHudModules(HudModuleManager manager) {
manager.registerModule(new MyCustomModule());
}
}
fabric.mod.json:
"entrypoints": {
"eymistaken_hud": [
"com.myname.myaddon.MyPluginInit"
]
}
The eymistaken_hud entrypoint key is processed by SimpleCPSClient during initialization. Every registered module is automatically included in the tickAll() and renderAll() cycles of HudModuleManager, and becomes fully editable in the in-game HUD Editor.