promotional bannermobile promotional banner

[EO] Enchanted Outlines

Each enchantment type is assigned a unique color identifier, allowing you to instantly comprehend the power of the item in your hand
Back to Files

enchanted_outlines-0.2.1.jar

File nameenchanted_outlines-0.2.1.jar
Uploader
LOVE_U987LOVE_U987
Uploaded
Oct 11, 2026
Downloads
292
Size
143.3 KB
Mod Loaders
NeoForge
File ID
9125852
Type
R
Release
Supported game versions
  • 1.21.1

Curse Maven Snippet

NeoForge

implementation "curse.maven:enchanted-outlines-1643642:9125852"

Learn more about Curse Maven

What's new

✨ Enchanted Outlines ✨ v0.2.1 — Where Every Silhouette Finally Breathes


"First, we teach the outline to follow the hand that drew it."

📖 This Update's Contents


🖼️ I · The Universal Capture, Unified

An outline should follow its weapon. It should breathe with every animation, sway with every frame, and stand where the item truly stands. Yet for three rounds of patches, the outline lagged behind. It froze mid-swing. It drifted off-screen. It grew into enormous shapes in the sky, or shrank into pale squares in the inventory. Every one of those failures traced back to a single truth: the outline was reading the wrong geometry, at the wrong moment, in the wrong space.
  • Universal BEWLR Capture (v2) — All models using a block-entity-without-level renderer are now captured with an identity pose, so the geometry is read in the renderer's own local model space. Camera-space and GUI-pixel-space contamination is eliminated.
  • Guards Rebuilt — Rejection now checks both span and center distance, closing the "small shape, very far away" loophole that allowed phantom geometry to slip through.
  • Real-Pose Replay — Captured vertices are replayed through the actual pose matrix, guaranteeing the outline lands exactly on top of the item, regardless of context.
  • Global Buffer Swap — Renderers that write to the global buffer (rather than the passed-in consumer) are now captured cleanly through a unified swap window.
  • Flat Geometry Redirected — Flat quads now emit an in-plane eight-direction offset with the sampled texture's alpha mask, instead of a vertex-normal expansion that would have rendered them as solid rectangles.
  • Legacy Fallback Preserved — When capture returns nothing, the reflection and Geo paths still serve as a safe descent.
The outline no longer reads a stale shadow. It reads the living hand.

🎨 II · Per-Item Control, Finally Yours

A player once asked: "Can I make the starfury thicker, and keep everything else thin?" The answer, until now, was no. The outline was global, or nothing.
  • Per-Item Thickness — A new configuration map lets you set outline thickness per item ID, with support for modded items. Programmatic registrations take precedence, followed by the config map, then the global value.
  • Forced Solid Color — A new list lets you lock certain items to a solid outline color, even when shader-mode blending would otherwise tint them. Supports wildcards.
  • Thread-Local Context — Deeply nested rendering paths that lack access to the item stack now query a thread-local "currently outlined item," set at every outline entry point and cleared in finally.
  • Config Screen Rows — Both new options are exposed in the colors category, with synchronized Chinese and English language keys.
Every item now answers to its own rules. The outline respects the hand that holds it.

⚙️ III · The Namespace Adapter Registry

Before this update, the dispatch chain was a series of handwritten if-else branches. Adding a new mod meant editing code. A misbehaving mod meant waiting for a patch.
  • Config-Driven Dispatch — A new configuration maps namespaces to adapter strategies: capture (animation-synced capture, default), legacy (reflection and Geo direct reads), or off (never outline).
  • No Code Changes for New Mods — A pack author can now redirect or disable outlining for any namespace with a single config line.
  • Unconfigured Namespaces — Fall through to the default capture-first chain.
  • Coexists with Existing Gates — The TACZ and Hazen compatibility switches still apply; when a master switch is off, the registry does not revive it.
The dispatch chain is a map now, not a maze.

🌈 IV · The Glint No Longer Pollutes the Shape

