CoolCatLib¶
Write it once, run it everywhere, and make it look purr-fect.
The foundation and the visuals for multi-loader Minecraft mods: one common codebase for Fabric, NeoForge and Forge, with no Architectury API needed.
Get started API reference Source
Two mods, one toolkit¶
-
CoolCatLib: Core
coolcatcore· the purr-fect foundation. Entrypoints that replace per-loader setup; events, registration and networking; TOML configs with in-game screens; attachments; containers and storage menus. -
CoolCatLib: Canvas
coolcatcanvas· the cat's whiskers of visuals, built on Core. Live post-processing shaders, layered skyboxes, gradient and rainbow text, outlines, panels, pan & zoom views and easing curves.
Why CoolCatLib¶
-
Truly cross-loader
Your logic lives in
common. Events, registries, payloads, menus and client registries are bridged to every loader. -
No boilerplate payloads
Record payloads get their
StreamCodecderived for you, from primitives to lists, maps, optionals and records. -
Configs players love
Searchable screens with sliders, color pickers, undo/redo, themes and presets. Server values sync live.
-
Data on anything
Attachments on entities, block entities and item stacks, with sync policies, copy on death and change events.
-
Inventories done right
Slot roles, per-face access, automation-style transfer and texture-free storage menus.
-
Visuals without the pain
Shader effects with per-frame uniforms, layered skies, gradient text and outlines, all animated.
A thirty-second tour¶
public class MyMod implements ModConstructor {
public static final ConfigBuilder CONFIG = Config.builder("mymod", ConfigScope.SERVER);
public static final ConfigValue<Integer> MAX_HOMES = CONFIG.intValue("maxHomes", 3).range(0, 64).slider().build();
@Override
public void onConstructMod() {
CONFIG.build(); // (1)!
Network.registerServerbound(PingPayload.class, (payload, context) -> // (2)!
context.getPlayer().sendSystemMessage(Component.literal("Pong from " + payload.pos())));
PlayerEvents.JOIN.register(player -> // (3)!
player.sendSystemMessage(ColorGradient.RAINBOW.literal("Welcome, " + player.getName().getString() + "!")));
}
}
public record PingPayload(BlockPos pos) implements CustomPacketPayload {
public static final Type<PingPayload> TYPE = new Type<>(Identifier.fromNamespaceAndPath("mymod", "ping"));
@Override public Type<PingPayload> type() { return TYPE; }
}
- Registers and loads
config/mymod-server.toml. Players can edit it in game, and its values sync to every client. - A record payload: CoolCatLib derives its network codec from the record's components.
- An animated rainbow message, drawn by Canvas wherever the text shows up.
How it fits together¶
flowchart LR
subgraph YourMod["Your mod"]
C["common module<br/>ModConstructor · ClientModConstructor"]
F["fabric"]
N["neoforge / forge"]
end
subgraph CCL["CoolCatLib"]
CORE["Core<br/>events · registries · network<br/>configs · attachments"]
CANVAS["Canvas<br/>effects · skyboxes · text · GUI"]
end
F -- "coolcatcore:* entrypoints" --> C
N -- "NeoForgeModEntrypoint<br/>ForgeModEntrypoint" --> C
C --> CORE
C --> CANVAS
CANVAS --> CORE
Versions and loaders¶
| Minecraft | NeoForge | Forge | Fabric | Source |
|---|---|---|---|---|
| 26.1 – 26.1.2 | – | 26.1.2 |
||
| 1.21 – 1.21.1 | 1.21 |
|||
| 1.20.1 | – | 1.20.1 |
About these docs
The pages are written against 26.1.2. The backports share the same API, adjusted for their Minecraft version: ResourceLocation instead of Identifier, GuiGraphics instead of GuiGraphicsExtractor, and a Forge entrypoint.