| gradle | ||
| kommand-lib@99ad500915 | ||
| src/main/kotlin/net/hareworks/ghostdisplays | ||
| .gitattributes | ||
| .gitignore | ||
| .gitmodules | ||
| build.gradle.kts | ||
| gradle.properties | ||
| gradlew | ||
| gradlew.bat | ||
| README.md | ||
| settings.gradle.kts | ||
GhostDisplays
Paper 1.21.10 向けの不可視ディスプレイ制御ライブラリです。TextDisplay / BlockDisplay / ItemDisplay をプレイヤー単位で表示・クリック検知できるようにし、ゴースト化した UI やガイドラインをサーバー側で柔軟に提供できます。
提供機能
DisplayServiceによる Text/Block/Item Display の生成 APIDisplayControllerを介したパケットベースの表示・非表示制御(参照カウント管理)AudiencePredicate/AudiencePredicatesによる可視対象の自動同期(ログイン・ワールド移動・リスポーンで再評価)- FakeInteraction エンティティを用いたクリック判定サポートと、優先度付きクリックハンドラー
- まとめて
destroyAll()できるリソース管理
スタンドアロンでの使い方
プラグインを plugins/ に配置して起動すると /ghostdisplay コマンドが利用できます。デフォルトで OP のみ実行可能ですが、ghostdisplays.command.* を付与すると通常権限でも操作できます。
| コマンド | 説明 |
|---|---|
/ghostdisplay create text <id> |
プレイヤー視点の約 1.5 ブロック先に TextDisplay を生成し、即座にチャット編集モードへ。次に送信したメッセージ(または cancel)が内容になります。 |
/ghostdisplay create block <id> <blockstate> |
BlockDisplay を生成します。oak_planks[facing=north] のような BlockData 文字列を指定してください。 |
/ghostdisplay create item <id> <material> |
ItemDisplay を生成します。minecraft:stick などのアイテム ID を受け付けます。 |
/ghostdisplay text set <id> <content> |
TextDisplay のテキストを即時更新します。_ はスペースに、\n は改行に変換されます。 |
| `/ghostdisplay viewer add | remove player/@a` |
/ghostdisplay audience permission add <id> <permission> |
指定パーミッションを持つプレイヤーに自動表示 (remove で解除)。 |
/ghostdisplay audience near set <id> <radius> |
Display 周囲の半径プレイヤーへ自動表示 (audience clear で全自動表示を解除)。 |
/ghostdisplay list / /ghostdisplay info <id> |
登録済み Display の一覧、情報(座標 / Viewers / Audiences / 内容)を表示。 |
/ghostdisplay delete <id> |
Display を完全に削除します。 |
技術的ポイント
- NMS パケットベースの FakeEntity 方式 — サーバー上に実エンティティを生成せず、クライアントへのパケット送信のみで表示を実現。エンティティティック・コリジョン・永続化のオーバーヘッドがゼロ
- パケット送信はスレッドセーフなため、Folia のリージョンスケジューリングに依存しないシンプルな設計
- クリック検知は Netty パイプラインで
ServerboundInteractPacketを傍受し、FakeInteraction の entityId にマッチしたらハンドラーを発火 - Predicate ごとにアクティブなプレイヤー集合を持つため、複数条件での重複表示にも対応
paperweight-userdevによる NMS アクセス(1.21.11 対応)
API 利用例
val service: DisplayService = GhostDisplaysPlugin.service()
// TextDisplay を生成
val controller = service.createTextDisplay(location) {
text = Component.text("Hello")
billboard = Display.Billboard.CENTER
viewRange = 0.5f
}
controller.show(player)
// テキスト更新
controller.updateText { it.text = Component.text("Updated") }
// 共通プロパティ更新
controller.updateDisplay { it.billboard = Display.Billboard.FIXED }
// テレポート
controller.teleport(newLocation)
// Audience ルール
controller.addAudienceRule(AudiencePredicates.near(location, 30.0), AudienceAction.ADD)
// クリックハンドラー
controller.onClick { ctx -> ctx.player.sendMessage("Clicked!") }
// 破棄
controller.destroy()
同梱ライブラリ
- コマンド定義は
kommand-lib(Kotlin DSL)を使用し、permits-libと連携してghostdisplays.command.*のパーミッションツリーを自動生成しています。 - どちらも本リポジトリの
kommand-lib/以下にサブモジュールとして含まれており、./gradlew build時に一緒にコンパイルされます。