refactor: extract shared overlay foundation - #177
Open
TheMeinerLP wants to merge 6 commits into
Open
Conversation
Four different services (tunnel vision, blood splatter, slender gaze, and the stamina bar) each hand-rolled the same start/stop guard around a Minestom Task: a nullable field, a null-check before scheduling, and a null-check before cancelling, repeated with small variations at every call site. Extract that guard once as RepeatingTask so the follow-up feature branches can adopt a single, tested implementation instead of copying the pattern a fifth time.
Five separate hand-rolled per-player maps existed across the tunnel vision, blood splatter, and slender gaze code, each keyed by UUID and each managing its own put-on-join/remove-on-leave lifecycle by hand. The duplication made every one of those call sites a place a leak or a stale-entry bug could hide. PlayerState wraps that lifecycle once behind a small, tested type, so the three follow-up feature branches can store their per-player values without re-deriving the same map bookkeeping.
The tunnel vision and slender gaze code each clamped values into range with their own Math.min(max, Math.max(min, value)) expression, which is easy to get backwards (min/max swapped) and gives no shared place to fix it once. Add int and double overloads of Helper.clamp so the follow-up feature branches can call one well-tested method instead of repeating the expression.
Three texture-key builders existed across the tunnel vision, blood splatter, and slender gaze designs, each assembling equipment-slot texture paths with its own naming convention (stage_<n>, <direction>_<variant>_<frame>, level_<level>_<frame>), so nothing about them could be reused or tested together. Add the shared overlay package: ScreenOverlay and OverlayLayer describe where an overlay sits and how it renders, OverlayProperties and EquipmentScreenOverlay handle applying it to a player's equipment slot, and OverlayTextureKeys unifies the three texture-key conventions behind one type. This is the rendering base the three follow-up feature branches (tunnel vision, blood splatter, slender gaze) build their per-effect logic on top of.
The three preview commands (tunnel vision, blood, glitch) each hand-rolled an identical private static asPlayer(CommandSender) check to narrow a CommandSender down to a Player, differing only in the error string sent back to the console. Extract that check once as CommandSenders.asPlayer, a stateless static method rather than an abstract base command, since narrowing the sender is the only thing the three commands have in common and a shared base class would force them into one constructor shape and inheritance chain for a single one-line check.
Contributor
Test results191 files 191 suites 1m 28s ⏱️ For more details on these failures, see this check. Results for commit 6140e55. ♻️ This comment has been updated with latest results. |
This was referenced Aug 12, 2026
Contributor
Job Summary for GradleBuild PR :: build
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
This is the shared foundation extracted from the mixed-together tunnel vision work, split
out on its own so it can land ahead of the three feature branches that build on it:
tunnel vision, blood splatter, and slender gaze. Each of those effects draws
something onto the player's screen and tracks per-player state, and each was about to
reinvent the same handful of building blocks independently. This branch adds those
building blocks once, tested, so the three feature PRs can adopt them instead of
duplicating them a third and fourth time.
What each new type replaces
common/util/PlayerStatereplaces five hand-rolled per-player maps spread acrossthe tunnel vision, blood splatter, and slender gaze code, each keyed by UUID and each
managing its own put-on-join/remove-on-leave lifecycle by hand — a natural place for a
leak or a stale entry to hide.
common/util/RepeatingTaskreplaces four copies of the same scheduler start/stopguard (tunnel vision, blood splatter, slender gaze, and the stamina bar), each a
nullable
Taskfield with a null-check before scheduling and a null-check beforecancelling.
overlay/OverlayTextureKeysreplaces three texture-key builders with threedifferent conventions (
stage_<n>,<direction>_<variant>_<frame>,level_<level>_<frame>), unifying them behind one type so equipment-slot texture pathsare assembled the same way everywhere.
command/CommandSendersreplaces three copies of the same command sender check(
TunnelVisionCommand,BloodCommand,GlitchCommand), each hand-rolling an identicalprivate static @Nullable Player asPlayer(CommandSender), differing only in the errorstring sent back to the console.
common/util/Helper#clamp(int and double overloads) replaces the hand-rolledMath.min(max, Math.max(min, value))expressions the tunnel vision and slender gaze codeeach wrote independently.
overlay/ScreenOverlay,OverlayLayer,OverlayProperties,EquipmentScreenOverlayform the shared rendering base: where an overlay sits, how it renders, and how it gets
applied to a player's equipment slot. The three feature branches layer their per-effect
logic (tunnel vision stages, blood splatter frames, slender gaze intensity) on top of
this instead of each building their own equipment-overlay plumbing.
Scope
Only the foundation types and their tests are included. No feature code (tunnel vision,
blood splatter, slender gaze, the preview commands, or
Cygnus.javawiring) is part ofthis branch — those land as separate follow-up PRs on top of this one.
How to verify
All existing and new tests pass; both modules compile cleanly against
main.