Changelog
Version: 1.1.0
Summary
Version 1.1.0 refactors the rendering architecture, introduces robust asset detection, improves client-server synchronization, adds death markers, enhances configuration capabilities, and fixes multiple bugs. Backwards compatibility with existing configs and use cases is preserved.
Major Enhancements & Additions
Rendering & Architecture
- Modular separation of rendering logic into:
RenderAddons
RenderUtils
TextureManager
TextureAnimator
- Introduction of
AssetScanner:
- Scans the resource manager for textures under
sprites/hud/
- Builds lists of available dot styles, arrow styles, icon borders, death marker types
- Caches texture dimensions to avoid repeated IO
- Death markers persistence:
Hud.deathMarkers store marker data with timestamp and world position
- Configurable limit of death markers
- Automatic cleanup of old or out-of-range markers
- Hybrid mode operation:
- Handshake with server to detect mod presence
- Fallback to local mode if server unresponsive beyond timeout (e.g.
SERVER_TIMEOUT_MS)
- Per-player overrides:
- In config, allow per-player settings: color, icon style, border style
Detailed Changes per Component
Main / Mod Initialization
- Register payload codecs for
HandshakePayload and PositionUpdatePayload with PayloadTypeRegistry
- Initialize server module (
BetterPlayerLocatorBarServer) on common side
- Add logging for handshake success/failure and mode switching events
Client / Initialization
- On resource reload, call
AssetScanner.reload(...)
- Instantiate
Hud and register HudRenderCallback
- In
ClientPlayNetworking, register receiver for handshake and position update
- Track
lastServerUpdateTime; if exceeds threshold, switch to local mode
HUD (BetterPlayerLocatorBarHud)
- Maintain maps:
playerPositions
lastKnownPositions
currentIconPositions
lastPositionUpdateTime
tick() and updateRenderCache():
- Filter players by distance and
maxVisibleIcons
- Sort by closeness or priority if needed
- Easing & interpolation:
- If distance jump is large (e.g. > 75% of bar width), snap to target
- Else, advance position using
easeInOutQuad
- Separate rendering methods:
renderPlayerIcon()
renderDeathMarker()
renderArrow()
renderNameplate()
- Hide logic:
shouldHideTarget() checks for sneaking, invisibility, helmet usage
- Angle & FOV:
- Use
CONFIG.getFovMultiplier() to adjust icon horizontal shift
- Alpha / fading:
calculateEdgeAlpha() and getDistanceAlpha() for smooth fade near edges or by distance
- Texture selection:
getAdjustedTextureIndex(distance, config) picks animation frame
AssetScanner
- On
reload, checks for presence of each expected texture (dots, outlines, arrows, markers, tags)
- Builds lists:
availableDots, availableArrows, availableDeathMarkers, etc.
- Caches texture widths and heights via
NativeImage to avoid repeated loads
RenderAddons
- Central rendering of tinted icons, outlines, names, arrows, and death markers
- Supports override of head texture by UUID or name, with fallback to default skin
renderIcon(), renderArrow(), renderNameplate() share common helper logic
- Outline rendering: darker border variants computed dynamically or via presets
TextureManager
- Centralizes
Identifier creation for texture paths
- Caches
Identifier objects to reduce allocation overhead
- Standardized naming scheme:
sprites/hud/player_dots/{type}_{frame}.png
sprites/hud/player_dots_outlines/...
sprites/hud/arrows/{type}.png
sprites/hud/death_markers_dots/{type}.png
sprites/hud/tags/{style}.png
TextureAnimator
- Handles time-based frame switching for animated textures (if any)
- Maintains current frame, elapsed time, duration per frame
Keybinds
- Register
SHOW_PLAYER_NAME and OPEN_CONFIG
OPEN_CONFIG opens ConfigScreen via client.setScreen(...)
RenderUtils
- Utilities for rendering:
renderTintedTexture(...)
drawNineSlicedTexture(...)
withMatrixPush(...)
setShaderColorRGBA(...)
getTextureDimensions(...) (delegates to AssetScanner cache)
Network
HandshakePayload contains fields: serverHasMod, playerIsOp
PositionUpdatePayload contains:
positions(): list of (UUID, Vec3d)
newPlayers(): optional list of new player info
disconnectedPlayers(): list of UUIDs
- Client receives payloads and updates internal maps in thread-safe manner (via
client.execute(...))
Bug Fixes
- Prevent NPE in
AssetScanner when a texture is missing (check .isPresent() first)
- Remove stale entries in
currentIconPositions when players disconnect or markers expire
- Fix jumping icons when large remote deltas: implement snapping threshold
- Fix fallback logic when
textureHeadOverride is non-UUID string; add resolution from usercache.json
- Clamp angle calculations so icons outside the horizontal range don’t render incorrectly
- Fix mod/mixin registration: ensure
BetterPlayerLocateBar.mixins.json declared correctly
- Ensure name rendering only when Tab is held or always enabled via config
Performance & Optimization
- Cache texture dimensions in
AssetScanner to avoid repeating image loads
- Cache
Identifier objects in TextureManager
- Pre-limit icon rendering count by
maxVisibleIcons before layout computation
- Maintain intermediate render caches (
positionsToRenderCache) to avoid recomputation each frame
- Asset scan only on resource reload, not every frame
- Minimize temporary allocations in loops (reuse collections, use
computeIfAbsent, subList)
Configuration & UX Enhancements
- Added config options:
deathMarkerInheritBorderColor
deathMarkerBorderStyle
assetScanner.textures list
adjust_to_fov, fov_multiplier
- ConfigScreen improvements:
- Renders real-time preview of names and icons
- Shows detected textures from
AssetScanner in dropdowns
- HUD offset auto-applied if icons present (
shouldApplyHudOffset() logic)
Client-Server Integration
- Server module now actively gathers player positions at interval
- Client handshake verifies server mod and sets flags accordingly
- If server stops sending updates, client falls back to local mode
PositionUpdatePayload sends full updates so client can reconstruct state
Robustness & Edge Cases
- UUID parsing wrapped in try/catch to avoid crashes
- File I/O (e.g.
usercache.json) wrapped with existence checks
- Clear logs in
Constants.LOGGER for mode switching and error conditions
Regression Risk & Testing
- Tested:
- Mode switching (server vs local)
- Name rendering via Tab
- Death markers creation and cleanup
- Asset detection when adding custom textures
- Edge cases:
- Player wearing helmet/skull — head override logic
- Invisible or sneaking players
- Large jumps in position between updates
Previous Version (1.0.0) — Summary
- Basic HUD rendering of nearby players
- Automatic colors, simple interpolation
- Static icon style, no death markers
- Minimal configuration
Notes
- This version emphasizes stability, modularity, and configurability
- If regressions occur, open issues with logs, steps to reproduce, and version info