11 KiB
kommand-lib マイグレーションガイド
このガイドでは、旧バージョンの kommand-lib から最新の Brigadier ネイティブ対応バージョンへの移行方法を説明します。
📋 目次
変更の概要
🎯 主な変更点
-
Brigadier ネイティブ対応
- Paper 1.21 の Lifecycle API を使用したコマンド登録
- クライアント側での構文ヒントと検証
- より正確な型システム
-
引数の型変更
coordinates()の返り値がCoordinates3からio.papermc.paper.math.Positionに変更- Player/Entity セレクターの内部処理が改善
-
自動登録
kommand()関数の呼び出しで自動的にコマンドが登録されるように変更
破壊的変更
🔴 1. coordinates() 引数の型変更
旧バージョン (動作しません)
coordinates("point") {
executes {
val coords = argument<Coordinates3>("point")
val target = coords.resolve(player.location)
// Coordinates3 型は存在しません
}
}
新バージョン (正しい方法)
coordinates("point") {
executes {
val position = argument<io.papermc.paper.math.Position>("point")
val location = position.toLocation(player.world)
// Position 型を使用します
}
}
理由: Paper の Brigadier API は io.papermc.paper.math.Position を返します。これは Paper の公式 API に準拠しています。
🟡 2. Player/Entity セレクターの内部処理
ユーザーコードに変更は不要ですが、内部的に以下の変更が行われました:
内部処理の改善
// 旧: 直接キャスト (実行時エラーの原因)
val player = context.getArgument("player", Player::class.java)
// 新: Resolver を使用して解決 (正しい方法)
val resolver = context.getArgument("player", PlayerSelectorArgumentResolver::class.java)
val player = resolver.resolve(source).firstOrNull()
影響: Player/Entity 引数がより安定して動作するようになりました。
マイグレーション手順
ステップ 1: 依存関係の確認
build.gradle.kts で Paper API のバージョンを確認してください:
dependencies {
compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT")
// 1.21 以降が必要です
}
ステップ 2: import 文の追加
coordinates() を使用している場合、import を追加してください:
import io.papermc.paper.math.Position
ステップ 3: コードの更新
以下のパターンを検索して置換してください:
パターン 1: coordinates の型指定
検索:
argument<Coordinates3>("
置換:
argument<io.papermc.paper.math.Position>("
または、import を追加して:
argument<Position>("
パターン 2: coordinates の解決方法
検索:
val coords = argument<Coordinates3>("pos")
val location = coords.resolve(baseLocation)
置換:
val position = argument<Position>("pos")
val location = position.toLocation(world)
ステップ 4: ビルドとテスト
./gradlew build
エラーがないことを確認してから、サーバーでテストしてください。
コード例の比較
例 1: スポーン地点の設定
❌ 旧バージョン
literal("setspawn") {
coordinates("point") {
executes {
val base = (sender as? Player)?.location ?: return@executes
val coords = argument<Coordinates3>("point")
val target = coords.resolve(base)
plugin.server.worlds.first().setSpawnLocation(target)
sender.sendMessage("Spawn set to ${target.x}, ${target.y}, ${target.z}")
}
}
}
✅ 新バージョン
literal("setspawn") {
coordinates("point") {
executes {
val player = sender as? Player ?: return@executes
val position = argument<Position>("point")
val location = position.toLocation(player.world)
player.world.setSpawnLocation(location)
sender.sendMessage("Spawn set to ${location.x}, ${location.y}, ${location.z}")
}
}
}
変更点:
Coordinates3→Positioncoords.resolve(base)→position.toLocation(world)- より明確な変数名
例 2: テレポートコマンド
❌ 旧バージョン
literal("tp") {
coordinates("destination") {
executes {
val player = sender as? Player ?: return@executes
val coords = argument<Coordinates3>("destination")
val target = coords.resolve(player.location)
player.teleport(target)
}
}
}
✅ 新バージョン
literal("tp") {
coordinates("destination") {
executes {
val player = sender as? Player ?: return@executes
val position = argument<Position>("destination")
val location = position.toLocation(player.world)
player.teleport(location)
}
}
}
例 3: 範囲指定コマンド
❌ 旧バージョン
literal("fill") {
coordinates("pos1") {
coordinates("pos2") {
executes {
val player = sender as? Player ?: return@executes
val base = player.location
val pos1 = argument<Coordinates3>("pos1").resolve(base)
val pos2 = argument<Coordinates3>("pos2").resolve(base)
// 処理...
}
}
}
}
✅ 新バージョン
literal("fill") {
coordinates("pos1") {
coordinates("pos2") {
executes {
val player = sender as? Player ?: return@executes
val world = player.world
val pos1 = argument<Position>("pos1").toLocation(world)
val pos2 = argument<Position>("pos2").toLocation(world)
// 処理...
}
}
}
}
Position API リファレンス
Position のメソッド
interface Position {
fun x(): Double
fun y(): Double
fun z(): Double
fun blockX(): Int
fun blockY(): Int
fun blockZ(): Int
fun toLocation(world: World): Location
}
使用例
val position = argument<Position>("pos")
// 座標の取得
val x = position.x()
val y = position.y()
val z = position.z()
// ブロック座標の取得
val blockX = position.blockX()
val blockY = position.blockY()
val blockZ = position.blockZ()
// Location への変換
val location = position.toLocation(player.world)
トラブルシューティング
問題 1: Coordinates3 が見つからない
エラー:
Unresolved reference: Coordinates3
解決方法:
Coordinates3 は存在しません。io.papermc.paper.math.Position を使用してください。
// ❌ 間違い
argument<Coordinates3>("pos")
// ✅ 正しい
argument<Position>("pos")
問題 2: resolve() メソッドが見つからない
エラー:
Unresolved reference: resolve
解決方法:
Position には resolve() メソッドはありません。toLocation(world) を使用してください。
// ❌ 間違い
val location = position.resolve(baseLocation)
// ✅ 正しい
val location = position.toLocation(world)
問題 3: Player セレクターが動作しない
症状: Player 引数を使用するとエラーが発生する
解決方法:
最新バージョンに更新してください。内部的に ArgumentResolver が自動的に処理します。
// これは自動的に動作します
val player = argument<Player>("target")
val players = argument<List<Player>>("targets")
問題 4: コマンドが登録されない
症状: /help にコマンドが表示されない
解決方法:
最新バージョンでは kommand() 関数の呼び出しで自動的に登録されます。
class MyPlugin : JavaPlugin() {
private lateinit var commands: KommandLib
override fun onEnable() {
// これだけで自動的に登録されます
commands = kommand(this) {
command("mycommand") {
// ...
}
}
}
}
よくある質問 (FAQ)
Q1: 相対座標 (~) は引き続き使えますか?
A: はい、引き続き使えます。Position は相対座標を完全にサポートしています。
// "~ ~1 ~-2" のような入力が可能
val position = argument<Position>("pos")
Q2: 旧バージョンとの互換性はありますか?
A: coordinates() 引数の型が変更されているため、互換性はありません。マイグレーションが必要です。
ただし、player(), players(), selector() などの他の引数は互換性があります。
Q3: マイグレーションにどのくらい時間がかかりますか?
A: プロジェクトの規模によりますが、通常は以下の通りです:
- 小規模 (1-5 コマンド): 5-10 分
- 中規模 (5-20 コマンド): 15-30 分
- 大規模 (20+ コマンド): 30-60 分
主な作業は検索と置換なので、比較的短時間で完了します。
Q4: 段階的な移行は可能ですか?
A: いいえ、coordinates() を使用している場合は一度にすべて移行する必要があります。
ただし、coordinates() を使用していないコマンドは変更不要です。
サポート
問題が発生した場合は、以下のドキュメントを参照してください:
- README.md - 基本的な使い方
- BRIGADIER_REVIEW.md - 詳細なレビュー
- Paper API Documentation - Position API の詳細
まとめ
✅ マイグレーションチェックリスト
- Paper API 1.21 以降を使用していることを確認
Coordinates3をPositionに置換coords.resolve()をposition.toLocation()に置換- 必要な import を追加
- ビルドが成功することを確認
- サーバーでテストして動作を確認
🎉 完了!
マイグレーションが完了すると、以下のメリットが得られます:
- ✅ クライアント側での構文ヒント
- ✅ より正確な型チェック
- ✅ Paper の公式 API に準拠
- ✅ より安定した動作
ご不明な点がございましたら、お気軽にお問い合わせください。