Language

CombatMetrics

CombatMetrics

ModrinthSpigotMC

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....

54 downloads updated 6mo ago
latest v1.0.0 Modrinth
Paper 1.21.1 – 1.21.8 Game-mechanicsUtility

**## Overview

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'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 |
|---------|-------------|
| Critical Hit Tracking | Detects vanilla-accurate critical hits using 11 strict conditions |
| Combo Hit Tracking | Detects sprint knockback hits for combo counting |
| Real-Time Display | Shows live counters in the Action Bar |
| Auto Reset | Counters automatically reset after 2 seconds of inactivity |
| Left-Aligned Display | Text positioned on left side of screen for better visibility |
| Hit Highlighting | Brief green flash when a hit is registered |

Persistence Features

| Feature | Description |
|---------|-------------|
| Per-Player Toggle | Each player can enable/disable their display |
| Survives Relog | Preference saved using PersistentDataContainer |
| Survives Restart | Settings persist across server restarts |
| No External Storage | Data stored directly on player entity |

⚡ Performance Features

| Feature | Description |
|---------|-------------|
| Async Timer Checks | Reset detection runs on async thread |
| Efficient Data Storage | ConcurrentHashMap for thread-safe access |
| Minimal Overhead | Early-return conditions prevent unnecessary processing |
| Lazy Initialization | Data created only when player attacks |
| Lightweight Task | Timer runs every 5 ticks (0.25 seconds) |


☠️ Critical Hit Detection

CombatMetrics uses vanilla-accurate 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 | Falling | fallDistance > 0.0 | Player must have positive fall distance |
| 2 | Airborne | !isOnGround() | Player cannot be touching the ground |
| 3 | Not Climbing | !isClimbing() | Cannot be on ladder, vine, or scaffolding |
| 4 | Not In Water | !isInWater() | Cannot be submerged in water |
| 5 | Not In Lava | !isInLava() | Cannot be submerged in lava |
| 6 | Not Swimming | !isSwimming() | Cannot be using swimming animation |
| 7 | Not Gliding | !isGliding() | Cannot be flying with Elytra |
| 8 | No Blindness | !hasPotionEffect(BLINDNESS) | Blindness effect blocks crits |
| 9 | No Slow Falling | !hasPotionEffect(SLOW_FALLING) | Slow falling prevents crits |
| 10 | Not Mounted | !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 | Sprinting | isSprinting() | Player must be actively sprinting |
| 2 | Charged Attack | 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:

// 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 |
|---------|-------------|
| No Files | No YAML/JSON configuration files per player |
| No Database | No MySQL/SQLite required |
| Automatic | Saved with player data automatically |
| Reliable | 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 |
|-----------|----------------|
| Early Returns | Check cooldown first before other conditions |
| Async Processing | Timer checks run off main thread |
| ConcurrentHashMap | Thread-safe without locks |
| Lazy Loading | MetricData created on first attack |
| Minimal Allocations | 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 |
|----------|---------|
| Competitive PvP | Players can track their crit consistency |
| Practice Servers | Train timing for critical hits |
| Combo Training | Improve sprint-reset techniques |
| Tournaments | Verify critical hit mechanics |

PvE Servers

| Use Case | Benefit |
|----------|---------|
| Mob Farming | Optimize damage output |
| Boss Fights | Track DPS effectiveness |
| Speedrunning | Monitor combat efficiency |

Content Creators

| Use Case | Benefit |
|----------|---------|
| YouTube/Twitch | Visual feedback for viewers |
| Tutorials | Demonstrate critical hit mechanics |
| Challenges | Create crit-based achievements |


Statistics Tracking

What Gets Tracked

| Metric | Description | Reset Condition |
|--------|-------------|-----------------|
| Crit Count | Total critical hits in current streak | 2 seconds no crit |
| Combo Count | Total combo hits in current streak | 2 seconds no combo |
| Last Crit 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

// Get plugin instance
CombatMetrics plugin = CombatMetrics.getInstance();

// Get the metric manager
MetricManager manager = plugin.getMetricManager();

Reading Player Data

// 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

// 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

// 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. Download the CombatMetrics-1.0.0.jar file
  2. Stop your server
  3. Place the JAR in your plugins/ folder
  4. Start 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:

Accurate vanilla-matching critical hit detection
Real-time action bar display
Automatic 2-second reset timers
Persistent per-player preferences
Performant async processing
Simple toggle commands
Zero configuration required
Zero dependencies

Perfect for PvP servers, practice servers, and any server where players want to track their combat effectiveness!**

Versions

Release
1.0.0
paper · 1.21.1, 1.21.2, 1.21.3 · 6mo ago
[more info](https://www.spigotmc.org/resources/combatmetrics.130762/)
54

Comments 0

No comments yet. Be the first to share your thoughts.

Download CombatMetrics

SpigotMC

Files are served directly from the original source. Modgrid does not host or modify them.