feat(blood): add blood splatter overlay on damage - #180
Merged
Conversation
TheMeinerLP
force-pushed
the
feat/blood-splatter
branch
from
August 23, 2026 09:11
7f3f77d to
4d55d9b
Compare
Cygnus needed a way to tell a survivor they were just hit and from which side, separate from the tunnel vision's read on how they are doing overall. The splatter rides the shared screen overlay's BLOOD layer, fades over twelve 100 ms frames (1.2 seconds total), and BloodDirection.between resolves the hit side from the victim's own facing rather than world coordinates, so a hit from the east reads differently depending on which way the player is looking.
SlenderBarHelper.applyDamage sets a target's health directly, which never raises Minestom's own EntityDamageEvent, so nothing reacting to a hit - the blood splatter above all - would otherwise hear about it. This adds PlayerDamagedEvent, carrying the victim, the source position and the amount, and dispatches it right after the health is lowered. The source position is what lets the splatter be aimed at the side the hit came from.
Waiting to get hit is a slow way to judge a splatter drawing. /blood throws one from a random side, and /blood front|right|back|left asks for a specific one, so the four directions and their variants can be checked without needing a slender in the game.
Builds the shared screen overlay and the blood splatter service, registers /blood, and hooks the service's listener behind the same OverlayProperties guard the other overlay effects use, since the splatter textures only exist when a resource pack that ships them is configured.
Records why the splatter shares the screen overlay's head slot with the tunnel vision instead of pre-rendering every combination, how the direction is worked out from the victim's facing, and the frame/texture layout the cygnus-pack generator relies on.
Contributor
Test results255 files 255 suites 1m 38s ⏱️ Results for commit 4d55d9b. |
…uses PlayerState and RepeatingTask moved to game/utils in the foundation; the imports follow. The "only players can bleed" text becomes Messages.ONLY_PLAYERS_CAN_BLEED, next to the other player-facing texts, now that CommandSenders takes a finished Component rather than assembling one from a sentence fragment. The recording ScreenOverlay the tests stood up twice is the foundation's RecordingScreenOverlay instead - the same duplication this stack removes from the production code had grown back in the test sources. The comment gating the effect in Cygnus still described a vignette font that no longer exists and tied the gate to the resource pack, which OverlayProperties deliberately is not tied to. Left alone on purpose: clear(Player) keeps its name. It removes one player, and on main the no-arg cleanUp() is the round teardown while removePlayer(Player) is the per-player counterpart - renaming it would have said the opposite of what it does.
TheMeinerLP
force-pushed
the
refactor/overlay-foundation
branch
from
August 23, 2026 09:17
af3dead to
e45d219
Compare
TheMeinerLP
force-pushed
the
feat/blood-splatter
branch
from
August 23, 2026 09:17
4d55d9b to
409f76b
Compare
theEvilReaper
requested changes
Aug 23, 2026
Contributor
There was a problem hiding this comment.
Commands should be removed before merging.
Contributor
There was a problem hiding this comment.
This test should be removed before merging.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
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.
Summary
Adds a blood splatter effect: when a survivor is hit, blood is thrown across the screen from the
side the hit came from and fades out over 1.2 seconds.
SlenderBarHelper.applyDamageby setting health directly, whichnever raises Minestom's own
EntityDamageEvent.PlayerDamagedEventfills that gap: it isdispatched right after the health is lowered and carries the victim, the source position, and the
amount, so listeners have something to react to.
BloodSplatterServicelistens forPlayerDamagedEventand throws a splatter on the shared screenoverlay's
BLOODlayer, stepping through twelve 100 ms frames (1.2 seconds total) before clearingit. A fresh hit replaces a still-fading splatter and restarts the sequence.
BloodDirection.betweenpicks one of four sides (front/right/back/left) from the victim's ownfacing, not world coordinates - a hit from the east lands on the left for a player looking south
and on the right for one looking north.
/blood [front|right|back|left]throws a splatter on demand (random side if none given), so thedrawings can be judged without waiting to get hit.
cygnus-pack; this PR only wires the overlaylogic and is inert wherever a resource pack that provides them isn't configured.
Notes for reviewers
Cygnus.javawill also be touched by the siblingtunnel vision and gaze PRs cut from the same working branch - whichever of the three merges second
will need a small rebase to reconcile the constructor/listener wiring.
Test plan
./gradlew test- full suite passes, includingBloodDirectionTest,BloodSplatterServiceTest,BloodCommandTest, andSlenderBarHelperDamageTest