File Details
Ember's Text API 3.0.0-beta.2 (NeoForge 26.1)
- B
- Jun 12, 2026
- 1.13 MB
- 14
- 26.1.2+2
- NeoForge
File Name
emberstextapi-neoforge-26.1-3.0.0-beta.2.jar
Supported Versions
- 26.1.2
- 26.1.1
- 26.1
Curse Maven Snippet
Changelog
v3.0.0-beta.2 — 2026-06-11
Neon glow
- New
gloweffect (aliasneon) renders an SDF-based halo around glyphs:<glow>,<glow radius=4 intensity=1.5 color=#00ffcc>,<glow softness=0 core=0.6>for a sharp neon-tube look,freqfor pulsing. When no color is given the halo picks up each glyph's final color, so<glow><rainbow>animates the halo with the text. - Glow color resolves per glyph at emit time. Replaces
NeonEffect— theneonmarkup name still works and now maps to the new effect. - Per-version render paths: core shaders on 1.21.1, the new render-pipeline API on 26.1, and a bitmap-only runtime SDF path on 1.20.1 (no FreeType required at runtime).
- Glow distance fields bake off the render thread with a per-frame budget; the atlas uploads only changed slots. Drop shadows are suppressed on glowing glyphs so halos don't double-darken.
MSDF font pipeline
- Pre-baked MSDF glyphs now persist to disk on all versions — fonts skip the bake cost on every launch after the first.
- SDF providers attach once per resource reload; fixed the glyph baseline on 1.20.1.
- Forge 1.20.1 embeds the FreeType natives in the
-alljar and fails the binding probe cleanly on servers without them.
KubeJS integration (NeoForge 1.21.1)
- New
EmbersTextbinding for scripts: send/queue immersive messages, manage HUD elements, and style item names and tooltips. - New
EmbersTextEvents.itemTooltipclient event for per-stack tooltip styling from scripts.
Version parity
- Item-name styling and the
EmbersTextFacadeentry point now ship on every loader/version target, and the item-name mixin is correctly registered on NeoForge 26.1. - FTB Quests view tracking ported to 26.1.
- Emojiful compat (1.20.1/1.21.1): effect shadows are dimmed and glow emits in the Emojiful render path. Not yet available on 26.1.
- Obfuscate reveal/hide order is now computed relative to the span start on 1.20.1/1.21.1, matching 26.1 — spans that start mid-text reveal correctly.
- Immersive overlay messages now attach span effect data (effect list, typewriter track, obfuscate keys) to their component styles, so typewriter, obfuscate reveal/random, scroll, and shadow animate in overlays the same way they do in chat. The per-char render tier is gated against re-applying style-carried effects (26.1 covers this with its existing render bypass).
Performance
- Eliminated multiple per-frame allocation and draw-call hot spots in the message renderer. Stress-test FPS at 50 concurrent messages on NeoForge 26.1 improved from ~70 to ~1500+ against a ~2000 FPS baseline.
EffectApplicator.applyEffectsno longer recursively applies sibling-spawning effects onto siblings they just created — those level-2 grandchildren never render. NewEffect#spawnsSiblings()opt-out lets sibling-spawning effects skip the redundant pass.ImmersiveMessage.buildComponentFromSpanscaches its output keyed on the typewriter index snapshot.- Per-codepoint glyph width and
FormattedCharSequencenow cached per(font, codepoint, bold)on each message. - Effects can opt out of per-char dispatch via
Effect#requiresPerChar().TypewriterEffectopts out whencursor=false— its cropping is already handled at the component layer. GuiGraphics.drawManagedwraps message rendering on 1.21.1/1.20.1 to collapse per-text-call buffer flushes (not applicable on 26.1's queued render model).- Background border drawing replaced per-pixel
fillloops with single rotatedfillGradientcalls per strip. Top/bottom borders use a 90° pose rotation so vanilla's vertical gradient becomes a smooth GPU-interpolated horizontal one. fillHorizontalGradient(multi-stop background fill) uses the same rotation trick — N-stop gradient renders as N-1 rotated calls per strip instead of one fill per pixel.
Background gradient extensions
[bg gradient=a,b,c,...]markup now accepts any number of stops (previously capped at 2).[bg border=a,b,c,...]markup adds N-stop border gradient support. Side borders use the first and last stops so corners blend cleanly with the N-stop top/bottom edges.- New
ImmersiveMessage.borderGradient(ImmersiveColor... stops)varargs API. The existing 2-arg overload continues to work unchanged.
Effect system unification
- Fade is now a
MessageEffectunder the hood.fadeInTicks/fadeOutTicksbuilders construct and addFadeInMessageEffect/FadeOutMessageEffectto the message's effect list. The parallel field-based fade state onImmersiveMessageis gone. - New effect names available in markup and
MessageEffectRegistry:fadein,fadeout. MessageEffect#target()(defaultEffectTarget.TEXT) controls whether the effect's pose transform scopes to text, background, or both.- New
AlphaContributorsub-interface lets effects contribute to a per-frame alpha multiplier shared by text and background.FadeInMessageEffectandFadeOutMessageEffectimplement it.
Slide effect background option
<slide>now accepts atargetparam (text,background,all). Default isall, which slides text and background together. The previous beta.1 behavior of sliding text only matchestarget=text.
Metadata
- Loader metadata now declares the EML licence (was incorrectly GPL-3.0) and the licence text is embedded in every jar.
Breaking changes from 3.0.0-beta.1
ImmersiveMessageconstructor,builder,fromMarkup,fromSpans,getDuration, andsetDurationnow take/returnintticks instead offloat. The internal field remainsfloatfor partial-tick interpolation.ImmersiveMessage.typewriter(float, boolean),.typewriter(float),.typewriterCentered(float), and.obfuscate(ObfuscateMode, float)are removed. Use<type>/<obfuscate>markup, or set typewriter/obfuscate at the span level viaTextSpan.typewriter(float)/.typewriterCentered(float)/.obfuscate(...).TextSpan.typewriter(float speed, boolean center)is removed. UseTextSpan.typewriter(float speed)orTextSpan.typewriterCentered(float speed).ImmersiveMessageno longer exposes publicfadeInTicks/fadeOutTicks/typewriter*/obfuscate*fields.fadeInTicks/fadeOutTicksbuilders still work and now construct effects; reflection-based consumers must read fromgetMessageEffects().- NBT key
"Duration"is now stored asIntTag(previouslyFloatTag). NBT saved by3.0.0-beta.1will not load. - NBT: legacy
fadeIn,fadeOut,Typewriter,TypewriterSpeed,TypewriterCenter,ObfuscateMode,ObfuscateSpeedkeys are no longer read or written. Fade state lives in the existingMessageEffectslist (e.g."fadein t=20"); typewriter and obfuscate live onTextSpanor come from markup. - S2C message wire format encodes duration as
VarInt(previouslyFloat), the legacy fade/typewriter/obfuscate per-feature fields are gone from the payload, and the payload gained a trailing(boolean, VarInt, int[])block forborderGradientStops. The effects list is the sole carrier for fade.3.0.0-beta.1clients/servers are incompatible. - NBT gained an optional
BorderGradientlist. Saves without the key load unchanged. - Default
<slide>behavior changed from text-only to text+background. Passtarget=textin markup, or constructSlideMessageEffectwith that param, to restore the old shape.

