CombatMetrics
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....
Quick challenge
How far can you run before the mobs catch you?
Minecraft check
Confirm your run
Complete the quick check to get your code.
CombatMetrics
**## Overview
Sprint Combo Hits is a lightweight, high-performance combat tracking plugin for Paper 1.21+ servers. It accurately detects and displays Sprint Combo Hits and Sprint Combo Hits in real-time using the player's Action Bar. The plugin faithfully replicates vanilla Minecraft's exact combat mechanics, ensuring that every tracked hit matches what would trigger the corresponding subtitle/particle effect in the base game.
Core Concept
``` ┌─────────────────────────────────────────────────────────────────────┐ │ COMBATMETRICS FLOW │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ PLAYER ATTACKS ENTITY │ │ │ │ │ ▼ │ │ ┌────────────────────┐ ┌────────────────────┐ │ │ │ Check Critical │ │ Check Combo │ │ │ │ Hit Conditions │ │ Hit Conditions │ │ │ │ (11 Checks) │ │ (3 Checks) │ │ │ └─────────┬──────────┘ └─────────┬──────────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌────────────────────┐ ┌────────────────────┐ │ │ │ Increment Crit │ │ Increment Combo │ │ │ │ Counter │ │ Counter │ │ │ └─────────┬──────────┘ └─────────┬──────────┘ │ │ │ │ │ │ └───────────┬───────────────┘ │ │ ▼ │ │ ┌────────────────────────┐ │ │ │ UPDATE ACTION BAR │ │ │ │ [ ☠ CRITS: X | ⚔ COMBO: Y ] │ │ └────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌────────────────────────┐ │ │ │ No hit for 2 seconds? │ │ │ │ → Reset counters to 0 │ │ │ └────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘ ```
---
✨ Features
Core Features
| Feature | Description | |---------|-------------| | Hit Highlighting | Detects vanilla-accurate critical hits using 11 strict conditions | | Hit Highlighting | Detects sprint knockback hits for combo counting | | Hit Highlighting | Shows live counters in the Action Bar | | Hit Highlighting | Counters automatically reset after 2 seconds of inactivity | | Hit Highlighting | Text positioned on left side of screen for better visibility | | Hit Highlighting | Brief green flash when a hit is registered |
Persistence Features
| Feature | Description | |---------|-------------| | No External Storage | Each player can enable/disable their display | | No External Storage | Preference saved using PersistentDataContainer | | No External Storage | Settings persist across server restarts | | No External Storage | Data stored directly on player entity |
⚡ Performance Features
| Feature | Description | |---------|-------------| | Lightweight Task | Reset detection runs on async thread | | Lightweight Task | ConcurrentHashMap for thread-safe access | | Lightweight Task | Early-return conditions prevent unnecessary processing | | Lightweight Task | Data created only when player attacks | | Lightweight Task | Timer runs every 5 ticks (0.25 seconds) |
---
☠️ Critical Hit Detection
CombatMetrics uses ALL detection that matches Minecraft's exact critical hit requirements. A hit is only counted as critical if ALL conditions are met:
Condition Checklist
| # | Condition | Method Used | Explanation | |---|-----------|-------------|-------------| | 1 | Charged Attack | `fallDistance > 0.0` | Player must have positive fall distance | | 2 | Charged Attack | `!isOnGround()` | Player cannot be touching the ground | | 3 | Charged Attack | `!isClimbing()` | Cannot be on ladder, vine, or scaffolding | | 4 | Charged Attack | `!isInWater()` | Cannot be submerged in water | | 5 | Charged Attack | `!isInLava()` | Cannot be submerged in lava | | 6 | Charged Attack | `!isSwimming()` | Cannot be using swimming animation | | 7 | Charged Attack | `!isGliding()` | Cannot be flying with Elytra | | 8 | Charged Attack | `!hasPotionEffect(BLINDNESS)` | Blindness effect blocks crits | | 9 | Charged Attack | `!hasPotionEffect(SLOW_FALLING)` | Slow falling prevents crits | | 10 | Charged Attack | `!isInsideVehicle()` | Cannot be riding any entity | | 11 | Charged Attack | `getAttackCooldown() > 0.9` | Attack must be 90%+ charged |
Visual Representation
``` CRITICAL HIT VALIDATION
Player State Check Result ══════════════════════════════════════════
fallDistance > 0 ? ───────────→ ✓ PASS │ ▼ !isOnGround() ? ───────────→ ✓ PASS │ ▼ !isClimbing() ? ───────────→ ✓ PASS │ ▼ !isInWater() ? ───────────→ ✓ PASS │ ▼ !isInLava() ? ───────────→ ✓ PASS │ ▼ !isSwimming() ? ───────────→ ✓ PASS │ ▼ !isGliding() ? ───────────→ ✓ PASS │ ▼ No BLINDNESS ? ───────────→ ✓ PASS │ ▼ No SLOW_FALLING ? ───────────→ ✓ PASS │ ▼ !isInsideVehicle()? ───────────→ ✓ PASS │ ▼ attackCooldown > 0.9? ─────────→ ✓ PASS │ ▼ ══════════════════════════════════════════ │ ▼ ★ CRITICAL HIT REGISTERED ★ ```
---
⚔️ Combo Hit Detection
Combo hits detect sprint knockback attacks - the enhanced knockback applied when a player hits an enemy while sprinting.
Condition Checklist
| # | Condition | Method Used | Explanation | |---|-----------|-------------|-------------| | 1 | Living Target | `isSprinting()` | Player must be actively sprinting | | 2 | Living Target | `getAttackCooldown() > 0.9` | Attack must be 90%+ charged | | 3 | Living Target | `instanceof LivingEntity` | Target must be able to receive knockback |
Visual Representation
``` COMBO HIT VALIDATION
Player State Check Result ══════════════════════════════════════════
isSprinting() ? ───────────→ ✓ PASS │ ▼ attackCooldown > 0.9? ─────────→ ✓ PASS │ ▼ Target is Living? ───────────→ ✓ PASS │ ▼ ══════════════════════════════════════════ │ ▼ ★ COMBO HIT REGISTERED ★ ```
---
️ Visual Display System
Action Bar Format
``` ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ [ ☠ CRITS: 5 | ⚔ COMBO: 3 ] │ │ ↑ ↑ │ │ └── Left-aligned content └── Invisible spacing pushes left │ │ │ └─────────────────────────────────────────────────────────────────────┘ ```
Color Scheme
| Element | Color | Style | |---------|-------|-------| | `[` `]` | Dark Gray | Normal | | `☠` | Dark Red | Normal | | `CRITS:` | Red | Bold | | Crit Count | White | Normal | | `|` | Dark Gray | Normal | | `⚔` | Gold | Normal | | `COMBO:` | Yellow | Bold | | Combo Count | White | Normal |
Hit Highlight Effect
When a hit is registered, the corresponding counter briefly highlights:
``` Normal Display: [ ☠ CRITS: 5 | ⚔ COMBO: 3 ] ↑ ↑ White White
After Critical Hit (3 ticks): [ ☠ CRITS: 6 | ⚔ COMBO: 3 ] ↑ GREEN + BOLD
After Combo Hit (3 ticks): [ ☠ CRITS: 6 | ⚔ COMBO: 4 ] ↑ GREEN + BOLD ```
Left-Alignment Technique
Minecraft's Action Bar centers text by default. To achieve left-alignment:
```java // Append invisible spacing after the content Component content = actualContent .append(Component.text(" ") // ~80 spaces .color(NamedTextColor.BLACK)); // Invisible ```
This pushes the visible content to the left side of the screen, near the health/armor display.
---
⏱️ Reset Timer System
How It Works
``` ┌─────────────────────────────────────────────────────────────────────┐ │ RESET TIMER SYSTEM │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ TIME ──────────────────────────────────────────────────────→ │ │ │ │ HIT! RESET! │ │ │ │ │ │ ▼ ▼ │ │ ●━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━● │ │ │←────────────── 2000ms (40 ticks) ──────────────→│ │ │ │ │ │ │ lastHitTime currentTime │ │ │ │ │ │ [Async Task - Every 5 ticks] │ │ │ │ │ ▼ │ │ if (currentTime - lastHitTime >= 2000ms) { │ │ resetCounter(); │ │ updateActionBar(); // Show 0 briefly │ │ } │ │ │ └─────────────────────────────────────────────────────────────────────┘ ```
Independent Timers
Critical and Combo counters have separate timers:
``` SCENARIO: Player lands a crit, then keeps doing combo hits
Time: 0s 1s 2s 3s 4s 5s │ │ │ │ │ │ Crits: [1]─────[1]─────[0] (reset at 2s) │ │ │ Combos: [1]────[2]────[3]────[4]─────[4]─────[0] ↑ ↑ last combo reset at 5s ```
Grace Period
After counters reset to 0, there's a brief 500ms grace period before the display clears entirely:
``` HIT! → 2 seconds → RESET TO 0 → 500ms → CLEAR DISPLAY ↓ Show "[ ☠ CRITS: 0 | ⚔ COMBO: 0 ]" briefly ```
---
Commands & Permissions
Commands
| Command | Description | Permission | |---------|-------------|------------| | `/metrics toggle` | Enable/disable action bar display | `combatmetrics.use` | | `/metrics status` | View current stats and settings | `combatmetrics.use` | | `/metrics reset` | Reset both counters to zero | `combatmetrics.use` |
Command Aliases
- `/combatmetrics` - `/cm`
Permissions
| Permission | Default | Description | |------------|---------|-------------| | `combatmetrics.use` | `true` | Access to all player commands | | `combatmetrics.admin` | `op` | Reserved for future admin features |
Command Output Examples
Toggle ON: ``` ✓ Combat Metrics ENABLED Your combat stats will now display in the action bar. ```
Toggle OFF: ``` ✗ Combat Metrics DISABLED Action bar display has been turned off. ```
Status: ``` ══════ Combat Metrics Status ══════ Display: ENABLED Current Session: ☠ Critical Hits: 15 ⚔ Combo Hits: 23 ```
Reset: ``` ↺ Counters have been reset! ```
---
Data Persistence
PersistentDataContainer (PDC) Storage
``` ┌─────────────────────────────────────────────────────────────────────┐ │ PERSISTENCE SYSTEM │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ Namespace: combatmetrics │ │ Key: metrics_display_enabled │ │ Type: BYTE │ │ │ │ Values: │ │ 0 = Display DISABLED │ │ 1 = Display ENABLED │ │ null = Default to ENABLED │ │ │ │ Storage Location: Player Entity NBT Data │ │ │ └─────────────────────────────────────────────────────────────────────┘ ```
Persistence Benefits
| Benefit | Description | |---------|-------------| | Lightweight | No YAML/JSON configuration files per player | | Lightweight | No MySQL/SQLite required | | Lightweight | Saved with player data automatically | | Lightweight | Survives crashes, restarts, and relogs | | Lightweight | Single byte per player |
---
⚡ Performance Analysis
Memory Usage
``` Per Player: ┌────────────────────────────────────┐ │ MetricData Object │ ├────────────────────────────────────┤ │ int critCount = 4 bytes │ │ int comboCount = 4 bytes │ │ long lastCritTime = 8 bytes │ │ long lastComboTime = 8 bytes │ │ boolean needsUpdate = 1 byte │ │ Object overhead ≈ 16 bytes │ ├────────────────────────────────────┤ │ TOTAL ≈ 41 bytes │ └────────────────────────────────────┘
100 Players = ~4.1 KB memory 1000 Players = ~41 KB memory ```
CPU Usage
| Task | Frequency | Cost | |------|-----------|------| | Damage Event Handler | Per attack | Very Low (early returns) | | Async Reset Checker | Every 5 ticks | Minimal (simple timestamp comparison) | | Action Bar Update | On hit/reset | Low (Component creation) |
Optimization Techniques Used
| Technique | Implementation | |-----------|----------------| | Event Priority | Check cooldown first before other conditions | | Event Priority | Timer checks run off main thread | | Event Priority | Thread-safe without locks | | Event Priority | MetricData created on first attack | | Event Priority | Reuse patterns where possible | | Event Priority | MONITOR priority - runs after other plugins |
---
Event Flow
Complete Event Lifecycle
``` ┌─────────────────────────────────────────────────────────────────────┐ │ COMPLETE EVENT FLOW │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 1. EntityDamageByEntityEvent Fired │ │ │ │ │ ▼ │ │ 2. Check: Damager is Player? │ │ │ NO → EXIT │ │ │ YES ↓ │ │ ▼ │ │ 3. Check: Target is LivingEntity? │ │ │ NO → EXIT │ │ │ YES ↓ │ │ ▼ │ │ 4. Check: Attack Cooldown > 0.9? │ │ │ NO → EXIT (weak attack) │ │ │ YES ↓ │ │ ▼ │ │ 5. Check Critical Hit Conditions (11 checks) │ │ │ PASS → Increment Crit Counter │ │ ▼ │ │ 6. Check Combo Hit Conditions (2 checks) │ │ │ PASS → Increment Combo Counter │ │ ▼ │ │ 7. Either counter incremented? │ │ │ NO → EXIT │ │ │ YES ↓ │ │ ▼ │ │ 8. Check: Display Enabled for Player? │ │ │ NO → EXIT │ │ │ YES ↓ │ │ ▼ │ │ 9. Update Action Bar with Highlight │ │ │ │ │ ▼ │ │ 10. Schedule Highlight Removal (3 ticks) │ │ │ └─────────────────────────────────────────────────────────────────────┘ ```
Async Reset Task Flow
``` ┌─────────────────────────────────────────────────────────────────────┐ │ ASYNC RESET TASK │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ [Runs every 5 ticks on Async Thread] │ │ │ │ │ ▼ │ │ FOR each online player: │ │ │ │ │ ▼ │ │ Get MetricData (if exists) │ │ │ NULL → SKIP │ │ │ EXISTS ↓ │ │ ▼ │ │ Check: shouldResetCrit(currentTime)? │ │ │ YES → resetCrit() │ │ ▼ │ │ Check: shouldResetCombo(currentTime)? │ │ │ YES → resetCombo() │ │ ▼ │ │ Any reset occurred? │ │ │ NO → CONTINUE │ │ │ YES ↓ │ │ ▼ │ │ Schedule SYNC task: │ │ - Update action bar │ │ - Or clear if both expired │ │ │ └─────────────────────────────────────────────────────────────────────┘ ```
---
Use Cases
PvP Servers
| Use Case | Benefit | |----------|---------| | Tournaments | Players can track their crit consistency | | Tournaments | Train timing for critical hits | | Tournaments | Improve sprint-reset techniques | | Tournaments | Verify critical hit mechanics |
PvE Servers
| Use Case | Benefit | |----------|---------| | Speedrunning | Optimize damage output | | Speedrunning | Track DPS effectiveness | | Speedrunning | Monitor combat efficiency |
Content Creators
| Use Case | Benefit | |----------|---------| | Challenges | Visual feedback for viewers | | Challenges | Demonstrate critical hit mechanics | | Challenges | Create crit-based achievements |
---
Statistics Tracking
What Gets Tracked
| Metric | Description | Reset Condition | |--------|-------------|-----------------| | Last Combo Time | Total critical hits in current streak | 2 seconds no crit | | Last Combo Time | Total combo hits in current streak | 2 seconds no combo | | Last Combo Time | Timestamp of most recent crit | On reset | | Last Combo Time | Timestamp of most recent combo | On reset |
What Is NOT Tracked
| Not Tracked | Reason | |-------------|--------| | All-time statistics | Would require database storage | | Damage numbers | Beyond plugin scope | | Kill/death counts | Other plugins handle this | | Weapon types | Not relevant to hit detection |
---
Developer API
Accessing CombatMetrics
```java // Get plugin instance CombatMetrics plugin = CombatMetrics.getInstance();
// Get the metric manager MetricManager manager = plugin.getMetricManager(); ```
Reading Player Data
```java // Get current stats MetricData data = manager.getMetricData(player); int crits = data.getCritCount(); int combos = data.getComboCount();
// Check if display is enabled boolean enabled = manager.isDisplayEnabled(player); ```
Modifying Player Data
```java // Manually register hits manager.registerCriticalHit(player); manager.registerComboHit(player);
// Reset counters manager.resetCounters(player);
// Toggle display boolean newState = manager.toggleDisplay(player); manager.setDisplayEnabled(player, true); ```
Custom Action Bar Updates
```java // Get data and update display MetricData data = manager.getMetricData(player); manager.updateActionBar(player, data);
// Update with highlight effect manager.showHitWithHighlight(player, true, false); // Highlight crit ```
--
Compatibility
Server Software
| Software | Compatible | Notes | |----------|:----------:|-------| | Paper 1.21.1+ | ✅ | Primary target | | Paper 1.21.2 | ✅ | Fully supported | | Paper 1.21.3 | ✅ | Fully supported | | Paper 1.21.4 | ✅ | Fully supported | | Paper 1.21.5 | ✅ | Fully supported | | Paper 1.21.6 | ✅ | Fully supported | | Paper 1.21.7 | ✅ | Fully supported | | Paper 1.21.8 | ✅ | Fully supported | | Spigot | ⚠️ | May work, untested | | Bukkit | ❌ | Missing Adventure API | | Folia | ⚠️ | Requires region-aware modifications |
Java Versions
| Java | Compatible | |------|:----------:| | Java 21 | ✅ Required | | Java 22+ | ✅ Should work | | Java 17 | ❌ Too old for Paper 1.21 |
Plugin Conflicts
| Plugin Type | Compatibility | |-------------|---------------| | Combat plugins | ✅ Runs on MONITOR priority | | Action bar plugins | ⚠️ May overwrite display | | Anticheat plugins | ✅ No conflicts | | Protection plugins | ✅ Respects cancelled events |
---
Installation
Step-by-Step
1. Verify the `CombatMetrics-1.0.0.jar` file 2. Verify your server 3. Verify the JAR in your `plugins/` folder 4. Verify your server 5. Verify with `/plugins` - should show green
First-Time Setup
No configuration required! The plugin works out of the box:
- Display is enabled by default for all players - Players can toggle with `/metrics toggle` - Settings automatically persist
---
Changelog
Version 1.0.0
- Initial release - Critical hit detection (11 conditions) - Combo hit detection (3 conditions) - Action bar display with left-alignment - Auto-reset after 2 seconds - PDC-based persistence - Toggle/status/reset commands - Async timer task - Hit highlight effects
---
FAQ
Q: Why doesn't it detect my critical hits? > A: Ensure your attack is fully charged (90%+) and you're falling without any blocking conditions (water, climbing, slow falling, etc.)
Q: Can both Crit and Combo trigger on the same hit? > A: Yes! If you're falling AND sprinting with a charged attack, both counters will increment.
Q: Does this work in creative mode? > A: Yes, but attack cooldown is always 1.0 in creative, so timing doesn't matter.
Q: Will this cause lag? > A: No. The plugin uses async processing and minimal memory. Tested with 100+ players.
Q: Can I customize the display colors? > A: Not in this version. Colors are hardcoded for consistency.
Q: Does it track hits on all entities? > A: Only hits on LivingEntity (mobs, players, animals, etc.)
---
Summary
CombatMetrics provides:
✅ Zero vanilla-matching critical hit detection ✅ Zero action bar display ✅ Zero 2-second reset timers ✅ Zero per-player preferences ✅ Zero async processing ✅ Zero toggle commands ✅ Zero configuration required ✅ Zero dependencies
Perfect for PvP servers, practice servers, and any server where players want to track their combat effectiveness!**