Scalaのファイルにおいては、null
を使用する代わりにOption
を使用してください。
Java (特に、Bukkit/Spigot API) から入ってきた値がnull
になる可能性がある場合は、その呼び出しを早いうちにOption(...)
で囲い、Option
にすることが推奨されます。この呼び出しで、引数がnull
だった場合はNone
に、そうでなかった場合はSome(...)
になります。
例外の代わりにEither
を使用してください。Either
を使用すると低コストで合成を行うことができるためです。
Scalaを書くことができる場合はScalaを使ってください。
メインスレッドで計算なども含めたすべての処理を行うことはサーバーのラグにつながるため、推奨されません。 推奨される処理の記述方法は次のとおりです。
- 処理に必要なデータを得る
- 非メインスレッドに遷移し、処理を行う
- 処理結果の反映を行う
特に、必要なデータや処理結果の反映にワールドやエンティティが含まれる場合は、データの取得と反映をメインスレッドで行う必要があります。これはBukkitによる制約で、私達ではどうすることも出来ません。
asInstanceOf
とisInstanceOf
はできるだけ使わないようにしましょう。Javaのキャスト演算子、instanceof
演算子と同様の危険性および非効率性があります。最悪の場合全く関係ない型にキャストすることによってClassCastException
が発生し、サーバーが落ちる危険性があるので避けられる場合は絶対に使わないでください。 shapelessなどのコンパイル時型プログラミングを積極的に活用するのも良いでしょう。
もしどうしても使わなければならない場合は、注意して影響範囲を最小限に押し込めるとともに、そこへのフローをできる限り制限してください。
※以下は、2023年7月25日現在の情報であり、古くなっている可能性があります
InventoryClickEvent
はメニュー以外のインベントリ (例: チェスト) を操作したときも拾ってしまうため、メニューを実装するためにホックすることは推奨されません。
代わりに、Menu
を使ってください。
SeichiAssistには複数の関心事があり、その大半が「サブシステム」と呼ばれるひとまとまりとしてcom.github.unchama.seichiassist.subsystems
以下にまとめられています。
最新の一覧
各サブシステムはそれぞれ他のサブシステムなどで使うことを想定したAPIをtrait
として持ち、各サブシステムはその抽象に対してのみ依存することができます。サブシステムの実装はAPIに具象的な実装を与える必要があります。APIの名前はおおよそApi
かAPI
で終わります。
関心事同士の依存 (例: 整地スキルによってマナを減少させるためにマナを操作する) は 抽象の型をimplicit
パラメーターとして渡すことにより表現されます。
新しくサブシステムを作った場合、SeichiAssist.scala
内で初期化することを忘れないでください。初期化を忘れると正しく機能しません。
サブシステムの構造は慣例的に次のようになっています。新しくサブシステムを作る場合は一貫性のためにこの構造に準拠することが推奨されます。
- (サブシステムのルート)
application
- タスク、データのレポジトリの初期化・終了処理などbukkit
- Bukkit固有の実装commands
- Bukkitのコマンドlisteners
- Bukkitのイベントリスナー
domain
- モデルinfrastructure
- インフラ (JDBCによるデータベースへの保存・読み込みなど)subsystems
- 子サブシステムSystem
- サブシステムの「親分」