Patchnote

Complete changelog of new features, changes, and bug fixes for each EriAPI release.

v1.6.8 May 07, 2026

Critical fix — EventBuilder.filter() overwrote previous filters

Each call to .filter(...) on an EventBuilder replaced the previous filter outright instead of combining them. As a result, listeners configured with multiple chained .filter(...) calls only honored the last one, leaking events that should have been rejected by earlier filters.

Real-world example: a PlayerTickEvent handler scoped to a specific dimension, configured like this:

EriEvents.on(TickEvent.PlayerTickEvent.class)
    .filter(e -> e.phase == TickEvent.Phase.END)
    .filter(e -> e.player.world.provider.getDimension() == TARGET_DIM)
    .filter(e -> !e.player.world.isRemote)   // this filter OVERWROTE the previous ones
    .handle(e -> applyEffect(e.player));

The dimension check was lost, and the effect was applied across every dimension on the server side.

Fixed: successive calls to filter(...) are now combined with logical AND via Predicate.and(). All predicates must return true for the handler to be invoked. The expected and natural behavior is restored, with no impact on listeners that used a single filter.

v1.6.7 May 05, 2026

Fix — 3D animated models offset from their hitbox

Blockbench models rendered by AnimatedEntityRenderer appeared visually shifted by half a block on X and Z compared to the entity hitbox. Cause: Blockbench centers models on (8, 0, 8) in pixels (= 0.5, 0, 0.5 in GL units), but the entity origin (posX/posY/posZ) is the bottom-center of the bounding box. Without an offset, the model's (0,0,0) corner is rendered at the hitbox center.

Fixed in doRender(): a GlStateManager.translate(-0.5f, 0.0f, -0.5f) is now applied right after the yaw rotation to recenter the model. Yaw rotation now happens around the model's actual vertical axis (its center) instead of an off-center pivot. Cascade-fixes movement animations that looked buggy — they were simply applied around the wrong pivot.

Fix — Hostile mobs targeting Creative / Spectator players

The HOSTILE_MELEE, HOSTILE_RANGED and BOSS presets of EriEntity created EntityAINearestAttackableTarget tasks without any predicate. Result: staff/admins in creative mode were targeted by mobs like any survival player.

  • EriEntityBase, GeneratedEntity and PathfinderBuilder.targetPlayers() — all target tasks aimed at EntityPlayer.class now use the 6-arg constructor with a Predicate<EntityPlayer> that rejects players in isCreative() or isSpectator().
  • The predicate is stored as a static singleton per class to avoid one lambda allocation per spawned entity — critical at 500-1000 concurrent players.

Perf — AnimatedEntityRenderer: per-texture draw call batching

The previous implementation called buffer.begin() + tessellator.draw() per face. A model with 200 elements and 6 faces per element therefore issued 1200 GPU draw calls per entity per frame — catastrophic FPS drop with even a handful of visible entities.