Enchanted weapons rendered as purple glowing blobs, not silhouettes. The cause: an enchanted item is drawn twice—once as the body, once as the glint overlay—and both layers were being captured into the same vertex stream. The outline took the glint's noisy texture as its alpha mask, and every quad appeared duplicated, which the zero-thickness detector misread as "all quads are flat."
  • Layer-Aware Capture — The capture now records the RenderType request order and each quad's source layer. When sampling, the first non-glint texture is chosen.
  • Overlay Detection — Cross-layer duplicate signatures are recognized as glint or glowmask overlays; the non-base copies are skipped, leaving one clean base layer.
  • Zero-Thickness Detection, Refined — Only same-layer duplicates are treated as zero-thickness patches. The signature is now a long hash, so no string allocation per frame.
The glint returns to its place as light. The silhouette returns to its place as shape.

❄️ V · Animated Textures, Frame by Frame

A 64×320 animated weapon texture should outline as a sword—not as the union of all five frames. The outline was reading the entire sheet, not the frame the game was currently displaying.
  • Frame-Zero Extraction — All CPU-side reads now parse the .png.mcmeta animation declaration and crop to the first frame. The Geo model's UV space matches a single frame, and so does the outline's.
  • Animated Texture Routing — When the registered texture is AzureLib's animated texture, the outline binds to the original location so it samples the current frame on the GPU, staying synchronized with the body.
  • Static Approximations Where Necessary — When only a static frame is available (CPU-baked shape textures), the first frame is used as a faithful approximation.
The outline now follows the animation, not the archive.

🧹 VI · The Foundation, Refactored

A 4,655-line file had become a liability. Every fix risked breaking another.
  • Modular Split — OutlineRenderer was split into focused submodules: BewlrCapture, LionfishOutline, TaczOutline, GeoOutline, BewlrModelResolver. Behavior preserved exactly; the mixin entry points remain unchanged.
  • Shared Cache Discipline — All outline caches now register with a single invalidation chain, cleaned on resource reload, world change, and config edits.
  • Batch Closure Enforced — Every mixin outline entry now flushes its batch in finally, so no half-written geometry can leak into the world render stage.
  • Verification, Automated — A new verify.py gate checks compilation, nine static rules, mixin registration, cache registration, and language key consistency. A self-test injects known violations to confirm the checks actually catch them.
The monolith becomes modules. The rules become executable.

📋 Update Overview

+ 🖼️ Universal BEWLR capture (v2) with identity-pose geometry and real-pose replay
+ 🖼️ Dual guards: span and center distance, closing the "far small shape" loophole
+ 🖼️ Global buffer swap unified across all capture paths
+ 🖼️ Flat quads redirected to in-plane 8-direction offset with texture alpha mask
+ 🎨 Per-item thickness map and forced solid color list (with wildcards)
+ 🎨 Thread-local "currently outlined item" context for deep decisions
+ ⚙️ Namespace → adapter config registry (capture / legacy / off)
+ 🌈 Layer-aware capture: glint overlays skipped, first non-glint texture sampled
+ 🌈 Zero-thickness detection refined; signature as long hash
+ ❄️ mcmeta-aware frame-zero extraction for animated textures
+ ❄️ Animated texture routing for AzureLib GPU sampling
+ 🧹 OutlineRenderer split into five submodules (behavior preserved)
+ 🧹 verify.py + verify_selftest.py: static gate with negative self-test
+ 🛡️ Solid color forced when shaders are off, across all paths
+ 🛡️ Creative and spectator players excluded from damage-attributed paths

- 🖼️ Identity-pose ghost geometry leaking into world render
- 🖼️ Square GUI backdrops from failed texture extraction
- 🖼️ Frozen outlines on animated weapons
- 🌈 Purple glint blobs that ignored the weapon's silhouette
- ❄️ The union-of-all-frames block on animated textures
- ⚙️ The handwritten if-else dispatch chain
- ⚠️ Silent divide-by-zero and integer overflow in edge cases

✨ Every silhouette, in its rightful place. ✨
"The outline was never meant to lag behind the weapon."
GitHub

This mod has no additional files