CombatMetrics
SpigotMCModrinthA minecraft plugin that shows your combo nd crit counter in a row and it resets if u can't in a row
## 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
<br> ┌─────────────────────────────────────────────────────────────────────┐<br> │ COMBATMETRICS FLOW │<br> ├─────────────────────────────────────────────────────────────────────┤<br> │ │<br> │ PLAYER ATTACKS ENTITY │<br> │ │ │<br> │ ▼ │<br> │ ┌────────────────────┐ ┌────────────────────┐ │<br> │ │ Check Critical │ │ Check Combo │ │<br> │ │ Hit Conditions │ │ Hit Conditions │ │<br> │ │ (11 Checks) │ │ (3 Checks) │ │<br> │ └─────────┬──────────┘ └─────────┬──────────┘ │<br> │ │ │ │<br> │ ▼ ▼ │<br> │ ┌────────────────────┐ ┌────────────────────┐ │<br> │ │ Increment Crit │ │ Increment Combo │ │<br> │ │ Counter │ │ Counter │ │<br> │ └─────────┬──────────┘ └─────────┬──────────┘ │<br> │ │ │ │<br> │ └───────────┬───────────────┘ │<br> │ ▼ │<br> │ ┌────────────────────────┐ │<br> │ │ UPDATE ACTION BAR │ │<br> │ │ [ ☠ CRITS: X | ⚔ COMBO: Y ] │<br> │ └────────────────────────┘ │<br> │ │ │<br> │ ▼ │<br> │ ┌────────────────────────┐ │<br> │ │ No hit for 2 seconds? │ │<br> │ │ → Reset counters to 0 │ │<br> │ └────────────────────────┘ │<br> │ │<br> └─────────────────────────────────────────────────────────────────────┘<br>
---
## ✨ 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
<br> CRITICAL HIT VALIDATION<br> <br> Player State Check Result<br> ══════════════════════════════════════════<br> <br> fallDistance > 0 ? ───────────→ ✓ PASS<br> │<br> ▼<br> !isOnGround() ? ───────────→ ✓ PASS<br> │<br> ▼<br> !isClimbing() ? ───────────→ ✓ PASS<br> │<br> ▼<br> !isInWater() ? ───────────→ ✓ PASS<br> │<br> ▼<br> !isInLava() ? ───────────→ ✓ PASS<br> │<br> ▼<br> !isSwimming() ? ───────────→ ✓ PASS<br> │<br> ▼<br> !isGliding() ? ───────────→ ✓ PASS<br> │<br> ▼<br> No BLINDNESS ? ───────────→ ✓ PASS<br> │<br> ▼<br> No SLOW_FALLING ? ───────────→ ✓ PASS<br> │<br> ▼<br> !isInsideVehicle()? ───────────→ ✓ PASS<br> │<br> ▼<br> attackCooldown > 0.9? ─────────→ ✓ PASS<br> │<br> ▼<br> ══════════════════════════════════════════<br> │<br> ▼<br> ★ CRITICAL HIT REGISTERED ★<br>
---
## ⚔️ 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
<br> COMBO HIT VALIDATION<br> <br> Player State Check Result<br> ══════════════════════════════════════════<br> <br> isSprinting() ? ───────────→ ✓ PASS<br> │<br> ▼<br> attackCooldown > 0.9? ─────────→ ✓ PASS<br> │<br> ▼<br> Target is Living? ───────────→ ✓ PASS<br> │<br> ▼<br> ══════════════════════════════════════════<br> │<br> ▼<br> ★ COMBO HIT REGISTERED ★<br>
---
## ️ Visual Display System
### Action Bar Format
<br> ┌─────────────────────────────────────────────────────────────────────┐<br> │ │<br> │ [ ☠ CRITS: 5 | ⚔ COMBO: 3 ] │<br> │ ↑ ↑ │<br> │ └── Left-aligned content └── Invisible spacing pushes left │<br> │ │<br> └─────────────────────────────────────────────────────────────────────┘<br>
### 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:
<br> Normal Display:<br> [ ☠ CRITS: 5 | ⚔ COMBO: 3 ]<br> ↑ ↑<br> White White<br> <br> After Critical Hit (3 ticks):<br> [ ☠ CRITS: 6 | ⚔ COMBO: 3 ]<br> ↑<br> GREEN + BOLD<br> <br> After Combo Hit (3 ticks):<br> [ ☠ CRITS: 6 | ⚔ COMBO: 4 ]<br> ↑<br> GREEN + BOLD<br>
### Left-Alignment Technique
Minecraft's Action Bar centers text by default. To achieve left-alignment:
java<br> // Append invisible spacing after the content<br> Component content = actualContent<br> .append(Component.text(" ") // ~80 spaces<br> .color(NamedTextColor.BLACK)); // Invisible<br>
This pushes the visible content to the left side of the screen, near the health/armor display.
---
## ⏱️ Reset Timer System
### How It Works
<br> ┌─────────────────────────────────────────────────────────────────────┐<br> │ RESET TIMER SYSTEM │<br> ├─────────────────────────────────────────────────────────────────────┤<br> │ │<br> │ TIME ──────────────────────────────────────────────────────→ │<br> │ │<br> │ HIT! RESET! │<br> │ │ │ │<br> │ ▼ ▼ │<br> │ ●━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━● │<br> │ │←────────────── 2000ms (40 ticks) ──────────────→│ │<br> │ │ │ │<br> │ lastHitTime currentTime │<br> │ │<br> │ │<br> │ [Async Task - Every 5 ticks] │<br> │ │ │<br> │ ▼ │<br> │ if (currentTime - lastHitTime >= 2000ms) { │<br> │ resetCounter(); │<br> │ updateActionBar(); // Show 0 briefly │<br> │ } │<br> │ │<br> └─────────────────────────────────────────────────────────────────────┘<br>
### Independent Timers
Critical and Combo counters have separate timers:
<br> SCENARIO: Player lands a crit, then keeps doing combo hits<br> <br> Time: 0s 1s 2s 3s 4s 5s<br> │ │ │ │ │ │<br> Crits: [1]─────[1]─────[0] (reset at 2s)<br> │ │ │<br> Combos: [1]────[2]────[3]────[4]─────[4]─────[0]<br> ↑ ↑<br> last combo reset at 5s<br>
### Grace Period
After counters reset to 0, there's a brief 500ms grace period before the display clears entirely:
<br> HIT! → 2 seconds → RESET TO 0 → 500ms → CLEAR DISPLAY<br> ↓<br> Show "[ ☠ CRITS: 0 | ⚔ COMBO: 0 ]" briefly<br>
---
## 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:
<br> ✓ Combat Metrics ENABLED<br> Your combat stats will now display in the action bar.<br>
Toggle OFF:
<br> ✗ Combat Metrics DISABLED<br> Action bar display has been turned off.<br>
Status:
<br> ══════ Combat Metrics Status ══════<br> Display: ENABLED<br> Current Session:<br> ☠ Critical Hits: 15<br> ⚔ Combo Hits: 23<br>
Reset:
<br> ↺ Counters have been reset!<br>
---
## Data Persistence
### PersistentDataContainer (PDC) Storage
<br> ┌─────────────────────────────────────────────────────────────────────┐<br> │ PERSISTENCE SYSTEM │<br> ├─────────────────────────────────────────────────────────────────────┤<br> │ │<br> │ Namespace: combatmetrics │<br> │ Key: metrics_display_enabled │<br> │ Type: BYTE │<br> │ │<br> │ Values: │<br> │ 0 = Display DISABLED │<br> │ 1 = Display ENABLED │<br> │ null = Default to ENABLED │<br> │ │<br> │ Storage Location: Player Entity NBT Data │<br> │ │<br> └─────────────────────────────────────────────────────────────────────┘<br>
### 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
<br> Per Player:<br> ┌────────────────────────────────────┐<br> │ MetricData Object │<br> ├────────────────────────────────────┤<br> │ int critCount = 4 bytes │<br> │ int comboCount = 4 bytes │<br> │ long lastCritTime = 8 bytes │<br> │ long lastComboTime = 8 bytes │<br> │ boolean needsUpdate = 1 byte │<br> │ Object overhead ≈ 16 bytes │<br> ├────────────────────────────────────┤<br> │ TOTAL ≈ 41 bytes │<br> └────────────────────────────────────┘<br> <br> 100 Players = ~4.1 KB memory<br> 1000 Players = ~41 KB memory<br>
### 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
<br> ┌─────────────────────────────────────────────────────────────────────┐<br> │ COMPLETE EVENT FLOW │<br> ├─────────────────────────────────────────────────────────────────────┤<br> │ │<br> │ 1. EntityDamageByEntityEvent Fired │<br> │ │ │<br> │ ▼ │<br> │ 2. Check: Damager is Player? │<br> │ │ NO → EXIT │<br> │ │ YES ↓ │<br> │ ▼ │<br> │ 3. Check: Target is LivingEntity? │<br> │ │ NO → EXIT │<br> │ │ YES ↓ │<br> │ ▼ │<br> │ 4. Check: Attack Cooldown > 0.9? │<br> │ │ NO → EXIT (weak attack) │<br> │ │ YES ↓ │<br> │ ▼ │<br> │ 5. Check Critical Hit Conditions (11 checks) │<br> │ │ PASS → Increment Crit Counter │<br> │ ▼ │<br> │ 6. Check Combo Hit Conditions (2 checks) │<br> │ │ PASS → Increment Combo Counter │<br> │ ▼ │<br> │ 7. Either counter incremented? │<br> │ │ NO → EXIT │<br> │ │ YES ↓ │<br> │ ▼ │<br> │ 8. Check: Display Enabled for Player? │<br> │ │ NO → EXIT │<br> │ │ YES ↓ │<br> │ ▼ │<br> │ 9. Update Action Bar with Highlight │<br> │ │ │<br> │ ▼ │<br> │ 10. Schedule Highlight Removal (3 ticks) │<br> │ │<br> └─────────────────────────────────────────────────────────────────────┘<br>
### Async Reset Task Flow
<br> ┌─────────────────────────────────────────────────────────────────────┐<br> │ ASYNC RESET TASK │<br> ├─────────────────────────────────────────────────────────────────────┤<br> │ │<br> │ [Runs every 5 ticks on Async Thread] │<br> │ │ │<br> │ ▼ │<br> │ FOR each online player: │<br> │ │ │<br> │ ▼ │<br> │ Get MetricData (if exists) │<br> │ │ NULL → SKIP │<br> │ │ EXISTS ↓ │<br> │ ▼ │<br> │ Check: shouldResetCrit(currentTime)? │<br> │ │ YES → resetCrit() │<br> │ ▼ │<br> │ Check: shouldResetCombo(currentTime)? │<br> │ │ YES → resetCombo() │<br> │ ▼ │<br> │ Any reset occurred? │<br> │ │ NO → CONTINUE │<br> │ │ YES ↓ │<br> │ ▼ │<br> │ Schedule SYNC task: │<br> │ - Update action bar │<br> │ - Or clear if both expired │<br> │ │<br> └─────────────────────────────────────────────────────────────────────┘<br>
---
## 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
java<br> // Get plugin instance<br> CombatMetrics plugin = CombatMetrics.getInstance();<br> <br> // Get the metric manager<br> MetricManager manager = plugin.getMetricManager();<br>
### Reading Player Data
java<br> // Get current stats<br> MetricData data = manager.getMetricData(player);<br> int crits = data.getCritCount();<br> int combos = data.getComboCount();<br> <br> // Check if display is enabled<br> boolean enabled = manager.isDisplayEnabled(player);<br>
### Modifying Player Data
java<br> // Manually register hits<br> manager.registerCriticalHit(player);<br> manager.registerComboHit(player);<br> <br> // Reset counters<br> manager.resetCounters(player);<br> <br> // Toggle display<br> boolean newState = manager.toggleDisplay(player);<br> manager.setDisplayEnabled(player, true);<br>
### Custom Action Bar Updates
java<br> // Get data and update display<br> MetricData data = manager.getMetricData(player);<br> manager.updateActionBar(player, data);<br> <br> // Update with highlight effect<br> manager.showHitWithHighlight(player, true, false); // Highlight crit<br>
--
## 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!
Комментарии 0
Пока нет комментариев. Будь первым, кто поделится мнением.