Refactor of renderElement(): faces of the same element are now grouped by texture into a single begin() / draw() pair. Most elements only use one or two textures — the reduction is typically 6x to 12x depending on the model. For a complex 200-element single-texture mob: 1200 draw calls -> 200.

  • New internal methods: resolveTexture(String) -> ResourceLocation (resolution without binding) and appendFaceVertices(buffer, ...) (appends a face's 4 vertices into an already-open buffer).
  • The old drawFace() method was replaced — no public API change, only the internal pipeline.
  • Compatible with all existing animations (translation, rotation, scale, cumulativeRotation, texture overrides). Matrix transforms are unchanged; only the draw-flushing is batched.

100% backward compatible — no public API change.

v1.6.6 May 05, 2026

Fix — EriEntityBase: eriDef resolved before AI / attribute setup

The EntityLiving constructor calls applyEntityAttributes() and initEntityAI() via super(world) before the EriEntityBase subclass can assign this.eriDef. Result: mobs spawned with no AI and vanilla default stats, regardless of what was declared via EriEntity.create(...).

Restructured: the applyEntityAttributes() and initEntityAI() overrides are now no-ops, and the constructor calls applyEriAttributes() + setupEriAI() after resolving eriDef via DEF_BY_CLASS. Subclasses of EriEntityBase (used for custom Java logic) now correctly receive their stats, AI and hitbox.

v1.6.5 May 02, 2026

Java animations on the builder — .javaAnimation()

The EriAnimBlock and EriEntity builders now expose .javaAnimation(String name, EriAnimJava anim) to register a Java animation directly on the fluent builder — no more need to create a custom TileEntity subclass nor to call addJavaAnimation() manually in the constructor. Anims are stored in the BlockDefinition / EntityDefinition and retrievable via the matching helpers.

  • EriAnimBlock.javaAnimation(name, anim) — appends to the AnimBlockDefinition.javaAnimations map. GeneratedBlock.createTileEntity() now calls configure() and loops to wire the anims onto the auto-generated AnimatedBlockTileEntityGeneric.
  • EriEntity.javaAnimation(name, anim) — appends to the EntityDefinition.javaAnimations map. Retrievable via ContentRegistry.getEntityDef(modId, name).getJavaAnimation("idle") in the entity constructor.
  • Coexists with .animation().erianim files and EriAnimJava classes can be mixed on the same builder.
  • New helper ContentRegistry.getEntityDef(modId, registryName) — direct lookup by name (previously you had to iterate getEntityDefs()).

Fix — AnimatedBlockTileEntityGeneric.configure() never called

Latent bug since v1.6.4: the no-arg constructor + configure() pattern of AnimatedBlockTileEntityGeneric was never invoked — animated blocks generated by EriAnimBlock without a custom .tileEntity(MyTE.class) had no modelId, no animFileId, and no defaultAnimation. Resolved in GeneratedBlock.createTileEntity(): configuration is now applied at TE creation, alongside the Java anims declared on the builder.

100% backward compatible — existing .erianim files and custom TEs continue to work unchanged.

v1.6.4 May 02, 2026

Java Animation API — write animations in pure Java

New API to write animations directly in Java, bypassing .erianim files. Ideal for procedural animations (sin/cos oscillations, reactions to entity state, parametric movements) impossible or tedious to express in JSON. Coexists with .erianim via the same te.playAnimation("name") API.

  • EriAnimJava — abstract class to extend. Two methods: defineKeyframes(ctx) (declarative, cached) and compute(ctx, pose) (procedural, per-frame). duration() required, endBehavior() optional.
  • AnimContext — context with animTick, partial, worldTick, target, helpers asEntity()/asTileEntity(), and DSL at(tick).group(name)....
  • GroupPoseBuilder — fluent API accessible via pose.group("name"). add* methods (additive on keyframes) and set* (replace).
  • Overlayte.playOverlay("name", anim) plays a second Java anim on top of the main one (overlay wins on touched groups). Client-local, never goes through packets.
  • Registrationte.addJavaAnimation("walk", new WalkAnim()) in the TileEntity constructor. Registry shared server+client.

See the full documentation in Animation System — Java Animation API.

No bug fixes — additions only, 100% backward compatible. Existing .erianim files continue to work unchanged.

v1.6.1 April 28, 2026

ListRenderContext — Proportional vertical offset (drawTextProp)

New method ListRenderContext.drawTextProp(String, int offsetX, int offsetYPermil, int maxWidth, int color). Unlike drawText() where offsetY is in raw screen pixels, drawTextProp expresses the vertical offset in permil of the row height (1/1000) — the layout stays correct at every window size.

Symptom before: a fixed -14 px offset that correctly placed the name above the center at fullscreen (itemHeight ~96 px) pushed the text out of the row bounds in a smaller window when the row was resized. drawTextProp(text, x, -150, w, color) places the text ~15% of the row height above the center, regardless of the actual row height.

Java
// BEFORE — offsetY in screen pixels (breaks in small windows)
ctx.drawText(name,   textX,         -14, textMaxW,      0xFFFFFFFF);
ctx.drawText(cost,   textX,         +14, textMaxW,      0xFF4ADE80);
ctx.drawText(status, statusOffsetX, -14, statusW + gap, 0xFFBB55FF);

// AFTER — offset in permil of the row height (correct at every resolution)
ctx.drawTextProp(name,   textX,         -150, textMaxW,      0xFFFFFFFF);
ctx.drawTextProp(cost,   textX,         +150, textMaxW,      0xFF4ADE80);
ctx.drawTextProp(status, statusOffsetX, -150, statusW + gap, 0xFFBB55FF);

The original drawText method is preserved — no breaking change.

v1.6.0 April 24, 2026

EriBlock — Block variants and entity callbacks

The EriBlock builder gains six new methods that cover most vanilla patterns (logs, leaves, plants) and expose entity walk/collision callbacks. No more custom BlockRotatedPillar or BlockLeaves subclasses: a simple .logLike() or .leavesLike(sapling) is enough.

  • .renderLayer(BlockRenderLayer) — sets the client render layer (SOLID, CUTOUT, CUTOUT_MIPPED, TRANSLUCENT). Required for leaves, plants, glass.
  • .onEntityWalk(TriConsumer<World, BlockPos, Entity>) — low-level callback when an entity walks on top of the block.
  • .onEntityCollision(TriConsumer<World, BlockPos, Entity>) — callback when an entity passes through the block (useful for traps / toxic plants).
  • .logLike() — generates a BlockRotatedPillar (AXIS property) for orientable logs.
  • .leavesLike(Block sapling) — generates a full BlockLeaves (CHECK_DECAY + DECAYABLE, natural decay, 5% sapling drop). Forces CUTOUT_MIPPED automatically.
  • .plantLike() — decorative plant: reduced hitbox, no collision, CUTOUT. The blockstate must point to block/cross.

TriConsumer — New functional interface

Java 8 does not provide a native TriConsumer<A, B, C>. EriAPI adds this interface in fr.eri.eriapi.content.TriConsumer for 3-parameter callbacks (used by onEntityWalk / onEntityCollision and available for your own builders).

Internal refactor — GeneratedBlockCommons

To avoid duplication between the 4 generated block variants (GeneratedBlock, GeneratedLogBlock, GeneratedLeavesBlock, GeneratedPlantBlock), shared logic (drops, hitbox, callbacks, TileEntity) has been extracted into GeneratedBlockCommons. No visible API change for users.

Full example

Java
// Custom tree log (automatic X/Y/Z axis)
Block ERINA_LOG = EriBlock.create("mymod", "erina_log")
    .material(Material.WOOD)
    .hardness(2.0f)
    .harvestTool("axe", 0)
    .soundType(SoundType.WOOD)
    .logLike()
    .register();

// Leaves that decay + 5% sapling drop
Block ERINA_LEAVES = EriBlock.create("mymod", "erina_leaves")
    .material(Material.LEAVES)
    .hardness(0.2f)
    .soundType(SoundType.PLANT)
    .leavesLike(ERINA_SAPLING)
    .register();

// Toxic plant that damages on contact
Block TOXIC_PLANT = EriBlock.create("mymod", "toxic_plant")
    .material(Material.PLANTS)
    .hardness(0.0f)
    .soundType(SoundType.PLANT)
    .plantLike()
    .onEntityCollision((world, pos, entity) -> {
        if (entity instanceof EntityLivingBase && !world.isRemote) {
            ((EntityLivingBase) entity).addPotionEffect(
                new PotionEffect(MobEffects.POISON, 60, 0)
            );
        }
    })
    .register();

v1.5.2 April 22, 2026

EriBlock — Custom hitboxes (.hitbox / .hitboxes)

EriBlock now supports custom collision and selection boxes directly in the builder, without manually subclassing Block.

  • .hitbox(AxisAlignedBB) — Replaces the default full-block hitbox with a single custom box. Automatically sets isFullCube and isOpaque to false. Unit: 1.0 = 1 block = 16 pixels.
  • .hitboxes(AxisAlignedBB...) — Defines multiple independent collision boxes. Each box is tested separately during entity collision via addCollisionBoxToList. The selection outline (hover highlight) shows the union of all boxes. Automatically sets isFullCube and isOpaque to false.
Java — Examples
// Single hitbox — half-block height (1.0 = 1 block = 16 pixels)
EriBlock.create("mymod", "half_slab")
    .material(Material.ROCK)
    .hardness(2.0f)
    .hitbox(new AxisAlignedBB(0, 0, 0, 1, 0.5, 1))
    .register();

// Multiple hitboxes — flat base + central pillar
EriBlock.create("mymod", "machine")
    .material(Material.IRON)
    .hardness(4.0f)
    .hitboxes(
        new AxisAlignedBB(0,    0,    0,    1,    0.25, 1),
        new AxisAlignedBB(0.25, 0.25, 0.25, 0.75, 1,    0.75)
    )
    .register();

v1.5.1 April 18, 2026

Element-level animation (elementTracks)

.erianim.json animations can now target individual elements inside a Blockbench group, not only the group as a whole. Each element has its own rotationOrigin (pivot) defined in the model, and animations can apply rotation, translation, scale, visibility and spin around that pivot. Fully backward compatible: existing animations without elementTracks render exactly as before.

  • JSON format — New optional "elementTracks" field alongside "tracks" in each AnimationDef. Keys use the "groupName:elementIndex" format (e.g. "body:2"). The structure of an element track is identical to a group track (rotation, rotate, translation, scale, visible, spin).
  • AnimationDef — New getElementTracks() getter, hasElementTracks() helper, shortcut getElementTrack(String groupName, int elementIndex), and static utility elementTrackKey(String, int) to format the canonical key.
  • AnimationPose — New elementPoses map parallel to the existing groupPoses, with getElement(groupName, elementIndex) and getOrCreateElement(...). The methods reset(), copyFrom() and lerpToward() now include element poses.
  • AnimationController — The sampler iterates elementTracks after the group tracks and populates element poses via a factored helper populatePoseFromTrack(...). Animation-to-animation blending (START / END) also applies to element poses.
  • AnimatedBlockTESR / AnimatedEntityRenderer — Both renderers read the element pose and apply a local OpenGL matrix around each element's rotationOrigin before rendering its faces. Static JSON rotation is preserved and applied first; the animated pose is applied on top.
JSON — elementTracks example
{
  "formatVersion": 1,
  "modelId": "mymod:block/turret",
  "animations": {
    "idle": {
      "length": 40,
      "loop": true,
      "tracks": {
        "base": { }
      },
      "elementTracks": {
        "body:2": {
          "rotation": [
            { "tick": 0,  "value": [0, 0, 0] },
            { "tick": 20, "value": [0, 180, 0] },
            { "tick": 40, "value": [0, 360, 0] }
          ]
        }
      }
    }
  }
}
Java — Reading an element pose
AnimationPose pose = controller.getCurrentPose(partialTicks);
AnimationPose.GroupPose bodyPose = pose.getGroup("body");
AnimationPose.GroupPose elemPose = pose.getElement("body", 2);
if (elemPose != null && !elemPose.visible) return;

Bug fixes

  • No bug fixes in this release — additions only, 100% backward compatible.

v1.4.2 April 17, 2026

EriProjectile — custom projectile builder

New fluent builder for declaring custom projectiles (thrown entities) without Forge boilerplate. Supports velocity, direct damage and area-of-effect (AOE) damage, physics (gravity, drag), hit effects, and lifecycle callbacks. Projectiles are generated at runtime via GeneratedProjectile and allocated a slot in GeneratedProjectileSlots (pool of 32 static subclasses) — CleanRoom compatible, no ASM.

  • EriProjectile — Fluent builder: model(), texture(), velocity(), gravity(), drag(), damage(), aoe(), effectOnHit(), onHitBlock(), onHitEntity(), onTick(), register().
  • ProjectileDefinition — Configuration POJO containing all projectile parameters.
  • GeneratedProjectile / GeneratedProjectileSlots — Entities generated dynamically from the definition, each in its own slot to respect Forge's "one Class per EntityEntry" constraint.
  • ContentRegistry — Automatic registration of projectiles during the RegistryEvent.Register<EntityEntry> event.

Bug fixes

  • No bug fixes in this release — additions only.

v1.4.1 April 17, 2026

PathfinderBuilder — custom AI tasks for EriEntity

Fluent builder to configure an EriEntity's AI tasks beyond the presets (PASSIVE, HOSTILE_MELEE, ...). Lets you add fine-grained behaviors (swim, melee attack, wander, panic, open doors, leap at target, etc.) in a single chain. Tasks are stored as factories (Function<EntityLiving, EntityAIBase>) to defer instantiation until the entity exists.

  • APIEriEntity.ai(ai -> ai.swim().meleeAttack(1.0, false).wander(1.0).watchPlayers(12f).lookIdle().targetPlayers().hurtByTarget(true))
  • Goals availableswim, meleeAttack, wander, watchClosest, watchPlayers, lookIdle, panicOnHurt, leapAtTarget, avoidEntity, openDoors, task(...) (custom).
  • Target goals availabletargetPlayers, targetClass, hurtByTarget, targetTask(...) (custom).

Bug fixes

  • No bug fixes in this release — additions only.

v1.4.0 April 17, 2026

Full Entity Framework — stats, AI presets, drops, spawn rules, callbacks

Major extension of EriEntity (39 fluent methods) to declare a full entity in a single chain: stats (health/armor/damage/speed/range), sounds, AI preset (PASSIVE / HOSTILE_MELEE / HOSTILE_RANGED / NEUTRAL / BOSS), drops, spawn rules (biomes/light/height/dimension), and lifecycle callbacks (onSpawn, onDeath, onUpdate, onAttack, onHurt, onInteract).

  • EntityDefinition — Extended with all the new fields + inner class EntityDrop.
  • AiPreset / EriSpawner — New configuration types for behavior and spawning.
  • GeneratedEntity — Generic entity (extends EntityMob) that applies the definition: applyEntityAttributes, initEntityAI (switches on preset), dropLoot, getExperiencePoints, sounds. onSpawn uses an NBT-persisted flag to avoid re-fires on chunk reload.
  • GeneratedEntitySlots — Pool of 32 static subclasses (Slot0..Slot31) to respect Forge 1.12.2's "one Class per EntityEntry" constraint without ASM (CleanRoom compatible).
  • ContentRegistry.onRegisterEntities — Automatic registration (egg, tracker, spawn rules) and client-side wiring of AnimatedEntityRenderer.

Bug fixes

  • No bug fixes in this release — additions only.

v1.3.2 April 16, 2026

AnimatedItemController: animation playback for animated items

Items created with EriItem.animatedModel() can now play .erianim.json animations in real time. The new AnimatedItemController exposes a simple static API (play / stop / isPlaying) and shares playback state per modelId for every item using the same model.

  • AnimatedItemController — New client-only controller in fr.eri.eriapi.anim. Handles looping (EndBehavior LOOP), one-shot playback, and per-modelId state.
  • AnimatedBlockItemRenderer — The renderer now queries the controller every frame and feeds the pose to the TESR pipeline through a proxy TileEntity. No more static pose.
Java — Example
EriItem.create("mymod", "sword")
    .animatedModel("mymod:item/sword")
    .onRightClick(ctx -> {
        if (ctx.world.isRemote) {
            AnimatedItemController.play("mymod:item/sword", "swing");
        }
    })
    .register();

Bug fixes

  • Documentation animation.html — removed the “no animation playback” warning and replaced it with documentation for the new controller.

v1.3.1 April 16, 2026

EriItem: .animatedModel() support for items with Blockbench 3D rendering

Items created via EriItem can now use an animated 3D Blockbench model when held or displayed in inventory, using the new .animatedModel(String modelId) method. Rendering is delegated to the same AnimatedBlockItemRenderer used for animated blocks.

  • EriItem.animatedModel(String) — New fluent method that configures an item to use a Blockbench model in "modid:item/name" format.
  • ContentRegistry — Automatically wires the TEISR (TileEntityItemStackRenderer) on animated items client-side, and registers the builtin/entity model so Forge delegates rendering.
  • ItemDefinition — New animatedModelId field to store the model identifier.
Java — Example
EriItem.create("eriniumfaction", "faction_sword")
    .maxStackSize(1)
    .rarity(EnumRarity.EPIC)
    .animatedModel("eriniumfaction:item/faction_sword")
    .register();

Bug fixes

  • No bug fixes in this release — additions only.

v1.3.0 April 16, 2026

New: AnimatedEntityRenderer — animated rendering for entities

Extension of the Blockbench rendering pipeline to entities. The renderer uses exactly the same pipeline as AnimatedBlockTESR (groups, elements, faces, UV, animated textures).

  • AnimatedEntityRenderer<T>RenderLiving that renders a Blockbench model with animations. Static factory methods for registration via RenderingRegistry.
  • IAnimatedEntity — Interface that entities implement to provide their animation pose to the renderer. Methods getCurrentPose(partialTicks) and getAnimState().

New: EriEntity builder

Fluent builder to define custom entities with Blockbench model, textures, animations, hitbox, passenger seats, and spawn eggs. Definitions are stored in ContentRegistry for the mod to register in Forge manually.

  • EriEntity — Fluent builder: model(), texture(), animation(), hitbox(), seat() (3 overloads), spawnEgg(), creativeTab(), register().
  • EntityDefinition — Configuration POJO containing all entity parameters.
  • EntitySeat — Passenger seat definition with Blockbench position, yaw offset, attached group, and camera lock.
  • ContentRegistry.registerEntity() / getEntityDefs() — Storage and access for entity definitions.

Category field in AnimationFile

.erianim.json files now support an optional "category" field ("block", "item", or "entity"). This field is informational and indicates which renderer type expects this animation file. Backwards compatible — defaults to "block".

Bug fixes

  • No bug fixes in this release — additions only.

v1.2.1 March 26, 2026

Label: new scaleToFit() and wrapped() modes

  • scaleToFit(boolean) — Instead of truncating text with "...", automatically reduces the text scale so it fits exactly within the component width. Mutually exclusive with wrapped() (wrapped takes priority).
  • wrapped(boolean) — Text wraps to multiple lines at word boundaries. If the wrapped content exceeds the component height, vertical mouse scroll is enabled (scissor clipped). Mutually exclusive with scaleToFit() (wrapped wins).

Tooltip: literal \n support from .lang files

Tooltip.render() now normalizes literal \\n (from .lang files) to real newlines before splitting. Both \n in Java strings and \\n from .lang files now work.

Dropdown: deferred rendering (always on top)

  • The drop-down list is now rendered AFTER all other components (deferred rendering), ensuring it always appears on top.
  • Click handling works even when the Dropdown is inside a ScrollPanel.
  • New static methods: Dropdown.renderDeferredDropdown(), Dropdown.handleDeferredClick(), Dropdown.resetState().
  • EriGuiScreen calls these methods automatically — no action needed for standard screens.

ItemStackRenderer: separate showDurability() from showCount()

New method showDurability(boolean) independent from showCount(boolean). Allows rendering the durability bar without the count text, or vice versa. Both default to true.

Bug fixes

  • No bug fixes in this release — additions and improvements only.

v1.2.0 March 22, 2026

Overlay editor: auto-snap alignment system

The in-game overlay editor now features an auto-snap system. When dragging an overlay in edit mode, it automatically snaps to the edges and centers of other overlays as well as to screen reference points, enabling precise positioning without manually entering coordinates.

  • Overlay edge snapping — The left, right, top and bottom edges of an overlay snap to the corresponding edges of neighboring overlays when within 5 design pixels. 10 snap types are supported: edge-to-edge and center-to-center alignment on both axes.
  • Screen edge snapping — The overlay snaps to all four screen borders (x = 0, x = 1920, y = 0, y = 1080) when approaching within 5 design pixels.
  • Screen center snapping — The overlay can align to the absolute center of the screen (960, 540), both horizontally and vertically.
  • Center-to-center alignment — The horizontal and vertical centers of two overlays can align with each other for symmetric layouts.
  • Cyan guide lines — When a snap is active, a semi-transparent cyan guide line appears on the snap axis to visualize the alignment.
  • Red overlap indicator — If an overlay overlaps another during dragging, it turns red to signal the overlap.
  • Hold Shift to bypass snap — Hold Shift while dragging to disable snapping and move the overlay freely pixel by pixel.

Bug fixes

  • No bug fixes in this release — additions only.

v1.1.0 March 22, 2026

New module: Security Framework

Added the fr.eri.eriapi.security package — a complete server-side anti-duplication and exploit prevention toolkit. Designed for high-player-count servers (500-1000 players).

  • GuiRateLimiter — Per-player action throttling with configurable sliding window. Prevents container click spam.
  • ItemIntegrityValidator — Snapshot/validate/rollback system to verify that the total item count doesn't change after a container operation. Automatically detects duplication attempts.
  • ContainerLock — Synchronized per-key locks to prevent concurrent access to shared containers (e.g. faction chest).
  • DupeAlertManager — Real-time alerts sent to all online operators via EriChat when a duplication attempt is detected.

New documentation: Network GUI

Added the Network GUI page documenting the client-server communication system for GUI interactions: GuiNetworkHandler, IGuiDataReceiver, packet formats, and complete examples.

GUI documentation expanded

  • Added visual effect components: GradientRectangle, Aurora, Starfield, ParticleSystem, SmokeFog
  • Network section moved to the dedicated Network GUI page
  • Sidebar links updated with Security and Network

Bug fixes

  • No bug fixes in this release — additions only.

v1.0.0 Initial release

Included modules

  • GUI Framework — Complete UI toolkit in 1920x1080 design pixels with 30+ components, animations, sounds, and automatic scaling.
  • Overlay HUD — Draggable overlay system with design-pixel positioning, anchoring, and in-game editor.
  • Config System — Annotation-based configuration with auto-generated GUI, client-server sync, and validation.
  • Command Framework — Command builder with auto-completion, typed arguments, permissions, cooldowns, and sub-commands.
  • Content Builder — Create items, blocks, recipes and entities via fluent API without Forge boilerplate.
  • Data & Storage — Persistent storage via annotated POJOs with automatic client sync via @Sync.
  • Scheduler — Schedule delayed, repeating, chained, and async tasks.
  • Chat Builder — Rich chat messages with colors, clicks, hover, and pagination.
  • Capability Helpers — Simplified Forge capabilities via annotations with auto-attach and auto-sync.
  • Event Simplifier — One-line Forge event subscriptions with filters, priority, and expiration.
  • Keybinding Manager — Fluent keyboard shortcuts with combos, double-tap, hold, and contexts.
  • Network GUI — Client-server communication for GUI interactions.