AutoHarvest+
AutoHarvest+ is a QoL survival mode plugin for easier crop harvesting and replanting mechanics.
AutoHarvest+
AutoHarvest
Vanilla+ auto-harvest and replant for Paper 1.21.x
Break a mature crop and it replants itself. Right-click with bonemeal and it grows, harvests, and replants in one action. No cheats, no duplication, no TPS impact. Just the QoL feature vanilla forgot.
---
Features
Break Harvesting
Break any mature crop and it drops normally — then replants at growth stage 0 automatically. Vanilla handles the break, drops, tool durability, enchantments, XP, and statistics. AutoHarvest only adds the replant.
Bonemeal Harvesting
Right-click an immature crop with bonemeal. Vanilla advances the growth. If the crop becomes mature from that application, AutoHarvest harvests it, drops the items, and replants — all in one click. One bonemeal consumed per use, exactly like vanilla.
Seed Fairness
The bonemeal path subtracts one seed from drops to prevent duplication. Without this, every bonemeal harvest would create a free seed (the crop is replanted but drops include the replant cost). AutoHarvest enforces net-zero: bonemeal harvesting produces the same drops as manually breaking and replanting.
Per-Player Toggle
`/autoharvest toggle` — players who want pure vanilla can opt out. State persists across relogs and server restarts via PersistentDataContainer. No database required.
---
Supported Crops
| Crop | Replant Age | Notes | |------|-------------|-------| | Wheat | 0 | Standard ageable crop | | Carrots | 0 | Standard ageable crop | | Potatoes | 0 | Poisonous potato drops preserved | | Beetroot | 0 | Standard ageable crop | | Nether Wart | 0 | Validates soul sand beneath before replanting | | Cocoa Beans | 0 | Preserves facing direction, validates jungle log | | Sweet Berries | 1 | Matches vanilla right-click harvest feel |
Explicitly Not Supported
- Chorus fruit — vertical growth, dupe risk with pistons - Chorus fruit — stem-based, already effectively auto-replant - Chorus fruit — not a farm crop
---
Commands
| Command | Description | Permission | |---------|-------------|------------| | `/autoharvest toggle` | Toggle for yourself | `autoharvest.use` | | `/autoharvest toggle <player>` | Toggle for another player | `autoharvest.admin.toggle-others` | | `/autoharvest info` | Show status, version, enabled crops | `autoharvest.use` | | `/autoharvest reload` | Reload configuration | `autoharvest.admin.reload` |
Alias: `/ah` works for all commands.
---
Permissions
| Permission | Default | Description | |------------|---------|-------------| | `autoharvest.use` | `true` | Toggle and info commands | | `autoharvest.break` | `true` | Auto-harvest on crop break | | `autoharvest.bonemeal` | `true` | Auto-harvest via bonemeal | | `autoharvest.admin` | `op` | All admin commands | | `autoharvest.admin.reload` | `op` | Reload configuration | | `autoharvest.admin.toggle-others` | `op` | Toggle for other players |
Set `require-permission: true` in config to require `autoharvest.use` for the plugin to function at all. By default, it works for everyone.
---
Configuration
All settings in `plugins/AutoHarvest/config.yml`. Changes take effect with `/autoharvest reload` — no server restart needed.
```yaml general: default-enabled: true # New players start with auto-harvest on require-permission: false # Require autoharvest.use permission enabled-worlds: [] # Empty = all worlds. List specific worlds to restrict. disabled-worlds: # These worlds are always excluded - "world_nether" - "world_the_end"
harvest: on-break: true # Auto-replant when breaking mature crops on-bonemeal: true # Harvest + replant when bonemealing to maturity require-hoe: false # Only trigger when holding a hoe bonemeal-subtract-replant-cost: true # Fairness: subtract 1 seed from bonemeal drops
drops: enabled: true # Set false to suppress all drops (adventure maps) drop-at-center: true # Drop at block center vs exact break location overflow-to-ground: true # Full inventory? Drop on ground, not void
crops: # Enable/disable individual crop types wheat: true carrots: true potatoes: true beetroot: true nether_wart: true cocoa: true sweet_berries: true
cooldown: bonemeal-ms: 50 # Anti-macro: ms between bonemeal harvests per player
feedback: particles: true # Green sparkle particles on harvest sound: true # Crop break sound on harvest sound-name: "block.crop.break" sound-volume: 0.5 sound-pitch: 1.2
debug: false # Log every harvest with player, location, crop, drops ```
Messages are customizable in `messages.yml` using MiniMessage format.
---
How It Works
AutoHarvest is designed to be invisible to the game engine. It never cancels events or re-implements vanilla mechanics.
Break Path
1. Player breaks a mature crop 2. `BlockBreakEvent` fires at `HIGH` priority with `ignoreCancelled = true` 3. AutoHarvest validates: survival mode, world enabled, player toggled on, crop mature, environment valid 4. Vanilla processes the break — handles drops, Fortune, tool durability, statistics, advancements 5. One tick later, AutoHarvest places the crop back at age 0
Bonemeal Path
1. Player right-clicks a crop with bonemeal 2. Vanilla applies the bonemeal — consumes item, advances growth, plays particles 3. One tick later, AutoHarvest checks if the crop is now mature 4. If mature: calculates drops, subtracts one seed (fairness), replants, drops items
Why Not Cancel + Manual Drops?
Many farming plugins cancel the break event and manually calculate drops. This breaks: - Any downstream plugin XP hooks (they read vanilla drops) - Any downstream plugin (`CROP_WASTED`, block break stats) - Any downstream plugin ("A Seedy Place", etc.) - Any downstream plugin - Any downstream plugin that listens to `BlockBreakEvent`
AutoHarvest avoids all of this by letting vanilla handle the break completely.
---
Performance
AutoHarvest is built for zero measurable TPS impact.
- Folia compatible — O(1), no hashing overhead - Folia compatible — plain loops for JIT-friendly hot paths - Folia compatible — immutable `PluginConfig` snapshot, atomically swapped on reload - Folia compatible at INFO level — debug-gated only - Folia compatible via `runTask`, not `runTaskLater(0)` - Folia compatible — uses `RegionScheduler` when Folia is detected, standard `BukkitScheduler` on Paper
Benchmarks
| Scenario | Target | |----------|--------| | 10k wheat farm, 5 players harvesting continuously | 19.8+ TPS | | Bonemeal spam (10 clicks/sec/player x 4 players) | 19.9+ TPS | | Plugin load time | < 50ms | | `/autoharvest reload` | < 100ms |
---
Compatibility
- Only fires in Survival mode (1.21 - 1.21.4+) - Only fires in Survival mode — detected at startup, uses region-aware scheduling - Only fires in Survival mode required - Only fires in Survival mode — AutoHarvest respects `BlockBreakEvent` cancellation. Any plugin that cancels the event (WorldGuard, GriefPrevention, Towny, Lands, Residence, etc.) will prevent auto-harvest in protected regions. No special configuration needed. - Only fires in Survival mode — Creative, Adventure, and Spectator are ignored
---
Installation
1. Download the jar from Modrinth 2. Place in your server's `plugins/` folder 3. Restart the server 4. Optionally edit `plugins/AutoHarvest/config.yml` and run `/autoharvest reload`
---
Building from Source
Requires Java 21.
```bash git clone https://github.com/yourusername/AutoHarvest.git cd AutoHarvest ./gradlew build ```
The plugin jar will be in `build/libs/`.
---
License
MIT