feat(tree-feller): migrate distribution and local harness to Purpur
Release / release (push) Successful in 7m13s
CI / build (push) Successful in 2m35s

BREAKING CHANGE: New releases require Java 25/Purpur 26.2 and use purpur-tree-feller-<version>.jar. Runtime TreeFeller identity, data folder, progression and felling/undo behavior are unchanged. Replace the old JAR rather than installing both distributions. The local harness now selects Purpur 2618; its stored worlds and operator/port/RCON settings are preserved. No containers are started by this migration.
This commit is contained in:
dmg
2026-09-12 15:04:03 -04:00
parent 2a793e8c69
commit 5b41190a09
15 changed files with 334 additions and 30 deletions
+14 -10
View File
@@ -1,13 +1,15 @@
# Tree Feller
# Purpur Tree Feller
Tree Feller is a Spigot 26.2 plugin that lets Survival players earn animated automatic felling independently for each vanilla tree family.
Tree Feller is a Purpur 26.2 plugin that lets Survival players earn animated automatic felling independently for each vanilla tree family.
The approved behavior and implementation record are in the [SoMC OKF wiki](https://git.garvis.dev/dmg/somc-okf/src/branch/main/projects/spigot-tree-feller/index.md).
The approved behavior and implementation record are in the [SoMC OKF wiki](https://git.garvis.dev/dmg/somc-okf/src/branch/main/projects/purpur-tree-feller/index.md).
## Requirements
- Spigot 26.2
- Java 17 or newer
- Purpur 26.2 build 2618
- Java 25
Repository, checkout and new artifacts use `purpur-tree-feller`. Runtime `TreeFeller`, Java packages/entrypoint, `plugins/TreeFeller/`, commands/permissions and player progression/preferences remain unchanged. Replace the old JAR rather than installing both distributions. Old release tags/assets remain available; new releases no longer support Java 17.
## Build
@@ -15,11 +17,11 @@ The approved behavior and implementation record are in the [SoMC OKF wiki](https
./gradlew clean check jar
```
The plugin JAR is written to `build/libs/`.
The plugin JAR is written to `build/libs/purpur-tree-feller-<version>.jar`. `check` includes `nativeTreeTest`, loading real item registries/services from SHA-256-verified Purpur 2618 under `build/tree-runtime/` without starting a listening server. Existing item/felling/undo assertions are retained. `LocalTestHarnessTest` checks parsed Compose settings and runs the actual startup script with isolated command doubles; it does not start Docker.
## Local Docker test server
Build the current plugin and start it on an isolated Spigot 26.2 server:
Build the current plugin and start it on an isolated Java 25/Purpur 26.2 build 2618 server:
```bash
./scripts/start-test-server.sh
@@ -27,7 +29,7 @@ Build the current plugin and start it on an isolated Spigot 26.2 server:
Connect to `localhost:25565` as `WindMagi`, which the harness configures as a level-4 operator using its deterministic offline-mode UUID. The committed `docker/test-ops.json` fixture replaces local operator state on every startup so the offline UUID remains deterministic. The server uses offline mode for local convenience and binds only to the loopback interface.
The first startup may take several minutes while the image downloads and Spigot is prepared. Override the 15-minute wait or local RCON password when needed:
The first startup may take several minutes while the image downloads and Purpur is prepared. Override the 15-minute wait or local RCON password when needed:
```bash
TREE_FELLER_START_TIMEOUT=1200 \
@@ -49,6 +51,8 @@ docker compose -f compose.test.yml down
rm -rf .docker/minecraft
```
The harness now mounts the `purpur-tree-feller` snapshot JAR at the unchanged `/plugins/TreeFeller.jar` path. A manual startup after migration switches the local test world from Spigot to Purpur; it preserves existing `.docker/minecraft/` state, so back up valuable test worlds before running it. The migration itself does not start or recreate containers.
Re-run the start script after code changes to rebuild the JAR and recreate the test container. Generated server state remains under `.docker/minecraft/` and is ignored by Git.
## Player commands
@@ -79,7 +83,7 @@ Administrative commands require `treefeller.admin`, granted to server operators
- Crimson and warped fungi
- Giant red and brown mushrooms
Azalea-grown logs count as oak. Unlock progress counts unstripped natural log and Nether stem materials even after the surrounding tree has been disrupted; wood, hyphae, stripped variants, and bamboo do not count. Player-placed qualifying materials are indistinguishable from generated materials in Spigot and therefore also count. Giant mushroom stems require enough cap context to identify their species.
Azalea-grown logs count as oak. Unlock progress counts unstripped natural log and Nether stem materials even after the surrounding tree has been disrupted; wood, hyphae, stripped variants, and bamboo do not count. Player-placed qualifying materials are indistinguishable from generated materials through the server API and therefore also count. Giant mushroom stems require enough cap context to identify their species.
## Configuration and state
@@ -91,7 +95,7 @@ Player preferences, administrative locks, progress, unlocks, and known names are
Tree detection searches matching natural trunk blocks laterally and upward, never below the initiating chop, and requires corresponding foliage or caps. Search bounds prevent unbounded traversal. Leaves, caps, roots, vines, and decorations are not automatically broken.
Automatic felling supports Spigot 26.2 wooden, stone, copper, iron, golden, diamond, and netherite axes. Additional trunk blocks use Spigot's `Player.breakBlock` path so block-break cancellation, drops, experience, enchantments, and axe durability remain authoritative. Protection plugins should cancel `BlockBreakEvent` normally. A cancelled additional break stops the remaining felling.
Automatic felling supports Purpur 26.2 wooden, stone, copper, iron, golden, diamond, and netherite axes. Additional trunk blocks use the server's `Player.breakBlock` path so block-break cancellation, drops, experience, enchantments, and axe durability remain authoritative. Protection plugins should cancel `BlockBreakEvent` normally. A cancelled additional break stops the remaining felling.
## Releases