{"id":44353,"date":"2026-06-02T05:27:34","date_gmt":"2026-06-02T02:27:34","guid":{"rendered":"https:\/\/vpesports.com\/minecraft\/mods\/combatmetrics\/"},"modified":"2026-06-02T05:27:34","modified_gmt":"2026-06-02T02:27:34","slug":"combatmetrics","status":"publish","type":"mod","link":"https:\/\/vpesports.com\/minecraft\/mods\/combatmetrics\/","title":{"rendered":"CombatMetrics"},"content":{"rendered":"<p>**## Overview<\/p>\n<p>**CombatMetrics** is a lightweight, high-performance combat tracking plugin for Paper 1.21+ servers. It accurately detects and displays **Critical Hits** and **Sprint Combo Hits** in real-time using the player&#8217;s Action Bar. The plugin faithfully replicates vanilla Minecraft&#8217;s exact combat mechanics, ensuring that every tracked hit matches what would trigger the corresponding subtitle\/particle effect in the base game.<\/p>\n<p>## Core Concept<\/p>\n<p>&#8220;`<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 COMBATMETRICS FLOW \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 \u2502<br \/>\n\u2502 PLAYER ATTACKS ENTITY \u2502<br \/>\n\u2502 \u2502 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502<br \/>\n\u2502 \u2502 Check Critical \u2502 \u2502 Check Combo \u2502 \u2502<br \/>\n\u2502 \u2502 Hit Conditions \u2502 \u2502 Hit Conditions \u2502 \u2502<br \/>\n\u2502 \u2502 (11 Checks) \u2502 \u2502 (3 Checks) \u2502 \u2502<br \/>\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502<br \/>\n\u2502 \u2502 \u2502 \u2502<br \/>\n\u2502 \u25bc \u25bc \u2502<br \/>\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502<br \/>\n\u2502 \u2502 Increment Crit \u2502 \u2502 Increment Combo \u2502 \u2502<br \/>\n\u2502 \u2502 Counter \u2502 \u2502 Counter \u2502 \u2502<br \/>\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502<br \/>\n\u2502 \u2502 \u2502 \u2502<br \/>\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502<br \/>\n\u2502 \u2502 UPDATE ACTION BAR \u2502 \u2502<br \/>\n\u2502 \u2502 [ \u2620 CRITS: X | \u2694 COMBO: Y ] \u2502<br \/>\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502<br \/>\n\u2502 \u2502 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502<br \/>\n\u2502 \u2502 No hit for 2 seconds? \u2502 \u2502<br \/>\n\u2502 \u2502 \u2192 Reset counters to 0 \u2502 \u2502<br \/>\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502<br \/>\n\u2502 \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n&#8220;`<\/p>\n<p>&#8212;<\/p>\n<p>## \u2728 Features<\/p>\n<p>### Core Features<\/p>\n<p>| Feature | Description |<br \/>\n|&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;&#8212;-|<br \/>\n| **Critical Hit Tracking** | Detects vanilla-accurate critical hits using 11 strict conditions |<br \/>\n| **Combo Hit Tracking** | Detects sprint knockback hits for combo counting |<br \/>\n| **Real-Time Display** | Shows live counters in the Action Bar |<br \/>\n| **Auto Reset** | Counters automatically reset after 2 seconds of inactivity |<br \/>\n| **Left-Aligned Display** | Text positioned on left side of screen for better visibility |<br \/>\n| **Hit Highlighting** | Brief green flash when a hit is registered |<\/p>\n<p>### Persistence Features<\/p>\n<p>| Feature | Description |<br \/>\n|&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;&#8212;-|<br \/>\n| **Per-Player Toggle** | Each player can enable\/disable their display |<br \/>\n| **Survives Relog** | Preference saved using PersistentDataContainer |<br \/>\n| **Survives Restart** | Settings persist across server restarts |<br \/>\n| **No External Storage** | Data stored directly on player entity |<\/p>\n<p>### \u26a1 Performance Features<\/p>\n<p>| Feature | Description |<br \/>\n|&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;&#8212;-|<br \/>\n| **Async Timer Checks** | Reset detection runs on async thread |<br \/>\n| **Efficient Data Storage** | ConcurrentHashMap for thread-safe access |<br \/>\n| **Minimal Overhead** | Early-return conditions prevent unnecessary processing |<br \/>\n| **Lazy Initialization** | Data created only when player attacks |<br \/>\n| **Lightweight Task** | Timer runs every 5 ticks (0.25 seconds) |<\/p>\n<p>&#8212;<\/p>\n<p>## \u2620\ufe0f Critical Hit Detection<\/p>\n<p>CombatMetrics uses **vanilla-accurate** detection that matches Minecraft&#8217;s exact critical hit requirements. A hit is only counted as critical if **ALL** conditions are met:<\/p>\n<p>### Condition Checklist<\/p>\n<p>| # | Condition | Method Used | Explanation |<br \/>\n|&#8212;|&#8212;&#8212;&#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;&#8212;-|<br \/>\n| 1 | **Falling** | `fallDistance > 0.0` | Player must have positive fall distance |<br \/>\n| 2 | **Airborne** | `!isOnGround()` | Player cannot be touching the ground |<br \/>\n| 3 | **Not Climbing** | `!isClimbing()` | Cannot be on ladder, vine, or scaffolding |<br \/>\n| 4 | **Not In Water** | `!isInWater()` | Cannot be submerged in water |<br \/>\n| 5 | **Not In Lava** | `!isInLava()` | Cannot be submerged in lava |<br \/>\n| 6 | **Not Swimming** | `!isSwimming()` | Cannot be using swimming animation |<br \/>\n| 7 | **Not Gliding** | `!isGliding()` | Cannot be flying with Elytra |<br \/>\n| 8 | **No Blindness** | `!hasPotionEffect(BLINDNESS)` | Blindness effect blocks crits |<br \/>\n| 9 | **No Slow Falling** | `!hasPotionEffect(SLOW_FALLING)` | Slow falling prevents crits |<br \/>\n| 10 | **Not Mounted** | `!isInsideVehicle()` | Cannot be riding any entity |<br \/>\n| 11 | **Charged Attack** | `getAttackCooldown() > 0.9` | Attack must be 90%+ charged |<\/p>\n<p>### Visual Representation<\/p>\n<p>&#8220;`<br \/>\nCRITICAL HIT VALIDATION<\/p>\n<p>Player State Check Result<br \/>\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<\/p>\n<p>fallDistance > 0 ? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2713 PASS<br \/>\n\u2502<br \/>\n\u25bc<br \/>\n!isOnGround() ? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2713 PASS<br \/>\n\u2502<br \/>\n\u25bc<br \/>\n!isClimbing() ? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2713 PASS<br \/>\n\u2502<br \/>\n\u25bc<br \/>\n!isInWater() ? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2713 PASS<br \/>\n\u2502<br \/>\n\u25bc<br \/>\n!isInLava() ? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2713 PASS<br \/>\n\u2502<br \/>\n\u25bc<br \/>\n!isSwimming() ? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2713 PASS<br \/>\n\u2502<br \/>\n\u25bc<br \/>\n!isGliding() ? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2713 PASS<br \/>\n\u2502<br \/>\n\u25bc<br \/>\nNo BLINDNESS ? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2713 PASS<br \/>\n\u2502<br \/>\n\u25bc<br \/>\nNo SLOW_FALLING ? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2713 PASS<br \/>\n\u2502<br \/>\n\u25bc<br \/>\n!isInsideVehicle()? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2713 PASS<br \/>\n\u2502<br \/>\n\u25bc<br \/>\nattackCooldown > 0.9? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2713 PASS<br \/>\n\u2502<br \/>\n\u25bc<br \/>\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<br \/>\n\u2502<br \/>\n\u25bc<br \/>\n\u2605 CRITICAL HIT REGISTERED \u2605<br \/>\n&#8220;`<\/p>\n<p>&#8212;<\/p>\n<p>## \u2694\ufe0f Combo Hit Detection<\/p>\n<p>Combo hits detect **sprint knockback attacks** &#8211; the enhanced knockback applied when a player hits an enemy while sprinting.<\/p>\n<p>### Condition Checklist<\/p>\n<p>| # | Condition | Method Used | Explanation |<br \/>\n|&#8212;|&#8212;&#8212;&#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;&#8212;-|<br \/>\n| 1 | **Sprinting** | `isSprinting()` | Player must be actively sprinting |<br \/>\n| 2 | **Charged Attack** | `getAttackCooldown() > 0.9` | Attack must be 90%+ charged |<br \/>\n| 3 | **Living Target** | `instanceof LivingEntity` | Target must be able to receive knockback |<\/p>\n<p>### Visual Representation<\/p>\n<p>&#8220;`<br \/>\nCOMBO HIT VALIDATION<\/p>\n<p>Player State Check Result<br \/>\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<\/p>\n<p>isSprinting() ? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2713 PASS<br \/>\n\u2502<br \/>\n\u25bc<br \/>\nattackCooldown > 0.9? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2713 PASS<br \/>\n\u2502<br \/>\n\u25bc<br \/>\nTarget is Living? \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2713 PASS<br \/>\n\u2502<br \/>\n\u25bc<br \/>\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<br \/>\n\u2502<br \/>\n\u25bc<br \/>\n\u2605 COMBO HIT REGISTERED \u2605<br \/>\n&#8220;`<\/p>\n<p>&#8212;<\/p>\n<p>## \ufe0f Visual Display System<\/p>\n<p>### Action Bar Format<\/p>\n<p>&#8220;`<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 \u2502<br \/>\n\u2502 [ \u2620 CRITS: 5 | \u2694 COMBO: 3 ] \u2502<br \/>\n\u2502 \u2191 \u2191 \u2502<br \/>\n\u2502 \u2514\u2500\u2500 Left-aligned content \u2514\u2500\u2500 Invisible spacing pushes left \u2502<br \/>\n\u2502 \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n&#8220;`<\/p>\n<p>### Color Scheme<\/p>\n<p>| Element | Color | Style |<br \/>\n|&#8212;&#8212;&#8212;|&#8212;&#8212;-|&#8212;&#8212;-|<br \/>\n| `[` `]` | Dark Gray | Normal |<br \/>\n| `\u2620` | Dark Red | Normal |<br \/>\n| `CRITS:` | Red | **Bold** |<br \/>\n| Crit Count | White | Normal |<br \/>\n| `|` | Dark Gray | Normal |<br \/>\n| `\u2694` | Gold | Normal |<br \/>\n| `COMBO:` | Yellow | **Bold** |<br \/>\n| Combo Count | White | Normal |<\/p>\n<p>### Hit Highlight Effect<\/p>\n<p>When a hit is registered, the corresponding counter briefly highlights:<\/p>\n<p>&#8220;`<br \/>\nNormal Display:<br \/>\n[ \u2620 CRITS: 5 | \u2694 COMBO: 3 ]<br \/>\n\u2191 \u2191<br \/>\nWhite White<\/p>\n<p>After Critical Hit (3 ticks):<br \/>\n[ \u2620 CRITS: 6 | \u2694 COMBO: 3 ]<br \/>\n\u2191<br \/>\nGREEN + BOLD<\/p>\n<p>After Combo Hit (3 ticks):<br \/>\n[ \u2620 CRITS: 6 | \u2694 COMBO: 4 ]<br \/>\n\u2191<br \/>\nGREEN + BOLD<br \/>\n&#8220;`<\/p>\n<p>### Left-Alignment Technique<\/p>\n<p>Minecraft&#8217;s Action Bar centers text by default. To achieve left-alignment:<\/p>\n<p>&#8220;`java<br \/>\n\/\/ Append invisible spacing after the content<br \/>\nComponent content = actualContent<br \/>\n.append(Component.text(&#8221; &#8220;) \/\/ ~80 spaces<br \/>\n.color(NamedTextColor.BLACK)); \/\/ Invisible<br \/>\n&#8220;`<\/p>\n<p>This pushes the visible content to the left side of the screen, near the health\/armor display.<\/p>\n<p>&#8212;<\/p>\n<p>## \u23f1\ufe0f Reset Timer System<\/p>\n<p>### How It Works<\/p>\n<p>&#8220;`<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 RESET TIMER SYSTEM \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 \u2502<br \/>\n\u2502 TIME \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 \u2502<br \/>\n\u2502 \u2502<br \/>\n\u2502 HIT! RESET! \u2502<br \/>\n\u2502 \u2502 \u2502 \u2502<br \/>\n\u2502 \u25bc \u25bc \u2502<br \/>\n\u2502 \u25cf\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u25cf \u2502<br \/>\n\u2502 \u2502\u2190\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 2000ms (40 ticks) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192\u2502 \u2502<br \/>\n\u2502 \u2502 \u2502 \u2502<br \/>\n\u2502 lastHitTime currentTime \u2502<br \/>\n\u2502 \u2502<br \/>\n\u2502 \u2502<br \/>\n\u2502 [Async Task &#8211; Every 5 ticks] \u2502<br \/>\n\u2502 \u2502 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 if (currentTime &#8211; lastHitTime >= 2000ms) { \u2502<br \/>\n\u2502 resetCounter(); \u2502<br \/>\n\u2502 updateActionBar(); \/\/ Show 0 briefly \u2502<br \/>\n\u2502 } \u2502<br \/>\n\u2502 \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n&#8220;`<\/p>\n<p>### Independent Timers<\/p>\n<p>Critical and Combo counters have **separate** timers:<\/p>\n<p>&#8220;`<br \/>\nSCENARIO: Player lands a crit, then keeps doing combo hits<\/p>\n<p>Time: 0s 1s 2s 3s 4s 5s<br \/>\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502<br \/>\nCrits: [1]\u2500\u2500\u2500\u2500\u2500[1]\u2500\u2500\u2500\u2500\u2500[0] (reset at 2s)<br \/>\n\u2502 \u2502 \u2502<br \/>\nCombos: [1]\u2500\u2500\u2500\u2500[2]\u2500\u2500\u2500\u2500[3]\u2500\u2500\u2500\u2500[4]\u2500\u2500\u2500\u2500\u2500[4]\u2500\u2500\u2500\u2500\u2500[0]<br \/>\n\u2191 \u2191<br \/>\nlast combo reset at 5s<br \/>\n&#8220;`<\/p>\n<p>### Grace Period<\/p>\n<p>After counters reset to 0, there&#8217;s a brief **500ms grace period** before the display clears entirely:<\/p>\n<p>&#8220;`<br \/>\nHIT! \u2192 2 seconds \u2192 RESET TO 0 \u2192 500ms \u2192 CLEAR DISPLAY<br \/>\n\u2193<br \/>\nShow &#8220;[ \u2620 CRITS: 0 | \u2694 COMBO: 0 ]&#8221; briefly<br \/>\n&#8220;`<\/p>\n<p>&#8212;<\/p>\n<p>## Commands &#038; Permissions<\/p>\n<p>### Commands<\/p>\n<p>| Command | Description | Permission |<br \/>\n|&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;&#8212;|<br \/>\n| `\/metrics toggle` | Enable\/disable action bar display | `combatmetrics.use` |<br \/>\n| `\/metrics status` | View current stats and settings | `combatmetrics.use` |<br \/>\n| `\/metrics reset` | Reset both counters to zero | `combatmetrics.use` |<\/p>\n<p>### Command Aliases<\/p>\n<p>&#8211; `\/combatmetrics`<br \/>\n&#8211; `\/cm`<\/p>\n<p>### Permissions<\/p>\n<p>| Permission | Default | Description |<br \/>\n|&#8212;&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;&#8212;-|<br \/>\n| `combatmetrics.use` | `true` | Access to all player commands |<br \/>\n| `combatmetrics.admin` | `op` | Reserved for future admin features |<\/p>\n<p>### Command Output Examples<\/p>\n<p>**Toggle ON:**<br \/>\n&#8220;`<br \/>\n\u2713 Combat Metrics ENABLED<br \/>\nYour combat stats will now display in the action bar.<br \/>\n&#8220;`<\/p>\n<p>**Toggle OFF:**<br \/>\n&#8220;`<br \/>\n\u2717 Combat Metrics DISABLED<br \/>\nAction bar display has been turned off.<br \/>\n&#8220;`<\/p>\n<p>**Status:**<br \/>\n&#8220;`<br \/>\n\u2550\u2550\u2550\u2550\u2550\u2550 Combat Metrics Status \u2550\u2550\u2550\u2550\u2550\u2550<br \/>\nDisplay: ENABLED<br \/>\nCurrent Session:<br \/>\n\u2620 Critical Hits: 15<br \/>\n\u2694 Combo Hits: 23<br \/>\n&#8220;`<\/p>\n<p>**Reset:**<br \/>\n&#8220;`<br \/>\n\u21ba Counters have been reset!<br \/>\n&#8220;`<\/p>\n<p>&#8212;<\/p>\n<p>## Data Persistence<\/p>\n<p>### PersistentDataContainer (PDC) Storage<\/p>\n<p>&#8220;`<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 PERSISTENCE SYSTEM \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 \u2502<br \/>\n\u2502 Namespace: combatmetrics \u2502<br \/>\n\u2502 Key: metrics_display_enabled \u2502<br \/>\n\u2502 Type: BYTE \u2502<br \/>\n\u2502 \u2502<br \/>\n\u2502 Values: \u2502<br \/>\n\u2502 0 = Display DISABLED \u2502<br \/>\n\u2502 1 = Display ENABLED \u2502<br \/>\n\u2502 null = Default to ENABLED \u2502<br \/>\n\u2502 \u2502<br \/>\n\u2502 Storage Location: Player Entity NBT Data \u2502<br \/>\n\u2502 \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n&#8220;`<\/p>\n<p>### Persistence Benefits<\/p>\n<p>| Benefit | Description |<br \/>\n|&#8212;&#8212;&#8212;|&#8212;&#8212;&#8212;&#8212;-|<br \/>\n| **No Files** | No YAML\/JSON configuration files per player |<br \/>\n| **No Database** | No MySQL\/SQLite required |<br \/>\n| **Automatic** | Saved with player data automatically |<br \/>\n| **Reliable** | Survives crashes, restarts, and relogs |<br \/>\n| **Lightweight** | Single byte per player |<\/p>\n<p>&#8212;<\/p>\n<p>## \u26a1 Performance Analysis<\/p>\n<p>### Memory Usage<\/p>\n<p>&#8220;`<br \/>\nPer Player:<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 MetricData Object \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 int critCount = 4 bytes \u2502<br \/>\n\u2502 int comboCount = 4 bytes \u2502<br \/>\n\u2502 long lastCritTime = 8 bytes \u2502<br \/>\n\u2502 long lastComboTime = 8 bytes \u2502<br \/>\n\u2502 boolean needsUpdate = 1 byte \u2502<br \/>\n\u2502 Object overhead \u2248 16 bytes \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 TOTAL \u2248 41 bytes \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<p>100 Players = ~4.1 KB memory<br \/>\n1000 Players = ~41 KB memory<br \/>\n&#8220;`<\/p>\n<p>### CPU Usage<\/p>\n<p>| Task | Frequency | Cost |<br \/>\n|&#8212;&#8212;|&#8212;&#8212;&#8212;&#8211;|&#8212;&#8212;|<br \/>\n| Damage Event Handler | Per attack | Very Low (early returns) |<br \/>\n| Async Reset Checker | Every 5 ticks | Minimal (simple timestamp comparison) |<br \/>\n| Action Bar Update | On hit\/reset | Low (Component creation) |<\/p>\n<p>### Optimization Techniques Used<\/p>\n<p>| Technique | Implementation |<br \/>\n|&#8212;&#8212;&#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;&#8212;-|<br \/>\n| **Early Returns** | Check cooldown first before other conditions |<br \/>\n| **Async Processing** | Timer checks run off main thread |<br \/>\n| **ConcurrentHashMap** | Thread-safe without locks |<br \/>\n| **Lazy Loading** | MetricData created on first attack |<br \/>\n| **Minimal Allocations** | Reuse patterns where possible |<br \/>\n| **Event Priority** | MONITOR priority &#8211; runs after other plugins |<\/p>\n<p>&#8212;<\/p>\n<p>## Event Flow<\/p>\n<p>### Complete Event Lifecycle<\/p>\n<p>&#8220;`<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 COMPLETE EVENT FLOW \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 \u2502<br \/>\n\u2502 1. EntityDamageByEntityEvent Fired \u2502<br \/>\n\u2502 \u2502 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 2. Check: Damager is Player? \u2502<br \/>\n\u2502 \u2502 NO \u2192 EXIT \u2502<br \/>\n\u2502 \u2502 YES \u2193 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 3. Check: Target is LivingEntity? \u2502<br \/>\n\u2502 \u2502 NO \u2192 EXIT \u2502<br \/>\n\u2502 \u2502 YES \u2193 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 4. Check: Attack Cooldown > 0.9? \u2502<br \/>\n\u2502 \u2502 NO \u2192 EXIT (weak attack) \u2502<br \/>\n\u2502 \u2502 YES \u2193 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 5. Check Critical Hit Conditions (11 checks) \u2502<br \/>\n\u2502 \u2502 PASS \u2192 Increment Crit Counter \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 6. Check Combo Hit Conditions (2 checks) \u2502<br \/>\n\u2502 \u2502 PASS \u2192 Increment Combo Counter \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 7. Either counter incremented? \u2502<br \/>\n\u2502 \u2502 NO \u2192 EXIT \u2502<br \/>\n\u2502 \u2502 YES \u2193 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 8. Check: Display Enabled for Player? \u2502<br \/>\n\u2502 \u2502 NO \u2192 EXIT \u2502<br \/>\n\u2502 \u2502 YES \u2193 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 9. Update Action Bar with Highlight \u2502<br \/>\n\u2502 \u2502 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 10. Schedule Highlight Removal (3 ticks) \u2502<br \/>\n\u2502 \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n&#8220;`<\/p>\n<p>### Async Reset Task Flow<\/p>\n<p>&#8220;`<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 ASYNC RESET TASK \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 \u2502<br \/>\n\u2502 [Runs every 5 ticks on Async Thread] \u2502<br \/>\n\u2502 \u2502 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 FOR each online player: \u2502<br \/>\n\u2502 \u2502 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 Get MetricData (if exists) \u2502<br \/>\n\u2502 \u2502 NULL \u2192 SKIP \u2502<br \/>\n\u2502 \u2502 EXISTS \u2193 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 Check: shouldResetCrit(currentTime)? \u2502<br \/>\n\u2502 \u2502 YES \u2192 resetCrit() \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 Check: shouldResetCombo(currentTime)? \u2502<br \/>\n\u2502 \u2502 YES \u2192 resetCombo() \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 Any reset occurred? \u2502<br \/>\n\u2502 \u2502 NO \u2192 CONTINUE \u2502<br \/>\n\u2502 \u2502 YES \u2193 \u2502<br \/>\n\u2502 \u25bc \u2502<br \/>\n\u2502 Schedule SYNC task: \u2502<br \/>\n\u2502 &#8211; Update action bar \u2502<br \/>\n\u2502 &#8211; Or clear if both expired \u2502<br \/>\n\u2502 \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n&#8220;`<\/p>\n<p>&#8212;<\/p>\n<p>## Use Cases<\/p>\n<p>### PvP Servers<\/p>\n<p>| Use Case | Benefit |<br \/>\n|&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;|<br \/>\n| **Competitive PvP** | Players can track their crit consistency |<br \/>\n| **Practice Servers** | Train timing for critical hits |<br \/>\n| **Combo Training** | Improve sprint-reset techniques |<br \/>\n| **Tournaments** | Verify critical hit mechanics |<\/p>\n<p>### PvE Servers<\/p>\n<p>| Use Case | Benefit |<br \/>\n|&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;|<br \/>\n| **Mob Farming** | Optimize damage output |<br \/>\n| **Boss Fights** | Track DPS effectiveness |<br \/>\n| **Speedrunning** | Monitor combat efficiency |<\/p>\n<p>### Content Creators<\/p>\n<p>| Use Case | Benefit |<br \/>\n|&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;|<br \/>\n| **YouTube\/Twitch** | Visual feedback for viewers |<br \/>\n| **Tutorials** | Demonstrate critical hit mechanics |<br \/>\n| **Challenges** | Create crit-based achievements |<\/p>\n<p>&#8212;<\/p>\n<p>## Statistics Tracking<\/p>\n<p>### What Gets Tracked<\/p>\n<p>| Metric | Description | Reset Condition |<br \/>\n|&#8212;&#8212;&#8211;|&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;|<br \/>\n| **Crit Count** | Total critical hits in current streak | 2 seconds no crit |<br \/>\n| **Combo Count** | Total combo hits in current streak | 2 seconds no combo |<br \/>\n| **Last Crit Time** | Timestamp of most recent crit | On reset |<br \/>\n| **Last Combo Time** | Timestamp of most recent combo | On reset |<\/p>\n<p>### What Is NOT Tracked<\/p>\n<p>| Not Tracked | Reason |<br \/>\n|&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8211;|<br \/>\n| All-time statistics | Would require database storage |<br \/>\n| Damage numbers | Beyond plugin scope |<br \/>\n| Kill\/death counts | Other plugins handle this |<br \/>\n| Weapon types | Not relevant to hit detection |<\/p>\n<p>&#8212;<\/p>\n<p>## Developer API<\/p>\n<p>### Accessing CombatMetrics<\/p>\n<p>&#8220;`java<br \/>\n\/\/ Get plugin instance<br \/>\nCombatMetrics plugin = CombatMetrics.getInstance();<\/p>\n<p>\/\/ Get the metric manager<br \/>\nMetricManager manager = plugin.getMetricManager();<br \/>\n&#8220;`<\/p>\n<p>### Reading Player Data<\/p>\n<p>&#8220;`java<br \/>\n\/\/ Get current stats<br \/>\nMetricData data = manager.getMetricData(player);<br \/>\nint crits = data.getCritCount();<br \/>\nint combos = data.getComboCount();<\/p>\n<p>\/\/ Check if display is enabled<br \/>\nboolean enabled = manager.isDisplayEnabled(player);<br \/>\n&#8220;`<\/p>\n<p>### Modifying Player Data<\/p>\n<p>&#8220;`java<br \/>\n\/\/ Manually register hits<br \/>\nmanager.registerCriticalHit(player);<br \/>\nmanager.registerComboHit(player);<\/p>\n<p>\/\/ Reset counters<br \/>\nmanager.resetCounters(player);<\/p>\n<p>\/\/ Toggle display<br \/>\nboolean newState = manager.toggleDisplay(player);<br \/>\nmanager.setDisplayEnabled(player, true);<br \/>\n&#8220;`<\/p>\n<p>### Custom Action Bar Updates<\/p>\n<p>&#8220;`java<br \/>\n\/\/ Get data and update display<br \/>\nMetricData data = manager.getMetricData(player);<br \/>\nmanager.updateActionBar(player, data);<\/p>\n<p>\/\/ Update with highlight effect<br \/>\nmanager.showHitWithHighlight(player, true, false); \/\/ Highlight crit<br \/>\n&#8220;`<\/p>\n<p>&#8212;<\/p>\n<p>## Compatibility<\/p>\n<p>### Server Software<\/p>\n<p>| Software | Compatible | Notes |<br \/>\n|&#8212;&#8212;&#8212;-|:&#8212;&#8212;&#8212;-:|&#8212;&#8212;-|<br \/>\n| Paper 1.21.1+ | \u2705 | Primary target |<br \/>\n| Paper 1.21.2 | \u2705 | Fully supported |<br \/>\n| Paper 1.21.3 | \u2705 | Fully supported |<br \/>\n| Paper 1.21.4 | \u2705 | Fully supported |<br \/>\n| Paper 1.21.5 | \u2705 | Fully supported |<br \/>\n| Paper 1.21.6 | \u2705 | Fully supported |<br \/>\n| Paper 1.21.7 | \u2705 | Fully supported |<br \/>\n| Paper 1.21.8 | \u2705 | Fully supported |<br \/>\n| Spigot | \u26a0\ufe0f | May work, untested |<br \/>\n| Bukkit | \u274c | Missing Adventure API |<br \/>\n| Folia | \u26a0\ufe0f | Requires region-aware modifications |<\/p>\n<p>### Java Versions<\/p>\n<p>| Java | Compatible |<br \/>\n|&#8212;&#8212;|:&#8212;&#8212;&#8212;-:|<br \/>\n| Java 21 | \u2705 Required |<br \/>\n| Java 22+ | \u2705 Should work |<br \/>\n| Java 17 | \u274c Too old for Paper 1.21 |<\/p>\n<p>### Plugin Conflicts<\/p>\n<p>| Plugin Type | Compatibility |<br \/>\n|&#8212;&#8212;&#8212;&#8212;-|&#8212;&#8212;&#8212;&#8212;&#8212;|<br \/>\n| Combat plugins | \u2705 Runs on MONITOR priority |<br \/>\n| Action bar plugins | \u26a0\ufe0f May overwrite display |<br \/>\n| Anticheat plugins | \u2705 No conflicts |<br \/>\n| Protection plugins | \u2705 Respects cancelled events |<\/p>\n<p>&#8212;<\/p>\n<p>## Installation<\/p>\n<p>### Step-by-Step<\/p>\n<p>1. **Download** the `CombatMetrics-1.0.0.jar` file<br \/>\n2. **Stop** your server<br \/>\n3. **Place** the JAR in your `plugins\/` folder<br \/>\n4. **Start** your server<br \/>\n5. **Verify** with `\/plugins` &#8211; should show green<\/p>\n<p>### First-Time Setup<\/p>\n<p>No configuration required! The plugin works out of the box:<\/p>\n<p>&#8211; Display is **enabled by default** for all players<br \/>\n&#8211; Players can toggle with `\/metrics toggle`<br \/>\n&#8211; Settings automatically persist<\/p>\n<p>&#8212;<\/p>\n<p>## Changelog<\/p>\n<p>### Version 1.0.0<br \/>\n&#8211; Initial release<br \/>\n&#8211; Critical hit detection (11 conditions)<br \/>\n&#8211; Combo hit detection (3 conditions)<br \/>\n&#8211; Action bar display with left-alignment<br \/>\n&#8211; Auto-reset after 2 seconds<br \/>\n&#8211; PDC-based persistence<br \/>\n&#8211; Toggle\/status\/reset commands<br \/>\n&#8211; Async timer task<br \/>\n&#8211; Hit highlight effects<\/p>\n<p>&#8212;<\/p>\n<p>## FAQ<\/p>\n<p>**Q: Why doesn&#8217;t it detect my critical hits?**<br \/>\n> A: Ensure your attack is fully charged (90%+) and you&#8217;re falling without any blocking conditions (water, climbing, slow falling, etc.)<\/p>\n<p>**Q: Can both Crit and Combo trigger on the same hit?**<br \/>\n> A: Yes! If you&#8217;re falling AND sprinting with a charged attack, both counters will increment.<\/p>\n<p>**Q: Does this work in creative mode?**<br \/>\n> A: Yes, but attack cooldown is always 1.0 in creative, so timing doesn&#8217;t matter.<\/p>\n<p>**Q: Will this cause lag?**<br \/>\n> A: No. The plugin uses async processing and minimal memory. Tested with 100+ players.<\/p>\n<p>**Q: Can I customize the display colors?**<br \/>\n> A: Not in this version. Colors are hardcoded for consistency.<\/p>\n<p>**Q: Does it track hits on all entities?**<br \/>\n> A: Only hits on LivingEntity (mobs, players, animals, etc.)<\/p>\n<p>&#8212;<\/p>\n<p>## Summary<\/p>\n<p>**CombatMetrics** provides:<\/p>\n<p>\u2705 **Accurate** vanilla-matching critical hit detection<br \/>\n\u2705 **Real-time** action bar display<br \/>\n\u2705 **Automatic** 2-second reset timers<br \/>\n\u2705 **Persistent** per-player preferences<br \/>\n\u2705 **Performant** async processing<br \/>\n\u2705 **Simple** toggle commands<br \/>\n\u2705 **Zero** configuration required<br \/>\n\u2705 **Zero** dependencies<\/p>\n<p>Perfect for PvP servers, practice servers, and any server where players want to track their combat effectiveness!**<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A minecraft plugin that shows your combo nd crit counter in a row and it resets if u can&#8217;t in a row which will help improve u with combo and crit chains&#8230;.<\/p>\n","protected":false},"featured_media":44354,"template":"","meta":{"_minecraft_slug":"combatmetrics","_minecraft_project_id":"lkFDj4XY","_minecraft_author":"geturplugins","_minecraft_license":"LicenseRef-All-Rights-Reserved","_minecraft_downloads":36,"_minecraft_follows":0,"_minecraft_client_side":"unsupported","_minecraft_server_side":"required","_minecraft_storage_type":"zip","_minecraft_archive_name":"combatmetrics.zip","_minecraft_size_bytes":14665,"_minecraft_version_count":1,"_minecraft_updated_at":"2026-05-15T21:47:57.795340Z","_minecraft_date_created":"2025-12-14T00:33:41.507632Z","_minecraft_date_modified":"2025-12-13T06:42:25.202517Z","_minecraft_project_url":"https:\/\/modrinth.com\/mod\/combatmetrics","_minecraft_icon_attachment_id":44354,"_minecraft_imported_at":"2026-06-02T02:27:35+00:00","_minecraft_import_hash":"aea7fd64fe57f946ff962cbd365099de","_minecraft_versions":"","_minecraft_links":"","_minecraft_gallery":"","_minecraft_api_metadata":""},"mod_category":[89,127,92],"mod_loader":[132],"minecraft_version":[37,73,74,38,78,79,80,81],"class_list":["post-44353","mod","type-mod","status-publish","has-post-thumbnail","hentry","mod_category-game-mechanics","mod_category-paper","mod_category-utility","mod_loader-paper","minecraft_version-1-21-1","minecraft_version-1-21-2","minecraft_version-1-21-3","minecraft_version-1-21-4","minecraft_version-1-21-5","minecraft_version-1-21-6","minecraft_version-1-21-7","minecraft_version-1-21-8"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>CombatMetrics - Minecraft<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/vpesports.com\/minecraft\/mods\/combatmetrics\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"CombatMetrics - Minecraft\" \/>\n<meta property=\"og:description\" content=\"A minecraft plugin that shows your combo nd crit counter in a row and it resets if u can&#039;t in a row which will help improve u with combo and crit chains....\" \/>\n<meta property=\"og:url\" content=\"https:\/\/vpesports.com\/minecraft\/mods\/combatmetrics\/\" \/>\n<meta property=\"og:site_name\" content=\"Minecraft\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/combatmetrics\\\/\",\"url\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/combatmetrics\\\/\",\"name\":\"CombatMetrics - Minecraft\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/combatmetrics\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/combatmetrics\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/combatmetrics-icon-41d2b11a9668bd177f57e24bc30656fccb0c7f04_96.webp\",\"datePublished\":\"2026-06-02T02:27:34+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/combatmetrics\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/combatmetrics\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/combatmetrics\\\/#primaryimage\",\"url\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/combatmetrics-icon-41d2b11a9668bd177f57e24bc30656fccb0c7f04_96.webp\",\"contentUrl\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/combatmetrics-icon-41d2b11a9668bd177f57e24bc30656fccb0c7f04_96.webp\",\"width\":96,\"height\":96},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/combatmetrics\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Mods\",\"item\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/mods\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"CombatMetrics\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/#website\",\"url\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/\",\"name\":\"Minecraft\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/vpesports.com\\\/minecraft\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"CombatMetrics - Minecraft","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/vpesports.com\/minecraft\/mods\/combatmetrics\/","og_locale":"en_US","og_type":"article","og_title":"CombatMetrics - Minecraft","og_description":"A minecraft plugin that shows your combo nd crit counter in a row and it resets if u can't in a row which will help improve u with combo and crit chains....","og_url":"https:\/\/vpesports.com\/minecraft\/mods\/combatmetrics\/","og_site_name":"Minecraft","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/vpesports.com\/minecraft\/mods\/combatmetrics\/","url":"https:\/\/vpesports.com\/minecraft\/mods\/combatmetrics\/","name":"CombatMetrics - Minecraft","isPartOf":{"@id":"https:\/\/vpesports.com\/minecraft\/#website"},"primaryImageOfPage":{"@id":"https:\/\/vpesports.com\/minecraft\/mods\/combatmetrics\/#primaryimage"},"image":{"@id":"https:\/\/vpesports.com\/minecraft\/mods\/combatmetrics\/#primaryimage"},"thumbnailUrl":"https:\/\/vpesports.com\/minecraft\/wp-content\/uploads\/2026\/06\/combatmetrics-icon-41d2b11a9668bd177f57e24bc30656fccb0c7f04_96.webp","datePublished":"2026-06-02T02:27:34+00:00","breadcrumb":{"@id":"https:\/\/vpesports.com\/minecraft\/mods\/combatmetrics\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/vpesports.com\/minecraft\/mods\/combatmetrics\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/vpesports.com\/minecraft\/mods\/combatmetrics\/#primaryimage","url":"https:\/\/vpesports.com\/minecraft\/wp-content\/uploads\/2026\/06\/combatmetrics-icon-41d2b11a9668bd177f57e24bc30656fccb0c7f04_96.webp","contentUrl":"https:\/\/vpesports.com\/minecraft\/wp-content\/uploads\/2026\/06\/combatmetrics-icon-41d2b11a9668bd177f57e24bc30656fccb0c7f04_96.webp","width":96,"height":96},{"@type":"BreadcrumbList","@id":"https:\/\/vpesports.com\/minecraft\/mods\/combatmetrics\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/vpesports.com\/minecraft\/"},{"@type":"ListItem","position":2,"name":"Mods","item":"https:\/\/vpesports.com\/minecraft\/mods\/"},{"@type":"ListItem","position":3,"name":"CombatMetrics"}]},{"@type":"WebSite","@id":"https:\/\/vpesports.com\/minecraft\/#website","url":"https:\/\/vpesports.com\/minecraft\/","name":"Minecraft","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/vpesports.com\/minecraft\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"_links":{"self":[{"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/mod\/44353","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/mod"}],"about":[{"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/types\/mod"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/media\/44354"}],"wp:attachment":[{"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/media?parent=44353"}],"wp:term":[{"taxonomy":"mod_category","embeddable":true,"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/mod_category?post=44353"},{"taxonomy":"mod_loader","embeddable":true,"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/mod_loader?post=44353"},{"taxonomy":"minecraft_version","embeddable":true,"href":"https:\/\/vpesports.com\/minecraft\/wp-json\/wp\/v2\/minecraft_version?post=44353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}