Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Automatically build the project and run any configured tests for every push
# and submitted pull request. This can help catch issues that only occur on
# certain platforms or Java versions, and provides a first line of defence
# against bad commits.

name: build
on: [pull_request, push]

jobs:
build:
runs-on: ubuntu-24.04
steps:
- name: checkout repository
uses: actions/checkout@v6
- name: validate gradle wrapper
uses: gradle/actions/wrapper-validation@v6
- name: setup jdk
uses: actions/setup-java@v5
with:
java-version: '25'
distribution: 'microsoft'
- name: make gradle wrapper executable
run: chmod +x ./gradlew
- name: build
run: ./gradlew build
- name: capture build artifacts
uses: actions/upload-artifact@v7
with:
name: Artifacts
path: build/libs/
45 changes: 45 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Creates a GitHub Release whenever a version tag (v*) is pushed.
# The release body is the matching section from CHANGELOG.md and the
# built plugin jar is attached as an asset.

name: release
on:
push:
tags:
- 'v*'

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-24.04
steps:
- name: checkout repository
uses: actions/checkout@v6
- name: setup jdk
uses: actions/setup-java@v5
with:
java-version: '25'
distribution: 'microsoft'
- name: make gradle wrapper executable
run: chmod +x ./gradlew
- name: build
run: ./gradlew build
- name: extract changelog section
run: |
VERSION="${GITHUB_REF_NAME#v}"
awk -v ver="$VERSION" '
$0 == "## Version " ver { found = 1; next }
found && /^## / { exit }
found { print }
' CHANGELOG.md > RELEASE_NOTES.md
if ! grep -q '[^[:space:]]' RELEASE_NOTES.md; then
echo "::error::No changelog section found for version $VERSION in CHANGELOG.md"
exit 1
fi
- name: create release
uses: softprops/action-gh-release@v2
with:
body_path: RELEASE_NOTES.md
files: build/libs/*.jar
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# TriHunt - Change Log

## Unreleased
67 changes: 67 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# TriHunt — Agent Instructions

TriHunt is a Manhunt plugin for Paper servers (Kotlin 2.3.10, Minecraft 26.2, Java 25): the Speedrunners race to beat
the chosen boss while the Hunters try to stop them. [README.md](README.md) has the player-facing overview.

## After every change: keep the changelog and docs in sync

Before finishing any task that changes the plugin, do all of the following:

1. **Update the changelog** — add an entry for the change under `## Unreleased` in [CHANGELOG.md](CHANGELOG.md), in the
same commit as the change. Every new feature gets an entry, and so does every improvement and fix.
- Follow the SkyHanni-style format documented in [docs/RELEASING.md](docs/RELEASING.md): category (`### New
Features` / `### Improvements` / `### Fixes` / `### Technical Details` / `### Removed Features`), then a
`#### Feature Area` heading, then `+` bullets.
- Reuse the category and feature-area headings already under `## Unreleased` instead of repeating them.
- Write player- and server-owner-facing entries for gameplay changes; put refactors, build, and tooling changes
under `### Technical Details`.
- Never edit the section of a version that has already been released.
- Skip changelog entries only for changes with no effect on the shipped plugin or its workflow (e.g. fixing a typo
in a doc).

2. **Update the developer docs** — if the change adds or alters a base class, registrar, utility, or data API, update
[docs/DEVELOPER_GUIDE.md](docs/DEVELOPER_GUIDE.md) or [docs/UTILITY_GUIDE.md](docs/UTILITY_GUIDE.md) in the same
task. A change to a documented workflow (e.g. the release process in [docs/RELEASING.md](docs/RELEASING.md)) updates
that doc too.

3. **Check the README** — if the change affects anything [README.md](README.md) mentions (game modes, features, planned
features, getting started), update it. When a planned feature ships, move it out of **Planned Features**.

## Build & run

```powershell
./gradlew build # Builds build/libs/TriHunt-<version>.jar
./gradlew copyPlugin # Copies the jar into run/plugins/
./gradlew startServer # Runs copyPlugin, then launches the paper-*.jar in run/
```

## Project conventions

- Plugin code is Kotlin under `src/main/kotlin/net/trilleo/mc/plugins/trihunt/`; `Main.kt` is the entry point.
- **Auto-registration** — `PackageScanner` discovers concrete classes at startup, so there is no manual wiring and no
`plugin.yml` edit. Extend the right base class and place the file in the right package:

| Component | Base Class | Package |
|:------------|:----------------|:------------------------|
| Command | `PluginCommand` | `commands` (any depth) |
| Listener | `Listener` | `listeners` (any depth) |
| GUI | `PluginGUI` | `guis` (any depth) |
| Task | `PluginTask` | `tasks` (any depth) |
| Item | `PluginItem` | `items` (any depth) |
| Recipe | `PluginRecipe` | `recipes` (any depth) |
| Config | `PluginConfig` | `config` (any depth) |
| Player data | `PlayerData` | `data` |
| Server data | `ServerData` | `data` |

Permissions are derived from commands automatically. Every command, listener, GUI, and task needs either a no-arg
constructor or one accepting a `JavaPlugin`. See [docs/DEVELOPER_GUIDE.md](docs/DEVELOPER_GUIDE.md).
- `plugin_version` in [gradle.properties](gradle.properties) is the single source of truth for the plugin version. It
flows into the jar filename and, through `processResources`, into `plugin.yml` (`version: ${projectVersion}`) — never
hardcode a version in `plugin.yml` or `build.gradle.kts`.
- [.github/workflows/build.yml](.github/workflows/build.yml) builds every push and pull request. Releases are made by
tagging `vX.Y.Z` — see [docs/RELEASING.md](docs/RELEASING.md). **Never tag or push tags unless explicitly asked** —
pushing a tag publishes a release.
- Commit messages follow the `<tag>: <message>` convention (`Feature:`, `Improvement:`, `Fix:`, `Internal:`,
`Backend:`, `Update:`) with one granular commit per logical change — see
[docs/COMMIT_STRUCTURE.md](docs/COMMIT_STRUCTURE.md). A `Feature:`, `Improvement:`, or `Fix:` commit carries its own
changelog entry.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ Custom items and recipes to enhance the gameplay experience.

## 🎮 Getting Started

Install the plugin and use the hotbar item to start!
Download the latest jar from the [releases page](https://github.com/Trilleo/TriHunt/releases), install the plugin and
use the hotbar item to start! See the [change log](CHANGELOG.md) for what's new in each release.

---

Expand Down
10 changes: 9 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group = "net.trilleo"
version = "0.7.0"
version = providers.gradleProperty("plugin_version").get()

idea {
module {
Expand Down Expand Up @@ -38,6 +38,14 @@ dependencies {
compileOnly("io.papermc.paper:paper-api:26.2.build.+")
}

tasks.processResources {
val props = mapOf("projectVersion" to version)
inputs.properties(props)
filesMatching("plugin.yml") {
expand(props)
}
}

tasks.jar {
from(configurations.runtimeClasspath.get().map { zipTree(it) })
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
Expand Down
17 changes: 15 additions & 2 deletions docs/COMMIT_STRUCTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Every commit message must follow this syntax:
| **Fix** | Repairing bugs, crashes, or logic errors. | `Fix: Resolve /help command output error` |
| **Improvement** | Refining existing code, UX, or performance. | `Improvement: Add tiered role removal logic` |
| **Internal** | Documentation, comments, or repository maintenance. | `Internal: Update COMMIT_STRUCTURE instructions` |
| **Backend** | Database schema changes or configuration updates. | `Backend: Add FeatureSwitch model for toggles` |
| **Backend** | Build system, dependency, or configuration updates. | `Backend: Update Gradle to 9.7.1` |
| **Update** | Plugin version changes. | `Update: 1.0.0 release` |

## Best Practices
Expand All @@ -25,4 +25,17 @@ Every commit message must follow this syntax:
* **Be Specific:** Instead of `Fix: bug`, use `Fix: Handle undefined member in /role command`.
* **No Period at End:** Do not end the commit message with a period.

---
## Mapping to Changelog Categories

Tags roughly correspond to [CHANGELOG.md](../CHANGELOG.md) categories (see [RELEASING.md](RELEASING.md) for the
changelog format):

| Tag | Changelog category |
|:---------------------------|:------------------------|
| **Feature** | `### New Features` |
| **Improvement** | `### Improvements` |
| **Fix** | `### Fixes` |
| **Backend** / **Internal** | `### Technical Details` |
| **Update** | Usually no entry |

---
127 changes: 127 additions & 0 deletions docs/RELEASING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# TriHunt - Changelog & Releasing

This guide covers how to maintain [CHANGELOG.md](../CHANGELOG.md) during development and how to publish a release on
GitHub. The release itself is automated by [.github/workflows/release.yml](../.github/workflows/release.yml) — pushing
a version tag builds the plugin, extracts the matching changelog section, and creates the GitHub Release with the jar
attached. Every push and pull request is also built by [.github/workflows/build.yml](../.github/workflows/build.yml).

## Changelog format

The changelog follows the [SkyHanni](https://github.com/hannibal002/SkyHanni) style:

```markdown
# TriHunt - Change Log

## Unreleased

## Version 1.1.0

### New Features

#### Game Modes

+ Added the Armed special mode.
+ Speedrunners start with a full set of iron gear.

### Improvements

#### Compass

+ Made the tracking compass point to the last portal used when the Speedrunner is in another dimension.

### Fixes

#### Items

+ Fixed custom recipes not showing in the recipe book.
```

Structure, top to bottom:

| Level | Heading | Purpose |
|--------|--------------------------------|---------------------------------------------------------------------------------------|
| `##` | `Unreleased` / `Version X.Y.Z` | One section per release; `Unreleased` collects entries during development |
| `###` | Category | `New Features`, `Improvements`, `Fixes`, `Technical Details`, `Removed Features` |
| `####` | Feature area | `Game Modes`, `Compass`, `Items`, `Misc`, … — free-form, `Misc` is the catch-all |
| `+` | Entry | One change per bullet; indent `+` sub-bullets for details |

Rules of thumb:

- Add an entry under `## Unreleased` in the same commit (or PR) as the change itself, so the changelog never lags
behind.
- Only include categories and feature areas that actually have entries — omit empty ones.
- Write entries for players and server owners, not developers: "Added the Armed special mode", not
"Refactored the game timer". Developer-facing changes go under `Technical Details`.
- With outside contributors, append attribution like SkyHanni does:
`+ Added X. - Name (https://github.com/Trilleo/TriHunt/pull/123)`

## Versioning

`plugin_version` in [gradle.properties](../gradle.properties) is the single source of truth — it flows into the jar
filename and the `version` field of `plugin.yml` automatically. Follow semver: **patch** for bugfixes, **minor** for new
features, **major** for breaking changes (e.g. config or data resets).

## Release walkthrough

Example: releasing version `1.1.0`.

1. **Finalize the changelog** — in `CHANGELOG.md`, rename the `## Unreleased` heading to `## Version 1.1.0` and add a
fresh empty `## Unreleased` above it:

```markdown
## Unreleased

## Version 1.1.0
...entries...
```

2. **Bump the version** — in `gradle.properties`:

```properties
plugin_version=1.1.0
```

3. **Verify the build** (optional but recommended):

```
./gradlew build
```

4. **Commit and tag** — the tag must be the version prefixed with `v`:

```
git commit -am "Update: Plugin version 1.1.0 release"
git tag v1.1.0
```

5. **Push** — this is the publish step; the release workflow fires on the tag:

```
git push && git push --tags
```

6. **Check the result** — the `release` workflow under the repo's *Actions* tab builds the jar and creates the GitHub
Release. Verify the release page shows the changelog text and has `TriHunt-1.1.0.jar` attached.

> **Never tag or push tags unless you have been explicitly asked to.** Pushing a tag publishes a release.

## How the automation matches things up

- The workflow strips the `v` from the tag (`v1.1.0` → `1.1.0`) and extracts everything between `## Version 1.1.0` and
the next `## ` heading in `CHANGELOG.md`. That text becomes the release body.
- **If no matching section exists, the workflow fails** — a release cannot ship with an empty changelog. Fix the heading
(exact match: `## Version 1.1.0`) and re-run the workflow, or delete and re-push the tag.
- The plugin jar from `build/libs/` is attached.

## Fixing a botched release

- **Wrong changelog / missing section**: fix `CHANGELOG.md`, commit, then move the tag and re-push it:

```
git tag -f v1.1.0
git push -f origin v1.1.0
```

Delete the draft/failed release on GitHub first if one was created.

- **Wrong version in the jar**: you tagged before bumping `plugin_version`. Bump it, commit, move the tag as above.
3 changes: 3 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
kotlin.code.style=official

# Plugin Properties
plugin_version=0.7.0
2 changes: 1 addition & 1 deletion src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: TriHunt
main: net.trilleo.mc.plugins.trihunt.Main
version: 0.7.0
version: ${projectVersion}
api-version: 1.21
description: Manhunt plugin for Minecraft.
author: Trilleo
Expand Down