Skip to content

Release/3.0.0#26

Merged
richardthornton merged 3 commits into
devfrom
release/3.0.0
Apr 30, 2026
Merged

Release/3.0.0#26
richardthornton merged 3 commits into
devfrom
release/3.0.0

Conversation

@richardthornton

Copy link
Copy Markdown
Owner

No description provided.

richardthornton and others added 3 commits April 27, 2026 16:05
- Remove unused ItemStack import from CreateWorldScreenMixin
- Guard empty targetItemId in ClientHuntState.handleWin to avoid null
- Cache display name alongside ItemStack in HuntHudRenderer
- Add fast-path flag and try-catch around bindComponents in ItemPool
- Compare MouseButtonEvent x/y as doubles for sub-pixel accuracy

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- HuntHudRenderer.resetCache() called from WorldLifecycleHandler on disconnect
  so a new hunt targeting the same item doesn't reuse a stale ItemStack.
- SpawnHuntScreen caches the display ItemStack and only recreates it when
  displayItem changes (rolling tick or reroll), matching the HUD pattern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@richardthornton richardthornton merged commit cf761e9 into dev Apr 30, 2026
9 of 10 checks passed
@richardthornton richardthornton deleted the release/3.0.0 branch April 30, 2026 05:40
@claude

claude Bot commented Apr 30, 2026

Copy link
Copy Markdown

Claude finished @richardthornton's task in 2m 10s —— View job


Code Review: Release/3.0.0 (PR #26)

  • Gather context and read PR diff
  • Review changed files in detail
  • Assess code quality, security, and performance
  • Post comprehensive review feedback

This is a clean, well-scoped release PR with 54 additions / 14 deletions across 8 files. The changes fall into three categories: caching improvements, defensive hardening, and minor cleanup. Overall this is solid work — my notes below are mostly minor observations.


Code Quality

ItemPool.java — Defensive error handling for component binding

The addition of try/catch around bindComponents() and the componentsBound guard flag are both good improvements:

  • The componentsBound flag prevents redundant re-binding across multiple screen opens — nice.
  • Catching Throwable (line 116) is appropriate here since this is a forward-compatibility guard against MC API changes, and you want to survive even Error-level problems in this non-critical path.
  • Logging with t.toString() instead of passing the throwable directly means you lose the stack trace in warn-level logs. Consider SpawnHuntMod.LOGGER.warn("...: {}", id, t) to preserve the full trace — helpful when debugging actual binding failures across MC updates. Fix this →

HuntHudRenderer.java — Display name caching

Good change. Previously ItemPool.getDisplayName() was called every frame (line 73 in the old code) even though ItemPool already has its own cache. Now the HUD caches the Component alongside the ItemStack, avoiding a map lookup per frame. The resetCache() method is properly called on disconnect via WorldLifecycleHandler — clean lifecycle management.

SpawnHuntScreen.java — ItemStack caching during roll animation

Previously a new ItemStack was created every render frame during the slot machine animation. With ~60 items cycled at 60fps, that's a lot of unnecessary allocation. The cachedStackItem / cachedDisplayStack pattern is the right fix — only create a new stack when the displayed item actually changes.

SpawnHuntScreen.javamouseClicked cast removal

Removing the (int) casts from the event.x() / event.y() comparisons (lines 350–351) is correct. Since historyLinkX etc. are int values, the comparison widens to double (or float) which is safe and avoids truncation at sub-pixel boundaries. Cleaner and slightly more accurate for high-DPI displays.

CreateWorldScreenMixin.java — Unused import cleanup

Removing the unused ItemStack import — trivial but good hygiene.


Security

ClientHuntState.java — Null guard on empty targetItemId

targetItem = !payload.targetItemId().isEmpty()
        ? Identifier.tryParse(payload.targetItemId()) : null;

This aligns handleWin() with the same guard already present in update() (line 19). Previously, an empty string from the server would pass through to Identifier.tryParse(""), which could return an invalid identifier. Good defensive fix against malformed or edge-case server packets.

No other security concerns — the changes are all client-side rendering and state management with no user input handling, file I/O, or network protocol changes.


Performance

The performance improvements are the highlight of this PR:

Change Impact
componentsBound flag Eliminates redundant registry iteration on repeated screen opens
HUD display name caching Removes per-frame HashMap.get() in the render loop
SpawnHuntScreen ItemStack caching Eliminates per-frame new ItemStack() allocation during rolling animation

All three are targeted, proportional optimizations — no premature abstraction, just eliminating obvious hot-path allocations. The caching invalidation strategies are simple and correct (identity check for items, equality check for identifiers).


Minor Observations

  1. CHANGELOG.md — The v3.0.0 entry is minimal ("SpawnHunt now supports Minecraft Java Edition version 26.1"). Consider noting the caching/stability improvements from this PR if they're user-facing, or leave as-is if this changelog entry was already written before these fixes were added to the release branch.

  2. CLAUDE.md — The v2.2.1 notes column was empty and now reads "Server players can immediately start a new hunt after winning" — good to backfill this.


Summary

Clean release PR. The changes improve runtime performance (eliminating per-frame allocations in the render loop), add forward-compatibility hardening (defensive try/catch for MC API changes), and fix a potential null identifier edge case in multiplayer packet handling. No issues that would block a release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant