Go to file
2026-04-27 17:37:50 +09:00
gradle FakeEntity化 2026-03-30 19:38:18 +09:00
kommand-lib@99ad500915 bump 26.1 2026-04-27 17:37:50 +09:00
src/main/kotlin/net/hareworks/ghostdisplays bump 26.1 2026-04-27 17:37:50 +09:00
.gitattributes init 2025-12-06 04:40:18 +09:00
.gitignore feat: Audienceのタイミング 2025-12-07 03:41:42 +09:00
.gitmodules init 2025-12-06 04:40:18 +09:00
build.gradle.kts bump 26.1 2026-04-27 17:37:50 +09:00
gradle.properties init 2025-12-06 04:40:18 +09:00
gradlew init 2025-12-06 04:40:18 +09:00
gradlew.bat init 2025-12-06 04:40:18 +09:00
README.md Fake-Interaction 2026-03-31 10:40:46 +09:00
settings.gradle.kts FakeEntity化 2026-03-30 19:38:18 +09:00

GhostDisplays

Paper 1.21.10 向けの不可視ディスプレイ制御ライブラリです。TextDisplay / BlockDisplay / ItemDisplay をプレイヤー単位で表示・クリック検知できるようにし、ゴースト化した UI やガイドラインをサーバー側で柔軟に提供できます。

提供機能

  • DisplayService による Text/Block/Item Display の生成 API
  • DisplayController を介したパケットベースの表示・非表示制御(参照カウント管理)
  • 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-libKotlin DSLを使用し、permits-lib と連携して ghostdisplays.command.* のパーミッションツリーを自動生成しています。
  • どちらも本リポジトリの kommand-lib/ 以下にサブモジュールとして含まれており、./gradlew build 時に一緒にコンパイルされます。