Purpur サーバーで水流を使ったアイテム仕分け機を作ったところ、バニラでは正常に動くのに、なぜか一部のアイテムをホッパーが吸い込んでくれない問題が起こりました。
本来であれば上流側のホッパーが吸い込むはずのアイテムがそのまま流れてしまい、下流のホッパーに吸われたり、場合によってはそのまま回収されずに流れていったりします。
仕分け機に問題があると思っていたのですが、シングルプレイのバニラ環境で同じ装置を試してみると正常に動作しました。
調べてみたところ、原因は Purpur の継承元である Paper のホッパー最適化設定にありました。
この記事では、実際に起きた症状と原因になった設定、バニラに近い挙動に戻す方法を紹介します。
起きていた症状
今回問題が起きたのは、水流でアイテムを運びながら、途中に設置したホッパーでアイテムを回収するタイプの仕分け機です。

本来であれば、対象のアイテムがホッパーの上を通過したときに、そのホッパーがアイテムを吸い込みます。
しかし Purpur サーバー上では、ホッパーに空きがあるにもかかわらずアイテムを吸い込まないことがありました。
その結果、本来吸い込まれるはずだったアイテムがそのまま下流へ流れ、次のホッパーに吸われてしまったり、どのホッパーにも座れずに最後まで流れてしまったりします。
100% 失敗するわけではなかったため、最初は水流の位置やアイテムの流れる速度に問題があるのではないかと考えていました。
バニラ環境では正常に動いた
まず、仕分け機そのものに問題がないか確認するため、同じ構造の装置をシングルプレイのバニラ環境でも動かしてみました。
すると、バニラ環境では水流を流れてきたアイテムを各ホッパーが想定どおりに吸い込み、Purpurサーバーで起きていたような取りこぼしは発生しませんでした。
この結果から、装置の構造や水流の作り方ではなく、Purpur側の設定や最適化によってホッパーの挙動が変わっている可能性が高いと考えました。
そこで、Purpurが継承しているPaperやSpigotのホッパー関連設定を確認していくことにしました。
原因はPaperのcooldown-when-full
今回原因になっていたのは、Paper のホッパー最適化設定である cooldown-when-full でした。
この設定が有効になていると、ホッパーがアイテムで満杯になった際に、一定時間アイテムを吸い込む処理を行わないようになります。
今回の仕分け機では、ホッパーが一度満杯になったあと、下のホッパーなどへアイテムが排出されて空きができても、すぐには吸い込む処理が再開されません。
そのため、ホッパーには空きがあるのに、水流を流れてきたアイテムを吸い込まないタイミングが発生していました。
結果として、本来そのホッパーで回収されるはずだったアイテムが下流へ流れてしまい、別のホッパーに吸われたり、そのまま回収されずに流れていったりしていました。
設定は config/paper-global.yml の以下の項目です
hopper:
cooldown-when-full: true
true の場合はこの最適化が有効になっています。
バニラに近いホッパーの挙動にしたい場合は、次のように false へ変更します。
hopper:
cooldown-when-full: false
この設定を変更したところ、今回使用していた水流式仕分け機でも、期待通りにアイテムを回収できるようになりました。
それでもホッパーがおかしい場合
cooldown-when-fullを変更してもホッパーの挙動がおかしい場合は、ほかのホッパー関連設定も確認してみてください。
PaperやSpigot系のサーバーには、負荷を抑えるためにホッパーの動作間隔や、一度に移動するアイテム数を変更する設定があります。
hopper-check
hopper-checkは、ホッパーが上にあるアイテムを吸い込めるか確認する間隔に関係する設定です。
この値がバニラと異なっていると、地面や水流を流れているアイテムを吸い込むタイミングが変わり、装置によっては期待した通りに動作しない可能性があります。
hopper-transfer
hopper-transferは、ホッパーから別のインベントリへアイテムを移動する間隔に関係する設定です。
値が変更されている場合、ホッパー同士のアイテム転送速度がバニラと異なるため、ホッパークロックや仕分け機など、タイミングに依存する装置に影響することがあります。
hopper-amount
hopper-amountは、ホッパーが1回の転送で移動させるアイテム数に関係する設定です。
バニラでは基本的に1個ずつアイテムを転送するため、この値が変更されていると、アイテムの流れ方そのものが変わります。
特にレッドストーンコンパレーターでホッパー内のアイテム数を検出している装置では、想定外の動作につながる可能性があります。
プラグインも確認する
設定ファイルに問題が見つからない場合は、導入しているプラグインも確認してみましょう。
サーバーの軽量化を目的としたプラグインや、ホッパー・アイテム・レッドストーン周りを最適化するプラグインが、バニラとは異なる挙動を発生させていることがあります。
原因を切り分ける場合は、まず同じ装置がシングルプレイのバニラ環境で動くかを確認し、そのあとサーバー側の設定やプラグインを一つずつ確認していくと見つけやすいです。
まとめ
Purpur などの Paper 系サーバーでは、パフォーマンス改善のためにバニラとは異なる最適化が行われている場合があります。
装置が想定どおりに動かないときは、まずシングルプレイなどのバニラ環境で同じ装置が正常に動くか確認すると、装置側の問題なのかサーバー側の問題なのかを切り分けやすくなります。
今回の水流式仕分け機では、Paperの cooldown-when-full が原因で、空きができたホッパーがすぐにアイテムを吸い込まず、一部のアイテムを取り逃していました。
cooldown-when-full を false に変更することで、今回の環境ではバニラに近い挙動に戻すことができました。
Purpur でホッパーやレッドストーン装置の挙動に違和感がある場合は、装置そのものだけでなく、Paper や Spigot 由来の最適化設定も確認してみると原因が見つかるかもしれません。