promotional bannermobile promotional banner

CoolCatLib

Write it once, run it everywhere. Events, networking, registries and configs, with screen effects, custom skies, cutscenes and GUI widgets on top: the purr-fect foundation for your mods.
Back to Files

[NeoForge] 26.1.2 | V6 RELEASE

File namecoolcatlib-neoforge-26.1.2-6.jar
Uploader
ixDarkLorDixDarkLorD
Uploaded
Oct 22, 2026
Downloads
29
Size
1.7 MB
Mod Loaders
NeoForge
File ID
9284826
Type
R
Release
Supported game versions
  • 26.1.2
  • 26.1.1
  • 26.1

Curse Maven Snippet

NeoForge

implementation "curse.maven:coolcatlib-916525:9284826"

Learn more about Curse Maven

What's new

v26.1.2-6 Release | Oct 22, 2026

✨ New Features

  • More common events (api.event.v2.common), fired the same on Fabric and NeoForge:
    • InteractionEvents: USE_BLOCK, USE_ITEM and USE_ENTITY (answer with an InteractionResult: PASS lets the game go on, anything else stops it there) and ATTACK_BLOCK and ATTACK_ENTITY (interrupt to stop them), on both sides, before the game acts.
    • LivingEvents: DAMAGE (before armor; interrupt and no damage is taken) and DEATH (interrupt to keep the entity alive), on the server.
    • PlayerEvents.CLONE (the new player object after death or the End, to carry data over), RESPAWN and CHANGE_DIMENSION; EntityEvents.UNLOAD.
  • Custom boss bars (api.bossbar, api.client.bossbar): boss bars drawn a mod's own way, each in a style.
    • From the server, CustomBossBars.style(bar, style) gives any ServerBossEvent a style (and optionally the entity it belongs to); players seeing it are told, and those shown it later are told when they are. EntityBossBar.of(entity).style(...).range(48).showWhen(...).show() keeps a bar for any living entity by itself: its name, its health, the players near it, until the entity is gone.
    • On the client, BossBarRenderers.register(style, renderer) draws bars of a style, stacked with the game's own as the game stacks them. Renderers get a BossBarView: the progress eased smoothly, a trail of what was just lost (held, then draining), how fresh the last hit is, the linked entity while it is loaded, and the time. TexturedBossBar is a renderer made from one texture: a frame, a fill and a trail in its track, marks that light once passed (phases), a glow that pulses faster as the bar empties, a jolt and a flash on each hit.
    • A style with no renderer on a client, or a client without CoolCatLib, gets the game's own bar.
  • Armatures (api.client.armature, api.armature): modelled, animated entities, block entities and items, made in Blockbench and played with layered animation.
    • Models: Blockbench projects (.bbmodel) are read as saved, with no export step: groups, cubes with per-face UVs, free-form meshes, locators and null objects, several textures and textures embedded in the file. Bedrock .geo.json with .animation.json work too, and an .animation.json alone is enough for clips meant for another model. Files go in assets/<namespace>/armatures/; an optional <name>.armature.json sets materials per joint (cutout, solid, translucent, emissive, glow), extra animation files, texture swaps, springs, head tracking, an idle clip, transitions, scale and .obj props. A texture named <texture>_glow is drawn on top at full brightness.
    • Animation: an Animator per entity, block entity or item stack, with AnimLayers that each play one clip over the joints in their JointMask, overriding or adding to the layers below, with a weight that can fade. A layer can be driven by a function asked every frame (layer.drive(ctx -> ctx.moving() ? WALK : IDLE)), and play sets the driver aside until its motion ends. Motion says how a clip plays: loop, once, hold, ping-pong, a repeat count, speed (backwards too), a start time and what plays next.
    • Transitions: Transition.crossfade, freeze (the old pose holds still while the new one blends in) and CUT, each with a duration and easing. A layer has a default, rules for pairs of clips (transition("run", "idle", ...)), a TransitionRule function, and a switch to turn blending off; the animator has a default and a switch for every layer. A motion can carry its own.
    • Keyframes: linear, Catmull-Rom, Bézier and step interpolation; Molang in any value (math.*, query.*, variable.*, assignments, several statements), with the common queries built in and ArmatureQueries.register for a mod's own; anim_time_update, blend_weight, start and loop delays. Sound and particle keyframes play by themselves (a particle effect naming a world effect plays it), timeline keyframes run Molang, and animator.onEvent gets them all.
    • Procedural motion: animator.spring(joint) for tails, ears and capes that lag and swing (chains of them whip), kept out of the body by colliders, balls round the model's points (spring.collider(point, radius), or "colliders" in the armature file), so a cape drapes over a back and the spikes on it; free parts that hang or float where the world puts them (a spring with no stiffness): buoyancy lifts one (a balloon on a string), rope lets its string go slack, wind drifts it in slow gusts and twist spins it on its string as it swings, all reacting to the clips that move where it hangs from ("buoyancy", "rope", "wind", "twist" in the armature file's springs); and the world: a spring's weight kept out of the blocks round it and the entities near it (collideBlocks, collideEntities, a ball of collisionRadius pixels), bouncing off and dragging along what it touches (bounce, friction), so a tail rests on the ground and a balloon is pushed aside by a player walking into it ("collide": true or {"blocks", "entities", "radius", "bounce", "friction"}); a spring that pulls ("pulls": true) tugs the spring on its joint's parent along its length when stretched taut, by its share of their mass, so tension runs down a chain: a balloon draws its string of cord lengths taut toward it and the string curves as it is swung, instead of standing stiff with the balloon folded over its top; springs marked bump keep their weights apart and bounce off each other ("bump": true, a ball of collisionRadius, or "radius"): a bunch of balloons jostling; and spacing ("spacing", pixels) keeps room between them, easing them apart before they touch, so a bunch of gently lifted balloons opens out into a bouquet; cloth: springs woven to their neighbours (spring.link(joint...), "links") keep the distance the animation puts between their weights, firmly when pulled apart and as softly as linkStiffness ("link_stiffness", 0.6) when pushed together, so a cape of hanging chains side by side or a skirt of panels round a waist moves, ripples and folds as one sheet instead of parting into strips; and cloth sheets ("cloth": [{"joints": [[...row...], ...], "wrap"}] in the armature file): the faces of a sheet's joints are skinned, each corner weighed between its own joint, the one below and the one beside it, so a cape or a skirt bends smoothly between its springs and stays whole, with no seam opening or folding over, and their seams welded first: neighbours' corners that are each other's nearest and within a pixel are joined at their middle and weighed alike, so square-cut boxes that cannot quite meet (the panels of a skirt flaring to its hem) close into one smooth sheet that never parts; what a cloth is made of: mass (heavy cloth swings slowly and shrugs off the wind), airDrag (air resistance growing with speed: it streams out behind and settles), flutter (ripples the faster its wearer moves), stretch (gives and springs back), bend (holds its shape however heavy it is, critically damped: long curves instead of sagging into sharp folds or whipping), follow (its damping works on its speed relative to where the animation carries it: cloth keeps up with its wearer instead of lagging as if dragged; "follow", 0 by default) and a steady windDirection on top of the drifting wind ("mass", "air_drag", "flutter", "stretch", "bend", "wind_direction"), or all at once with a Fabric (spring.fabric(Fabric.WOOL), "fabric": "wool": silk, linen, cotton, wool, canvas, leather, rags, leaves, and cord for strings: a balloon's string as a chain of springs, skinned as a one-column sheet so it curves; keys after it change just what they name); springs are kept light: no allocation per frame, at most 8 sub-steps, a spring at rest with nothing moving it sleeps, block shapes are looked up a few times a second and entities every few frames, and past simulationDistance blocks from the camera (64; "simulation_distance") a spring isn't worked out at all; animator.lookAt(joint) follows where a mob looks, or the nearest player for blocks and items; animator.modify changes the pose in code; joints can be hidden, tinted and lit up.
    • Effects: .obj props carried on joints and points (ObjProp), glowing trails behind a point (animator.trail), and effect particles pouring from one (animator.emitter).
    • Rendering: ArmatureMobRenderer (keeps vanilla's hurt flash, death topple, sleeping, invisibility, glowing outline, name tags, leashes and render layers; holds items at points with holdItem/ItemSocket, dims or darkens its glow textures with glow), ArmatureEntityRenderer, ArmatureBlockRenderer (turns to the block's facing, shows the breaking cracks) and the coolcatlib:armature item model type, with ArmatureItems for per-item setup. Anything can be drawn at a point with attach, and ArmatureDraw draws a posed armature in a mod's own renderer (Style.glow sets how bright its glow textures are).
    • Per-entity variants and see-through drawing in ArmatureMobRenderer: armature(entity -> ...) picks the armature each entity is drawn with (variants whose bodies differ, each entity's animator made for the one it uses), tint((entity, partialTicks) -> argb) tints it each frame, and translucent(...) draws it see-through so the tint's alpha shows (ArmatureDraw.Style.translucent; glowing parts unchanged).
    • From the server: ArmatureControl.play, stop and setVariable for an entity, a block entity or the item in an entity's hand, sent to the players who can see it. On the client, Animators.of(...) and Animators.whenReady(...).
  • Vanilla models (api.client.armature.vanilla): clips, changes and worn armatures for vanilla mobs and players, without replacing their models. VanillaModels.player() or VanillaModels.of(type):
    • animations(armature) plays clips on the parts named like the joints (head, body, right_arm...; any spelling); a part a clip moves is taken over, the rest keep vanilla's animation, and armor and held items follow. A root joint moves the whole model (flips, sitting, lying down). Clips can be mirrored for left-handed entities (mirrorLeftHanded), and torsoJointNames() reads emote files whose torso is the body part and body the whole model.
    • Limbs bend: a bend channel (or pose.bend) curves an arm or leg smoothly at its middle, with its sleeve or pants layer, its armor and the item in its hand.
    • pose(...), hide, scale, rotate and translate change parts every frame; attach(part, armature) wears an animated armature on a part; when(...) limits all of it to some entities.
    • firstPersonArms(...) shows your own arms in first person posed as the clips pose them, with what you hold, in place of vanilla's hands.
    • Other mods animating the same parts: Better Combat's attacks and weapon poses are recognized, and the clips leave those parts to them by default (overlapRule(OverlapRule.YIELD / OVERRIDE / ADD)). Other animation mods can be made known with VanillaModels.registerOverlap, and VanillaModels.hasOverlap(entity) tells drivers when one is animating.
  • Scene viewports can lay text flat on their picture, in the texture's own pixels (SceneViewport.text(line, x, y, colour, scale), clearText()): a picture of nothing but text is drawn once, so text can be shown as a texture and cut, stretched or bent with what it is on.
  • Scene viewports can stand on a ground: SceneViewport.ground(y, cells, floor, lines, shadows) lays a floor with a grid of lines under the scene, turning with it, as large as what stands on it and a margin more, with a soft shadow under each entity.
  • Event phases reach other mods' own listeners: EventPhase.band() sorts phases into FIRST (FIRST and earlier), MIDDLE and LAST (LAST and later), and events whose loader hook fires each band at its own place run FIRST listeners before other mods' NeoForge or Fabric listeners of the game event and LAST ones after them. EventInvoker.invoker(Band) and hasListeners(Band) let a hook fire one band; invoker() still fires them all, in order.
  • ItemTooltipEvents.MODIFY does this on both loaders (NeoForge's highest, normal and lowest priorities; Fabric phases before, at and after the default one).
  • ItemTooltipEvents.APPEND: lines added at the very end of an item's tooltip, after the loaders' tooltip events and every other mod's lines, with the player when there is one; not fired for tooltips an item hides.
  • World effects can be drawn pixel for pixel: VfxMaterial.withSmoothing(false) samples the texture with nearest filtering instead of linear, so pixel art (block and item textures) stays crisp up close. Materials are smooth by default, as before.
  • Config screens without Glazed Menu: ConfigScreens now opens CoolCatLib's own screen when Glazed Menu isn't installed, in the look of the screen effects screen (the config's categories on the left, its settings on the right, a search over all of them, light and dark mode), instead of returning null. Switches, sliders, dropdowns for enums, a color picker and text boxes for everything else; changes wait for Done, server configs are sent to the server when playing on one (or shown read only), and settings needing a restart are marked. Glazed Menu's screens are still used whenever it is installed; ConfigScreens.isGlazedMenu() tells which.
    • ConfigScreens.categoryPopup(...) opens a popup floating over the current screen, editing just that category's settings (with reset buttons and Save), instead of the full screen. A server config the player may not change is greyed out and marked read only.
  • Quiet held-item changes (HeldItemSwaps, client): data a mod changes on a held item no longer makes it dip out of view and back as if swapped. HeldItemSwaps.quiet(component...) names components whose changes alone are quiet; HeldItemSwaps.register((shown, next) -> ...) decides for any change, from the stack shown and the one now held. Changes to attachments on an item are quiet by default; Attachment.Builder.swapAnimation() makes an attachment's changes play the swap as before.
  • GhostBlocks (api.client.vfx): blocks drawn as ghosts with their real models (block entities too), one see-through picture so only their outside shows, tinted and faded by one colour; shown through walls, in the world as real blocks would be, or always; full bright or shaded.
  • HeldItemSwaps.quiet(Supplier): a component registered later (a RegistryEntry) can be named while a mod sets up; it is looked up once stacks are first compared. Calling .get() on it then fails on NeoForge, where components aren't registered yet.

🔧 Changes

  • Block entity attachments kept in dropped items are written and read with plain injections instead of redirects, which the MixinExtras bundled with NeoForge could fail on at startup.
  • NeoForge: payloads are registered as optional, CoolCatLib's own included, so a client with CoolCatLib (and client-only mods built on it) can join a server without it and the other way round, as on Fabric (NeoForge used to disconnect whichever side lacked a channel). Configuration payloads are only sent to clients that have their channel. Network.sendToPlayer skips a player whose client lacks the payload's channel instead of throwing.
  • Rifts (WorldRifts) can be held facing one way (rift.facing(direction)), as a portal set in a wall, instead of turning to the camera.
  • Canvas's namespace is coolcatlib too: its assets (coolcatlib:bloom, coolcatlib:tint, #moj_import <coolcatlib:vfx.glsl>, coolcatlib:sky.glsl, coolcatlib:screen_effect.glsl, the GUI and VFX textures), text colours in JSON and commands ("coolcatlib:rainbow", "coolcatlib:gradient/..."), saved cutscenes (coolcatlib:saved/<name>, from config/coolcatlib/cutscenes/), translation keys, key bindings and payload ids. Its development commands are under /coolcatlib_client (effects, cutscene ...), and the effects screen's choices are saved to config/coolcatlib-screen-effects.json (choices saved by Canvas are not carried over). Shaders, resource packs and text that named coolcatcanvas: need the new name.
  • The packages are still net.ixdarklord.coolcatcore and net.ixdarklord.coolcatcanvas, so code that calls CoolCatLib needs no import changes.

This mod has no additional files