diff --git a/.github/workflows/1_18.yml b/.github/workflows/1_18.yml
new file mode 100644
index 0000000000..769c87b710
--- /dev/null
+++ b/.github/workflows/1_18.yml
@@ -0,0 +1,99 @@
+name: 1.18 build check
+
+on:
+  push:
+    branches:
+      - 1_18
+    paths:
+      - src/**
+      - build.sbt
+      - .scalafix.conf
+      - .scalafmt.conf
+      - project/*
+      - .github/workflows/**.yml
+      - .github/actions/**/**.yml
+
+jobs:
+  build_check:
+    env:
+      BUILD_ENVIRONMENT_IS_CI_OR_LOCAL: "CI"
+    runs-on: ubuntu-24.04
+    container: ghcr.io/giganticminecraft/seichiassist-builder-v2:1df7cf5
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+        with:
+          submodules: 'recursive'
+
+      - name: Prepare build dependencies cache
+        uses: actions/cache@v4
+        env:
+          cache-name: cache-build-dependencies
+          cache-version: v-5
+        with:
+          # sbt等は$HOMEではなくユーザーディレクトリを見ているようで、
+          # GH Actionsでの ~ は /github/home/ に展開されるにもかかわらず
+          # 実際のキャッシュは /root/ 以下に配備される。
+          #
+          # /root/.ivy/cache, /root/.sbt - sbt関連のキャッシュ
+          # /root/.m2 - ビルドログを観察した感じprotoc等はここを利用する
+          # /root/.cache - cousierがscalasbt等をキャッシュするのに使っている
+          path: |
+            /root/.ivy2/cache
+            /root/.sbt
+            /root/.m2
+            /root/.cache
+          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-${{ github.ref }}-${{ hashFiles('**/build.sbt') }}
+          restore-keys: |
+            ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-${{ github.ref }}-
+            ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-
+
+      - name: Prepare build cache
+        if: github.ref != 'refs/heads/master'
+        uses: actions/cache@v4
+        env:
+          cache-name: cache-build
+          cache-version: v-5
+        with:
+          path: |
+            target
+            project/target
+            project/project/target
+          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-${{ github.ref }}-${{ github.sha }}
+          restore-keys: |
+            ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-${{ github.ref }}-
+            ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-
+
+      # CIでのcheckoutはファイルのタイムスタンプをチェックアウト時刻に設定するため、
+      # そのままビルドするとlocalDependenciesにあるjarに変更が行われたと見なされ
+      # 不要なインクリメンタルコンパイルが走る
+      # タイムスタンプをコミット時刻に設定することでこれが回避できる
+      - name: Restore localDependencies' timestamps
+        # 参考: https://qiita.com/tomlla/items/219cea9dd071c8a9e147
+        run: |
+          git config --global --add safe.directory /__w/SeichiAssist/SeichiAssist
+          for jar in localDependencies/*.jar; do
+            timestamp=`git log -1 --pretty=format:'%cd' --date=format:'%Y%m%d%H%M.%S' $jar`
+            touch -t "$timestamp" $jar
+          done
+
+      # scalapbは.protoの再コンパイルの必要性を判定する際にタイムスタンプを見ているから、コミット時刻に合わせる
+      - name: Restore protocol timestamps
+        ## 参考: https://qiita.com/tomlla/items/219cea9dd071c8a9e147
+        run: |
+          for proto in protocol/*.proto; do
+            timestamp=`git log -1 --pretty=format:'%cd' --date=format:'%Y%m%d%H%M.%S' $proto`
+            touch -t "$timestamp" $proto
+          done
+
+      - name: Check format with Scalafmt
+        run: ./sbt scalafmtCheckAll
+
+      - name: Check lint with Scalafix on push
+        run: ./sbt "scalafix --check"
+
+      - name: Test and build artifact
+        run: mkdir -p target/build && ./sbt assembly
+
+      - name: Clean build artifact for caching target folder
+        run: rm -r target/build
diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml
index dbd30c1b0a..b31315ac90 100644
--- a/.github/workflows/build_and_deploy.yml
+++ b/.github/workflows/build_and_deploy.yml
@@ -5,7 +5,6 @@ on:
     branches:
       - develop
       - master
-
   pull_request:
     branches:
       - develop
@@ -14,8 +13,8 @@ jobs:
   build_test_and_upload:
     env:
       BUILD_ENVIRONMENT_IS_CI_OR_LOCAL: "CI"
-    runs-on: ubuntu-22.04
-    container: ghcr.io/giganticminecraft/seichiassist-builder:1a64049
+    runs-on: ubuntu-24.04
+    container: ghcr.io/giganticminecraft/seichiassist-builder-v2:1df7cf5
     steps:
       - name: Checkout repository
         uses: actions/checkout@v4
@@ -23,7 +22,7 @@ jobs:
           submodules: 'recursive'
 
       - name: Prepare build dependencies cache
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         env:
           cache-name: cache-build-dependencies
           cache-version: v-5
@@ -47,7 +46,7 @@ jobs:
 
       - name: Prepare build cache
         if: github.ref != 'refs/heads/master'
-        uses: actions/cache@v3
+        uses: actions/cache@v4
         env:
           cache-name: cache-build
           cache-version: v-5
@@ -68,6 +67,8 @@ jobs:
       - name: Restore localDependencies' timestamps
         # 参考: https://qiita.com/tomlla/items/219cea9dd071c8a9e147
         run: |
+          git config --global --add safe.directory /__w/SeichiAssist/SeichiAssist
+          
           for jar in localDependencies/*.jar; do
             timestamp=`git log -1 --pretty=format:'%cd' --date=format:'%Y%m%d%H%M.%S' $jar`
             touch -t "$timestamp" $jar
@@ -102,7 +103,7 @@ jobs:
           github-token: ${{ secrets.GITHUB_TOKEN }}
 
       - name: Test and build artifact
-        run: sbt assembly
+        run: mkdir -p target/build && sbt assembly
 
       - name: Upload artifact
         uses: actions/upload-artifact@v4
@@ -125,7 +126,7 @@ jobs:
 
   output-sha:
     name: 最終コミットのSHA値を取得する
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
     outputs:
       sha: ${{ steps.output-sha.outputs.sha }}
     steps:
@@ -140,7 +141,7 @@ jobs:
 
   create_prerelease:
     name: GitHub ReleasesにPreReleaseを作成する
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
     if: github.ref == 'refs/heads/develop'
     needs:
       - build_test_and_upload
@@ -171,7 +172,7 @@ jobs:
           prerelease: true
 
   push_artifact_to_debug_server_definition:
-    runs-on: ubuntu-22.04
+    runs-on: ubuntu-24.04
     if: github.ref == 'refs/heads/develop'
     needs:
       - build_test_and_upload
@@ -237,7 +238,7 @@ jobs:
           avatar_url: ${{ secrets.DISCORD_AVATAR_URL }}
 
   deploy_artifact_to_production:
-    runs-on: ubuntu-22.04
+    runs-on: ubuntu-24.04
     if: github.ref == 'refs/heads/master'
     needs:
       - build_test_and_upload
diff --git a/.github/workflows/check-sql-version-duplicated-files.yml b/.github/workflows/check-sql-version-duplicated-files.yml
index 73588d78fe..2a3ef1e724 100644
--- a/.github/workflows/check-sql-version-duplicated-files.yml
+++ b/.github/workflows/check-sql-version-duplicated-files.yml
@@ -15,7 +15,7 @@ on:
       - .github/workflows/check-sql-version-duplicated-files.yml
 jobs:
   check:
-    runs-on: ubuntu-22.04
+    runs-on: ubuntu-24.04
     steps:
       - name: Checkout repository
         uses: actions/checkout@v4
diff --git a/.github/workflows/create_1_18_release.yml b/.github/workflows/create_1_18_release.yml
new file mode 100644
index 0000000000..575bffcb3f
--- /dev/null
+++ b/.github/workflows/create_1_18_release.yml
@@ -0,0 +1,111 @@
+name: Create 1.18 release
+
+on:
+  pull_request:
+    paths:
+      - src/**
+      - build.sbt
+      - .scalafix.conf
+      - .scalafmt.conf
+      - project/*
+      - .github/workflows/**.yml
+      - .github/actions/**/**.yml
+
+jobs:
+  create_release:
+    runs-on: ubuntu-24.04
+    container: ghcr.io/giganticminecraft/seichiassist-builder-v2:1df7cf5
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+        with:
+          submodules: 'recursive'
+
+      - name: Prepare build dependencies cache
+        uses: actions/cache@v4
+        env:
+          cache-name: cache-build-dependencies
+          cache-version: v-5
+        with:
+          # sbt等は$HOMEではなくユーザーディレクトリを見ているようで、
+          # GH Actionsでの ~ は /github/home/ に展開されるにもかかわらず
+          # 実際のキャッシュは /root/ 以下に配備される。
+          #
+          # /root/.ivy/cache, /root/.sbt - sbt関連のキャッシュ
+          # /root/.m2 - ビルドログを観察した感じprotoc等はここを利用する
+          # /root/.cache - cousierがscalasbt等をキャッシュするのに使っている
+          path: |
+            /root/.ivy2/cache
+            /root/.sbt
+            /root/.m2
+            /root/.cache
+          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-${{ github.ref }}-${{ hashFiles('**/build.sbt') }}
+          restore-keys: |
+            ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-${{ github.ref }}-
+            ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-
+
+      - name: Prepare build cache
+        if: github.ref != 'refs/heads/master'
+        uses: actions/cache@v4
+        env:
+          cache-name: cache-build
+          cache-version: v-5
+        with:
+          path: |
+            target
+            project/target
+            project/project/target
+          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-${{ github.ref }}-${{ github.sha }}
+          restore-keys: |
+            ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-${{ github.ref }}-
+            ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-
+
+      # CIでのcheckoutはファイルのタイムスタンプをチェックアウト時刻に設定するため、
+      # そのままビルドするとlocalDependenciesにあるjarに変更が行われたと見なされ
+      # 不要なインクリメンタルコンパイルが走る
+      # タイムスタンプをコミット時刻に設定することでこれが回避できる
+      - name: Restore localDependencies' timestamps
+        # 参考: https://qiita.com/tomlla/items/219cea9dd071c8a9e147
+        run: |
+          git config --global --add safe.directory /__w/SeichiAssist/SeichiAssist
+          for jar in localDependencies/*.jar; do
+            timestamp=`git log -1 --pretty=format:'%cd' --date=format:'%Y%m%d%H%M.%S' $jar`
+            touch -t "$timestamp" $jar
+          done
+
+      # scalapbは.protoの再コンパイルの必要性を判定する際にタイムスタンプを見ているから、コミット時刻に合わせる
+      - name: Restore protocol timestamps
+        ## 参考: https://qiita.com/tomlla/items/219cea9dd071c8a9e147
+        run: |
+          for proto in protocol/*.proto; do
+            timestamp=`git log -1 --pretty=format:'%cd' --date=format:'%Y%m%d%H%M.%S' $proto`
+            touch -t "$timestamp" $proto
+          done
+
+      # sbt-assembly 2以降からディレクトリを作ってくれなくなった
+      - name: Build artifact
+        run: mkdir -p target/build && ./sbt assembly
+
+      - name: Create and push a tag
+        id: tag-name
+        # GiganticMinecraftにあるSeichiAssistリポジトリのブランチからのPRのみ実行
+        if: ${{ github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name }}
+        run: |
+          TAG_NAME=pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}
+          git tag $TAG_NAME
+          git push origin $TAG_NAME
+          echo "value=$TAG_NAME" >> $GITHUB_OUTPUT
+
+      - name: Create release
+        uses: softprops/action-gh-release@v1
+        # GiganticMinecraftにあるSeichiAssistリポジトリのブランチからのPRのみ実行
+        if: ${{ github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name }}
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          files: target/build/SeichiAssist.jar
+          tag_name: ${{ steps.tag-name.outputs.value }}
+          draft: false
+
+      - name: Clean build artifact for caching target folder
+        run: rm -r target/build
diff --git a/.github/workflows/create_new_release.yml b/.github/workflows/create_new_release.yml
index 9d8fa2b7cd..1119dc135d 100644
--- a/.github/workflows/create_new_release.yml
+++ b/.github/workflows/create_new_release.yml
@@ -5,7 +5,7 @@ on:
 
 jobs:
   get_branch_name:
-    runs-on: ubuntu-22.04
+    runs-on: ubuntu-24.04
     outputs:
       value: ${{ steps.job.outputs.value }}
     steps:
@@ -14,7 +14,7 @@ jobs:
         run: echo "value=$(echo ${GITHUB_REF#refs/heads/})" >> $GITHUB_OUTPUT
 
   bump_version:
-    runs-on: ubuntu-22.04
+    runs-on: ubuntu-24.04
     needs: get_branch_name
     outputs:
       old_version: ${{ steps.bump.outputs.old_version }}
@@ -72,21 +72,21 @@ jobs:
             HEAD:${{ needs.get_branch_name.outputs.value }}
 
   create_release:
-    runs-on: ubuntu-22.04
+    runs-on: ubuntu-24.04
     needs: bump_version
     steps:
       - uses: actions/checkout@master
         with:
           # これがないとchunk_searchで引っかかってリリースのjarアップロードに失敗する
-          submodules: 'recursive'
+          submodules: "recursive"
 
       - uses: actions/setup-java@v4
         with:
-          distribution: 'temurin'
-          java-version: '8'
+          distribution: "temurin"
+          java-version: "17"
 
       - name: build artifacts
-        run: sbt assembly
+        run: mkdir -p target/build && sbt assembly
 
       - name: Create release
         id: create_release
@@ -100,7 +100,7 @@ jobs:
           prerelease: false
 
   create_pull-request_to_master:
-    runs-on: ubuntu-22.04
+    runs-on: ubuntu-24.04
     needs: [get_branch_name, bump_version]
     steps:
       - uses: actions/checkout@master
diff --git a/.github/workflows/publish_develop_builds.yml b/.github/workflows/publish_develop_builds.yml
new file mode 100644
index 0000000000..e72d05e0b6
--- /dev/null
+++ b/.github/workflows/publish_develop_builds.yml
@@ -0,0 +1,18 @@
+name: publish develop build
+
+on:
+  push:
+    branches:
+      - develop
+
+jobs:
+  publish_build:
+    runs-on: ubuntu-24.04
+    steps:
+      - name: Publish develop build
+        env:
+          SEICHIASSIST_DOWNLOADER_TOKEN: ${{ secrets.SEICHIASSIST_DOWNLOADER_TOKEN }}
+        run: |
+          curl -s -X 'POST' 'http://localhost/publish/develop' \
+          -H 'accept: */*' \
+          -H 'Authorization: Bearer $SEICHIASSIST_DOWNLOADER_TOKEN'
diff --git a/.github/workflows/publish_stable_builds.yml b/.github/workflows/publish_stable_builds.yml
new file mode 100644
index 0000000000..0b00893ede
--- /dev/null
+++ b/.github/workflows/publish_stable_builds.yml
@@ -0,0 +1,18 @@
+name: publish stable build
+
+on:
+  push:
+    branches:
+      - master
+
+jobs:
+  publish_build:
+    runs-on: ubuntu-24.04
+    steps:
+      - name: Publish stable build
+        env:
+          SEICHIASSIST_DOWNLOADER_TOKEN: ${{ secrets.SEICHIASSIST_DOWNLOADER_TOKEN }}
+        run: |
+          curl -s -X 'POST' 'http://localhost/publish/stable' \
+          -H 'accept: */*' \
+          -H 'Authorization: Bearer $SEICHIASSIST_DOWNLOADER_TOKEN'
diff --git a/.gitignore b/.gitignore
index bade594553..36e104a5a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,7 +13,8 @@
 
 # Local files
 deployLocal.sh
-localDependencies/spigot-1.12.2.jar
+localDependencies/spigot-1.18.2.jar
+plugins/*
 
 # Docker
 docker/spigot/serverfiles/eula.txt
@@ -25,3 +26,6 @@ docker/spigot/serverfiles/eula.txt
 .metals
 project/.bloop/
 project/metals.sbt
+
+# scalac に -Yprofile-trace profile.trace を渡しているので、Chrome Trace file が生成される
+/profile.trace
diff --git a/.java-version b/.java-version
new file mode 100644
index 0000000000..c7604a4e6f
--- /dev/null
+++ b/.java-version
@@ -0,0 +1 @@
+17.0.10
diff --git a/.scalafmt.conf b/.scalafmt.conf
index 1083745791..5701df8ade 100644
--- a/.scalafmt.conf
+++ b/.scalafmt.conf
@@ -1,4 +1,4 @@
-version = 3.4.3
+version = 3.8.3
 preset=IntelliJ
 runner.dialect = scala213
 
diff --git a/CODING_GUIDELINE.md b/CODING_GUIDELINE.md
index efbdef77c5..2de468f9c9 100644
--- a/CODING_GUIDELINE.md
+++ b/CODING_GUIDELINE.md
@@ -3,7 +3,7 @@
 ## \[Scala\] nullを使わない
 Scalaのファイルにおいては、`null`を使用する代わりに`Option`を使用してください。
 
-Java (特に、Bukkit/Spigot API) から入ってきた値が`null`になる可能性がある場合は、その呼び出しを早いうちに[`Option(...)`](https://www.scala-lang.org/api/2.13.4/scala/Option$.html#apply[A](x:A):Option[A])で囲い、`Option`にすることが推奨されます。この呼び出しで、引数が`null`だった場合は`None`に、そうでなかった場合は`Some(...)`になります。
+Java (特に、Bukkit/Spigot API) から入ってきた値が`null`になる可能性がある場合は、その呼び出しを早いうちに[`Option(...)`](https://www.scala-lang.org/api/2.13.14/scala/Option$.html#apply[A](x:A):Option[A])で囲い、`Option`にすることが推奨されます。この呼び出しで、引数が`null`だった場合は`None`に、そうでなかった場合は`Some(...)`になります。
 
 ## \[Scala\] 例外を使わない
 例外の代わりに`Either`を使用してください。`Either`を使用すると低コストで合成を行うことができるためです。
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 209f3292d6..c9b19c70f4 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,18 +2,18 @@
 
 ## 開発を始めるために必要なもの
 - [IntelliJ IDEA](https://www.jetbrains.com/idea/) などの統合開発環境
-- [JDK 8](https://adoptopenjdk.net/?variant=openjdk8&jvmVariant=hotspot)
+- [AdoptOpenJDK 17](https://adoptium.net/temurin/releases/?version=17)
 - [sbt 1.9](https://www.scala-sbt.org/1.x/docs/Setup.html)
 - [Scala 2.13](https://www.scala-lang.org/download/)
-- Spigot 1.12.2
+- Spigot 1.18.2
 - Docker
 - GitHubのアカウント
 - Git
 
 ### 準備
 #### Java Development Kit
-最初に、Java Development Kit (JDK) 8をインストールする必要があります。
-[AdoptOpenJDK 1.8](https://adoptopenjdk.net/?variant=openjdk8&jvmVariant=hotspot) のインストールを推奨します。
+最初に、Java Development Kit (JDK) 17をインストールする必要があります。
+[AdoptOpenJDK 17](https://adoptium.net/temurin/releases/?version=17) のインストールを推奨します。
 
 #### 統合開発環境
 次に、[IntelliJ IDEA](https://www.jetbrains.com/idea/)などの統合開発環境を導入します。
@@ -63,7 +63,7 @@ GitHubにアカウントを[登録](https://github.com/join)します。
 
 ```bash
 $ rm -rf target/build # 再ビルドしたいなら既存のターゲットは削除
-$ docker run --rm -it -v `pwd`:/app ghcr.io/giganticminecraft/seichiassist-builder:1a64049 sh -c "cd /app && sbt assembly"
+$ docker run --rm -it -v `pwd`:/app ghcr.io/giganticminecraft/seichiassist-builder-v2:1df7cf5 sh -c "cd /app && sbt assembly"
 $ sudo chown -R `whoami` target/build # docker上でsbtを実行するとrootになってしまうため権限を変える
 $ cp -n docker/spigot/eula.txt docker/spigot/serverfiles/eula.txt || true
 $ docker compose up --build -d
@@ -152,6 +152,10 @@ IntelliJ IDEAの設定でフォーマットに `scalafmt` を使う
 #### 手元でデバッグ
 SeichiAssistは手元でデバッグできる環境を整えています。環境を立ち上げるためには、Dockerが必要です。
 
+/pluginsディレクトリに対してjarファイル配置すると、そのjarファイルとSeichiAssistを同時に起動した場合の動作を確認することができます。
+整地鯖で利用しているプラグインはGiganticMinecraftのメンバーのみ[MinIOからダウンロード](https://minio-console.onp-k8s.admin.seichi.click/browser/seichi-plugins/ZGViLTEtMTYtNS8=)することができます。
+接続情報などの詳しい情報は、Discordで聞いてください。
+
 ##### Dockerを立ち上げる
 
 Linux環境では、`./prepare-docker.sh`、Windowsでは`prepare-docker.bat`を実行することで
@@ -167,7 +171,7 @@ Linux環境では、`./prepare-docker.sh`、Windowsでは`prepare-docker.bat`を
 
 サーバーやDB等を停止する場合、 `docker compose down` を実行してください。
 
-なお、SeichiAssistがJDK 8以外でコンパイルされた場合は、実行時にエラーとなります。必ずJDKのバージョンを揃えるようにしてください。
+なお、SeichiAssistがJava 17未満でコンパイルされた場合は、実行時にエラーとなります。必ずJDKのバージョンを揃えるようにしてください。
 
 
 ##### デバッグ用環境への接続
diff --git a/README.md b/README.md
index 1ef9bf3a88..632f0bcc5f 100644
--- a/README.md
+++ b/README.md
@@ -3,14 +3,14 @@
 [![GitHub Actions](https://github.com/GiganticMinecraft/SeichiAssist/actions/workflows/build_and_deploy.yml/badge.svg)](https://github.com/GiganticMinecraft/SeichiAssist/actions/workflows/build_and_deploy.yml)
 
 ## 前提プラグイン
-- [CoreProtect-2.14.4](https://www.spigotmc.org/resources/coreprotect.8631/download?version=231781)
-- [item-nbt-api-plugin-1.8.2-SNAPSHOT](https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/download?version=241690)
-- [Multiverse-Core-2.5.0](https://dev.bukkit.org/projects/multiverse-core/files/2428161/download)
-- [Multiverse-Portals-2.5.0](https://dev.bukkit.org/projects/multiverse-portals/files/2428333/download)
+- [CoreProtect-2.15.0](https://www.spigotmc.org/resources/coreprotect.8631/download?version=231781)
+- [item-nbt-api-plugin-2.11.2](https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/download?version=241690)
+- [Multiverse-Core-4.3.1](https://dev.bukkit.org/projects/multiverse-core/files/2428161/download)
+- [Multiverse-Portals-4.2.1](https://dev.bukkit.org/projects/multiverse-portals/files/2428333/download)
 - [ParticleAPI_v2.1.1](https://dl.inventivetalent.org/download/?file=plugin/ParticleAPI_v2.1.1)
-- [WorldBorder1.8.7](https://dev.bukkit.org/projects/worldborder/files/2415838/download)
-- [worldedit-bukkit-6.1.9](https://dev.bukkit.org/projects/worldedit/files/2597538/download)
-- [worldguard-bukkit-6.2.2](https://dev.bukkit.org/projects/worldguard/files/2610618/download)
+- [WorldBorder1.9.10 (beta)](https://www.spigotmc.org/resources/worldborder.60905/download?version=275003)
+- [worldedit-bukkit-7.0.0](https://dev.bukkit.org/projects/worldedit/files/2597538/download)
+- [worldguard-bukkit-7.0.0](https://dev.bukkit.org/projects/worldguard/files/2610618/download)
 
 ## 前提プラグイン(整地鯖内製)
 - RegenWorld [リポジトリ](https://github.com/GiganticMinecraft/RegenWorld) | [jar](https://redmine.seichi.click/attachments/download/890/RegenWorld-1.0.jar)
diff --git a/build.sbt b/build.sbt
index fa7972da82..0f1991b877 100644
--- a/build.sbt
+++ b/build.sbt
@@ -5,7 +5,7 @@ import java.io._
 
 // region 全プロジェクト共通のメタデータ
 
-ThisBuild / scalaVersion := "2.13.12"
+ThisBuild / scalaVersion := "2.13.14"
 // ThisBuild / version はGitHub Actionsによって取得/自動更新される。
 // 次の行は ThisBuild / version := "(\d*)" の形式でなければならない。
 ThisBuild / version := "89"
@@ -23,7 +23,7 @@ ThisBuild / scalafixScalaBinaryVersion :=
 // region 雑多な設定
 
 // kind-projector 構文を使いたいため
-addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.13.2" cross CrossVersion.full)
+addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.13.3" cross CrossVersion.full)
 
 // CIビルドで詳細なログを確認するため
 ThisBuild / logLevel := {
@@ -58,22 +58,28 @@ resolvers ++= Seq(
 
 val providedDependencies = Seq(
   "org.jetbrains" % "annotations" % "24.1.0",
-  "org.spigotmc" % "spigot-api" % "1.12.2-R0.1-SNAPSHOT",
+  "org.apache.commons" % "commons-lang3" % "3.17.0",
+  "commons-codec" % "commons-codec" % "1.17.1",
+  "org.spigotmc" % "spigot-api" % "1.18.2-R0.1-SNAPSHOT",
   // https://maven.enginehub.org/repo/com/sk89q/worldedit/worldedit-bukkit/
-  "com.sk89q.worldguard" % "worldguard-legacy" % "6.2",
-  "net.coreprotect" % "coreprotect" % "2.14.2",
-  "com.mojang" % "authlib" % "1.6.25",
+  "com.sk89q.worldguard" % "worldguard-bukkit" % "7.0.7",
+  "net.coreprotect" % "coreprotect" % "21.3",
+  "com.mojang" % "authlib" % "6.0.55",
 
   // no runtime
   "org.typelevel" %% "simulacrum" % "1.0.1"
 ).map(_ % "provided")
 
 val scalafixCoreDep =
-  "ch.epfl.scala" %% "scalafix-core" % _root_.scalafix.sbt.BuildInfo.scalafixVersion % ScalafixConfig
+  "ch.epfl.scala" %% "scalafix-core" % _root_
+    .scalafix
+    .sbt
+    .BuildInfo
+    .scalafixVersion % ScalafixConfig
 
 val testDependencies = Seq(
   "org.scalamock" %% "scalamock" % "5.2.0",
-  "org.scalatest" %% "scalatest" % "3.2.17",
+  "org.scalatest" %% "scalatest" % "3.2.19",
   "org.scalatestplus" %% "scalacheck-1-14" % "3.2.2.0",
   // テスト用のTestSchedulerを使うため
   "io.monix" %% "monix" % "3.4.1"
@@ -84,16 +90,17 @@ val dependenciesToEmbed = Seq(
 
   // DB
   "org.mariadb.jdbc" % "mariadb-java-client" % "3.4.1",
-  "org.flywaydb" % "flyway-core" % "5.2.4",
-  "org.scalikejdbc" %% "scalikejdbc" % "3.5.0",
+  "org.flywaydb" % "flyway-core" % "10.19.0",
+  "org.flywaydb" % "flyway-mysql" % "10.19.0",
+  "org.scalikejdbc" %% "scalikejdbc" % "4.3.2",
 
   // redis
   "com.github.etaty" %% "rediscala" % "1.9.0",
 
   // effect system
-  "org.typelevel" %% "cats-core" % "2.10.0",
+  "org.typelevel" %% "cats-core" % "2.12.0",
   "org.typelevel" %% "cats-effect" % "2.5.5",
-  "co.fs2" %% "fs2-core" % "2.5.11",
+  "co.fs2" %% "fs2-core" % "2.5.12",
 
   // algebra
   "io.chrisdavenport" %% "log4cats-core" % "1.1.1",
@@ -106,22 +113,22 @@ val dependenciesToEmbed = Seq(
   "com.typesafe.scala-logging" % "scala-logging-slf4j_2.10" % "2.1.2",
 
   // type-safety utils
-  "eu.timepit" %% "refined" % "0.11.0",
+  "eu.timepit" %% "refined" % "0.11.2",
   "com.beachape" %% "enumeratum" % "1.7.4",
 
   // protobuf
   "com.thesamet.scalapb" %% "scalapb-runtime" % scalapb.compiler.Version.scalapbVersion,
 
   // JSON
-  "io.circe" %% "circe-core" % "0.14.6",
-  "io.circe" %% "circe-generic" % "0.14.6",
-  "io.circe" %% "circe-parser" % "0.14.6",
+  "io.circe" %% "circe-core" % "0.14.10",
+  "io.circe" %% "circe-generic" % "0.14.10",
+  "io.circe" %% "circe-parser" % "0.14.10",
 
   // ajd4jp
   "com.github.KisaragiEffective" % "ajd4jp-mirror" % "8.0.2.2021",
 
   // Sentry
-  "io.sentry" % "sentry" % "7.12.1"
+  "io.sentry" % "sentry" % "7.18.1"
 )
 
 // endregion
@@ -141,6 +148,8 @@ assembly / assemblyExcludedJars := {
 // protocol配下とルートのLICENSEが衝突してCIが落ちる
 // cf. https://github.com/sbt/sbt-assembly/issues/141
 assembly / assemblyMergeStrategy := {
+  // cf. https://qiita.com/yokra9/items/1e72646623f962ce02ee と ChatGPTに聞いた
+  case PathList("META-INF", "versions", "9", "module-info.class") => MergeStrategy.discard
   case PathList(ps @ _*) if ps.last endsWith "LICENSE" => MergeStrategy.rename
   case PathList("org", "apache", "commons", "logging", xs @ _*) =>
     MergeStrategy.last
@@ -196,6 +205,8 @@ lazy val root = (project in file(".")).settings(
   excludeDependencies := Seq(ExclusionRule(organization = "org.bukkit", name = "bukkit")),
   unmanagedBase := baseDirectory.value / "localDependencies",
   scalacOptions ++= Seq(
+    "-Yprofile-trace",
+    "profile.trace",
     "-encoding",
     "utf8",
     "-unchecked",
@@ -208,7 +219,11 @@ lazy val root = (project in file(".")).settings(
   ),
   javacOptions ++= Seq("-encoding", "utf8"),
   assembly / assemblyShadeRules ++= Seq(
-    ShadeRule.rename("org.mariadb.jdbc.**" -> "com.github.unchama.seichiassist.relocateddependencies.org.mariadb.jdbc.@1").inAll
+    ShadeRule
+      .rename(
+        "org.mariadb.jdbc.**" -> "com.github.unchama.seichiassist.relocateddependencies.org.mariadb.jdbc.@1"
+      )
+      .inAll
   ),
   // sbt-assembly 1.0.0からはTestを明示的にタスクツリーに入れる必要がある
   // cf. https://github.com/sbt/sbt-assembly/pull/432/commits/361224a6202856bc2e572df811d0e6a1f1efda98
diff --git a/compose.yml b/compose.yml
index 386425942b..b9306adc4a 100644
--- a/compose.yml
+++ b/compose.yml
@@ -21,9 +21,9 @@ services:
       - "25566:25565"
       - "7091:7091"
     environment:
-      - VERSION=1.12.2
+      - VERSION=1.18.2
       - EULA=TRUE
-      - TYPE=SPIGOT
+      - TYPE=PAPER
       - ONLINE_MODE=FALSE
       - ENABLE_JMX=true
       - JMX_PORT=7091
@@ -51,9 +51,9 @@ services:
       - "25567:25565"
       - "7092:7091"
     environment:
-      - VERSION=1.12.2
+      - VERSION=1.18.2
       - EULA=TRUE
-      - TYPE=SPIGOT
+      - TYPE=PAPER
       - ONLINE_MODE=FALSE
       - ENABLE_JMX=true
       - JMX_PORT=7091
@@ -70,7 +70,7 @@ services:
       - redis
     stdin_open: true
   bungeecord:
-    image: itzg/bungeecord:java8
+    image: itzg/bungeecord:java17
     ports:
       - "25565:25577"
     volumes:
diff --git a/docker/mariadb/Dockerfile b/docker/mariadb/Dockerfile
index 63f4614a66..d4daa689cd 100644
--- a/docker/mariadb/Dockerfile
+++ b/docker/mariadb/Dockerfile
@@ -1,5 +1,5 @@
-# syntax=docker/dockerfile:1.9
-FROM mariadb:10.11.6
+# syntax=docker/dockerfile:1.10
+FROM mariadb:10.11.9
 
 WORKDIR /docker-entrypoint-initdb.d
 
diff --git a/docker/spigot/Dockerfile b/docker/spigot/Dockerfile
index 15b0d13acd..43e81c47c3 100644
--- a/docker/spigot/Dockerfile
+++ b/docker/spigot/Dockerfile
@@ -1,28 +1,26 @@
-# syntax=docker/dockerfile:1.9
-FROM ghcr.io/giganticminecraft/chunk-search-rs:sha-598517c as chunk-search-provider
-FROM ghcr.io/giganticminecraft/seichiassist-runner:ba2aa54
+# syntax=docker/dockerfile:1.10
+FROM ghcr.io/giganticminecraft/chunk-search-rs:sha-f1943b1 as chunk-search-provider
+FROM ghcr.io/giganticminecraft/seichiassist-runner-v2:890105f
+FROM mikefarah/yq:4.44.3 as yq
 
-FROM itzg/minecraft-server:java8-multiarch
+FROM itzg/minecraft-server:java17-jdk
 
-# JDKとnkfをインストール
-RUN apt-get update && apt-get install -y \
-    nkf \
-    openjdk-8-jdk \
-&& apt-get clean \
-&& rm -rf /var/lib/apt/lists/*
+# nkfをインストール
+RUN apt-get update && apt-get install -y nkf \
+    && apt-get clean \
+    && rm -rf /var/lib/apt/lists/*
 
 #yqをインストール
-RUN curl -LJO https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 && \
-mv yq_linux_amd64 /usr/local/bin/yq && \
-chmod a+x /usr/local/bin/yq
+COPY --from=yq /usr/bin/yq /usr/bin/yq
 
 # chunk-search-rsをインストール
 COPY --link --from=chunk-search-provider /build/chunk-search-rs /usr/bin/chunk-search-rs
 
 # プラグインとスクリプトをローカルからコピーする
-COPY --link ./localDependencies/ /data/plugins/
 COPY --link ./target/build/ /SeichiAssist/
 COPY --link ./docker/spigot/ /data/
+ADD ./localDependencies/ /data/plugins/
+ADD ./plugins /plugins
 
 RUN chmod a+x /data/update-seichiassist.sh
 RUN nkf -Lu --overwrite /data/update-seichiassist.sh
diff --git a/docker/spigot/spigot.yml b/docker/spigot/spigot.yml
new file mode 100644
index 0000000000..ff92ba13da
--- /dev/null
+++ b/docker/spigot/spigot.yml
@@ -0,0 +1,171 @@
+# This is the main configuration file for Spigot.
+# As you can see, there's tons to configure. Some options may impact gameplay, so use
+# with caution, and make sure you know what each option does before configuring.
+# For a reference for any variable inside this file, check out the Spigot wiki at
+# http://www.spigotmc.org/wiki/spigot-configuration/
+#
+# If you need help with the configuration or have any questions related to Spigot,
+# join us at the Discord or drop by our forums and leave a post.
+#
+# Discord: https://www.spigotmc.org/go/discord
+# Forums: http://www.spigotmc.org/
+
+messages:
+  whitelist: You are not whitelisted on this server!
+  unknown-command: Unknown command. Type "/help" for help.
+  server-full: The server is full!
+  outdated-client: Outdated client! Please use {0}
+  outdated-server: Outdated server! I'm still on {0}
+  restart: Server is restarting
+advancements:
+  disable-saving: false
+  disabled:
+  - minecraft:story/disabled
+settings:
+  sample-count: 12
+  bungeecord: true
+  player-shuffle: 0
+  user-cache-size: 1000
+  save-user-cache-on-stop-only: false
+  moved-wrongly-threshold: 0.0625
+  moved-too-quickly-multiplier: 10.0
+  timeout-time: 60
+  restart-on-crash: true
+  restart-script: ./start.sh
+  netty-threads: 4
+  attribute:
+    maxHealth:
+      max: 2048.0
+    movementSpeed:
+      max: 2048.0
+    attackDamage:
+      max: 2048.0
+  log-villager-deaths: true
+  log-named-deaths: true
+  debug: false
+players:
+  disable-saving: false
+commands:
+  spam-exclusions:
+  - /skill
+  silent-commandblock-console: false
+  replace-commands:
+  - setblock
+  - summon
+  - testforblock
+  - tellraw
+  log: true
+  tab-complete: 0
+  send-namespaced: true
+config-version: 12
+stats:
+  disable-saving: false
+  forced-stats: {}
+world-settings:
+  default:
+    below-zero-generation-in-existing-chunks: true
+    verbose: false
+    merge-radius:
+      exp: 3.0
+      item: 2.5
+    growth:
+      cactus-modifier: 100
+      cane-modifier: 100
+      melon-modifier: 100
+      mushroom-modifier: 100
+      pumpkin-modifier: 100
+      sapling-modifier: 100
+      beetroot-modifier: 100
+      carrot-modifier: 100
+      potato-modifier: 100
+      wheat-modifier: 100
+      netherwart-modifier: 100
+      vine-modifier: 100
+      cocoa-modifier: 100
+      bamboo-modifier: 100
+      sweetberry-modifier: 100
+      kelp-modifier: 100
+      twistingvines-modifier: 100
+      weepingvines-modifier: 100
+      cavevines-modifier: 100
+      glowberry-modifier: 100
+    entity-activation-range:
+      animals: 32
+      monsters: 32
+      raiders: 48
+      misc: 16
+      water: 16
+      villagers: 32
+      flying-monsters: 32
+      wake-up-inactive:
+        animals-max-per-tick: 4
+        animals-every: 1200
+        animals-for: 100
+        monsters-max-per-tick: 8
+        monsters-every: 400
+        monsters-for: 100
+        villagers-max-per-tick: 4
+        villagers-every: 600
+        villagers-for: 100
+        flying-monsters-max-per-tick: 8
+        flying-monsters-every: 200
+        flying-monsters-for: 100
+      villagers-work-immunity-after: 100
+      villagers-work-immunity-for: 20
+      villagers-active-for-panic: true
+      tick-inactive-villagers: true
+      ignore-spectators: false
+    entity-tracking-range:
+      players: 48
+      animals: 48
+      monsters: 48
+      misc: 32
+      other: 64
+    ticks-per:
+      hopper-transfer: 8
+      hopper-check: 1
+    hopper-amount: 1
+    dragon-death-sound-radius: 0
+    seed-village: 10387312
+    seed-desert: 14357617
+    seed-igloo: 14357618
+    seed-jungle: 14357619
+    seed-swamp: 14357620
+    seed-monument: 10387313
+    seed-shipwreck: 165745295
+    seed-ocean: 14357621
+    seed-outpost: 165745296
+    seed-endcity: 10387313
+    seed-slime: 987234911
+    seed-nether: 30084232
+    seed-mansion: 10387319
+    seed-fossil: 14357921
+    seed-portal: 34222645
+    seed-stronghold: default
+    hunger:
+      jump-walk-exhaustion: 0.05
+      jump-sprint-exhaustion: 0.2
+      combat-exhaustion: 0.1
+      regen-exhaustion: 6.0
+      swim-multiplier: 0.01
+      sprint-multiplier: 0.1
+      other-multiplier: 0.0
+    max-tnt-per-tick: 100
+    max-tick-time:
+      tile: 50
+      entity: 50
+    arrow-despawn-rate: 1200
+    trident-despawn-rate: 1200
+    hanging-tick-frequency: 100
+    view-distance: default
+    simulation-distance: default
+    thunder-chance: 100000
+    item-despawn-rate: 6000
+    enable-zombie-pigmen-portal-spawns: true
+    nerf-spawner-mobs: false
+    wither-spawn-sound-radius: 0
+    zombie-aggressive-towards-villager: true
+    mob-spawn-range: 8
+    end-portal-sound-radius: 0
+  worldeditregentempworld:
+    verbose: false
diff --git a/localDependencies/Multiverse-Core-2.5.0.jar b/localDependencies/Multiverse-Core-2.5.0.jar
deleted file mode 100644
index bb694d66ae..0000000000
Binary files a/localDependencies/Multiverse-Core-2.5.0.jar and /dev/null differ
diff --git a/localDependencies/Multiverse-Core-4.3.1.jar b/localDependencies/Multiverse-Core-4.3.1.jar
new file mode 100644
index 0000000000..09b089552f
Binary files /dev/null and b/localDependencies/Multiverse-Core-4.3.1.jar differ
diff --git a/localDependencies/Multiverse-Portals-2.5.0.jar b/localDependencies/Multiverse-Portals-2.5.0.jar
deleted file mode 100644
index 1527c60b6a..0000000000
Binary files a/localDependencies/Multiverse-Portals-2.5.0.jar and /dev/null differ
diff --git a/localDependencies/Multiverse-Portals-4.2.1.jar b/localDependencies/Multiverse-Portals-4.2.1.jar
new file mode 100644
index 0000000000..f4ed83cc7c
Binary files /dev/null and b/localDependencies/Multiverse-Portals-4.2.1.jar differ
diff --git a/localDependencies/WorldBorder.jar b/localDependencies/WorldBorder.jar
index a6388760d2..151682c937 100644
Binary files a/localDependencies/WorldBorder.jar and b/localDependencies/WorldBorder.jar differ
diff --git a/localDependencies/item-nbt-api-plugin-1.8.2-SNAPSHOT.jar b/localDependencies/item-nbt-api-plugin-1.8.2-SNAPSHOT.jar
deleted file mode 100644
index 6c399eab4a..0000000000
Binary files a/localDependencies/item-nbt-api-plugin-1.8.2-SNAPSHOT.jar and /dev/null differ
diff --git a/localDependencies/item-nbt-api-plugin-2.11.2.jar b/localDependencies/item-nbt-api-plugin-2.11.2.jar
new file mode 100644
index 0000000000..f1f6904215
Binary files /dev/null and b/localDependencies/item-nbt-api-plugin-2.11.2.jar differ
diff --git a/localDependencies/worldedit-bukkit-6.1.9.jar b/localDependencies/worldedit-bukkit-6.1.9.jar
deleted file mode 100644
index fd5d0036f5..0000000000
Binary files a/localDependencies/worldedit-bukkit-6.1.9.jar and /dev/null differ
diff --git a/localDependencies/worldedit-bukkit-7.2.14.jar b/localDependencies/worldedit-bukkit-7.2.14.jar
new file mode 100644
index 0000000000..76af69ee03
Binary files /dev/null and b/localDependencies/worldedit-bukkit-7.2.14.jar differ
diff --git a/localDependencies/worldguard-bukkit-6.2.2.jar b/localDependencies/worldguard-bukkit-6.2.2.jar
deleted file mode 100644
index 2f615d493c..0000000000
Binary files a/localDependencies/worldguard-bukkit-6.2.2.jar and /dev/null differ
diff --git a/localDependencies/worldguard-bukkit-7.0.7-dist.jar b/localDependencies/worldguard-bukkit-7.0.7-dist.jar
new file mode 100644
index 0000000000..9c4ea0bb77
Binary files /dev/null and b/localDependencies/worldguard-bukkit-7.0.7-dist.jar differ
diff --git a/prepare-docker.bat b/prepare-docker.bat
index 8477178b7c..942f3069da 100644
--- a/prepare-docker.bat
+++ b/prepare-docker.bat
@@ -1,5 +1,5 @@
 call rd /s /q target\build
-
+mkdir target\build
 call sbt assembly || goto :onerror
 
 if "%1" == "update-gachadata" (
diff --git a/prepare-docker.sh b/prepare-docker.sh
index e64d5d8193..08214265d1 100755
--- a/prepare-docker.sh
+++ b/prepare-docker.sh
@@ -6,7 +6,7 @@ build_image() {
   rm -r target/build || true
 
   ## ソースコードからSeichiAssist.jarをビルド
-  ./sbt assembly
+  mkdir -p target/build && ./sbt assembly
 
   ## dockerイメージのビルド
   docker compose build -m 2g
diff --git a/project/build.properties b/project/build.properties
index ee4c672cd0..0b699c3052 100644
--- a/project/build.properties
+++ b/project/build.properties
@@ -1 +1 @@
-sbt.version=1.10.1
+sbt.version=1.10.2
diff --git a/project/plugins.sbt b/project/plugins.sbt
index afd81e0668..44e634dc07 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -1,8 +1,8 @@
 // プラグインJarを(依存関係にあるJarをすべて同梱して)出力するため
-addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0")
+addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.2.0")
 
 // Lintを掛けるため
-addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.11.1")
+addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.13.0")
 
 // コードフォーマットするため
 addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2")
diff --git a/project/scalapb.sbt b/project/scalapb.sbt
index 6bd8afeb02..318bd48b7a 100644
--- a/project/scalapb.sbt
+++ b/project/scalapb.sbt
@@ -1,3 +1,3 @@
-addSbtPlugin("com.thesamet" % "sbt-protoc" % "1.0.6")
+addSbtPlugin("com.thesamet" % "sbt-protoc" % "1.0.7")
 
-libraryDependencies += "com.thesamet.scalapb" %% "compilerplugin" % "0.11.14"
+libraryDependencies += "com.thesamet.scalapb" %% "compilerplugin" % "0.11.17"
diff --git a/sbt b/sbt
index f63a9ee5a7..a5ba7dc2c1 100755
--- a/sbt
+++ b/sbt
@@ -34,11 +34,11 @@
 
 set -o pipefail
 
-declare -r sbt_release_version="1.9.7"
-declare -r sbt_unreleased_version="1.9.7"
+declare -r sbt_release_version="1.10.2"
+declare -r sbt_unreleased_version="1.10.2"
 
-declare -r latest_213="2.13.12"
-declare -r latest_212="2.12.18"
+declare -r latest_213="2.13.14"
+declare -r latest_212="2.12.20"
 declare -r latest_211="2.11.12"
 declare -r latest_210="2.10.7"
 declare -r latest_29="2.9.3"
diff --git a/src/main/resources/db/migration/V1.18.2__Add_gachaevent_foreign_key.sql b/src/main/resources/db/migration/V1.18.2__Add_gachaevent_foreign_key.sql
new file mode 100644
index 0000000000..80be304b87
--- /dev/null
+++ b/src/main/resources/db/migration/V1.18.2__Add_gachaevent_foreign_key.sql
@@ -0,0 +1,7 @@
+USE seichiassist;
+
+-- V1.18.1 で外部キー制約を追加しようとしていたが、gacha_events テーブルに存在しない event_id を持つレコードが gachadata テーブルに存在していたため、外部キー制約の追加に失敗していた。
+-- しかし、マイグレーション自体は success になっていたので、このバージョンで外部キー制約を追加することで、不整合データを削除する。
+DELETE FROM gachadata WHERE event_id NOT IN (SELECT id FROM gacha_events) AND event_id IS NOT NULL;
+
+ALTER TABLE gachadata ADD FOREIGN KEY (event_id) REFERENCES gacha_events(id) ON DELETE CASCADE;
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 3def2e3633..99dfab09e6 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -2,7 +2,9 @@ name: @name@
 main: com.github.unchama.seichiassist.SeichiAssist
 version: @version@
 
-softdepend: [WorldGuard, CoreProtect]
+api-version: 1.18
+
+softdepend: [WorldGuard, CoreProtect, NBTAPI, Multiverse-Core, RegenWorld]
 
 loadbefore:
   # ワールドマイグレーション時にこれらプラグインのタスクがworldへの参照を持ちデータのGCが行われなくなる
diff --git a/src/main/scala/com/github/unchama/buildassist/BuildAssist.scala b/src/main/scala/com/github/unchama/buildassist/BuildAssist.scala
index 32072d60da..3201cd2419 100644
--- a/src/main/scala/com/github/unchama/buildassist/BuildAssist.scala
+++ b/src/main/scala/com/github/unchama/buildassist/BuildAssist.scala
@@ -11,6 +11,7 @@ import com.github.unchama.seichiassist.subsystems.buildcount.domain.playerdata.B
 import com.github.unchama.seichiassist.subsystems.mana.ManaApi
 import com.github.unchama.seichiassist.subsystems.managedfly.ManagedFlyApi
 import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.{DefaultEffectEnvironment, subsystems}
 import org.bukkit.entity.Player
 import org.bukkit.inventory.ItemStack
@@ -26,7 +27,8 @@ class BuildAssist(plugin: Plugin)(
   buildCountAPI: subsystems.buildcount.BuildCountAPI[IO, SyncIO, Player],
   manaApi: ManaApi[IO, SyncIO, Player],
   mineStackAPI: MineStackAPI[IO, Player, ItemStack],
-  ioConcurrentEffect: ConcurrentEffect[IO]
+  ioConcurrentEffect: ConcurrentEffect[IO],
+  playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
 ) {
 
   // TODO この辺のフィールドを整理する
@@ -97,8 +99,11 @@ object BuildAssist {
       ,
       Material.COBBLESTONE // 丸石
       ,
-      Material.WOOD // 木
-      ,
+      Material.ACACIA_WOOD,
+      Material.BIRCH_WOOD,
+      Material.DARK_OAK_WOOD,
+      Material.JUNGLE_WOOD,
+      Material.OAK_WOOD,
       Material.SAND // 砂
       ,
       Material.GRAVEL // 砂利
@@ -109,18 +114,34 @@ object BuildAssist {
       ,
       Material.COAL_ORE // 石炭鉱石
       ,
-      Material.LOG // 原木
-      ,
+      Material.ACACIA_LOG,
+      Material.BIRCH_LOG,
+      Material.DARK_OAK_LOG,
+      Material.JUNGLE_LOG,
+      Material.OAK_LOG,
       Material.GLASS // ガラス
       ,
       Material.LAPIS_ORE // ラピス鉱石
       ,
       Material.LAPIS_BLOCK // ラピスB
       ,
-      Material.SANDSTONE // 砂岩
-      ,
-      Material.WOOL // 羊毛
-      ,
+      Material.SANDSTONE, // 砂岩
+      Material.BLACK_WOOL,
+      Material.BLUE_WOOL,
+      Material.BROWN_WOOL,
+      Material.CYAN_WOOL,
+      Material.GRAY_WOOL,
+      Material.GREEN_WOOL,
+      Material.LIGHT_BLUE_WOOL,
+      Material.LIGHT_GRAY_WOOL,
+      Material.LIME_WOOL,
+      Material.MAGENTA_WOOL,
+      Material.ORANGE_WOOL,
+      Material.PINK_WOOL,
+      Material.PURPLE_WOOL,
+      Material.RED_WOOL,
+      Material.WHITE_WOOL,
+      Material.YELLOW_WOOL,
       Material.GOLD_BLOCK // 金B
       ,
       Material.IRON_BLOCK // 鉄B
@@ -149,38 +170,76 @@ object BuildAssist {
       ,
       Material.SOUL_SAND // ソウルサンド
       ,
-      Material.GLOWSTONE // グロウストーン
-      ,
-      Material.STAINED_GLASS // 色付きガラス
-      ,
-      Material.SMOOTH_BRICK // 石レンガ
-      ,
-      Material.MYCEL // 菌糸
+      Material.GLOWSTONE,
+      Material.BLACK_STAINED_GLASS,
+      Material.BLUE_STAINED_GLASS,
+      Material.BROWN_STAINED_GLASS,
+      Material.CYAN_STAINED_GLASS,
+      Material.GRAY_STAINED_GLASS,
+      Material.GREEN_STAINED_GLASS,
+      Material.LIGHT_BLUE_STAINED_GLASS,
+      Material.LIGHT_GRAY_STAINED_GLASS,
+      Material.LIME_STAINED_GLASS,
+      Material.MAGENTA_STAINED_GLASS,
+      Material.ORANGE_STAINED_GLASS,
+      Material.PINK_STAINED_GLASS,
+      Material.PURPLE_STAINED_GLASS,
+      Material.RED_STAINED_GLASS,
+      Material.WHITE_STAINED_GLASS,
+      Material.YELLOW_STAINED_GLASS,
+      Material.STONE_BRICKS // 石レンガ
+      ,
+      Material.MYCELIUM // 菌糸
       ,
       Material.NETHER_BRICK // ネザーレンガ
       ,
-      Material.ENDER_STONE // エンドストーン
+      Material.END_STONE // エンドストーン
       ,
       Material.EMERALD_ORE // エメ鉱石
       ,
       Material.EMERALD_BLOCK // エメB
       ,
-      Material.COBBLE_WALL // 丸石の壁
+      Material.COBBLESTONE_WALL // 丸石の壁
       ,
-      Material.QUARTZ_ORE // 水晶鉱石
+      Material.NETHER_QUARTZ_ORE // 水晶鉱石
       ,
       Material.QUARTZ_BLOCK // 水晶B
       ,
-      Material.STAINED_CLAY // 色付き固焼き粘土
-      ,
-      Material.LOG_2 // 原木2
-      ,
+      Material.BLACK_TERRACOTTA,
+      Material.BLUE_TERRACOTTA,
+      Material.BROWN_TERRACOTTA,
+      Material.CYAN_TERRACOTTA,
+      Material.GRAY_TERRACOTTA,
+      Material.GREEN_TERRACOTTA,
+      Material.LIGHT_BLUE_TERRACOTTA,
+      Material.LIGHT_GRAY_TERRACOTTA,
+      Material.LIME_TERRACOTTA,
+      Material.MAGENTA_TERRACOTTA,
+      Material.ORANGE_TERRACOTTA,
+      Material.PINK_TERRACOTTA,
+      Material.PURPLE_TERRACOTTA,
+      Material.RED_TERRACOTTA,
+      Material.WHITE_TERRACOTTA,
+      Material.YELLOW_TERRACOTTA,
       Material.PRISMARINE // プリズマリン
       ,
-      Material.SEA_LANTERN // シーランタン
-      ,
-      Material.HARD_CLAY // 固焼き粘土
-      ,
+      Material.SEA_LANTERN, // シーランタン
+      Material.BLACK_GLAZED_TERRACOTTA,
+      Material.BLUE_GLAZED_TERRACOTTA,
+      Material.BROWN_GLAZED_TERRACOTTA,
+      Material.CYAN_GLAZED_TERRACOTTA,
+      Material.GRAY_GLAZED_TERRACOTTA,
+      Material.GREEN_GLAZED_TERRACOTTA,
+      Material.LIGHT_BLUE_GLAZED_TERRACOTTA,
+      Material.LIGHT_GRAY_GLAZED_TERRACOTTA,
+      Material.LIME_GLAZED_TERRACOTTA,
+      Material.MAGENTA_GLAZED_TERRACOTTA,
+      Material.ORANGE_GLAZED_TERRACOTTA,
+      Material.PINK_GLAZED_TERRACOTTA,
+      Material.PURPLE_GLAZED_TERRACOTTA,
+      Material.RED_GLAZED_TERRACOTTA,
+      Material.WHITE_GLAZED_TERRACOTTA,
+      Material.YELLOW_GLAZED_TERRACOTTA,
       Material.COAL_BLOCK // 石炭B
       ,
       Material.PACKED_ICE // 氷塊
@@ -191,22 +250,49 @@ object BuildAssist {
       ,
       Material.PURPUR_PILLAR // 柱状プルパーブ
       ,
-      Material.END_BRICKS // エンドレンガB
+      Material.END_STONE_BRICKS // エンドレンガB
       ,
-      Material.RED_NETHER_BRICK // 赤ネザーレンガB
+      Material.RED_NETHER_BRICKS // 赤ネザーレンガB
       ,
       Material.BONE_BLOCK // 骨B
       ,
-      Material.NETHER_WART_BLOCK // ネザーウォートB
-      ,
-      Material.CONCRETE // コンクリート
-      ,
-      Material.CONCRETE_POWDER // コンクリートパウダー
-      ,
+      Material.NETHER_WART_BLOCK, // ネザーウォートB
+      Material.BLACK_CONCRETE,
+      Material.BLUE_CONCRETE,
+      Material.BROWN_CONCRETE,
+      Material.CYAN_CONCRETE,
+      Material.GRAY_CONCRETE,
+      Material.GREEN_CONCRETE,
+      Material.LIGHT_BLUE_CONCRETE,
+      Material.LIGHT_GRAY_CONCRETE,
+      Material.LIME_CONCRETE,
+      Material.MAGENTA_CONCRETE,
+      Material.ORANGE_CONCRETE,
+      Material.PINK_CONCRETE,
+      Material.PURPLE_CONCRETE,
+      Material.RED_CONCRETE,
+      Material.WHITE_CONCRETE,
+      Material.YELLOW_CONCRETE,
+      Material.BLACK_CONCRETE_POWDER,
+      Material.BLUE_CONCRETE_POWDER,
+      Material.BROWN_CONCRETE_POWDER,
+      Material.CYAN_CONCRETE_POWDER,
+      Material.GRAY_CONCRETE_POWDER,
+      Material.GREEN_CONCRETE_POWDER,
+      Material.LIGHT_BLUE_CONCRETE_POWDER,
+      Material.LIGHT_GRAY_CONCRETE_POWDER,
+      Material.LIME_CONCRETE_POWDER,
+      Material.MAGENTA_CONCRETE_POWDER,
+      Material.ORANGE_CONCRETE_POWDER,
+      Material.PINK_CONCRETE_POWDER,
+      Material.PURPLE_CONCRETE_POWDER,
+      Material.RED_CONCRETE_POWDER,
+      Material.WHITE_CONCRETE_POWDER,
+      Material.YELLOW_CONCRETE_POWDER,
       Material.ACACIA_STAIRS,
       Material.ACACIA_FENCE,
       Material.ACACIA_FENCE_GATE,
-      Material.BIRCH_WOOD_STAIRS,
+      Material.BIRCH_STAIRS,
       Material.BIRCH_FENCE,
       Material.BIRCH_FENCE_GATE,
       Material.BONE_BLOCK,
@@ -215,28 +301,33 @@ object BuildAssist {
       Material.BRICK_STAIRS,
       Material.CACTUS,
       Material.CHEST,
-      Material.CLAY_BRICK,
       Material.DARK_OAK_STAIRS,
       Material.DARK_OAK_FENCE,
       Material.DARK_OAK_FENCE_GATE,
-      Material.END_BRICKS,
+      Material.END_STONE_BRICKS,
       Material.FURNACE,
       Material.GLOWSTONE,
-      Material.HARD_CLAY,
       Material.JACK_O_LANTERN,
       Material.JUKEBOX,
       Material.JUNGLE_FENCE,
       Material.JUNGLE_FENCE_GATE,
-      Material.JUNGLE_WOOD_STAIRS,
+      Material.STRIPPED_JUNGLE_WOOD,
       Material.LADDER,
-      Material.LEAVES,
-      Material.LEAVES_2,
-      Material.LOG,
-      Material.LOG_2,
+      Material.OAK_LEAVES,
+      Material.BIRCH_LEAVES,
+      Material.JUNGLE_LEAVES,
+      Material.ACACIA_LEAVES,
+      Material.DARK_OAK_LEAVES,
+      Material.SPRUCE_LEAVES,
+      Material.ACACIA_LOG,
+      Material.BIRCH_LOG,
+      Material.DARK_OAK_LOG,
+      Material.JUNGLE_LOG,
+      Material.OAK_LOG,
       Material.NETHER_BRICK,
       Material.NETHER_BRICK_STAIRS,
       Material.NETHER_WART_BLOCK,
-      Material.RED_NETHER_BRICK,
+      Material.RED_NETHER_BRICKS,
       Material.OBSIDIAN,
       Material.PACKED_ICE,
       Material.PRISMARINE,
@@ -252,31 +343,72 @@ object BuildAssist {
       Material.SANDSTONE_STAIRS,
       Material.SEA_LANTERN,
       Material.SLIME_BLOCK,
-      Material.SMOOTH_BRICK,
-      Material.SMOOTH_STAIRS,
+      Material.SMOOTH_STONE,
+      Material.CHISELED_STONE_BRICKS,
+      Material.CRACKED_STONE_BRICKS,
+      Material.INFESTED_STONE_BRICKS,
+      Material.MOSSY_STONE_BRICKS,
+      Material.STONE_BRICK_STAIRS,
       Material.SNOW_BLOCK,
       Material.SPRUCE_FENCE,
       Material.SPRUCE_FENCE_GATE,
-      Material.SPRUCE_WOOD_STAIRS,
-      Material.FENCE,
-      Material.FENCE_GATE,
-      Material.STAINED_CLAY,
-      Material.STAINED_GLASS,
-      Material.STAINED_GLASS_PANE,
-      Material.STEP,
+      Material.STRIPPED_ACACIA_WOOD,
+      Material.STRIPPED_BIRCH_WOOD,
+      Material.STRIPPED_DARK_OAK_WOOD,
+      Material.STRIPPED_JUNGLE_WOOD,
+      Material.STRIPPED_OAK_WOOD,
+      Material.OAK_FENCE,
+      Material.ACACIA_FENCE,
+      Material.BIRCH_FENCE,
+      Material.DARK_OAK_FENCE,
+      Material.JUNGLE_FENCE,
+      Material.OAK_FENCE_GATE,
+      Material.ACACIA_FENCE_GATE,
+      Material.BIRCH_FENCE_GATE,
+      Material.DARK_OAK_FENCE_GATE,
+      Material.JUNGLE_FENCE_GATE,
+      Material.OAK_FENCE_GATE,
+      Material.BLACK_STAINED_GLASS_PANE,
+      Material.BLUE_STAINED_GLASS_PANE,
+      Material.BROWN_STAINED_GLASS_PANE,
+      Material.CYAN_STAINED_GLASS_PANE,
+      Material.GRAY_STAINED_GLASS_PANE,
+      Material.GREEN_STAINED_GLASS_PANE,
+      Material.LIGHT_BLUE_STAINED_GLASS_PANE,
+      Material.LIGHT_GRAY_STAINED_GLASS_PANE,
+      Material.LIME_STAINED_GLASS_PANE,
+      Material.MAGENTA_STAINED_GLASS_PANE,
+      Material.ORANGE_STAINED_GLASS_PANE,
+      Material.PINK_STAINED_GLASS_PANE,
+      Material.PURPLE_STAINED_GLASS_PANE,
+      Material.RED_STAINED_GLASS_PANE,
+      Material.WHITE_STAINED_GLASS_PANE,
+      Material.YELLOW_STAINED_GLASS_PANE,
+      Material.ACACIA_SLAB,
+      Material.BIRCH_SLAB,
+      Material.DARK_OAK_SLAB,
+      Material.JUNGLE_SLAB,
+      Material.OAK_SLAB,
       Material.STONE,
-      Material.STONE_SLAB2,
-      Material.THIN_GLASS,
+      Material.STONE_SLAB,
       Material.TORCH,
-      Material.WOOD,
-      Material.WOOD_STAIRS,
-      Material.WOOD_STEP,
-      Material.WOOL,
-      Material.CARPET,
-      Material.WORKBENCH,
-      // #1008
-      Material.LEAVES,
-      Material.LEAVES_2
+      Material.BLACK_CARPET,
+      Material.BLUE_CARPET,
+      Material.BROWN_CARPET,
+      Material.CYAN_CARPET,
+      Material.GRAY_CARPET,
+      Material.GREEN_CARPET,
+      Material.LIGHT_BLUE_CARPET,
+      Material.LIGHT_GRAY_CARPET,
+      Material.LIME_CARPET,
+      Material.MAGENTA_CARPET,
+      Material.ORANGE_CARPET,
+      Material.PINK_CARPET,
+      Material.PURPLE_CARPET,
+      Material.RED_CARPET,
+      Material.WHITE_CARPET,
+      Material.YELLOW_CARPET,
+      Material.CRAFTING_TABLE
     )
 
   // 直列設置ブロックの対象リスト
@@ -291,8 +423,11 @@ object BuildAssist {
       ,
       Material.COBBLESTONE // 丸石
       ,
-      Material.WOOD // 木
-      ,
+      Material.ACACIA_WOOD,
+      Material.BIRCH_WOOD,
+      Material.DARK_OAK_WOOD,
+      Material.JUNGLE_WOOD,
+      Material.OAK_WOOD,
       Material.SAND // 砂
       ,
       Material.GRAVEL // 砂利
@@ -303,8 +438,11 @@ object BuildAssist {
       ,
       Material.COAL_ORE // 石炭鉱石
       ,
-      Material.LOG // 原木
-      ,
+      Material.ACACIA_LOG,
+      Material.BIRCH_LOG,
+      Material.DARK_OAK_LOG,
+      Material.JUNGLE_LOG,
+      Material.OAK_LOG,
       Material.GLASS // ガラス
       ,
       Material.LAPIS_ORE // ラピス鉱石
@@ -313,8 +451,22 @@ object BuildAssist {
       ,
       Material.SANDSTONE // 砂岩
       ,
-      Material.WOOL // 羊毛
-      ,
+      Material.BLACK_WOOL,
+      Material.BLUE_WOOL,
+      Material.BROWN_WOOL,
+      Material.CYAN_WOOL,
+      Material.GRAY_WOOL,
+      Material.GREEN_WOOL,
+      Material.LIGHT_BLUE_WOOL,
+      Material.LIGHT_GRAY_WOOL,
+      Material.LIME_WOOL,
+      Material.MAGENTA_WOOL,
+      Material.ORANGE_WOOL,
+      Material.PINK_WOOL,
+      Material.PURPLE_WOOL,
+      Material.RED_WOOL,
+      Material.WHITE_WOOL,
+      Material.YELLOW_WOOL,
       Material.GOLD_BLOCK // 金B
       ,
       Material.IRON_BLOCK // 鉄B
@@ -345,36 +497,76 @@ object BuildAssist {
       ,
       Material.GLOWSTONE // グロウストーン
       ,
-      Material.STAINED_GLASS // 色付きガラス
-      ,
-      Material.SMOOTH_BRICK // 石レンガ
-      ,
-      Material.MYCEL // 菌糸
+      Material.BLACK_STAINED_GLASS,
+      Material.BLUE_STAINED_GLASS,
+      Material.BROWN_STAINED_GLASS,
+      Material.CYAN_STAINED_GLASS,
+      Material.GRAY_STAINED_GLASS,
+      Material.GREEN_STAINED_GLASS,
+      Material.LIGHT_BLUE_STAINED_GLASS,
+      Material.LIGHT_GRAY_STAINED_GLASS,
+      Material.LIME_STAINED_GLASS,
+      Material.MAGENTA_STAINED_GLASS,
+      Material.ORANGE_STAINED_GLASS,
+      Material.PINK_STAINED_GLASS,
+      Material.PURPLE_STAINED_GLASS,
+      Material.RED_STAINED_GLASS,
+      Material.WHITE_STAINED_GLASS,
+      Material.YELLOW_STAINED_GLASS,
+      Material.STONE_BRICKS // 石レンガ
+      ,
+      Material.MYCELIUM // 菌糸
       ,
       Material.NETHER_BRICK // ネザーレンガ
       ,
-      Material.ENDER_STONE // エンドストーン
+      Material.END_STONE // エンドストーン
       ,
       Material.EMERALD_ORE // エメ鉱石
       ,
       Material.EMERALD_BLOCK // エメB
       ,
-      Material.COBBLE_WALL // 丸石の壁
+      Material.COBBLESTONE_WALL // 丸石の壁
       ,
-      Material.QUARTZ_ORE // 水晶鉱石
+      Material.NETHER_QUARTZ_ORE // 水晶鉱石
       ,
       Material.QUARTZ_BLOCK // 水晶B
       ,
-      Material.STAINED_CLAY // 色付き固焼き粘土
-      ,
-      Material.LOG_2 // 原木2
-      ,
+      Material.BLACK_TERRACOTTA,
+      Material.BLUE_TERRACOTTA,
+      Material.BROWN_TERRACOTTA,
+      Material.CYAN_TERRACOTTA,
+      Material.GRAY_TERRACOTTA,
+      Material.GREEN_TERRACOTTA,
+      Material.LIGHT_BLUE_TERRACOTTA,
+      Material.LIGHT_GRAY_TERRACOTTA,
+      Material.LIME_TERRACOTTA,
+      Material.MAGENTA_TERRACOTTA,
+      Material.ORANGE_TERRACOTTA,
+      Material.PINK_TERRACOTTA,
+      Material.PURPLE_TERRACOTTA,
+      Material.RED_TERRACOTTA,
+      Material.WHITE_TERRACOTTA,
+      Material.YELLOW_TERRACOTTA,
       Material.PRISMARINE // プリズマリン
       ,
       Material.SEA_LANTERN // シーランタン
       ,
-      Material.HARD_CLAY // 固焼き粘土
-      ,
+      Material.BLACK_GLAZED_TERRACOTTA,
+      Material.BLUE_GLAZED_TERRACOTTA,
+      Material.BROWN_GLAZED_TERRACOTTA,
+      Material.CYAN_GLAZED_TERRACOTTA,
+      Material.GRAY_GLAZED_TERRACOTTA,
+      Material.GREEN_GLAZED_TERRACOTTA,
+      Material.LIGHT_BLUE_GLAZED_TERRACOTTA,
+      Material.LIGHT_GRAY_GLAZED_TERRACOTTA,
+      Material.LIME_GLAZED_TERRACOTTA,
+      Material.MAGENTA_GLAZED_TERRACOTTA,
+      Material.ORANGE_GLAZED_TERRACOTTA,
+      Material.PINK_GLAZED_TERRACOTTA,
+      Material.PURPLE_GLAZED_TERRACOTTA,
+      Material.RED_GLAZED_TERRACOTTA,
+      Material.WHITE_GLAZED_TERRACOTTA,
+      Material.YELLOW_GLAZED_TERRACOTTA,
       Material.COAL_BLOCK // 石炭B
       ,
       Material.PACKED_ICE // 氷塊
@@ -385,22 +577,53 @@ object BuildAssist {
       ,
       Material.PURPUR_PILLAR // 柱状プルパーブ
       ,
-      Material.END_BRICKS // エンドレンガB
+      Material.END_STONE_BRICKS // エンドレンガB
       ,
-      Material.RED_NETHER_BRICK // 赤ネザーレンガB
+      Material.RED_NETHER_BRICKS // 赤ネザーレンガB
       ,
       Material.BONE_BLOCK // 骨B
       ,
-      Material.FENCE // オークフェンス
-      ,
-      Material.IRON_FENCE // 鉄フェンス
-      ,
-      Material.THIN_GLASS // 板ガラス
-      ,
-      Material.NETHER_FENCE // ネザーフェンス
-      ,
-      Material.STAINED_GLASS_PANE // 色付き板ガラス
-      ,
+      Material.OAK_FENCE,
+      Material.ACACIA_FENCE,
+      Material.BIRCH_FENCE,
+      Material.DARK_OAK_FENCE,
+      Material.JUNGLE_FENCE,
+      Material.IRON_BARS // 鉄フェンス
+      ,
+      Material.BLACK_STAINED_GLASS,
+      Material.BLUE_STAINED_GLASS,
+      Material.BROWN_STAINED_GLASS,
+      Material.CYAN_STAINED_GLASS,
+      Material.GRAY_STAINED_GLASS,
+      Material.GREEN_STAINED_GLASS,
+      Material.LIGHT_BLUE_STAINED_GLASS,
+      Material.LIGHT_GRAY_STAINED_GLASS,
+      Material.LIME_STAINED_GLASS,
+      Material.MAGENTA_STAINED_GLASS,
+      Material.ORANGE_STAINED_GLASS,
+      Material.PINK_STAINED_GLASS,
+      Material.PURPLE_STAINED_GLASS,
+      Material.RED_STAINED_GLASS,
+      Material.WHITE_STAINED_GLASS,
+      Material.YELLOW_STAINED_GLASS,
+      Material.NETHER_BRICK_FENCE // ネザーフェンス
+      ,
+      Material.BLACK_STAINED_GLASS_PANE,
+      Material.BLUE_STAINED_GLASS_PANE,
+      Material.BROWN_STAINED_GLASS_PANE,
+      Material.CYAN_STAINED_GLASS_PANE,
+      Material.GRAY_STAINED_GLASS_PANE,
+      Material.GREEN_STAINED_GLASS_PANE,
+      Material.LIGHT_BLUE_STAINED_GLASS_PANE,
+      Material.LIGHT_GRAY_STAINED_GLASS_PANE,
+      Material.LIME_STAINED_GLASS_PANE,
+      Material.MAGENTA_STAINED_GLASS_PANE,
+      Material.ORANGE_STAINED_GLASS_PANE,
+      Material.PINK_STAINED_GLASS_PANE,
+      Material.PURPLE_STAINED_GLASS_PANE,
+      Material.RED_STAINED_GLASS_PANE,
+      Material.WHITE_STAINED_GLASS_PANE,
+      Material.YELLOW_STAINED_GLASS_PANE,
       Material.SLIME_BLOCK // スライムB
       ,
       Material.SPRUCE_FENCE // 松フェンス
@@ -413,40 +636,79 @@ object BuildAssist {
       ,
       Material.ACACIA_FENCE // アカシアフェンス
       ,
-      Material.NETHER_WART_BLOCK // ネザーウォートB
-      ,
-      Material.CONCRETE // コンクリート
-      ,
-      Material.CONCRETE_POWDER // コンクリートパウダー
-      ,
-      Material.LEAVES,
-      Material.LEAVES_2
+      Material.NETHER_WART_BLOCK, // ネザーウォートB
+      Material.BLACK_CONCRETE,
+      Material.BLUE_CONCRETE,
+      Material.BROWN_CONCRETE,
+      Material.CYAN_CONCRETE,
+      Material.GRAY_CONCRETE,
+      Material.GREEN_CONCRETE,
+      Material.LIGHT_BLUE_CONCRETE,
+      Material.LIGHT_GRAY_CONCRETE,
+      Material.LIME_CONCRETE,
+      Material.MAGENTA_CONCRETE,
+      Material.ORANGE_CONCRETE,
+      Material.PINK_CONCRETE,
+      Material.PURPLE_CONCRETE,
+      Material.RED_CONCRETE,
+      Material.WHITE_CONCRETE,
+      Material.YELLOW_CONCRETE,
+      Material.BLACK_CONCRETE_POWDER,
+      Material.BLUE_CONCRETE_POWDER,
+      Material.BROWN_CONCRETE_POWDER,
+      Material.CYAN_CONCRETE_POWDER,
+      Material.GRAY_CONCRETE_POWDER,
+      Material.GREEN_CONCRETE_POWDER,
+      Material.LIGHT_BLUE_CONCRETE_POWDER,
+      Material.LIGHT_GRAY_CONCRETE_POWDER,
+      Material.LIME_CONCRETE_POWDER,
+      Material.MAGENTA_CONCRETE_POWDER,
+      Material.ORANGE_CONCRETE_POWDER,
+      Material.PINK_CONCRETE_POWDER,
+      Material.PURPLE_CONCRETE_POWDER,
+      Material.RED_CONCRETE_POWDER,
+      Material.WHITE_CONCRETE_POWDER,
+      Material.YELLOW_CONCRETE_POWDER,
+      Material.OAK_LEAVES,
+      Material.BIRCH_LEAVES,
+      Material.JUNGLE_LEAVES,
+      Material.ACACIA_LEAVES,
+      Material.DARK_OAK_LEAVES,
+      Material.SPRUCE_LEAVES
     )
 
   // ハーフブロックとして扱うMaterial
   val material_slab2: java.util.Set[Material] = util
     .EnumSet
     .of(
-      Material.STONE_SLAB2 // 赤砂岩
-      ,
-      Material.PURPUR_SLAB // プルパー
-      ,
-      Material.WOOD_STEP // 木
-      ,
-      Material.STEP // 石
+      Material.RED_SANDSTONE_SLAB,
+      Material.PURPUR_SLAB,
+      Material.ACACIA_SLAB,
+      Material.BIRCH_SLAB,
+      Material.DARK_OAK_SLAB,
+      Material.JUNGLE_SLAB,
+      Material.OAK_SLAB,
+      Material.STONE_SLAB,
+      Material.STONE_BRICK_SLAB
     )
 
   val material_destruction: java.util.Set[Material] = util
     .EnumSet
     .of(
-      Material.LONG_GRASS // 草
-      ,
+      Material.GRASS,
+      Material.TALL_GRASS,
       Material.DEAD_BUSH // 枯れ木
       ,
-      Material.YELLOW_FLOWER // タンポポ
-      ,
-      Material.RED_ROSE // 花9種
-      ,
+      Material.DANDELION,
+      Material.POPPY,
+      Material.BLUE_ORCHID,
+      Material.ALLIUM,
+      Material.AZURE_BLUET,
+      Material.RED_TULIP,
+      Material.ORANGE_TULIP,
+      Material.WHITE_TULIP,
+      Material.PINK_TULIP,
+      Material.OXEYE_DAISY,
       Material.BROWN_MUSHROOM // きのこ
       ,
       Material.RED_MUSHROOM // 赤きのこ
@@ -455,16 +717,15 @@ object BuildAssist {
       ,
       Material.SNOW // 雪
       ,
-      Material.DOUBLE_PLANT // 高い花、草
-      ,
+      Material.SUNFLOWER,
+      Material.LILAC,
+      Material.LARGE_FERN,
+      Material.ROSE_BUSH,
+      Material.PEONY,
       Material.WATER // 水
       ,
-      Material.STATIONARY_WATER // 水
-      ,
       Material.LAVA // 溶岩
       ,
-      Material.STATIONARY_LAVA // 溶岩
-      ,
       Material.VINE // ツタ
     )
 
diff --git a/src/main/scala/com/github/unchama/buildassist/MenuInventoryData.scala b/src/main/scala/com/github/unchama/buildassist/MenuInventoryData.scala
index 95666d3373..fded2b11c5 100644
--- a/src/main/scala/com/github/unchama/buildassist/MenuInventoryData.scala
+++ b/src/main/scala/com/github/unchama/buildassist/MenuInventoryData.scala
@@ -1,12 +1,14 @@
 package com.github.unchama.buildassist
 
-import cats.effect.SyncIO
+import cats.effect.{IO, SyncIO}
 import com.github.unchama.buildassist.util.AsyncInventorySetter
+import com.github.unchama.itemstackbuilder.{IconItemStackBuilder, SkullItemStackBuilder}
+import com.github.unchama.seichiassist.SkullOwners
 import com.github.unchama.seichiassist.subsystems.itemmigration.infrastructure.minecraft.JdbcBackedUuidRepository
-import com.github.unchama.seichiassist.util.ItemMetaFactory
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import org.bukkit.ChatColor._
 import org.bukkit.entity.Player
-import org.bukkit.inventory.meta.{ItemMeta, SkullMeta}
+import org.bukkit.inventory.meta.ItemMeta
 import org.bukkit.inventory.{Inventory, ItemStack}
 import org.bukkit.{Bukkit, Material}
 
@@ -17,7 +19,9 @@ object MenuInventoryData {
   JdbcBackedUuidRepository.initializeStaticInstance[SyncIO].unsafeRunSync().apply[SyncIO]
 
   // ブロックを並べる設定メニュー
-  def getBlockLineUpData(p: Player): Inventory = {
+  def getBlockLineUpData(
+    p: Player
+  )(implicit playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]): Inventory = {
     // プレイヤーを取得
     val player = p.getPlayer
     // UUID取得
@@ -26,41 +30,34 @@ object MenuInventoryData {
     val playerdata = BuildAssist.instance.temporaryData(uuid)
 
     val inventory = Bukkit.getServer.createInventory(null, 4 * 9, s"$DARK_PURPLE$BOLD「直列設置」設定")
-    var itemstack = new ItemStack(Material.SKULL_ITEM, 1)
-    var itemmeta: ItemMeta = Bukkit.getItemFactory.getItemMeta(Material.WOOD)
-    val skullmeta: SkullMeta = ItemMetaFactory.SKULL.getValue
+    var itemstack = new ItemStack(Material.PLAYER_HEAD, 11)
+    var itemmeta: ItemMeta = itemstack.getItemMeta
     var lore = List(s"$RESET$DARK_RED${UNDERLINE}クリックで移動")
 
     // ホームを開く
-    itemstack.setDurability(3.toShort)
-    skullmeta.setDisplayName(s"$YELLOW$UNDERLINE${BOLD}ホームへ")
-    skullmeta.setLore(lore.asJava)
-
-    /**
-     * 参加したことのないプレーヤーはgetOfflinePlayerでデータが取れないのでこうするしか無い
-     */
-    skullmeta.setOwner("MHF_ArrowLeft")
-    itemstack.setItemMeta(skullmeta)
+    itemstack = new SkullItemStackBuilder(SkullOwners.MHF_ArrowLeft)
+      .title(s"$YELLOW$UNDERLINE${BOLD}ホームへ")
+      .lore(lore)
+      .build()
     AsyncInventorySetter.setItemAsync(inventory, 27, itemstack)
 
-    // 直列設置設定
-    itemstack = new ItemStack(Material.WOOD, 1)
-    itemmeta.setDisplayName(
-      s"$YELLOW$UNDERLINE${BOLD}直列設置 :${BuildAssist.line_up_str(playerdata.line_up_flg)}"
-    )
-    lore = List(
-      s"$RESET${GRAY}オフハンドに木の棒、メインハンドに設置したいブロックを持って",
-      s"$RESET${GRAY}左クリックすると向いてる方向に並べて設置します。",
-      s"$RESET${GRAY}建築Lv${BuildAssist.config.getblocklineuplevel}以上で利用可能",
-      s"$RESET${GRAY}クリックで切り替え"
-    )
-    itemmeta.setLore(lore.asJava)
-    itemstack.setItemMeta(itemmeta)
+    itemstack = new IconItemStackBuilder(Material.OAK_PLANKS)
+      .title(
+        s"$YELLOW$UNDERLINE${BOLD}直列設置 :${BuildAssist.line_up_str(playerdata.line_up_flg)}"
+      )
+      .lore(
+        s"$RESET${GRAY}オフハンドに木の棒、メインハンドに設置したいブロックを持って",
+        s"$RESET${GRAY}左クリックすると向いてる方向に並べて設置します。",
+        s"$RESET${GRAY}建築Lv${BuildAssist.config.getblocklineuplevel}以上で利用可能",
+        s"$RESET${GRAY}クリックで切り替え"
+      )
+      .build()
+
     inventory.setItem(0, itemstack)
 
     // 直列設置ハーフブロック設定
-    itemstack = new ItemStack(Material.STEP, 1)
-    itemmeta = Bukkit.getItemFactory.getItemMeta(Material.STEP)
+    itemstack = new ItemStack(Material.STONE_SLAB, 1)
+    itemmeta = itemstack.getItemMeta
     itemmeta.setDisplayName(
       s"$YELLOW$UNDERLINE${BOLD}ハーフブロック設定 :${BuildAssist.line_up_step_str(playerdata.line_up_step_flg)}"
     )
diff --git a/src/main/scala/com/github/unchama/buildassist/PlayerInventoryListener.scala b/src/main/scala/com/github/unchama/buildassist/PlayerInventoryListener.scala
index 539535777f..c79c7875b5 100644
--- a/src/main/scala/com/github/unchama/buildassist/PlayerInventoryListener.scala
+++ b/src/main/scala/com/github/unchama/buildassist/PlayerInventoryListener.scala
@@ -5,6 +5,7 @@ import com.github.unchama.generic.effect.unsafe.EffectEnvironment
 import com.github.unchama.menuinventory.router.CanOpen
 import com.github.unchama.seichiassist.effects.player.CommonSoundEffects
 import com.github.unchama.seichiassist.menus.BuildMainMenu
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import net.md_5.bungee.api.ChatColor._
 import org.bukkit.entity.{EntityType, Player}
 import org.bukkit.event.inventory.{InventoryClickEvent, InventoryType}
@@ -13,7 +14,8 @@ import org.bukkit.{Material, Sound}
 
 class PlayerInventoryListener(
   implicit effectEnvironment: EffectEnvironment,
-  ioCanOpenBuildMainMenu: IO CanOpen BuildMainMenu.type
+  ioCanOpenBuildMainMenu: IO CanOpen BuildMainMenu.type,
+  playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
 ) extends Listener {
 
   import com.github.unchama.targetedeffect._
@@ -58,7 +60,7 @@ class PlayerInventoryListener(
     // プレイヤーデータが無い場合は処理終了
 
     // インベントリ名が以下の時処理
-    if (topinventory.getTitle == s"${DARK_PURPLE.toString}$BOLD「直列設置」設定") {
+    if (view.getTitle == s"${DARK_PURPLE.toString}$BOLD「直列設置」設定") {
       event.setCancelled(true)
 
       // プレイヤーインベントリのクリックの場合終了
@@ -68,7 +70,7 @@ class PlayerInventoryListener(
       /*
        * クリックしたボタンに応じた各処理内容の記述ここから
        */
-      if (itemstackcurrent.getType == Material.SKULL_ITEM) {
+      if (itemstackcurrent.getType == Material.PLAYER_HEAD) {
         // ホームメニューへ帰還
 
         effectEnvironment.unsafeRunAsyncTargetedEffect(player)(
@@ -78,7 +80,7 @@ class PlayerInventoryListener(
           ),
           "BuildMainMenuを開く"
         )
-      } else if (itemstackcurrent.getType == Material.WOOD) {
+      } else if (itemstackcurrent.getType == Material.OAK_PLANKS) {
         // 直列設置設定
         if (playerLevel < BuildAssist.config.getblocklineuplevel) {
           player.sendMessage(RED.toString + "建築Lvが足りません")
@@ -91,7 +93,7 @@ class PlayerInventoryListener(
           player.playSound(player.getLocation, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 1f)
           player.openInventory(MenuInventoryData.getBlockLineUpData(player))
         }
-      } else if (itemstackcurrent.getType == Material.STEP) {
+      } else if (itemstackcurrent.getType == Material.STONE_SLAB) {
         // 直列設置ハーフブロック設定
         if (playerdata.line_up_step_flg >= 2) {
           playerdata.line_up_step_flg = 0
diff --git a/src/main/scala/com/github/unchama/buildassist/listener/BlockLineUpTriggerListener.scala b/src/main/scala/com/github/unchama/buildassist/listener/BlockLineUpTriggerListener.scala
index 5aa13a032a..f1ec54ae36 100644
--- a/src/main/scala/com/github/unchama/buildassist/listener/BlockLineUpTriggerListener.scala
+++ b/src/main/scala/com/github/unchama/buildassist/listener/BlockLineUpTriggerListener.scala
@@ -7,7 +7,8 @@ import com.github.unchama.seichiassist.subsystems.buildcount.application.actions
 import com.github.unchama.seichiassist.subsystems.buildcount.domain.explevel.BuildExpAmount
 import com.github.unchama.seichiassist.subsystems.mana.ManaApi
 import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
-import com.github.unchama.util.external.ExternalPlugins
+import com.github.unchama.util.external.WorldGuardWrapper
+import org.bukkit.block.data.`type`.Slab
 import org.bukkit.entity.Player
 import org.bukkit.event.block.Action
 import org.bukkit.event.player.PlayerInteractEvent
@@ -15,6 +16,7 @@ import org.bukkit.event.{EventHandler, Listener}
 import org.bukkit.inventory.ItemStack
 import org.bukkit.{Material, Sound}
 
+import scala.util.chaining.scalaUtilChainingOps
 import scala.util.control.Breaks
 
 class BlockLineUpTriggerListener[
@@ -61,7 +63,6 @@ class BlockLineUpTriggerListener[
 
     val pl = player.getLocation
     val mainHandItemType = mainHandItem.getType
-    val mainHandItemData = mainHandItem.getData.getData
 
     // 仰角は下向きがプラスで上向きがマイナス
     val pitch = pl.getPitch
@@ -103,8 +104,10 @@ class BlockLineUpTriggerListener[
       if (buildAssistData.line_up_minestack_flg == 1) {
         mineStackAPI
           .mineStackObjectList
-          .findBySignedItemStack(mainHandItem, player)
+          .findBySignedItemStacks(Vector(mainHandItem), player)
           .unsafeRunSync()
+          .head
+          ._2
       } else None
 
     val maxBlockUsage = {
@@ -132,30 +135,20 @@ class BlockLineUpTriggerListener[
       Seq(Some(available), manaCap, Some(64L)).flatten.min
     }.toInt
 
-    def slabToDoubleSlab(material: Material) = material match {
-      case Material.STONE_SLAB2 => Material.DOUBLE_STONE_SLAB2
-      case Material.PURPUR_SLAB => Material.PURPUR_DOUBLE_SLAB
-      case Material.WOOD_STEP   => Material.WOOD_DOUBLE_STEP
-      case Material.STEP        => Material.DOUBLE_STEP
-      case _                    => mainHandItemType
-    }
+    def slabToDoubleSlab(material: Material): Material =
+      if (material.createBlockData().isInstanceOf[Slab]) {
+        material.asInstanceOf[Slab].tap(slab => slab.setType(Slab.Type.DOUBLE)).getMaterial
+      } else material
 
     val playerHoldsSlabBlock = BuildAssist.material_slab2.contains(mainHandItemType)
-    val doesHoldLeaves =
-      (mainHandItemType eq Material.LEAVES) || (mainHandItemType eq Material.LEAVES_2)
+    (mainHandItemType eq Material.OAK_LEAVES) || (mainHandItemType eq Material.DARK_OAK_LEAVES) || (
+      mainHandItemType eq Material.BIRCH_LEAVES
+    ) || (mainHandItemType eq Material.ACACIA_LEAVES) || (
+      mainHandItemType eq Material.JUNGLE_LEAVES
+    ) || (mainHandItemType eq Material.SPRUCE_LEAVES)
     val slabLineUpStepMode = buildAssistData.line_up_step_flg
     val shouldPlaceDoubleSlabs = playerHoldsSlabBlock && slabLineUpStepMode == 2
 
-    val upsideBit = 8
-    val noDecayBit = 4
-    val placingBlockData: Byte =
-      if (playerHoldsSlabBlock && slabLineUpStepMode == 0)
-        (mainHandItemData | upsideBit).toByte
-      else if (doesHoldLeaves)
-        (mainHandItemData | noDecayBit).toByte
-      else
-        mainHandItemData
-
     val (placingBlockType, itemConsumptionPerPlacement, placementIteration) =
       if (shouldPlaceDoubleSlabs)
         (slabToDoubleSlab(mainHandItemType), 2, maxBlockUsage / 2)
@@ -174,7 +167,7 @@ class BlockLineUpTriggerListener[
         val block = playerWorld.getBlockAt(px, py, pz)
 
         // 他人の保護がかかっている場合は設置終わり
-        if (!ExternalPlugins.getWorldGuard.canBuild(player, block.getLocation)) b.break
+        if (!WorldGuardWrapper.canBuild(player, block.getLocation)) b.break()
 
         if (block.getType != Material.AIR) {
           // 空気以外にぶつかり、ブロック破壊をしないならば終わる
@@ -183,7 +176,7 @@ class BlockLineUpTriggerListener[
               .material_destruction
               .contains(block.getType) || buildAssistData.line_up_des_flg == 0
           ) {
-            b.break
+            b.break()
           }
 
           block.getDrops.asScala.foreach {
@@ -192,7 +185,6 @@ class BlockLineUpTriggerListener[
         }
 
         block.setType(placingBlockType)
-        block.setData(placingBlockData)
 
         placedBlockCount += itemConsumptionPerPlacement
       }
diff --git a/src/main/scala/com/github/unchama/buildassist/listener/TilingSkillTriggerListener.scala b/src/main/scala/com/github/unchama/buildassist/listener/TilingSkillTriggerListener.scala
index 6b530f7166..2a41a3b462 100644
--- a/src/main/scala/com/github/unchama/buildassist/listener/TilingSkillTriggerListener.scala
+++ b/src/main/scala/com/github/unchama/buildassist/listener/TilingSkillTriggerListener.scala
@@ -2,11 +2,13 @@ package com.github.unchama.buildassist.listener
 
 import cats.effect.ConcurrentEffect.ops.toAllConcurrentEffectOps
 import cats.effect.{ConcurrentEffect, SyncEffect, SyncIO}
-import com.github.unchama.buildassist.{BuildAssist, Util}
+import com.github.unchama.buildassist.BuildAssist
 import com.github.unchama.seichiassist.subsystems.buildcount.application.actions.IncrementBuildExpWhenBuiltWithSkill
 import com.github.unchama.seichiassist.subsystems.buildcount.domain.explevel.BuildExpAmount
 import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
+import com.github.unchama.util.external.WorldGuardWrapper
 import org.bukkit.ChatColor.RED
+import org.bukkit.block.data.`type`.Leaves
 import org.bukkit.entity.Player
 import org.bukkit.event.block.Action
 import org.bukkit.event.player.PlayerInteractEvent
@@ -48,10 +50,7 @@ class TilingSkillTriggerListener[G[_]: ConcurrentEffect, F[
     ) return
 
     val clickedBlock = event.getClickedBlock
-    val offHandItemSelector = offHandItem.getData.getData
-    if (
-      !(offHandItem.getType == clickedBlock.getType && offHandItemSelector == clickedBlock.getData)
-    ) {
+    if (!(offHandItem.getType == clickedBlock.getType)) {
       player.sendMessage(s"$RED「オフハンドと同じブロック」をクリックしてください。(基準になります)")
       return
     }
@@ -71,37 +70,40 @@ class TilingSkillTriggerListener[G[_]: ConcurrentEffect, F[
     val minestackObjectToUse =
       mineStackAPI
         .mineStackObjectList
-        .findBySignedItemStack(offHandItem, player)
+        .findBySignedItemStacks(Vector(offHandItem), player)
         .toIO
         .unsafeRunSync()
+        .head
+        ._2
         .filter(_ => buildAssistPlayerData.zs_minestack_flag)
 
     val replaceableMaterials = Set(
       Material.AIR,
       Material.SNOW,
-      Material.LONG_GRASS,
+      Material.TALL_GRASS,
       Material.DEAD_BUSH,
-      Material.YELLOW_FLOWER,
-      Material.RED_ROSE,
+      Material.DANDELION,
+      Material.POPPY,
+      Material.BLUE_ORCHID,
+      Material.ALLIUM,
+      Material.AZURE_BLUET,
+      Material.RED_TULIP,
+      Material.ORANGE_TULIP,
+      Material.WHITE_TULIP,
+      Material.PINK_TULIP,
+      Material.OXEYE_DAISY,
+      Material.SUNFLOWER,
+      Material.LILAC,
+      Material.LARGE_FERN,
+      Material.ROSE_BUSH,
+      Material.PEONY,
       Material.RED_MUSHROOM,
       Material.BROWN_MUSHROOM
     )
 
-    val fillTargetMaterials = Set(
-      Material.AIR,
-      Material.LAVA,
-      Material.STATIONARY_LAVA,
-      Material.WATER,
-      Material.STATIONARY_WATER
-    )
+    val fillTargetMaterials = Set(Material.AIR, Material.LAVA, Material.WATER)
 
     val b1 = new Breaks
-    val rawDataModifier: Byte => Byte = offHandItem.getType match {
-      case Material.LEAVES | Material.LEAVES_2 =>
-        val noDecayBit: Byte = 8
-        x => (x | noDecayBit).asInstanceOf[Byte]
-      case _ => identity
-    }
 
     b1.breakable {
       val targetXValues = centerX - areaInt to centerX + areaInt
@@ -121,7 +123,7 @@ class TilingSkillTriggerListener[G[_]: ConcurrentEffect, F[
                 val blockToBeReplaced = fillLocation.getBlock
 
                 if (fillTargetMaterials.contains(blockToBeReplaced.getType)) {
-                  if (Util.getWorldGuard.canBuild(player, fillLocation)) {
+                  if (WorldGuardWrapper.canBuild(player, fillLocation)) {
                     blockToBeReplaced.setType(Material.DIRT)
                   } else {
                     // 他人の保護がかかっている場合は通知を行う
@@ -137,7 +139,15 @@ class TilingSkillTriggerListener[G[_]: ConcurrentEffect, F[
               }
 
               targetSurfaceBlock.setType(offHandItem.getType)
-              targetSurfaceBlock.setData(rawDataModifier(offHandItemSelector))
+
+              val block = targetSurfaceLocation.getBlock
+
+              block.getBlockData match {
+                case leavesData: Leaves =>
+                  leavesData.setPersistent(true)
+                  block.setBlockData(leavesData)
+                case _ =>
+              }
 
               placementCount += 1
             }
@@ -179,7 +189,7 @@ class TilingSkillTriggerListener[G[_]: ConcurrentEffect, F[
 
             if (replaceableMaterials.contains(targetSurfaceBlock.getType)) {
               // 他人の保護がかかっている場合は処理を終了
-              if (!Util.getWorldGuard.canBuild(player, targetSurfaceLocation)) {
+              if (!WorldGuardWrapper.canBuild(player, targetSurfaceLocation)) {
                 player.sendMessage(s"${RED}付近に誰かの保護がかかっているようです")
                 b1.break()
               }
diff --git a/src/main/scala/com/github/unchama/buildassist/menu/BlockPlacementSkillMenu.scala b/src/main/scala/com/github/unchama/buildassist/menu/BlockPlacementSkillMenu.scala
index 858e921d01..13b4685adc 100644
--- a/src/main/scala/com/github/unchama/buildassist/menu/BlockPlacementSkillMenu.scala
+++ b/src/main/scala/com/github/unchama/buildassist/menu/BlockPlacementSkillMenu.scala
@@ -7,8 +7,10 @@ import com.github.unchama.menuinventory.router.CanOpen
 import com.github.unchama.menuinventory.slot.button.action.LeftClickButtonEffect
 import com.github.unchama.menuinventory.slot.button.{Button, RecomputedButton}
 import com.github.unchama.menuinventory.{Menu, MenuFrame, MenuSlotLayout}
+import com.github.unchama.seichiassist.SkullOwners
 import com.github.unchama.seichiassist.effects.player.CommonSoundEffects
 import com.github.unchama.seichiassist.menus.BuildMainMenu
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.targetedeffect.commandsender.MessageEffect
 import com.github.unchama.targetedeffect.player.FocusedSoundEffect
 import com.github.unchama.targetedeffect.{
@@ -30,7 +32,10 @@ object BlockPlacementSkillMenu extends Menu {
   }
   import menuinventory.syntax._
 
-  class Environment(implicit val canOpenMainMenu: CanOpen[IO, BuildMainMenu.type])
+  class Environment(
+    implicit val canOpenMainMenu: CanOpen[IO, BuildMainMenu.type],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
+  )
 
   override val frame: MenuFrame =
     MenuFrame(4.chestRows, s"$DARK_PURPLE$BOLD「範囲設置スキル」設定画面")
@@ -54,6 +59,7 @@ object BlockPlacementSkillMenu extends Menu {
 
     import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts.layoutPreparationContext
     import player._
+    import environment._
 
     private def computeCurrentSkillAreaInt(range: Int): Int = (range - 1) / 2
     private val maxRange = 15
@@ -115,7 +121,7 @@ object BlockPlacementSkillMenu extends Menu {
       val playerData = BuildAssist.instance.temporaryData(getUniqueId)
       val currentRange = playerData.computeCurrentSkillRange()
 
-      val iconItemStack = new SkullItemStackBuilder("MHF_ArrowUp")
+      val iconItemStack = new SkullItemStackBuilder(SkullOwners.MHF_ArrowUp)
         .title(s"$RED$UNDERLINE${BOLD}範囲設定を最大値に変更")
         .lore(
           s"$RESET${AQUA}現在の範囲設定: $currentRange×$currentRange",
@@ -142,7 +148,7 @@ object BlockPlacementSkillMenu extends Menu {
       val currentRange = playerData.computeCurrentSkillRange()
       val changedRange = 11
 
-      val iconItemStack = new SkullItemStackBuilder("MHF_ArrowUp")
+      val iconItemStack = new SkullItemStackBuilder(SkullOwners.MHF_ArrowUp)
         .title(s"$RED$UNDERLINE${BOLD}範囲設定を$changedRange×${changedRange}に変更")
         .lore(
           s"$RESET${AQUA}現在の範囲設定: $currentRange×$currentRange",
@@ -169,7 +175,7 @@ object BlockPlacementSkillMenu extends Menu {
       val currentRange = playerData.computeCurrentSkillRange()
       val changedRange = currentRange + 2
 
-      val iconItemStack = new SkullItemStackBuilder("MHF_ArrowUp")
+      val iconItemStack = new SkullItemStackBuilder(SkullOwners.MHF_ArrowUp)
         .title(s"$YELLOW$UNDERLINE${BOLD}範囲設定を一段階大きくする")
         .lore {
           List(s"$RESET${AQUA}現在の範囲設定: $currentRange×$currentRange").concat(
@@ -208,7 +214,7 @@ object BlockPlacementSkillMenu extends Menu {
       val currentRange = playerData.computeCurrentSkillRange()
       val changedRange = 5
 
-      val iconItemStack = new SkullItemStackBuilder("MHF_TNT")
+      val iconItemStack = new SkullItemStackBuilder(SkullOwners.MHF_TNT)
         .title(s"$RED$UNDERLINE${BOLD}範囲設定を初期値に変更")
         .lore(
           s"$RESET${AQUA}現在の範囲設定: $currentRange×$currentRange",
@@ -235,7 +241,7 @@ object BlockPlacementSkillMenu extends Menu {
       val currentRange = playerData.computeCurrentSkillRange()
       val changedRange = currentRange - 2
 
-      val iconItemStack = new SkullItemStackBuilder("MHF_ArrowDown")
+      val iconItemStack = new SkullItemStackBuilder(SkullOwners.MHF_ArrowDown)
         .title(s"$YELLOW$UNDERLINE${BOLD}範囲設定を一段階小さくする")
         .lore(
           List(s"$RESET${AQUA}現在の範囲設定: $currentRange×$currentRange")
@@ -272,7 +278,7 @@ object BlockPlacementSkillMenu extends Menu {
       val playerData = BuildAssist.instance.temporaryData(getUniqueId)
       val currentRange = playerData.computeCurrentSkillRange()
 
-      val iconItemStack = new SkullItemStackBuilder("MHF_ArrowDown")
+      val iconItemStack = new SkullItemStackBuilder(SkullOwners.MHF_ArrowDown)
         .title(s"$RED$UNDERLINE${BOLD}範囲設定を最小値に変更")
         .lore(
           s"$RESET${AQUA}現在の範囲設定: $currentRange×$currentRange",
diff --git a/src/main/scala/com/github/unchama/buildassist/menu/BuildAssistMenuRouter.scala b/src/main/scala/com/github/unchama/buildassist/menu/BuildAssistMenuRouter.scala
index 5c974a67f1..9580080427 100644
--- a/src/main/scala/com/github/unchama/buildassist/menu/BuildAssistMenuRouter.scala
+++ b/src/main/scala/com/github/unchama/buildassist/menu/BuildAssistMenuRouter.scala
@@ -7,6 +7,7 @@ import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.menus.BuildMainMenu
 import com.github.unchama.seichiassist.subsystems.managedfly.ManagedFlyApi
 import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import org.bukkit.entity.Player
 import org.bukkit.inventory.ItemStack
 
@@ -19,7 +20,8 @@ object BuildAssistMenuRouter {
     implicit flyApi: ManagedFlyApi[SyncIO, Player],
     mineStackAPI: MineStackAPI[IO, Player, ItemStack],
     layoutPreparationContext: LayoutPreparationContext,
-    onMainThread: OnMinecraftServerThread[IO]
+    onMainThread: OnMinecraftServerThread[IO],
+    playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   ): BuildAssistMenuRouter[IO] = new BuildAssistMenuRouter[IO] {
     implicit lazy val blockPlacementSkillMenuEnvironment: BlockPlacementSkillMenu.Environment =
       new BlockPlacementSkillMenu.Environment
diff --git a/src/main/scala/com/github/unchama/buildassist/menu/MineStackMassCraftMenu.scala b/src/main/scala/com/github/unchama/buildassist/menu/MineStackMassCraftMenu.scala
index e3fcd892ea..c62f2235e3 100644
--- a/src/main/scala/com/github/unchama/buildassist/menu/MineStackMassCraftMenu.scala
+++ b/src/main/scala/com/github/unchama/buildassist/menu/MineStackMassCraftMenu.scala
@@ -13,6 +13,7 @@ import com.github.unchama.seichiassist.SkullOwners
 import com.github.unchama.seichiassist.menus.{BuildMainMenu, ColorScheme, CommonButtons}
 import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
 import com.github.unchama.seichiassist.subsystems.minestack.domain.minestackobject.MineStackObject
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.targetedeffect.SequentialEffect
 import com.github.unchama.targetedeffect.TargetedEffect.emptyEffect
 import com.github.unchama.targetedeffect.commandsender.{MessageEffect, MessageEffectF}
@@ -40,7 +41,8 @@ object MineStackMassCraftMenu {
   class Environment(
     implicit val canOpenBuildMainMenu: CanOpen[IO, BuildMainMenu.type],
     val canOpenItself: CanOpen[IO, MineStackMassCraftMenu],
-    val mineStackAPI: MineStackAPI[IO, Player, ItemStack]
+    val mineStackAPI: MineStackAPI[IO, Player, ItemStack],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
   case class MassCraftRecipe(
diff --git a/src/main/scala/com/github/unchama/contextualexecutor/builder/Parsers.scala b/src/main/scala/com/github/unchama/contextualexecutor/builder/Parsers.scala
index 12b9c10096..f8fd70fdcb 100644
--- a/src/main/scala/com/github/unchama/contextualexecutor/builder/Parsers.scala
+++ b/src/main/scala/com/github/unchama/contextualexecutor/builder/Parsers.scala
@@ -93,6 +93,6 @@ object Parsers {
     } catch {
       case _: DateTimeParseException =>
         Left(failureMessage)
-      case e => throw e
+      case e: Throwable => throw e
     }
 }
diff --git a/src/main/scala/com/github/unchama/datarepository/bukkit/player/BukkitRepositoryControls.scala b/src/main/scala/com/github/unchama/datarepository/bukkit/player/BukkitRepositoryControls.scala
index 27063da5f5..182e352452 100644
--- a/src/main/scala/com/github/unchama/datarepository/bukkit/player/BukkitRepositoryControls.scala
+++ b/src/main/scala/com/github/unchama/datarepository/bukkit/player/BukkitRepositoryControls.scala
@@ -164,7 +164,7 @@ object BukkitRepositoryControls {
   private def backupProcess[F[_]: Sync, Key, R](
     finalization: RepositoryFinalization[F, Key, R]
   )(dataMap: TrieMap[Key, R]): F[Unit] = {
-    Sync[F].suspend {
+    Sync[F].defer {
       dataMap.toList.traverse(finalization.persistPair.tupled).as(())
     }
   }
diff --git a/src/main/scala/com/github/unchama/fs2/workaround/fs3/Fs3Topic.scala b/src/main/scala/com/github/unchama/fs2/workaround/fs3/Fs3Topic.scala
index 58bced3bb3..806fdb33ed 100644
--- a/src/main/scala/com/github/unchama/fs2/workaround/fs3/Fs3Topic.scala
+++ b/src/main/scala/com/github/unchama/fs2/workaround/fs3/Fs3Topic.scala
@@ -210,10 +210,8 @@ object Fs3Topic {
           def close: F[Unit] = {
             Bracket[F, Throwable].uncancelable {
               signalClosure.complete(()).flatMap { _ =>
-                state
-                  .get
-                  .flatMap { case (subs, _) => foreach(subs)(_.close.void) }
-                  .as(Fs3Topic.rightUnit)
+                state.get.flatMap { case (subs, _) => foreach(subs)(_.close.void) }
+//                  .as(Fs3Topic.rightUnit)
               }
             }
           }
diff --git a/src/main/scala/com/github/unchama/generic/Diff.scala b/src/main/scala/com/github/unchama/generic/Diff.scala
index 3d517bb6d5..2cd94183b5 100644
--- a/src/main/scala/com/github/unchama/generic/Diff.scala
+++ b/src/main/scala/com/github/unchama/generic/Diff.scala
@@ -7,7 +7,7 @@ import cats.Eq
  *
  * [[A]] に関連付いた [[Eq]] インスタンスによって [[left]] と [[right]] が等価でないと判定されることが保証される。
  */
-case class Diff[A: Eq] private (left: A, right: A)
+case class Diff[A] private (left: A, right: A)
 
 object Diff {
 
diff --git a/src/main/scala/com/github/unchama/generic/ListExtra.scala b/src/main/scala/com/github/unchama/generic/ListExtra.scala
index 57eedb323e..06622109e1 100644
--- a/src/main/scala/com/github/unchama/generic/ListExtra.scala
+++ b/src/main/scala/com/github/unchama/generic/ListExtra.scala
@@ -2,24 +2,6 @@ package com.github.unchama.generic
 
 object ListExtra {
 
-  /**
-   * Listの内容を[[B]]または[[C]]に分類し、
-   * tupleとして返します。
-   */
-  def partitionWith[A, B, C](
-    list: List[A]
-  )(partitioningFunction: A => Either[B, C]): (List[B], List[C]) = {
-    list match {
-      case ::(head, next) =>
-        val partitionedNext = partitionWith(next)(partitioningFunction)
-        partitioningFunction(head) match {
-          case Left(value)  => (value :: partitionedNext._1, partitionedNext._2)
-          case Right(value) => (partitionedNext._1, value :: partitionedNext._2)
-        }
-      case Nil => (Nil, Nil)
-    }
-  }
-
   /**
    * Listの中身で条件に一致するものがあったときに`element`を先頭に追加し直します
    * listの中に与えられたpredicateに合致する要素があった場合、その要素をelementで写して変換します。そのような要素がなかった場合、そのままlistを返却します。
diff --git a/src/main/scala/com/github/unchama/generic/effect/concurrent/AsymmetricSignallingRef.scala b/src/main/scala/com/github/unchama/generic/effect/concurrent/AsymmetricSignallingRef.scala
index a48ed7755b..a287935e9a 100644
--- a/src/main/scala/com/github/unchama/generic/effect/concurrent/AsymmetricSignallingRef.scala
+++ b/src/main/scala/com/github/unchama/generic/effect/concurrent/AsymmetricSignallingRef.scala
@@ -90,7 +90,7 @@ object AsymmetricSignallingRef {
     override val valuesAwait: Resource[F, Stream[F, A]] =
       changeTopic.subscribeAwait(topicQueueSize).flatMap { subscription =>
         Resource
-          .liftF {
+          .eval {
             state.get.map { currentValue =>
               subscription
                 .through(ReorderingPipe.withInitialToken[F, A](currentValue.nextStamp))
diff --git a/src/main/scala/com/github/unchama/generic/effect/concurrent/AsymmetricTryableDeferred.scala b/src/main/scala/com/github/unchama/generic/effect/concurrent/AsymmetricTryableDeferred.scala
index 17373b4c1b..d6debefe1a 100644
--- a/src/main/scala/com/github/unchama/generic/effect/concurrent/AsymmetricTryableDeferred.scala
+++ b/src/main/scala/com/github/unchama/generic/effect/concurrent/AsymmetricTryableDeferred.scala
@@ -119,7 +119,7 @@ object AsymmetricTryableDeferred {
     implicit F: Concurrent[F]
   ) extends AsymmetricTryableDeferred[F, A] {
     def get: F[A] =
-      F.suspend {
+      F.defer {
         ref.get match {
           case State.Set(a) =>
             F.pure(a)
@@ -168,7 +168,7 @@ object AsymmetricTryableDeferred {
     }
 
     def complete(a: A): F[Unit] =
-      F.suspend(unsafeComplete(a))
+      F.defer(unsafeComplete(a))
 
     @tailrec
     private def unsafeComplete(a: A): F[Unit] =
diff --git a/src/main/scala/com/github/unchama/itemmigration/bukkit/targets/WorldLevelData.scala b/src/main/scala/com/github/unchama/itemmigration/bukkit/targets/WorldLevelData.scala
index 54664f1147..e2f66e33c2 100644
--- a/src/main/scala/com/github/unchama/itemmigration/bukkit/targets/WorldLevelData.scala
+++ b/src/main/scala/com/github/unchama/itemmigration/bukkit/targets/WorldLevelData.scala
@@ -74,6 +74,7 @@ object WorldLevelData {
 
         val creator = WorldCreator.name(world.getName).copy(world)
         if (!Bukkit.unloadWorld(world, true)) {
+          // NOTE: Bukkitにデフォルトとして設定されているワールド(初期値world)はアンロードに失敗する
           logger.warn(s"${world.getName}はアンロードされませんでした。")
         }
         Bukkit.createWorld(creator)
@@ -103,13 +104,13 @@ object WorldLevelData {
     }
 
     // メモリ解放を促す
-    if (!world.unloadChunk(chunk)) {
+    if (!world.unloadChunkRequest(chunk.getX, chunk.getZ)) {
       logger.warn(s"チャンク(${chunk.getX}, ${chunk.getZ})はアンロードされませんでした。")
     }
   }
 
   private def queueChunkSaverFlush[F[_]](implicit F: Concurrent[F], logger: Logger) = {
-    import com.github.unchama.util.nms.v1_12_2.world.WorldChunkSaving
+    import com.github.unchama.util.nms.v1_18_2.world.WorldChunkSaving
 
     F.delay {
       logger.info("チャンクの保存キューの処理を要求します…")
@@ -122,12 +123,6 @@ object WorldLevelData {
       .as(())
   }
 
-  private def flushEntityRemovalQueue[F[_]: Sync](worldRef: Ref[F, World]): F[Unit] = {
-    import com.github.unchama.util.nms.v1_12_2.world.WorldChunkSaving
-
-    worldRef.get >>= WorldChunkSaving.flushEntityRemovalQueue[F]
-  }
-
   private def logProgress[F[_]](chunkIndex: Int, totalChunks: Int)(
     worldRef: Ref[F, World]
   )(implicit F: Sync[F], logger: Logger): F[Unit] = {
@@ -143,7 +138,7 @@ object WorldLevelData {
   private final val progressLogInterval = 1000
   private final val reloadWorldInterval = 10000
 
-  def convertChunkWise[F[_]](
+  private def convertChunkWise[F[_]](
     originalWorld: World,
     targetChunks: Seq[(Int, Int)],
     conversion: ItemStack => ItemStack
@@ -168,10 +163,18 @@ object WorldLevelData {
          *
          * OutOfMemoryErrorが観測された際には、プロファイラで残留しているワールドのインスタンスを確認し、
          * GC Rootからの参照パスを特定することを推奨する。
+         *
+         *
+         * 2024/02/20 追記: flushEntityRemovalQueueが短期的なメモリ確保に寄与するとあるが、
+         * 1.12.2から1.18.2にアップデートする際に、この処理内で使われている「EntityRemovalQueue」
+         * というものが1.18.2で存在しているかが不明であること(調べても存在が明らかではなかった)と、
+         * ドキュメントとコードを読む限りパフォーマンス以外の影響がないと思われることから無効化した。
+         * しかしながら、本当に他の影響が出ないかがまだ不鮮明なためコメントアウトにとどめているが、
+         * 本当に影響がないと確認されれば削除して良い。
          */
         chunkConversionEffects
           .atEvery(chunkSaverQueueFlushInterval)(_ =>
-            flushEntityRemovalQueue(worldRef) >> queueChunkSaverFlush
+            /*flushEntityRemovalQueue(worldRef) >>*/ queueChunkSaverFlush
           )
           .atEvery(progressLogInterval)(index =>
             logProgress(index, chunkConversionEffects.size)(worldRef)
diff --git a/src/main/scala/com/github/unchama/itemstackbuilder/AbstractItemStackBuilder.scala b/src/main/scala/com/github/unchama/itemstackbuilder/AbstractItemStackBuilder.scala
index 2048320be8..dd2db3b87a 100644
--- a/src/main/scala/com/github/unchama/itemstackbuilder/AbstractItemStackBuilder.scala
+++ b/src/main/scala/com/github/unchama/itemstackbuilder/AbstractItemStackBuilder.scala
@@ -13,12 +13,10 @@ import org.bukkit.inventory.{ItemFlag, ItemStack}
  * @author
  *   karayuu
  */
-abstract class AbstractItemStackBuilder[-M <: ItemMeta] protected (
-  material: Material,
-  durability: Short
-) extends ItemStackBuilder {
+abstract class AbstractItemStackBuilder[-M <: ItemMeta] protected (material: Material)
+    extends ItemStackBuilder {
 
-  private val component: IconComponent = new IconComponent(material, durability)
+  private val component: IconComponent = new IconComponent(material)
 
   final override def build(): ItemStack = {
     val itemStack = component.itemStack()
diff --git a/src/main/scala/com/github/unchama/itemstackbuilder/IconItemStackBuilder.scala b/src/main/scala/com/github/unchama/itemstackbuilder/IconItemStackBuilder.scala
index 1e1a3fa24b..ff33a32f77 100644
--- a/src/main/scala/com/github/unchama/itemstackbuilder/IconItemStackBuilder.scala
+++ b/src/main/scala/com/github/unchama/itemstackbuilder/IconItemStackBuilder.scala
@@ -12,8 +12,8 @@ import org.bukkit.inventory.meta.ItemMeta
  * @param durability
  *   ダメージ値 Created by karayuu on 2019/03/30
  */
-class IconItemStackBuilder(material: Material, durability: Short = 0.toShort)
-    extends AbstractItemStackBuilder[ItemMeta](material, durability) {
+class IconItemStackBuilder(material: Material)
+    extends AbstractItemStackBuilder[ItemMeta](material) {
   private var shouldShowAttribute: Boolean = false
 
   /**
diff --git a/src/main/scala/com/github/unchama/itemstackbuilder/SkullItemStackBuilder.scala b/src/main/scala/com/github/unchama/itemstackbuilder/SkullItemStackBuilder.scala
index 32a5326e42..3e8c417fb8 100644
--- a/src/main/scala/com/github/unchama/itemstackbuilder/SkullItemStackBuilder.scala
+++ b/src/main/scala/com/github/unchama/itemstackbuilder/SkullItemStackBuilder.scala
@@ -1,50 +1,44 @@
 package com.github.unchama.itemstackbuilder
 
+import cats.effect.IO
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.mojang.authlib.GameProfile
 import com.mojang.authlib.properties.Property
+import org.bukkit.entity.Player
 import org.bukkit.inventory.meta.SkullMeta
-import org.bukkit.{Bukkit, Material, SkullType}
+import org.bukkit.{Bukkit, Material}
 
+import java.net.URI
 import java.util.UUID
 
-/**
- * Created by karayuu on 2019/04/09
- */
-class SkullItemStackBuilder(private val owner: SkullOwnerReference)
-    extends AbstractItemStackBuilder[SkullMeta](
-      Material.SKULL_ITEM,
-      SkullType.PLAYER.ordinal.toShort
-    ) {
+class SkullItemStackBuilder(private val owner: SkullOwnerReference)(
+  implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
+) extends AbstractItemStackBuilder[SkullMeta](Material.PLAYER_HEAD) {
 
   /**
-   * プレーヤーがサーバーに参加したことのない場合に 頭のスキンを読み込むことができないため、そのようなケースが想定されるされる箇所では
-   * プレーヤー名を[[String]]として取るコンストラクタを使用せよ。
-   *
-   * それ以外の場合はこのコンストラクタを使うようにせよ。 Bukkitは`Persistent storage of users should be by UUID`と記している。
-   *
-   * @see
-   *   SkullMeta.setOwner
    * @param ownerUUID
-   *   [Material.SKULL_ITEM] に表示するプレーヤーのUUID
+   *   [Material.PLAYER_HEAD] に表示するプレーヤーのUUID
    */
-  def this(ownerUUID: UUID) = this(SkullOwnerUuid(ownerUUID))
+  def this(ownerUUID: UUID)(implicit playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]) =
+    this(SkullOwnerUuid(ownerUUID))(playerHeadSkinAPI)
 
-  /**
-   * @param ownerName
-   *   [Material.SKULL_ITEM] に表示するプレーヤーの名前
-   */
-  def this(ownerName: String) = this(SkullOwnerName(ownerName))
-
-  override def transformItemMetaOnBuild(meta: SkullMeta): Unit = {
+  override protected def transformItemMetaOnBuild(meta: SkullMeta): Unit = {
     owner match {
       case SkullOwnerUuid(uuid) =>
         meta.setOwningPlayer(Bukkit.getOfflinePlayer(uuid))
-      case SkullOwnerName(name) =>
-        /**
-         * 参加したことのないプレーヤーはgetOfflinePlayerでデータが取れないのでこうするしか無い
-         */
-        // noinspection ScalaDeprecation
-        meta.setOwner(name)
+
+        playerHeadSkinAPI.playerHeadSkinUrlByUUID(uuid).unsafeRunSync() match {
+          case Some(url) =>
+            val playerProfile = Bukkit.createPlayerProfile(uuid)
+            playerProfile.getTextures.setSkin(URI.create(url.url).toURL)
+            meta.setOwnerProfile(playerProfile)
+          case None =>
+        }
+
+      case SkullOwnerUuidWithNameWithTextureUrl(uuid, name, url) =>
+        val playerProfile = Bukkit.createPlayerProfile(uuid, name)
+        playerProfile.getTextures.setSkin(URI.create(url).toURL)
+        meta.setOwnerProfile(playerProfile)
 
       /**
        * @see
diff --git a/src/main/scala/com/github/unchama/itemstackbuilder/SkullOwnerReference.scala b/src/main/scala/com/github/unchama/itemstackbuilder/SkullOwnerReference.scala
index 9f86fd223a..0774e700e3 100644
--- a/src/main/scala/com/github/unchama/itemstackbuilder/SkullOwnerReference.scala
+++ b/src/main/scala/com/github/unchama/itemstackbuilder/SkullOwnerReference.scala
@@ -6,9 +6,14 @@ sealed trait SkullOwnerReference
 
 case class SkullOwnerUuid(uuid: UUID) extends SkullOwnerReference
 
-case class SkullOwnerName(name: String) extends SkullOwnerReference
-
 /**
  * UUID指定だけでは、カスタムテクスチャをヘッドに設定することができない場合に備えて、`TextureValue`を指定するもの
  */
 case class SkullOwnerTextureValue(textureValue: String) extends SkullOwnerReference
+
+/**
+ * `textureUrl`は以下の記事の方法で取得されたスキンのURL
+ * @see https://qiita.com/yuta0801/items/edb4804dfb867ea82c5a
+ */
+case class SkullOwnerUuidWithNameWithTextureUrl(uuid: UUID, name: String, textureUrl: String)
+    extends SkullOwnerReference
diff --git a/src/main/scala/com/github/unchama/itemstackbuilder/TippedArrowIconItemStackBuilder.scala b/src/main/scala/com/github/unchama/itemstackbuilder/TippedArrowIconItemStackBuilder.scala
index 2cfde169b9..02113dd995 100644
--- a/src/main/scala/com/github/unchama/itemstackbuilder/TippedArrowIconItemStackBuilder.scala
+++ b/src/main/scala/com/github/unchama/itemstackbuilder/TippedArrowIconItemStackBuilder.scala
@@ -6,7 +6,7 @@ import org.bukkit.inventory.meta.PotionMeta
 import org.bukkit.potion.{PotionData, PotionType}
 
 class TippedArrowIconItemStackBuilder(val potionData: PotionData)
-    extends AbstractItemStackBuilder[PotionMeta](Material.TIPPED_ARROW, 0) {
+    extends AbstractItemStackBuilder[PotionMeta](Material.TIPPED_ARROW) {
 
   def this(potionType: PotionType) = this(new PotionData(potionType))
 
diff --git a/src/main/scala/com/github/unchama/itemstackbuilder/component/IconComponent.scala b/src/main/scala/com/github/unchama/itemstackbuilder/component/IconComponent.scala
index f36c28c4b1..9164c87019 100644
--- a/src/main/scala/com/github/unchama/itemstackbuilder/component/IconComponent.scala
+++ b/src/main/scala/com/github/unchama/itemstackbuilder/component/IconComponent.scala
@@ -13,7 +13,7 @@ import scala.jdk.javaapi.CollectionConverters.asJava
  *
  * Created by karayuu on 2019/04/09
  */
-class IconComponent(val material: Material, private val durability: Short = 0.toShort) {
+class IconComponent(val material: Material) {
   var title: String = Bukkit.getItemFactory.getItemMeta(material).ifNotNull(_.getDisplayName)
   var lore: List[String] = Nil
 
@@ -24,7 +24,7 @@ class IconComponent(val material: Material, private val durability: Short = 0.to
 
   var itemFlagSet: Set[ItemFlag] = Set()
 
-  def itemStack(): ItemStack = new ItemStack(material, amount, durability)
+  def itemStack(): ItemStack = new ItemStack(material, amount)
 
   def itemMeta(): ItemMeta = {
     val meta = Bukkit.getItemFactory.getItemMeta(material)
diff --git a/src/main/scala/com/github/unchama/minecraft/algebra/HasName.scala b/src/main/scala/com/github/unchama/minecraft/algebra/HasName.scala
new file mode 100644
index 0000000000..6c6a340a5c
--- /dev/null
+++ b/src/main/scala/com/github/unchama/minecraft/algebra/HasName.scala
@@ -0,0 +1,13 @@
+package com.github.unchama.minecraft.algebra
+
+trait HasName[T] {
+
+  def of(x: T): String
+
+}
+
+object HasName {
+
+  def apply[T](implicit ev: HasName[T]): HasName[T] = ev
+
+}
diff --git a/src/main/scala/com/github/unchama/minecraft/bukkit/actions/BroadcastBukkitMessage.scala b/src/main/scala/com/github/unchama/minecraft/bukkit/actions/BroadcastBukkitMessage.scala
index a94d055081..42b34164da 100644
--- a/src/main/scala/com/github/unchama/minecraft/bukkit/actions/BroadcastBukkitMessage.scala
+++ b/src/main/scala/com/github/unchama/minecraft/bukkit/actions/BroadcastBukkitMessage.scala
@@ -1,10 +1,10 @@
 package com.github.unchama.minecraft.bukkit.actions
 
-import cats.effect.{Sync, SyncIO}
+import cats.effect.SyncIO
 import com.github.unchama.minecraft.actions.{BroadcastMinecraftMessage, OnMinecraftServerThread}
 import org.bukkit.Bukkit
 
-class BroadcastBukkitMessage[F[_]: Sync: OnMinecraftServerThread]
+class BroadcastBukkitMessage[F[_]: OnMinecraftServerThread]
     extends BroadcastMinecraftMessage[F] {
 
   import scala.jdk.CollectionConverters._
@@ -19,7 +19,7 @@ class BroadcastBukkitMessage[F[_]: Sync: OnMinecraftServerThread]
 
 object BroadcastBukkitMessage {
 
-  def apply[F[_]: Sync: OnMinecraftServerThread]: BroadcastMinecraftMessage[F] =
+  def apply[F[_]: OnMinecraftServerThread]: BroadcastMinecraftMessage[F] =
     new BroadcastBukkitMessage[F]
 
 }
diff --git a/src/main/scala/com/github/unchama/minecraft/bukkit/actions/GetConnectedBukkitPlayers.scala b/src/main/scala/com/github/unchama/minecraft/bukkit/actions/GetConnectedBukkitPlayers.scala
index 0684e38bbf..df103ae51c 100644
--- a/src/main/scala/com/github/unchama/minecraft/bukkit/actions/GetConnectedBukkitPlayers.scala
+++ b/src/main/scala/com/github/unchama/minecraft/bukkit/actions/GetConnectedBukkitPlayers.scala
@@ -1,11 +1,11 @@
 package com.github.unchama.minecraft.bukkit.actions
 
-import cats.effect.{Sync, SyncIO}
+import cats.effect.SyncIO
 import com.github.unchama.minecraft.actions.{GetConnectedPlayers, OnMinecraftServerThread}
 import org.bukkit.Bukkit
 import org.bukkit.entity.Player
 
-class GetConnectedBukkitPlayers[F[_]: Sync: OnMinecraftServerThread]
+class GetConnectedBukkitPlayers[F[_]: OnMinecraftServerThread]
     extends GetConnectedPlayers[F, Player] {
 
   import scala.jdk.CollectionConverters._
diff --git a/src/main/scala/com/github/unchama/minecraft/bukkit/algebra/BukkitPlayerHasName.scala b/src/main/scala/com/github/unchama/minecraft/bukkit/algebra/BukkitPlayerHasName.scala
new file mode 100644
index 0000000000..c6e3f153fa
--- /dev/null
+++ b/src/main/scala/com/github/unchama/minecraft/bukkit/algebra/BukkitPlayerHasName.scala
@@ -0,0 +1,16 @@
+package com.github.unchama.minecraft.bukkit.algebra
+
+import com.github.unchama.minecraft.algebra.HasName
+import org.bukkit.entity.Player
+
+class BukkitPlayerHasName extends HasName[Player] {
+
+  override def of(x: Player): String = x.getName
+
+}
+
+object BukkitPlayerHasName {
+
+  implicit val instance: HasName[Player] = new BukkitPlayerHasName
+
+}
diff --git a/src/main/scala/com/github/unchama/minecraft/bukkit/objects/BukkitMaterial.scala b/src/main/scala/com/github/unchama/minecraft/bukkit/objects/BukkitMaterial.scala
index 67e7db1990..48b02de127 100644
--- a/src/main/scala/com/github/unchama/minecraft/bukkit/objects/BukkitMaterial.scala
+++ b/src/main/scala/com/github/unchama/minecraft/bukkit/objects/BukkitMaterial.scala
@@ -5,6 +5,7 @@ import org.bukkit.Material
 import org.bukkit.inventory.ItemStack
 
 class BukkitMaterial extends MinecraftMaterial[Material, ItemStack] {
-  override def toItemStack(material: Material, durability: Short): ItemStack =
-    new ItemStack(material, 1, durability)
+  override def toItemStack(material: Material): ItemStack =
+    new ItemStack(material, 1)
+
 }
diff --git a/src/main/scala/com/github/unchama/minecraft/objects/MinecraftMaterial.scala b/src/main/scala/com/github/unchama/minecraft/objects/MinecraftMaterial.scala
index 8446c9c693..e2b567916b 100644
--- a/src/main/scala/com/github/unchama/minecraft/objects/MinecraftMaterial.scala
+++ b/src/main/scala/com/github/unchama/minecraft/objects/MinecraftMaterial.scala
@@ -5,6 +5,6 @@ package com.github.unchama.minecraft.objects
  */
 trait MinecraftMaterial[Material, ItemStack] {
 
-  def toItemStack(material: Material, durability: Short): ItemStack
+  def toItemStack(material: Material): ItemStack
 
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/ManagedWorld.scala b/src/main/scala/com/github/unchama/seichiassist/ManagedWorld.scala
index a7cc146843..2621cafc9a 100644
--- a/src/main/scala/com/github/unchama/seichiassist/ManagedWorld.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/ManagedWorld.scala
@@ -83,6 +83,8 @@ case object ManagedWorld extends Enum[ManagedWorld] {
 
     def isSeichi: Boolean = asManagedWorld().exists(_.isSeichi)
 
+    def isNotSeichi: Boolean = !isSeichi
+
     def shouldTrackBuildBlock: Boolean = asManagedWorld().exists(_.shouldTrackBuildBlock)
 
     def isSeichiSkillAllowed: Boolean = asManagedWorld().exists(_.isSeichiSkillAllowed)
diff --git a/src/main/scala/com/github/unchama/seichiassist/MaterialSets.scala b/src/main/scala/com/github/unchama/seichiassist/MaterialSets.scala
index 5f8a9a6498..426abbe212 100644
--- a/src/main/scala/com/github/unchama/seichiassist/MaterialSets.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/MaterialSets.scala
@@ -7,151 +7,150 @@ import org.bukkit.block.Block
 import org.bukkit.inventory.ItemStack
 
 object MaterialSets {
-  val fortuneMaterials: Set[Material] = Set(
-    Material.COAL_ORE,
-    Material.DIAMOND_ORE,
-    Material.LAPIS_ORE,
-    Material.EMERALD_ORE,
-    Material.REDSTONE_ORE,
-    Material.GLOWING_REDSTONE_ORE,
-    Material.QUARTZ_ORE,
-    Material.MELON_BLOCK,
-    Material.SEA_LANTERN
-  )
+
+  private val notApplicableSeichiSkillMaterials =
+    Set(
+      Material.WATER,
+      Material.LAVA,
+      Material.AIR,
+      Material.BEDROCK,
+      Material.TORCH,
+      Material.SOUL_TORCH,
+      Material.REDSTONE_TORCH,
+      Material.REPEATER,
+      Material.COMPARATOR,
+      Material.END_ROD,
+      Material.FIRE,
+      Material.WHITE_CARPET,
+      Material.ORANGE_CARPET,
+      Material.MAGENTA_CARPET,
+      Material.LIGHT_BLUE_CARPET,
+      Material.YELLOW_CARPET,
+      Material.LIME_CARPET,
+      Material.PINK_CARPET,
+      Material.GRAY_CARPET,
+      Material.LIGHT_GRAY_CARPET,
+      Material.CYAN_CARPET,
+      Material.PURPLE_CARPET,
+      Material.BLUE_CARPET,
+      Material.BROWN_CARPET,
+      Material.GREEN_CARPET,
+      Material.RED_CARPET,
+      Material.BLACK_CARPET,
+      Material.WHITE_BANNER,
+      Material.ORANGE_BANNER,
+      Material.MAGENTA_BANNER,
+      Material.LIGHT_BLUE_BANNER,
+      Material.YELLOW_BANNER,
+      Material.LIME_BANNER,
+      Material.PINK_BANNER,
+      Material.GRAY_BANNER,
+      Material.LIGHT_GRAY_BANNER,
+      Material.CYAN_BANNER,
+      Material.PURPLE_BANNER,
+      Material.BLUE_BANNER,
+      Material.BROWN_BANNER,
+      Material.GREEN_BANNER,
+      Material.RED_BANNER,
+      Material.BLACK_BANNER,
+      Material.RAIL,
+      Material.POWERED_RAIL,
+      Material.ACTIVATOR_RAIL,
+      Material.DETECTOR_RAIL,
+      Material.REDSTONE,
+      Material.REDSTONE_WIRE,
+      Material.TRIPWIRE_HOOK,
+      Material.OAK_WALL_SIGN,
+      Material.SPRUCE_WALL_SIGN,
+      Material.BIRCH_WALL_SIGN,
+      Material.ACACIA_WALL_SIGN,
+      Material.JUNGLE_WALL_SIGN,
+      Material.DARK_OAK_WALL_SIGN,
+      Material.WARPED_WALL_SIGN,
+      Material.OAK_SIGN,
+      Material.SPRUCE_SIGN,
+      Material.BIRCH_SIGN,
+      Material.ACACIA_SIGN,
+      Material.JUNGLE_SIGN,
+      Material.DARK_OAK_SIGN,
+      Material.WARPED_SIGN,
+      Material.LEVER,
+      Material.STONE_BUTTON,
+      Material.POLISHED_BLACKSTONE_BUTTON,
+      Material.OAK_BUTTON,
+      Material.SPRUCE_BUTTON,
+      Material.BIRCH_BUTTON,
+      Material.JUNGLE_BUTTON,
+      Material.ACACIA_BUTTON,
+      Material.DARK_OAK_BUTTON,
+      Material.CRIMSON_BUTTON,
+      Material.WARPED_BUTTON,
+      Material.STONE_PRESSURE_PLATE,
+      Material.POLISHED_BLACKSTONE_PRESSURE_PLATE,
+      Material.LIGHT_WEIGHTED_PRESSURE_PLATE,
+      Material.HEAVY_WEIGHTED_PRESSURE_PLATE,
+      Material.OAK_PRESSURE_PLATE,
+      Material.SPRUCE_PRESSURE_PLATE,
+      Material.BIRCH_PRESSURE_PLATE,
+      Material.JUNGLE_PRESSURE_PLATE,
+      Material.ACACIA_PRESSURE_PLATE,
+      Material.DARK_OAK_PRESSURE_PLATE,
+      Material.CRIMSON_PRESSURE_PLATE,
+      Material.WARPED_PRESSURE_PLATE,
+      Material.DROPPER,
+      Material.PISTON,
+      Material.OAK_SAPLING,
+      Material.SPRUCE_SAPLING,
+      Material.BIRCH_SAPLING,
+      Material.JUNGLE_SAPLING,
+      Material.ACACIA_SAPLING,
+      Material.DARK_OAK_SAPLING,
+      Material.DEAD_BUSH,
+      Material.SEA_PICKLE,
+      Material.CORNFLOWER,
+      Material.LILY_OF_THE_VALLEY,
+      Material.WITHER_ROSE,
+      Material.SPORE_BLOSSOM,
+      Material.IRON_BLOCK,
+      Material.COPPER_BLOCK,
+      Material.DIAMOND_BLOCK,
+      Material.NETHERITE_BLOCK,
+      Material.FLOWER_POT,
+      Material.ANVIL,
+      Material.BEACON,
+      Material.ENCHANTING_TABLE,
+      Material.LADDER,
+      Material.SNOW,
+      Material.WITHER_SKELETON_SKULL,
+      Material.DRAGON_HEAD,
+      Material.PLAYER_HEAD,
+      Material.SHULKER_BOX,
+      Material.JUKEBOX,
+      Material.HOPPER,
+      Material.DAYLIGHT_DETECTOR,
+      Material.OBSERVER,
+      Material.CAKE,
+      Material.NOTE_BLOCK,
+      Material.REDSTONE_LAMP,
+      Material.EMERALD_BLOCK,
+      Material.COAL_BLOCK,
+      Material.LAPIS_BLOCK
+    )
 
   // このMaterialは整地スキルに対応する
-  val materials: Set[Material] = Set(
-    Material.STONE,
-    Material.NETHERRACK,
-    Material.NETHER_BRICK,
-    Material.DIRT,
-    Material.GRAVEL,
-    Material.LOG,
-    Material.LOG_2,
-    Material.GRASS,
-    Material.IRON_ORE,
-    Material.GOLD_ORE,
-    Material.SAND,
-    Material.SANDSTONE,
-    Material.RED_SANDSTONE,
-    Material.END_BRICKS,
-    Material.ENDER_STONE,
-    Material.ICE,
-    Material.PACKED_ICE,
-    Material.OBSIDIAN,
-    Material.MAGMA,
-    Material.SOUL_SAND,
-    Material.LEAVES,
-    Material.LEAVES_2,
-    Material.CLAY,
-    Material.STAINED_CLAY,
-    Material.COBBLESTONE,
-    Material.MOSSY_COBBLESTONE,
-    Material.HARD_CLAY,
-    Material.MONSTER_EGGS,
-    Material.WEB,
-    Material.WOOD,
-    Material.FENCE,
-    Material.DARK_OAK_FENCE,
-    Material.RAILS,
-    Material.MYCEL,
-    Material.SNOW_BLOCK,
-    Material.HUGE_MUSHROOM_1,
-    Material.HUGE_MUSHROOM_2,
-    Material.BONE_BLOCK,
-    Material.PURPUR_BLOCK,
-    Material.PURPUR_PILLAR,
-    Material.SEA_LANTERN,
-    Material.PRISMARINE,
-    Material.SMOOTH_BRICK,
-    Material.GLOWSTONE,
-    Material.STAINED_GLASS,
-    Material.STAINED_GLASS_PANE,
-    Material.THIN_GLASS,
-    Material.GLASS,
-    Material.WOOD_STAIRS,
-    Material.BIRCH_WOOD_STAIRS,
-    Material.SPRUCE_WOOD_STAIRS,
-    Material.ACACIA_STAIRS,
-    Material.DARK_OAK_STAIRS,
-    Material.BIRCH_FENCE,
-    Material.SPRUCE_FENCE,
-    Material.ACACIA_FENCE,
-    Material.FENCE_GATE,
-    Material.BIRCH_FENCE_GATE,
-    Material.SPRUCE_FENCE_GATE,
-    Material.ACACIA_FENCE_GATE,
-    Material.DARK_OAK_FENCE_GATE,
-    Material.COBBLESTONE_STAIRS,
-    Material.SANDSTONE_STAIRS,
-    Material.BRICK_STAIRS,
-    Material.QUARTZ_STAIRS,
-    Material.BOOKSHELF,
-    Material.IRON_FENCE,
-    Material.ICE,
-    Material.WOOL,
-    Material.GOLD_BLOCK,
-    Material.END_ROD,
-    Material.PUMPKIN,
-    Material.MELON_BLOCK,
-    Material.STONE_SLAB2,
-    Material.SPONGE,
-    Material.SOIL,
-    Material.GRASS_PATH,
-    Material.MOB_SPAWNER,
-    Material.WORKBENCH,
-    Material.FURNACE,
-    Material.QUARTZ_BLOCK,
-    Material.CHEST,
-    Material.TRAPPED_CHEST,
-    Material.NETHER_FENCE,
-    Material.NETHER_BRICK_STAIRS,
-    Material.CAULDRON,
-    Material.END_ROD,
-    Material.PURPUR_STAIRS,
-    Material.END_BRICKS,
-    Material.PURPUR_SLAB,
-    Material.ENDER_CHEST,
-    Material.PURPUR_SLAB,
-    Material.STEP,
-    Material.DOUBLE_STEP,
-    Material.ENDER_PORTAL_FRAME,
-    Material.ENDER_PORTAL,
-    Material.VINE,
-    // #913
-    Material.BED_BLOCK,
-    Material.TRAP_DOOR,
-    Material.IRON_TRAPDOOR,
-    Material.CARPET,
-    Material.IRON_DOOR_BLOCK,
-    // 木のドアはそれぞれMaterialが別れている
-    Material.WOODEN_DOOR,
-    Material.ACACIA_DOOR,
-    Material.BIRCH_DOOR,
-    Material.DARK_OAK_DOOR,
-    Material.JUNGLE_DOOR,
-    Material.SPRUCE_DOOR,
-    Material.SMOOTH_STAIRS,
-    Material.BREWING_STAND,
-    Material.WOOD_STEP,
-    Material.TNT,
-    // #1027,#1159
-    Material.WOOD_STEP,
-    Material.WOOD_DOUBLE_STEP,
-    Material.DISPENSER,
-    Material.PISTON_STICKY_BASE,
-    Material.WEB
-  ) ++ fortuneMaterials
+  // TODO(1.18): 1.18のコードに書き換えるときに、materialsの列挙をホワイトリスト方式からブラックリスト方式に書き換えたので、
+  //  元のコードとMaterial.values()のdiffを取って、なぜホワイトリスト方式が採用されたかを考えてみる
+  val materials: Set[Material] = Material.values().toSet.diff(notApplicableSeichiSkillMaterials)
 
   // これらのマテリアルを持つブロックは破壊を整地量に計上しない
   val exclude: Set[Material] = Set(
-    Material.GRASS_PATH,
-    Material.SOIL,
-    Material.MOB_SPAWNER,
+    Material.DIRT_PATH,
+    Material.FARMLAND,
+    Material.SPAWNER,
     Material.CAULDRON,
     Material.ENDER_CHEST,
-    Material.ENDER_PORTAL_FRAME,
-    Material.ENDER_PORTAL
+    Material.END_PORTAL_FRAME,
+    Material.END_PORTAL
   )
 
   val materialsToCountBlockBreak: Set[Material] = materials -- exclude
@@ -163,21 +162,25 @@ object MaterialSets {
    *
    * 例えば石をシャベルで掘った時にも、ツールのエンチャントを保ったままダイヤツルハシで掘ったものとして計算し、 結果得られるスタック数が最大のものが結果として採用される。
    */
-  val breakTestToolMaterials: Seq[Material] =
-    Seq(Material.DIAMOND_PICKAXE, Material.DIAMOND_AXE, Material.DIAMOND_SPADE)
+  private val breakTestToolMaterials: Set[Material] =
+    Set(Material.DIAMOND_PICKAXE, Material.DIAMOND_AXE, Material.DIAMOND_SHOVEL)
 
   val breakToolMaterials: Set[Material] = Set(
-    Material.WOOD_PICKAXE,
-    Material.WOOD_SPADE,
+    Material.WOODEN_AXE,
+    Material.WOODEN_PICKAXE,
+    Material.WOODEN_SHOVEL,
     Material.STONE_PICKAXE,
     Material.STONE_AXE,
-    Material.STONE_SPADE,
+    Material.STONE_SHOVEL,
     Material.IRON_PICKAXE,
     Material.IRON_AXE,
-    Material.IRON_SPADE,
-    Material.GOLD_PICKAXE,
-    Material.GOLD_AXE,
-    Material.GOLD_SPADE
+    Material.IRON_SHOVEL,
+    Material.GOLDEN_PICKAXE,
+    Material.GOLDEN_AXE,
+    Material.GOLDEN_SHOVEL,
+    Material.NETHERITE_PICKAXE,
+    Material.NETHERITE_AXE,
+    Material.NETHERITE_SHOVEL
   ) ++ breakTestToolMaterials
 
   val cancelledMaterials: Set[Material] = Set(
@@ -189,10 +192,15 @@ object MaterialSets {
     Material.BEACON,
     Material.BIRCH_DOOR,
     Material.BIRCH_FENCE_GATE,
-    Material.BIRCH_WOOD_STAIRS,
-    Material.BOAT,
+    Material.BIRCH_STAIRS,
+    Material.BIRCH_BOAT,
+    Material.OAK_BOAT,
+    Material.ACACIA_BOAT,
+    Material.JUNGLE_BOAT,
+    Material.DARK_OAK_BOAT,
+    Material.SPRUCE_BOAT,
     Material.FURNACE,
-    Material.WORKBENCH,
+    Material.CRAFTING_TABLE,
     Material.HOPPER,
     Material.MINECART
   )
@@ -200,7 +208,19 @@ object MaterialSets {
   val transparentMaterials: Set[Material] = Set(Material.BEDROCK, Material.AIR)
 
   val gravityMaterials: Set[Material] =
-    Set(Material.LOG, Material.LOG_2, Material.LEAVES, Material.LEAVES_2)
+    Set(
+      Material.ACACIA_LOG,
+      Material.BIRCH_LOG,
+      Material.DARK_OAK_LOG,
+      Material.JUNGLE_LOG,
+      Material.OAK_LOG,
+      Material.OAK_LEAVES,
+      Material.BIRCH_LEAVES,
+      Material.JUNGLE_LEAVES,
+      Material.ACACIA_LEAVES,
+      Material.DARK_OAK_LEAVES,
+      Material.SPRUCE_LEAVES
+    )
 
   val fluidMaterials: Set[Material] =
     Set(Material.WATER, Material.LAVA)
diff --git a/src/main/scala/com/github/unchama/seichiassist/SeichiAssist.scala b/src/main/scala/com/github/unchama/seichiassist/SeichiAssist.scala
index b77a5063e8..f7359a6b8b 100644
--- a/src/main/scala/com/github/unchama/seichiassist/SeichiAssist.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/SeichiAssist.scala
@@ -59,6 +59,7 @@ import com.github.unchama.seichiassist.menus.{BuildMainMenu, TopLevelRouter}
 import com.github.unchama.seichiassist.meta.subsystem.Subsystem
 import com.github.unchama.seichiassist.subsystems._
 import com.github.unchama.seichiassist.subsystems.anywhereender.AnywhereEnderChestAPI
+import com.github.unchama.seichiassist.subsystems.autosave.application.SystemConfiguration
 import com.github.unchama.seichiassist.subsystems.breakcount.{BreakCountAPI, BreakCountReadAPI}
 import com.github.unchama.seichiassist.subsystems.breakcountbar.BreakCountBarAPI
 import com.github.unchama.seichiassist.subsystems.breakskilltargetconfig.BreakSkillTargetConfigAPI
@@ -86,6 +87,7 @@ import com.github.unchama.seichiassist.subsystems.mana.{ManaApi, ManaReadApi}
 import com.github.unchama.seichiassist.subsystems.managedfly.ManagedFlyApi
 import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
 import com.github.unchama.seichiassist.subsystems.minestack.bukkit.MineStackCommand
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.present.infrastructure.GlobalPlayerAccessor
 import com.github.unchama.seichiassist.subsystems.seasonalevents.api.SeasonalEventsAPI
 import com.github.unchama.seichiassist.subsystems.sharedinventory.SharedInventoryAPI
@@ -221,7 +223,6 @@ class SeichiAssist extends JavaPlugin() {
 
   private lazy val itemMigrationSystem: subsystems.itemmigration.System[IO] = {
     import PluginExecutionContexts.asyncShift
-    implicit val effectEnvironment: EffectEnvironment = DefaultEffectEnvironment
 
     subsystems.itemmigration.System.wired[IO, SyncIO].unsafeRunSync()
   }
@@ -259,6 +260,9 @@ class SeichiAssist extends JavaPlugin() {
     implicit val globalNotification: DiscordNotificationAPI[IO] =
       discordNotificationSystem.globalNotification
 
+    implicit val getConnectedPlayers: GetConnectedPlayers[IO, Player] =
+      new GetConnectedBukkitPlayers[IO]
+
     subsystems.buildcount.System.wired[IO, SyncIO].unsafeRunSync()
   }
 
@@ -291,6 +295,7 @@ class SeichiAssist extends JavaPlugin() {
     implicit val concurrentEffect: ConcurrentEffect[IO] = IO.ioConcurrentEffect(asyncShift)
     implicit val manaApi: ManaApi[IO, SyncIO, Player] = manaSystem.manaApi
     implicit val gtToSiinaAPI: GtToSiinaAPI[ItemStack] = gtToSiinaSystem.api
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player] = playerHeadSkinSystem.api
 
     subsystems.seasonalevents.System.wired[IO, SyncIO, IO](this)
   }
@@ -344,8 +349,7 @@ class SeichiAssist extends JavaPlugin() {
     import PluginExecutionContexts.{asyncShift, onMainThread, timer}
 
     implicit val concurrentEffect: ConcurrentEffect[IO] = IO.ioConcurrentEffect(asyncShift)
-    implicit val getConnectedPlayers: GetConnectedPlayers[IO, Player] =
-      new GetConnectedBukkitPlayers[IO]
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player] = playerHeadSkinSystem.api
 
     subsystems.gachapoint.System.wired[IO, SyncIO](breakCountSystem.api).unsafeRunSync()
   }
@@ -385,7 +389,6 @@ class SeichiAssist extends JavaPlugin() {
   private lazy val presentSystem: Subsystem[IO] = {
     import PluginExecutionContexts.{asyncShift, onMainThread}
 
-    implicit val effectEnvironment: EffectEnvironment = DefaultEffectEnvironment
     implicit val concurrentEffect: ConcurrentEffect[IO] = IO.ioConcurrentEffect(asyncShift)
     implicit val uuidToLastSeenName: UuidToLastSeenName[IO] = new GlobalPlayerAccessor[IO]
     subsystems.present.System.wired
@@ -405,7 +408,7 @@ class SeichiAssist extends JavaPlugin() {
     mineStackSystem.api
 
   private lazy val sharedInventorySystem: subsystems.sharedinventory.System[IO] = {
-    import PluginExecutionContexts.timer
+    import PluginExecutionContexts.{timer, onMainThread}
     subsystems.sharedinventory.System.wired[IO, IO].unsafeRunSync()
   }
 
@@ -417,6 +420,8 @@ class SeichiAssist extends JavaPlugin() {
 
   private lazy val gachaSystem: subsystems.gacha.System[IO, Player] = {
     implicit val gachaTicketAPI: GachaTicketAPI[IO] = gachaTicketSystem.api
+    implicit val getConnectedPlayers: GetConnectedPlayers[IO, Player] =
+      new GetConnectedBukkitPlayers[IO]
 
     subsystems.gacha.System.wired[IO]
   }
@@ -435,6 +440,8 @@ class SeichiAssist extends JavaPlugin() {
 
   private lazy val gachaTradeSystem: Subsystem[IO] = {
     implicit val gachaPointApi: GachaPointApi[IO, SyncIO, Player] = gachaPointSystem.api
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player] = playerHeadSkinSystem.api
+
     subsystems.tradesystems.subsystems.gachatrade.System.wired[IO, SyncIO]
   }
 
@@ -460,6 +467,7 @@ class SeichiAssist extends JavaPlugin() {
   // TODO: これはprivateであるべきだが、Achievementシステムが再実装されるまでやむを得ずpublicにする
   lazy val voteSystem: subsystems.vote.System[IO, Player] = {
     implicit val breakCountAPI: BreakCountAPI[IO, SyncIO, Player] = breakCountSystem.api
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player] = playerHeadSkinSystem.api
 
     subsystems.vote.System.wired[IO, SyncIO]
   }
@@ -495,6 +503,27 @@ class SeichiAssist extends JavaPlugin() {
   private lazy val gridRegionSystem: subsystems.gridregion.System[IO, Player, Location] =
     subsystems.gridregion.System.wired[IO, SyncIO].unsafeRunSync()
 
+  private lazy val joinAndQuitMessenger: Subsystem[IO] =
+    subsystems.joinandquitmessenger.System.wired[IO]
+
+  private lazy val elevatorSystem: Subsystem[IO] = {
+    implicit val effectEnvironment: EffectEnvironment = DefaultEffectEnvironment
+
+    subsystems.elevator.System.wired[IO]
+  }
+
+  private lazy val blockLiquidStreamSystem: Subsystem[IO] =
+    subsystems.blockliquidstream.System.wired[IO]
+
+  private lazy val cancelDamageByFallingBlocksSystem: Subsystem[IO] =
+    subsystems.canceldamagebyfallingblocks.System.wired[IO]
+
+  private lazy val playerHeadSkinSystem: subsystems.playerheadskin.System[IO, Player] = {
+    import PluginExecutionContexts.asyncShift
+
+    subsystems.playerheadskin.System.wired[IO]
+  }
+
   private lazy val wiredSubsystems: List[Subsystem[IO]] = List(
     mebiusSystem,
     expBottleStackSystem,
@@ -532,13 +561,19 @@ class SeichiAssist extends JavaPlugin() {
     consumeGachaTicketSystem,
     openirontrapdoor.System.wired,
     gridRegionSystem,
-    breakSkillTargetConfigSystem
+    breakSkillTargetConfigSystem,
+    joinAndQuitMessenger,
+    elevatorSystem,
+    blockLiquidStreamSystem,
+    cancelDamageByFallingBlocksSystem,
+    playerHeadSkinSystem
   )
 
   private lazy val buildAssist: BuildAssist = {
     implicit val flyApi: ManagedFlyApi[SyncIO, Player] = managedFlySystem.api
     implicit val buildCountAPI: BuildCountAPI[IO, SyncIO, Player] = buildCountSystem.api
     implicit val manaApi: ManaApi[IO, SyncIO, Player] = manaSystem.manaApi
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player] = playerHeadSkinSystem.api
 
     new BuildAssist(this)
   }
@@ -602,8 +637,8 @@ class SeichiAssist extends JavaPlugin() {
     // BungeeCordとのI/O
     Bukkit
       .getMessenger
-      .registerIncomingPluginChannel(this, "SeichiAssistBungee", new BungeeReceiver(this))
-    Bukkit.getMessenger.registerOutgoingPluginChannel(this, "SeichiAssistBungee")
+      .registerIncomingPluginChannel(this, "BungeeCord", new BungeeReceiver(this))
+    Bukkit.getMessenger.registerOutgoingPluginChannel(this, "BungeeCord")
 
     // コンフィグ系の設定は全てConfig.javaに移動
     SeichiAssist.seichiAssistConfig = Config.loadFrom(this)
@@ -613,7 +648,7 @@ class SeichiAssist extends JavaPlugin() {
     if (!serverId.startsWith("local-")) {
       Sentry.init { options =>
         options.setDsn(
-          "https://7f241763b17c49db982ea29ad64b0264@sentry.onp.admin.seichi.click/2"
+          "https://66a9eb71bd1663f76df971d0b632b855@sentry.onp.admin.seichi.click/2"
         )
         // パフォーマンスモニタリングに使うトレースサンプルの送信割合
         // tracesSampleRateを1.0にすると全てのイベントが送られるため、送りすぎないように調整する必要がある
@@ -670,6 +705,7 @@ class SeichiAssist extends JavaPlugin() {
       )
     }
 
+    // TODO: 後でもどす
     itemMigrationSystem.entryPoints.runDatabaseMigration[SyncIO].unsafeRunSync()
     itemMigrationSystem.entryPoints.runWorldMigration.unsafeRunSync()
 
@@ -710,6 +746,7 @@ class SeichiAssist extends JavaPlugin() {
     implicit val gridRegionAPI: GridRegionAPI[IO, Player, Location] = gridRegionSystem.api
     implicit val breakSkillTargetConfigAPI: BreakSkillTargetConfigAPI[IO, Player] =
       breakSkillTargetConfigSystem.api
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player] = playerHeadSkinSystem.api
 
     val menuRouter = TopLevelRouter.apply
     import SeichiAssist.Scopes.globalChatInterceptionScope
@@ -760,7 +797,7 @@ class SeichiAssist extends JavaPlugin() {
       new ChatInterceptor(List(globalChatInterceptionScope)),
       new MenuHandler(),
       SpawnRegionProjectileInterceptor,
-      Y5DoubleSlabCanceller
+      YMinus59DoubleSlabCanceller
     ).concat(bungeeSemaphoreResponderSystem.listenersToBeRegistered)
       .concat {
         Seq(
@@ -835,8 +872,12 @@ class SeichiAssist extends JavaPlugin() {
       implicit val ioConcurrent: ConcurrentEffect[IO] = IO.ioConcurrentEffect(asyncShift)
       implicit val sendMessages: SendMinecraftMessage[IO, Player] = new SendBukkitMessage[IO]
 
-      val dragonNightTimeProcess: IO[Nothing] =
+      val dragonNightTimeProcess: IO[Nothing] = {
+        implicit val getConnectedPlayers: GetConnectedPlayers[IO, Player] =
+          new GetConnectedBukkitPlayers[IO]
+
         subsystems.dragonnighttime.System.backgroundProcess[IO, SyncIO, Player]
+      }
 
       val halfHourRankingRoutineOption: Option[IO[Nothing]] =
         // 公共鯖(7)と建築鯖(8)なら整地量のランキングを表示する必要はない
@@ -851,9 +892,12 @@ class SeichiAssist extends JavaPlugin() {
         subsystems.seichilevelupmessage.System.backgroundProcess[IO, SyncIO, Player]
 
       val autoSaveProcess: IO[Nothing] = {
-        val configuration = seichiAssistConfig.getAutoSaveSystemConfiguration
+        implicit val configuration: SystemConfiguration =
+          seichiAssistConfig.getAutoSaveSystemConfiguration
+        implicit val getConnectedPlayers: GetConnectedPlayers[IO, Player] =
+          new GetConnectedBukkitPlayers[IO]
 
-        subsystems.autosave.System.backgroundProcess[IO, IO](configuration)
+        subsystems.autosave.System.backgroundProcess[IO]
       }
 
       val programs: List[IO[Nothing]] =
diff --git a/src/main/scala/com/github/unchama/seichiassist/SkullOwners.scala b/src/main/scala/com/github/unchama/seichiassist/SkullOwners.scala
index d4ca6a2313..41ca62c9c5 100644
--- a/src/main/scala/com/github/unchama/seichiassist/SkullOwners.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/SkullOwners.scala
@@ -1,25 +1,70 @@
 package com.github.unchama.seichiassist
 
-import com.github.unchama.itemstackbuilder.{SkullOwnerName, SkullOwnerReference}
+import com.github.unchama.itemstackbuilder.SkullOwnerUuidWithNameWithTextureUrl
+
+import java.util.UUID
 
 /**
  * プレーヤーヘッドにownerとして設定されるプレーヤー達に関する定数を保持するオブジェクト
  */
 object SkullOwners {
-  val whitecat_haru: SkullOwnerReference = "whitecat_haru".asSkullOwnerReference()
-  val unchama: SkullOwnerReference = "unchama".asSkullOwnerReference()
+  val whitecat_haru: SkullOwnerUuidWithNameWithTextureUrl =
+    SkullOwnerUuidWithNameWithTextureUrl(
+      UUID.fromString("394f76df-883d-4855-9e6a-d1a800c1ab1c"),
+      "whitecat_haru",
+      "http://textures.minecraft.net/texture/2e3a634a9276303c0fa480460391ea16fc50363913ba6cad078163398435b3dd"
+    )
+  val unchama: SkullOwnerUuidWithNameWithTextureUrl =
+    SkullOwnerUuidWithNameWithTextureUrl(
+      UUID.fromString("b66cc3f6-a045-42ad-b4b8-320f20caf140"),
+      "unchama",
+      "http://textures.minecraft.net/texture/7abe76c114f44d0b114db30a49a5539f53fefad03c683306f5af9f3e76bfd36d"
+    )
+
+  val MHF_ArrowUp: SkullOwnerUuidWithNameWithTextureUrl = SkullOwnerUuidWithNameWithTextureUrl(
+    UUID.fromString("fef039ef-e6cd-4987-9c84-26a3e6134277"),
+    "MHF_ArrowUp",
+    "http://textures.minecraft.net/texture/a156b31cbf8f774547dc3f9713a770ecc5c727d967cb0093f26546b920457387"
+  )
+
+  val MHF_ArrowDown: SkullOwnerUuidWithNameWithTextureUrl =
+    SkullOwnerUuidWithNameWithTextureUrl(
+      UUID.fromString("68f59b9b-5b0b-4b05-a9f2-e1d1405aa348"),
+      "MHF_ArrowDown",
+      "http://textures.minecraft.net/texture/fe3d755cecbb13a39e8e9354823a9a02a01dce0aca68ffd42e3ea9a9d29e2df2"
+    )
 
-  val MHF_ArrowUp: SkullOwnerReference = "MHF_ArrowUp".asSkullOwnerReference()
-  val MHF_ArrowDown: SkullOwnerReference = "MHF_ArrowDown".asSkullOwnerReference()
-  val MHF_ArrowLeft: SkullOwnerReference = "MHF_ArrowLeft".asSkullOwnerReference()
-  val MHF_ArrowRight: SkullOwnerReference = "MHF_ArrowRight".asSkullOwnerReference()
+  val MHF_ArrowLeft: SkullOwnerUuidWithNameWithTextureUrl =
+    SkullOwnerUuidWithNameWithTextureUrl(
+      UUID.fromString("a68f0b64-8d14-4000-a95f-4b9ba14f8df9"),
+      "MHF_ArrowLeft",
+      "http://textures.minecraft.net/texture/f7aacad193e2226971ed95302dba433438be4644fbab5ebf818054061667fbe2"
+    )
 
-  val MHF_Exclamation: SkullOwnerReference = "MHF_Exclamation".asSkullOwnerReference()
+  val MHF_ArrowRight: SkullOwnerUuidWithNameWithTextureUrl =
+    SkullOwnerUuidWithNameWithTextureUrl(
+      UUID.fromString("50c8510b-5ea0-4d60-be9a-7d542d6cd156"),
+      "MHF_ArrowRight",
+      "http://textures.minecraft.net/texture/d34ef0638537222b20f480694dadc0f85fbe0759d581aa7fcdf2e43139377158"
+    )
 
-  val MHF_Villager: SkullOwnerReference = "MHF_Villager".asSkullOwnerReference()
+  val MHF_Exclamation: SkullOwnerUuidWithNameWithTextureUrl =
+    SkullOwnerUuidWithNameWithTextureUrl(
+      UUID.fromString("d3c47f6f-ae3a-45c1-ad7c-e2c762b03ae6"),
+      "MHF_Exclamation",
+      "http://textures.minecraft.net/texture/40b05e699d28b3a278a92d169dca9d57c0791d07994d82de3f9ed4a48afe0e1d"
+    )
 
-  implicit class StringOps(val string: String) {
-    def asSkullOwnerReference(): SkullOwnerReference = SkullOwnerName(string)
-  }
+  val MHF_Villager: SkullOwnerUuidWithNameWithTextureUrl = SkullOwnerUuidWithNameWithTextureUrl(
+    UUID.fromString("bd482739-767c-45dc-a1f8-c33c40530952"),
+    "MHF_Villager",
+    "http://textures.minecraft.net/texture/b4bd832813ac38e68648938d7a32f6ba29801aaf317404367f214b78b4d4754c"
+  )
 
+  val MHF_TNT: SkullOwnerUuidWithNameWithTextureUrl =
+    SkullOwnerUuidWithNameWithTextureUrl(
+      UUID.fromString("d43af93c-c330-4a3d-bab8-ee74234a011a"),
+      "MHF_TNT",
+      "http://textures.minecraft.net/texture/f92408fe8d0a3ef5531065e9f566c31aa6eb37484031a46e4466615daf64f705"
+    )
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/achievement/AchievementConditions.scala b/src/main/scala/com/github/unchama/seichiassist/achievement/AchievementConditions.scala
index bdac55431f..0731288c0e 100644
--- a/src/main/scala/com/github/unchama/seichiassist/achievement/AchievementConditions.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/achievement/AchievementConditions.scala
@@ -214,7 +214,7 @@ object AchievementConditions {
             import scala.util.chaining._
 
             stack != null &&
-            stack.getType == Material.SKULL_ITEM &&
+            stack.getType == Material.PLAYER_HEAD &&
             stack
               .getItemMeta
               .asInstanceOf[SkullMeta]
diff --git a/src/main/scala/com/github/unchama/seichiassist/achievement/hierarchy/AchievementGroup.scala b/src/main/scala/com/github/unchama/seichiassist/achievement/hierarchy/AchievementGroup.scala
index 31cf66ec16..8641097b10 100644
--- a/src/main/scala/com/github/unchama/seichiassist/achievement/hierarchy/AchievementGroup.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/achievement/hierarchy/AchievementGroup.scala
@@ -28,4 +28,27 @@ object AchievementGroup {
   case object VoteCounts extends AchievementGroup("JMS投票数", Specials)
 
   case object Secrets extends AchievementGroup("極秘任務", Specials)
+
+  private val achievementIdRangeToGroupNameList = List(
+    (1001 to 1012, BrokenBlockRanking),
+    (2001 to 2014, PlacedBlockAmount),
+    (3001 to 3019, BrokenBlockAmount),
+    (4001 to 4023, PlayTime),
+    (5101 to 5125, TotalLogins),
+    (5001 to 5008, ConsecutiveLogins),
+    (6001 to 6008, VoteCounts),
+    (7001 to 7027, OfficialEvent),
+    (7901 to 7906, OfficialEvent),
+    (8001 to 8003, Secrets),
+    (9001 to 9047, Anniversaries)
+  )
+
+  /**
+   * @return 実績IDから実績IDが属する実績グループ名を取得する
+   */
+  def getGroupNameByEntryId(entryId: Int): Option[String] = {
+    achievementIdRangeToGroupNameList.collectFirst {
+      case (range, group) if range contains entryId => group.name
+    }
+  }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/commands/HatCommand.scala b/src/main/scala/com/github/unchama/seichiassist/commands/HatCommand.scala
index 5d09be1140..1985c70e42 100644
--- a/src/main/scala/com/github/unchama/seichiassist/commands/HatCommand.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/commands/HatCommand.scala
@@ -4,6 +4,8 @@ import cats.effect.IO
 import com.github.unchama.seichiassist.commands.contextual.builder.BuilderTemplates
 import com.github.unchama.targetedeffect.commandsender.MessageEffect
 import com.github.unchama.targetedeffect.{SequentialEffect, TargetedEffect}
+import com.github.unchama.targetedeffect.TargetedEffect.emptyEffect
+import org.bukkit.Material
 import org.bukkit.command.TabExecutor
 import org.bukkit.entity.Player
 
@@ -16,14 +18,18 @@ object HatCommand {
       val currentHeadItem = player.getInventory.getHelmet
 
       IO {
-        SequentialEffect(
-          TargetedEffect.delay[IO, Player] { p =>
-            // swapすることでアイテムの過不足を防ぐ
-            p.getInventory.setHelmet(mainHandItem)
-            p.getInventory.setItemInOffHand(currentHeadItem)
-          },
-          MessageEffect("メインハンドに持っていたアイテムを頭にかぶりました。")
-        )
+        if (mainHandItem.getType != Material.AIR) {
+          SequentialEffect(
+            TargetedEffect.delay[IO, Player] { p =>
+              // swapすることでアイテムの過不足を防ぐ
+              p.getInventory.setHelmet(mainHandItem)
+              p.getInventory.setItemInMainHand(currentHeadItem)
+            },
+            MessageEffect("メインハンドに持っていたアイテムを頭にかぶりました。")
+          )
+        } else {
+          emptyEffect
+        }
       }
     }
     .asNonBlockingTabExecutor()
diff --git a/src/main/scala/com/github/unchama/seichiassist/commands/RegionOwnerTransferCommand.scala b/src/main/scala/com/github/unchama/seichiassist/commands/RegionOwnerTransferCommand.scala
index 08135a03bd..c732886a91 100644
--- a/src/main/scala/com/github/unchama/seichiassist/commands/RegionOwnerTransferCommand.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/commands/RegionOwnerTransferCommand.scala
@@ -1,69 +1,72 @@
 package com.github.unchama.seichiassist.commands
 
+import cats.data.Kleisli
 import cats.effect.IO
 import com.github.unchama.contextualexecutor.builder.Parsers
 import com.github.unchama.seichiassist.commands.contextual.builder.BuilderTemplates.playerCommandBuilder
-import com.github.unchama.targetedeffect.TargetedEffect
-import com.github.unchama.targetedeffect.commandsender.MessageEffect
+import com.github.unchama.targetedeffect.TargetedEffectF
+import com.github.unchama.targetedeffect.commandsender.MessageEffectF
 import com.github.unchama.util.external.WorldGuardWrapper
 import com.sk89q.worldguard.bukkit.WorldGuardPlugin
 import com.sk89q.worldguard.protection.regions.ProtectedRegion
 import org.bukkit.Bukkit
 import org.bukkit.command.TabExecutor
 import org.bukkit.entity.Player
-import shapeless.{HNil, ::}
+import shapeless.{::, HNil}
 
 object RegionOwnerTransferCommand {
   import com.github.unchama.contextualexecutor.builder.ParserResponse._
 
   val executor: TabExecutor = playerCommandBuilder
     .thenParse(Parsers.identity)
-    .thenParse(recipientName => {
+    .thenParse { recipientName =>
       Bukkit.getPlayer(recipientName) match {
         case recipient: Player => succeedWith(recipient)
         case _                 => failWith(s"${recipientName}というプレイヤーはサーバーに参加したことがありません。")
       }
-    })
-    .buildWithExecutionF { context =>
-      val (regionName :: newOwner :: HNil) = context.args.parsed
+    }
+    .buildWithExecutionCSEffect { context =>
+      val regionName :: newOwner :: HNil = context.args.parsed
       val sender = context.sender
 
-      IO {
-        WorldGuardPlugin.inst().getRegionManager(sender.getWorld).getRegion(regionName)
-      }.flatMap { region =>
-        if (region == null) {
-          MessageEffect(s"${regionName}という名前の保護は存在しません。").run(sender)
-        } else {
-          attemptRegionTransfer(sender, newOwner, region)
-        }
+      val region =
+        WorldGuardWrapper.findByRegionName(regionName)
+
+      region match {
+        case Some(region) =>
+          attemptRegionTransfer(sender, newOwner, region.getRegion(regionName))
+        case None => MessageEffectF[IO](s"${regionName}という名前の保護は存在しません。")
       }
     }
     .asNonBlockingTabExecutor()
 
+  import cats.implicits._
+
   private def attemptRegionTransfer(
     donner: Player,
     recipient: Player,
     region: ProtectedRegion
-  ): IO[TargetedEffect[Player]] = IO {
-    val owners = region.getOwners
-    val regionWorld = donner.getWorld
-
-    val recipientLimit = WorldGuardWrapper.getMaxRegionCount(recipient, regionWorld)
-    val recipientHas = WorldGuardWrapper.getNumberOfRegions(recipient, regionWorld)
-
+  ): TargetedEffectF[IO, Player] = (for {
+    owners <- Kleisli.liftF(IO(region.getOwners))
+    regionWorld <- Kleisli.liftF(IO(donner.getWorld))
+    recipientLimit <- Kleisli.liftF(IO(WorldGuardWrapper.getMaxRegion(recipient, regionWorld)))
+    recipientHas <- Kleisli.liftF(
+      IO(WorldGuardWrapper.getNumberOfRegions(recipient, regionWorld))
+    )
+  } yield {
     if (recipientLimit <= recipientHas) {
-      MessageEffect(s"相手が保護を上限 ($recipientLimit)まで所持しているため権限を譲渡できません。")
+      MessageEffectF[IO](s"相手が保護を上限 ($recipientLimit)まで所持しているため権限を譲渡できません。")
     } else if (owners.contains(WorldGuardPlugin.inst().wrapPlayer(recipient))) {
-      MessageEffect("相手がすでにオーナーであるため権限を譲渡できません。")
+      MessageEffectF[IO]("相手がすでにオーナーであるため権限を譲渡できません。")
     } else if (!owners.contains(donner.getUniqueId)) {
-      MessageEffect("オーナーではないため権限を譲渡できません。")
+      MessageEffectF[IO]("オーナーではないため権限を譲渡できません。")
     } else if (owners.size() != 1) {
-      MessageEffect("オーナーが複数人いるため権限を譲渡できません。")
+      MessageEffectF[IO]("オーナーが複数人いるため権限を譲渡できません。")
     } else {
       owners.clear()
       owners.addPlayer(recipient.getUniqueId)
 
-      MessageEffect(s"${recipient.getName}に${region.getId}のオーナー権限を譲渡しました。")
+      MessageEffectF[IO](s"${recipient.getName}に${region.getId}のオーナー権限を譲渡しました。")
     }
-  }
+  }).flatten
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/commands/RmpCommand.scala b/src/main/scala/com/github/unchama/seichiassist/commands/RmpCommand.scala
index cbc782e1a1..5e781c3df8 100644
--- a/src/main/scala/com/github/unchama/seichiassist/commands/RmpCommand.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/commands/RmpCommand.scala
@@ -12,7 +12,7 @@ import com.github.unchama.seichiassist.{ManagedWorld, SeichiAssist}
 import com.github.unchama.targetedeffect
 import com.github.unchama.targetedeffect.TargetedEffect
 import com.github.unchama.targetedeffect.commandsender.MessageEffect
-import com.github.unchama.util.external.ExternalPlugins
+import com.github.unchama.util.external.WorldGuardWrapper
 import com.sk89q.worldguard.protection.regions.ProtectedRegion
 import org.bukkit.ChatColor._
 import org.bukkit.command.{CommandSender, ConsoleCommandSender, TabExecutor}
@@ -78,13 +78,7 @@ object RmpCommand {
         case None | Some(false) => MessageEffect(s"第1整地以外の保護をかけて整地する整地ワールドでのみ使用出来ます")
         case Some(true) =>
           getOldRegionsIn(world, days).map { removalTargets =>
-            removalTargets.foreach { target =>
-              ExternalPlugins
-                .getWorldGuard
-                .getRegionContainer
-                .get(world)
-                .removeRegion(target.getId)
-            }
+            removalTargets.foreach(WorldGuardWrapper.removeByProtectedRegionRegion(world, _))
 
             // メッセージ生成
             if (removalTargets.isEmpty) {
@@ -112,15 +106,15 @@ object RmpCommand {
       return Left(MessageEffect(s"${RED}データベースアクセスに失敗しました。"))
     }
 
-    val regions = ExternalPlugins.getWorldGuard.getRegionContainer.get(world).getRegions.asScala
+    val regions = WorldGuardWrapper.getRegions(world)
 
-    val oldRegions = regions
-      .values
-      .filter { region =>
-        region.getId != "__global__" && region.getId != "spawn" &&
-        region.getOwners.getUniqueIds.asScala.forall(leavers.contains(_))
-      }
-      .toList
+    val oldRegions = regions.filter { region =>
+      region.getId != "spawn" && region
+        .getOwners
+        .getUniqueIds
+        .asScala
+        .forall(leavers.contains(_))
+    }
 
     Right(oldRegions)
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/commands/StickCommand.scala b/src/main/scala/com/github/unchama/seichiassist/commands/StickCommand.scala
index 8fec08a81e..54e3c9ae73 100644
--- a/src/main/scala/com/github/unchama/seichiassist/commands/StickCommand.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/commands/StickCommand.scala
@@ -14,7 +14,7 @@ object StickCommand {
   val executor: TabExecutor = playerCommandBuilder
     .buildWithExecutionF { context =>
       // 初見プレイヤー用とは別に簡潔な説明
-      val stickLore = List("棒を持って右クリックもしくは左クリックでメニューを開きます。", "各メニューの詳細は公式サイトで確認できます。")
+      val stickLore = List("棒を持って右クリックもしくは", "左クリックでメニューを開きます。", "各メニューの詳細は公式サイトで確認できます。")
       val stickItemStack = new ItemStack(Material.STICK, 1).tap { itemStack =>
         import itemStack._
         val meta = getItemMeta
diff --git a/src/main/scala/com/github/unchama/seichiassist/data/MenuInventoryData.java b/src/main/scala/com/github/unchama/seichiassist/data/MenuInventoryData.java
index f5a75a1d6c..fc0159d7d6 100644
--- a/src/main/scala/com/github/unchama/seichiassist/data/MenuInventoryData.java
+++ b/src/main/scala/com/github/unchama/seichiassist/data/MenuInventoryData.java
@@ -450,8 +450,14 @@ public static Inventory getGiganticBerserkBeforeEvolutionMenu(final Player p) {
         final Inventory inventory = getEmptyInventory(6, ChatColor.DARK_PURPLE + "" + ChatColor.BOLD + "スキルを進化させますか?");
         {
             // 色
-            final byte[] table = {12, 15, 4, 0, 3};
-            final ItemStack itemstack = new ItemStack(Material.STAINED_GLASS_PANE, 1, table[playerdata.giganticBerserk().stage()]);
+            final Material[] table = {
+                Material.ORANGE_STAINED_GLASS_PANE,
+                Material.BLACK_STAINED_GLASS_PANE,
+                Material.YELLOW_STAINED_GLASS_PANE,
+                Material.WHITE_STAINED_GLASS_PANE,
+                Material.LIGHT_BLUE_STAINED_GLASS_PANE
+            };
+            final ItemStack itemstack = new ItemStack(table[playerdata.giganticBerserk().stage()], 1);
             final ItemMeta itemmeta = itemstack.getItemMeta();
             itemmeta.setDisplayName(" ");
             itemstack.setItemMeta(itemmeta);
@@ -495,10 +501,16 @@ public static Inventory getGiganticBerserkAfterEvolutionMenu(final Player p) {
         if (isError(p, playerdata, "GiganticBerserk進化後画面")) return null;
         final Inventory inventory = getEmptyInventory(6, ChatColor.LIGHT_PURPLE + "" + ChatColor.BOLD + "スキルを進化させました");
         {
-            final byte[] table = {12, 15, 4, 0, 3, 12};
-            final byte b = table[playerdata.giganticBerserk().stage()];
+            final Material[] table = {
+                Material.BROWN_STAINED_GLASS_PANE,
+                Material.BLACK_STAINED_GLASS_PANE,
+                Material.YELLOW_STAINED_GLASS_PANE,
+                Material.WHITE_STAINED_GLASS_PANE,
+                Material.LIGHT_BLUE_STAINED_GLASS_PANE,
+                Material.BROWN_STAINED_GLASS_PANE
+            };
 
-            final ItemStack itemstack = new ItemStack(Material.STAINED_GLASS_PANE, 1, b);
+            final ItemStack itemstack = new ItemStack(table[playerdata.giganticBerserk().stage()], 1);
 
             final ItemMeta itemmeta = itemstack.getItemMeta();
             if (playerdata.giganticBerserk().stage() >= 4) {
@@ -570,7 +582,7 @@ private static ItemStack buildPlayerSkull(final String name, final List<String>
     }
 
     private static ItemStack buildPlayerSkull(final String name, final List<String> lore, final String owner, final Consumer<? super SkullMeta> modify) {
-        final ItemStack ret = new ItemStack(Material.SKULL_ITEM, 1, PLAYER_SKULL);
+        final ItemStack ret = new ItemStack(Material.PLAYER_HEAD, 1, PLAYER_SKULL);
         final SkullMeta sm = ItemMetaFactory.SKULL.getValue();
         if (name != null) {
             sm.setDisplayName(name);
diff --git a/src/main/scala/com/github/unchama/seichiassist/data/player/GiganticBerserk.scala b/src/main/scala/com/github/unchama/seichiassist/data/player/GiganticBerserk.scala
index 823d126560..d165487061 100644
--- a/src/main/scala/com/github/unchama/seichiassist/data/player/GiganticBerserk.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/data/player/GiganticBerserk.scala
@@ -25,12 +25,12 @@ case class GiganticBerserk(
 
   def materialOnUI(): Material = {
     stage match {
-      case 0 => Material.WOOD_SWORD
+      case 0 => Material.WOODEN_SWORD
       case 1 => Material.STONE_SWORD
-      case 2 => Material.GOLD_SWORD
+      case 2 => Material.GOLDEN_SWORD
       case 3 => Material.IRON_SWORD
       case 4 => Material.DIAMOND_SWORD
-      case 5 => Material.WOOD_SWORD
+      case 5 => Material.WOODEN_SWORD
       case _ => throw new RuntimeException("This branch should not be reached")
     }
   }
@@ -44,4 +44,15 @@ case class GiganticBerserk(
     val current = stage * 10 + level
     LevelThresholds.giganticBerserkLevelList(current)
   }
+
+  /**
+   * @return 今までに倒した敵の総数
+   */
+  def totalNumberOfKilledEnemies: Int = {
+    val currentStage = stage * 10
+    val previousLevel = level - 1
+    val previousStageLevel = currentStage + previousLevel
+    LevelThresholds.giganticBerserkLevelList.take(previousStageLevel).sum + exp
+  }
+
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/data/player/PlayerData.scala b/src/main/scala/com/github/unchama/seichiassist/data/player/PlayerData.scala
index 35ba034cf3..5122d81c7b 100644
--- a/src/main/scala/com/github/unchama/seichiassist/data/player/PlayerData.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/data/player/PlayerData.scala
@@ -220,7 +220,7 @@ class PlayerData(@Deprecated() val uuid: UUID, val name: String) {
   // 総プレイ時間を更新する
   def updatePlayTick(): Unit = {
     // WARN: 1分毎にupdatePlayTickが呼び出されるというコンテクストに依存している.
-    val nowTotalPlayTick = player.getStatistic(Statistic.PLAY_ONE_TICK).toLong
+    val nowTotalPlayTick = player.getStatistic(Statistic.PLAY_ONE_MINUTE).toLong
     val diff = nowTotalPlayTick - totalPlayTick.getOrElse(nowTotalPlayTick)
 
     totalPlayTick = Some(nowTotalPlayTick)
diff --git a/src/main/scala/com/github/unchama/seichiassist/data/player/settings/PlayerSettings.scala b/src/main/scala/com/github/unchama/seichiassist/data/player/settings/PlayerSettings.scala
index a4f9e1b93f..9d4f08533b 100644
--- a/src/main/scala/com/github/unchama/seichiassist/data/player/settings/PlayerSettings.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/data/player/settings/PlayerSettings.scala
@@ -48,7 +48,7 @@ class PlayerSettings {
   val toggleHalfBreakFlag: TargetedEffect[Player] = DeferredEffect(IO {
     allowBreakingHalfBlocks = !allowBreakingHalfBlocks
 
-    val newStatus = if (allowBreakingHalfBlocks) s"${GREEN}破壊可能" else "${RED}破壊不可能"
+    val newStatus = if (allowBreakingHalfBlocks) s"${GREEN}破壊可能" else s"${RED}破壊不可能"
     val responseMessage = s"現在ハーフブロックは$newStatus${RESET}です."
 
     MessageEffect(responseMessage)
diff --git a/src/main/scala/com/github/unchama/seichiassist/domain/explevel/FiniteExpLevelTable.scala b/src/main/scala/com/github/unchama/seichiassist/domain/explevel/FiniteExpLevelTable.scala
index ca722bada6..c5844b9b60 100644
--- a/src/main/scala/com/github/unchama/seichiassist/domain/explevel/FiniteExpLevelTable.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/domain/explevel/FiniteExpLevelTable.scala
@@ -22,6 +22,7 @@ class FiniteExpLevelTable[L: PositiveInt, ExpAmount: Order: LowerBounded](
       internalTable.sliding(2).forall {
         case Seq(x1, x2) =>
           x1 <= x2
+        case _ => false
       }
     },
     "internalTable must be sorted"
diff --git a/src/main/scala/com/github/unchama/seichiassist/infrastructure/minecraft/JdbcLastSeenNameToUuid.scala b/src/main/scala/com/github/unchama/seichiassist/infrastructure/minecraft/JdbcLastSeenNameToUuid.scala
index 446ef4d58b..f5e29253d5 100644
--- a/src/main/scala/com/github/unchama/seichiassist/infrastructure/minecraft/JdbcLastSeenNameToUuid.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/infrastructure/minecraft/JdbcLastSeenNameToUuid.scala
@@ -31,7 +31,6 @@ class JdbcLastSeenNameToUuid[F[_]: Sync]
         val foundUuid = sql"SELECT uuid FROM playerdata WHERE name = $playerName"
           .map(rs => UUID.fromString(rs.string("uuid")))
           .toList()
-          .apply()
 
         if (foundUuid.isEmpty) Left(LastSeenNameToUuidError.NotFound)
         else if (foundUuid.length >= 2) Left(LastSeenNameToUuidError.MultipleFound)
diff --git a/src/main/scala/com/github/unchama/seichiassist/infrastructure/scalikejdbc/ScalikeJDBCConfiguration.scala b/src/main/scala/com/github/unchama/seichiassist/infrastructure/scalikejdbc/ScalikeJDBCConfiguration.scala
index 28acc5ae32..90c9d5882e 100644
--- a/src/main/scala/com/github/unchama/seichiassist/infrastructure/scalikejdbc/ScalikeJDBCConfiguration.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/infrastructure/scalikejdbc/ScalikeJDBCConfiguration.scala
@@ -18,7 +18,7 @@ object ScalikeJDBCConfiguration {
     singleLineMode = true,
     printUnprocessedStackTrace = false,
     stackTraceDepth = 15,
-    logLevel = Symbol("debug"),
+    logLevel = "debug",
     warningEnabled = false
   )
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/listener/BuildMainMenuOpener.scala b/src/main/scala/com/github/unchama/seichiassist/listener/BuildMainMenuOpener.scala
index 3cd8534404..7784de4316 100644
--- a/src/main/scala/com/github/unchama/seichiassist/listener/BuildMainMenuOpener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/listener/BuildMainMenuOpener.scala
@@ -21,18 +21,15 @@ class BuildMainMenuOpener(
   @EventHandler
   def onPlayerLeftClickWithStick(event: PlayerInteractEvent): Unit = {
     val player = event.getPlayer
+    val action = event.getAction
 
-    event.getAction match {
-      case Action.LEFT_CLICK_AIR | Action.LEFT_CLICK_BLOCK =>
-      case _                                               => return
-    }
+    if (action != Action.LEFT_CLICK_AIR && action != Action.LEFT_CLICK_BLOCK) return
 
-    {
-      val hasStickOnMainHand = player.getInventory.getItemInMainHand.getType == Material.STICK
-      val actionWasOnMainHand = event.getHand == EquipmentSlot.HAND
+    val hasNotStickOnMainHand =
+      player.getInventory.getItemInMainHand.getType != Material.STICK
+    val actionWasNotOnMainHand = event.getHand != EquipmentSlot.HAND
 
-      if (!hasStickOnMainHand || !actionWasOnMainHand) return
-    }
+    if (hasNotStickOnMainHand || actionWasNotOnMainHand) return
 
     effectEnvironment.unsafeRunAsyncTargetedEffect(player)(
       SequentialEffect(
diff --git a/src/main/scala/com/github/unchama/seichiassist/listener/EntityListener.scala b/src/main/scala/com/github/unchama/seichiassist/listener/EntityListener.scala
index a3fd697648..55063127d2 100644
--- a/src/main/scala/com/github/unchama/seichiassist/listener/EntityListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/listener/EntityListener.scala
@@ -18,6 +18,7 @@ import org.bukkit.enchantments.Enchantment
 import org.bukkit.entity.{Player, Projectile}
 import org.bukkit.event.entity._
 import org.bukkit.event.{EventHandler, Listener}
+import org.bukkit.inventory.meta.Damageable
 
 class EntityListener(
   implicit effectEnvironment: EffectEnvironment,
@@ -77,16 +78,21 @@ class EntityListener(
       )
 
     // 耐久値がマイナスかつ耐久無限ツールでない時処理を終了
-    if (tool.getDurability > tool.getType.getMaxDurability && !tool.getItemMeta.isUnbreakable)
+    if (
+      tool.getItemMeta.asInstanceOf[Damageable].getDamage > tool
+        .getType
+        .getMaxDurability && !tool.getItemMeta.isUnbreakable
+    )
       return
 
-    runArrowSkillOfHitBlock(player, block, tool)
+    runArrowSkillOfHitBlock(player, block, tool, projectile)
   }
 
   private def runArrowSkillOfHitBlock(
     player: Player,
     hitBlock: BlockBreakableBySkill,
-    tool: BreakTool
+    tool: BreakTool,
+    projectile: Projectile
   ): Unit = {
     val playerData = playermap(player.getUniqueId)
 
@@ -132,7 +138,7 @@ class EntityListener(
     val nextDurability = {
       val durabilityEnchantment = tool.getEnchantmentLevel(Enchantment.DURABILITY)
 
-      tool.getDurability +
+      tool.getItemMeta.asInstanceOf[Damageable].getDamage +
         BreakUtil.calcDurability(
           durabilityEnchantment,
           breakBlocks.size + 10 * (lavaBlocks.size + waterBlocks.size)
@@ -157,7 +163,11 @@ class EntityListener(
       return
 
     // 耐久値を減らす
-    if (!tool.getItemMeta.isUnbreakable) tool.setDurability(nextDurability)
+    if (!tool.getItemMeta.isUnbreakable) {
+      val meta = tool.getItemMeta
+      meta.asInstanceOf[Damageable].setDamage(nextDurability)
+      tool.setItemMeta(meta)
+    }
 
     // 以降破壊する処理
     // 溶岩と水を破壊する
@@ -166,6 +176,8 @@ class EntityListener(
     // 元ブロックの真ん中の位置
     val centerOfBlock = hitBlock.getLocation.add(0.5, 0.5, 0.5)
 
+    projectile.remove()
+
     effectEnvironment.unsafeRunEffectAsync(
       "破壊エフェクトを再生する",
       playerData
diff --git a/src/main/scala/com/github/unchama/seichiassist/listener/PlayerBlockBreakListener.scala b/src/main/scala/com/github/unchama/seichiassist/listener/PlayerBlockBreakListener.scala
index d46674543f..ebc784fff2 100644
--- a/src/main/scala/com/github/unchama/seichiassist/listener/PlayerBlockBreakListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/listener/PlayerBlockBreakListener.scala
@@ -15,21 +15,24 @@ import com.github.unchama.seichiassist.subsystems.mana.ManaApi
 import com.github.unchama.seichiassist.subsystems.mana.domain.ManaAmount
 import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
 import com.github.unchama.seichiassist.util.BreakUtil
-import com.github.unchama.seichiassist.util.BreakUtil.BlockBreakResult
 import com.github.unchama.seichiassist.{MaterialSets, SeichiAssist}
 import com.github.unchama.targetedeffect.player.FocusedSoundEffect
+import com.github.unchama.util.bukkit.ItemStackUtil
 import com.github.unchama.util.effect.BukkitResources
-import com.github.unchama.util.external.ExternalPlugins
+import com.github.unchama.util.external.WorldGuardWrapper
 import org.bukkit.ChatColor.RED
 import org.bukkit._
-import org.bukkit.block.Block
+import org.bukkit.block.{Block, Container}
+import org.bukkit.block.data.`type`.Slab
 import org.bukkit.enchantments.Enchantment
 import org.bukkit.entity.Player
 import org.bukkit.event.block.BlockBreakEvent
 import org.bukkit.event.{EventHandler, EventPriority, Listener}
 import org.bukkit.inventory.ItemStack
+import org.bukkit.inventory.meta.Damageable
 
 import scala.collection.mutable.ArrayBuffer
+import scala.jdk.CollectionConverters.CollectionHasAsScala
 import scala.util.control.Breaks
 
 class PlayerBlockBreakListener(
@@ -48,6 +51,8 @@ class PlayerBlockBreakListener(
   def onPlayerActiveSkillEvent(event: BlockBreakEvent): Unit = {
     val player = event.getPlayer
 
+    if (!player.getWorld.isSeichiSkillAllowed) return
+
     val block = MaterialSets
       .refineBlock(event.getBlock, MaterialSets.materials)
       .getOrElse(
@@ -68,14 +73,6 @@ class PlayerBlockBreakListener(
       return
     }
 
-    if (!player.getWorld.isSeichiSkillAllowed) return
-
-    // 破壊不可能ブロックの時処理を終了
-    if (!BreakUtil.canBreakWithSkill(player, block)) {
-      event.setCancelled(true)
-      return
-    }
-
     // 実際に使用するツール
     val tool: BreakTool = MaterialSets
       .refineItemStack(player.getInventory.getItemInMainHand, MaterialSets.breakToolMaterials)
@@ -84,7 +81,11 @@ class PlayerBlockBreakListener(
       )
 
     // 耐久値がマイナスかつ耐久無限ツールでない時処理を終了
-    if (tool.getDurability > tool.getType.getMaxDurability && !tool.getItemMeta.isUnbreakable)
+    if (
+      tool.getItemMeta.asInstanceOf[Damageable].getDamage > tool
+        .getType
+        .getMaxDurability && !tool.getItemMeta.isUnbreakable
+    )
       return
 
     // もしサバイバルでなければ、またはフライ中なら終了
@@ -93,8 +94,6 @@ class PlayerBlockBreakListener(
     val playerData = SeichiAssist.playermap(player.getUniqueId)
     val skillState = playerData.skillState.get.unsafeRunSync()
 
-    if (!player.getWorld.isSeichiSkillAllowed) return
-
     // クールダウンタイム中は処理を終了
     if (!activeSkillAvailability(player).get.unsafeRunSync()) {
       // SEを再生
@@ -116,6 +115,12 @@ class PlayerBlockBreakListener(
 
     if (!selectedSkill.range.isInstanceOf[MultiArea] || skillState.usageMode == Disabled) return
 
+    // 破壊不可能ブロックの時処理を終了
+    if (!BreakUtil.canBreakWithSkill(player, block)) {
+      event.setCancelled(true)
+      return
+    }
+
     event.setCancelled(true)
 
     {
@@ -140,7 +145,7 @@ class PlayerBlockBreakListener(
       // 壊される水ブロックの全てのリストデータ
       val multiWaterList = new ArrayBuffer[Set[Block]]
       // 全ての耐久消費量
-      var toolDamageToSet = tool.getDurability.toInt
+      var toolDamageToSet = tool.getItemMeta.asInstanceOf[Damageable].getDamage
 
       // 消費が予約されたマナ
       val reservedMana = new ArrayBuffer[ManaAmount]
@@ -272,12 +277,16 @@ class PlayerBlockBreakListener(
 
         // ツールの耐久値を減らす
         val adjustManaAndDurability = IO {
-          if (!tool.getItemMeta.isUnbreakable) tool.setDurability(toolDamageToSet.toShort)
+          if (!tool.getItemMeta.isUnbreakable) {
+            val meta = tool.getItemMeta
+            meta.asInstanceOf[Damageable].setDamage(toolDamageToSet)
+            tool.setItemMeta(meta)
+          }
         }
 
         effectEnvironment.unsafeRunEffectAsync(
           "複数破壊エフェクトを実行する",
-          effectPrograms.toList.sequence[IO, Fiber[IO, Unit]]
+          effectPrograms.sequence[IO, Fiber[IO, Unit]]
         )
         effectEnvironment.unsafeRunEffectAsync(
           "複数破壊エフェクトの後処理を実行する",
@@ -297,51 +306,48 @@ class PlayerBlockBreakListener(
         .map(multiplier => BreakUtil.totalBreakCount(Seq(block.getType)) * multiplier)
         .unsafeRunSync()
     }
+
+    val program = for {
+      block <- IO(event.getBlock)
+      isContainer <- IO(block.getState.isInstanceOf[Container])
+      // NOTE: Spigot 1.18.2のAPIではチェストの中身のドロップを計算することは不可能である。
+      // そのため、破壊したブロックがインベントリをもつ場合はドロップをキャンセルせず、
+      // MineStackの中身に入れることはせずにそのままドロップする
+      //
+      // また、ドロップしたアイテムをイベントで検知して取得するのも難しい。
+      // BlockDropItemEventは、playerがブロックを破壊したことをトリガーとするが、
+      // player#breakBlock関数を使用してブロックを破壊するとBlockBreakEventが再度発火し、
+      // その場合のみイベントの処理を実行しなかったとしてもサーバーに負荷がかかるので現実的ではない。
+      // これらのことから、やむを得ずこのような実装になっている。
+      _ <- (for {
+        _ <- IO(event.setDropItems(false))
+        blockDrops <- IO(
+          event.getBlock.getDrops(player.getInventory.getItemInMainHand).asScala.toVector
+        )
+        drops = ItemStackUtil.amalgamate(blockDrops).toVector
+        currentAutoMineStackState <- mineStackAPI.autoMineStack(player)
+        intoFailedItemStacksAndSuccessItemStacks <- whenAOrElse(currentAutoMineStackState)(
+          mineStackAPI.mineStackRepository.tryIntoMineStack(player, drops),
+          (drops, Vector.empty)
+        )
+        _ <- IO {
+          intoFailedItemStacksAndSuccessItemStacks._1.foreach { itemStack =>
+            player.getWorld.dropItemNaturally(player.getLocation, itemStack)
+          }
+        }
+      } yield ()).unlessA(isContainer)
+    } yield ()
+
     effectEnvironment.unsafeRunEffectAsync(
       "通常破壊されたブロックを整地量に計上する",
       SeichiAssist.instance.breakCountSystem.api.incrementSeichiExp.of(player, amount).toIO
     )
 
-    val tool: BreakTool = MaterialSets
-      .refineItemStack(player.getInventory.getItemInMainHand, MaterialSets.breakToolMaterials)
-      .getOrElse(
-        return
-      )
-
-    /**
-     * 手彫りで破壊したアイテムを直接MineStackに入れる
-     * 一つのBlockBreakEventから複数の種類のアイテムが出てくることはない。
-     * チェスト等のインベントリスロットのあるブロック`b`を破壊したときは、
-     * 破壊された`b`のみが`BlockBreakEvent`のドロップ対象となるため、
-     * 中身のドロップがキャンセルされることはない。
-     */
-    val drops = BreakUtil
-      .dropItemOnTool(tool)((block.getLocation(), block.getType, block.getData))
-      .getOrElse(
-        return
-      )
-
-    drops match {
-      case BlockBreakResult.ItemDrop(itemStack) =>
-        val program = for {
-          currentAutoMineStackState <- mineStackAPI.autoMineStack(player)
-          isSucceedTryIntoMineStack <- whenAOrElse(currentAutoMineStackState)(
-            mineStackAPI
-              .mineStackRepository
-              .tryIntoMineStack(player, itemStack, itemStack.getAmount),
-            false
-          )
-        } yield {
-          if (isSucceedTryIntoMineStack) event.setDropItems(false)
-          else ()
-        }
-        program.unsafeRunSync()
-      case _ => ()
-    }
+    effectEnvironment.unsafeRunEffectAsync("破壊されたアイテムをMineStackに入れるかドロップする", program)
   }
 
   /**
-   * y5ハーフブロック破壊抑制
+   * y-59ハーフブロック破壊抑制
    *
    * @param event
    *   BlockBreakEvent
@@ -349,22 +355,22 @@ class PlayerBlockBreakListener(
   @EventHandler(priority = EventPriority.LOWEST)
   @SuppressWarnings(Array("deprecation"))
   def onPlayerBlockHalf(event: BlockBreakEvent): Unit = {
-    val p = event.getPlayer
-    val b = event.getBlock
-    val world = p.getWorld
+    val player = event.getPlayer
+    val block = event.getBlock
+    val world = player.getWorld
     // そもそも自分の保護じゃなきゃ処理かけない
-    if (!ExternalPlugins.getWorldGuard.canBuild(p, b.getLocation)) return
-    if ((b.getType eq Material.DOUBLE_STEP) && b.getData == 0) {
-      b.setType(Material.STEP)
-      b.setData(0.toByte)
-      val location = b.getLocation
-      world.dropItemNaturally(location, new ItemStack(Material.STEP))
+    if (!WorldGuardWrapper.canBuild(player, block.getLocation)) return
+    block.getBlockData match {
+      case slab: Slab if slab.getType == Slab.Type.DOUBLE =>
+        val location = block.getLocation
+        world.dropItemNaturally(location, new ItemStack(block.getType))
+      case _: Slab =>
+      case _       => return
     }
-    if (b.getType ne Material.STEP) return
-    if (b.getY > 5) return
-    if (b.getData != 0) return
+    if (block.getY > -59) return
+    if (block.getBlockData.asInstanceOf[Slab].getType != Slab.Type.BOTTOM) return
     if (!world.isSeichi) return
     event.setCancelled(true)
-    p.sendMessage(s"${RED}Y5以下に敷かれたハーフブロックは破壊不可能です。")
+    player.sendMessage(s"${RED}Y-59以下に敷かれたハーフブロックは破壊不可能です。")
   }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/listener/PlayerClickListener.scala b/src/main/scala/com/github/unchama/seichiassist/listener/PlayerClickListener.scala
index 6ddf552e27..b8521d7972 100644
--- a/src/main/scala/com/github/unchama/seichiassist/listener/PlayerClickListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/listener/PlayerClickListener.scala
@@ -116,7 +116,7 @@ class PlayerClickListener(
     val equipmentSlot = event.getHand
 
     val currentItem = player.getInventory.getItemInMainHand.getType
-    if (currentItem == Material.STICK || currentItem == Material.SKULL_ITEM) return
+    if (currentItem == Material.STICK || currentItem == Material.PLAYER_HEAD) return
 
     val playerData = playerMap(player.getUniqueId)
     val playerLevel = SeichiAssist
@@ -242,7 +242,7 @@ class PlayerClickListener(
 
     val targetBlock = e.getClickedBlock
     // 頭じゃない場合無視
-    if (targetBlock.getType != Material.SKULL) {
+    if (targetBlock.getType != Material.PLAYER_HEAD) {
       return
     }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/listener/PlayerDeathEventListener.java b/src/main/scala/com/github/unchama/seichiassist/listener/PlayerDeathEventListener.java
index 3ea7629d96..781156094e 100644
--- a/src/main/scala/com/github/unchama/seichiassist/listener/PlayerDeathEventListener.java
+++ b/src/main/scala/com/github/unchama/seichiassist/listener/PlayerDeathEventListener.java
@@ -35,5 +35,7 @@ public void onDeath(PlayerDeathEvent event) {
                 p.sendMessage(msg);
             }
         }
+
+        event.setDeathMessage(null);
     }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/listener/PlayerInventoryListener.scala b/src/main/scala/com/github/unchama/seichiassist/listener/PlayerInventoryListener.scala
index 9371b85643..fbb2a2132d 100644
--- a/src/main/scala/com/github/unchama/seichiassist/listener/PlayerInventoryListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/listener/PlayerInventoryListener.scala
@@ -49,7 +49,7 @@ class PlayerInventoryListener(
     // インベントリサイズが54でない時終了
     if (inventory.row != 6) return
 
-    if (inventory.getTitle != s"$LIGHT_PURPLE${BOLD}交換したい鉱石を入れてください") return
+    if (event.getView.getTitle != s"$LIGHT_PURPLE${BOLD}交換したい鉱石を入れてください") return
 
     /*
      * step1 for文でinventory内の対象商品の個数を計算
@@ -57,36 +57,40 @@ class PlayerInventoryListener(
      */
 
     // 石炭とラピスラズリを適切に処理するため、typeとdurabilityを持つクラスを用意
-    case class ExchangeableMaterial(materialType: Material, durability: Short)
+    case class ExchangeableMaterial(materialType: Material)
 
     val requiredAmountPerTicket = Map(
-      ExchangeableMaterial(Material.COAL_ORE, 0) -> 128,
-      ExchangeableMaterial(Material.IRON_ORE, 0) -> 64,
-      ExchangeableMaterial(Material.GOLD_ORE, 0) -> 8,
-      ExchangeableMaterial(Material.LAPIS_ORE, 0) -> 8,
-      ExchangeableMaterial(Material.DIAMOND_ORE, 0) -> 4,
-      ExchangeableMaterial(Material.REDSTONE_ORE, 0) -> 32,
-      ExchangeableMaterial(Material.EMERALD_ORE, 0) -> 4,
-      ExchangeableMaterial(Material.QUARTZ_ORE, 0) -> 16,
-      ExchangeableMaterial(Material.COAL, 0) -> 432,
-      ExchangeableMaterial(Material.REDSTONE, 0) -> 288,
-      ExchangeableMaterial(Material.INK_SACK, 4) -> 64,
-      ExchangeableMaterial(Material.DIAMOND, 0) -> 8
+      ExchangeableMaterial(Material.COAL_ORE) -> 128,
+      ExchangeableMaterial(Material.COPPER_ORE) -> 128,
+      ExchangeableMaterial(Material.IRON_ORE) -> 64,
+      ExchangeableMaterial(Material.GOLD_ORE) -> 8,
+      ExchangeableMaterial(Material.LAPIS_ORE) -> 8,
+      ExchangeableMaterial(Material.DIAMOND_ORE) -> 4,
+      ExchangeableMaterial(Material.REDSTONE_ORE) -> 32,
+      ExchangeableMaterial(Material.EMERALD_ORE) -> 4,
+      ExchangeableMaterial(Material.NETHER_QUARTZ_ORE) -> 16,
+      ExchangeableMaterial(Material.NETHER_GOLD_ORE) -> 32,
+      ExchangeableMaterial(Material.DEEPSLATE_COAL_ORE) -> 128,
+      ExchangeableMaterial(Material.DEEPSLATE_COPPER_ORE) -> 128,
+      ExchangeableMaterial(Material.DEEPSLATE_IRON_ORE) -> 64,
+      ExchangeableMaterial(Material.DEEPSLATE_GOLD_ORE) -> 8,
+      ExchangeableMaterial(Material.DEEPSLATE_LAPIS_ORE) -> 8,
+      ExchangeableMaterial(Material.DEEPSLATE_DIAMOND_ORE) -> 4,
+      ExchangeableMaterial(Material.DEEPSLATE_REDSTONE_ORE) -> 32,
+      ExchangeableMaterial(Material.DEEPSLATE_EMERALD_ORE) -> 4
     )
 
     val inventoryContents = inventory.getContents.filter(_ != null)
 
     val (itemsToExchange, rejectedItems) =
       inventoryContents.partition { stack =>
-        requiredAmountPerTicket.contains(
-          ExchangeableMaterial(stack.getType, stack.getDurability)
-        )
+        requiredAmountPerTicket.contains(ExchangeableMaterial(stack.getType))
       }
 
-    val exchangingAmount = itemsToExchange
-      .groupBy(stacks => ExchangeableMaterial(stacks.getType, stacks.getDurability))
-      .toList
-      .map { case (key, stacks) => key -> stacks.map(_.getAmount).sum }
+    val exchangingAmount =
+      itemsToExchange.groupBy(stacks => ExchangeableMaterial(stacks.getType)).toList.map {
+        case (key, stacks) => key -> stacks.map(_.getAmount).sum
+      }
 
     val ticketAmount = exchangingAmount.map {
       case (exchangeableMaterial, amount) =>
@@ -139,13 +143,7 @@ class PlayerInventoryListener(
           case (exchangedMaterial, exchangedAmount) =>
             val returningAmount = exchangedAmount % requiredAmountPerTicket(exchangedMaterial)
             if (returningAmount != 0)
-              Some(
-                new ItemStack(
-                  exchangedMaterial.materialType,
-                  returningAmount,
-                  exchangedMaterial.durability
-                )
-              )
+              Some(new ItemStack(exchangedMaterial.materialType, returningAmount))
             else
               None
         }
@@ -186,15 +184,15 @@ class PlayerInventoryListener(
     val uuid = player.getUniqueId
     val playerdata = playerMap(uuid)
 
-    if (topinventory.getTitle == DARK_PURPLE.toString + "" + BOLD + "スキルを進化させますか?") {
+    if (view.getTitle == DARK_PURPLE.toString + "" + BOLD + "スキルを進化させますか?") {
       event.setCancelled(true)
       if (itemstackcurrent.getType == Material.NETHER_STAR) {
         playerdata.giganticBerserk = GiganticBerserk(0, 0, playerdata.giganticBerserk.stage + 1)
         player.playSound(player.getLocation, Sound.BLOCK_END_GATEWAY_SPAWN, 1f, 0.5f)
-        player.playSound(player.getLocation, Sound.ENTITY_ENDERDRAGON_AMBIENT, 1f, 0.8f)
+        player.playSound(player.getLocation, Sound.ENTITY_ENDER_DRAGON_AMBIENT, 1f, 0.8f)
         player.openInventory(MenuInventoryData.getGiganticBerserkAfterEvolutionMenu(player))
       }
-    } else if (topinventory.getTitle == LIGHT_PURPLE.toString + "" + BOLD + "スキルを進化させました") {
+    } else if (view.getTitle == LIGHT_PURPLE.toString + "" + BOLD + "スキルを進化させました") {
       event.setCancelled(true)
     }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/listener/PlayerJoinListener.scala b/src/main/scala/com/github/unchama/seichiassist/listener/PlayerJoinListener.scala
index 8a219d981b..b7a63143ee 100644
--- a/src/main/scala/com/github/unchama/seichiassist/listener/PlayerJoinListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/listener/PlayerJoinListener.scala
@@ -13,7 +13,7 @@ import com.github.unchama.seichiassist.subsystems.mebius.domain.property.{
 }
 import com.github.unchama.seichiassist.util.{SendMessageEffect, SendSoundEffect}
 import com.github.unchama.targetedeffect.player.FocusedSoundEffect
-import net.coreprotect.model.Config
+import net.coreprotect.config.ConfigHandler
 import org.bukkit.ChatColor._
 import org.bukkit.enchantments.Enchantment
 import org.bukkit.entity.Player
@@ -97,12 +97,17 @@ class PlayerJoinListener extends Listener {
     // 初見さんへの処理
     if (!player.hasPlayedBefore) {
       // 初見さんであることを全体告知
-      SendMessageEffect.sendMessageToEveryoneIgnoringPreference(
-        s"$LIGHT_PURPLE$BOLD${player.getName}さんはこのサーバーに初めてログインしました!"
-      )
-      SendMessageEffect.sendMessageToEveryoneIgnoringPreference(
-        s"${WHITE}webサイトはもう読みましたか?→$YELLOW${UNDERLINE}https://www.seichi.network/gigantic"
-      )
+      SendMessageEffect
+        .sendMessageToEveryoneIgnoringPreferenceIO(
+          s"$LIGHT_PURPLE$BOLD${player.getName}さんはこのサーバーに初めてログインしました!"
+        )
+        .unsafeRunAsyncAndForget()
+      SendMessageEffect
+        .sendMessageToEveryoneIgnoringPreferenceIO(
+          s"${WHITE}webサイトはもう読みましたか?→$YELLOW${UNDERLINE}https://www.seichi.network/gigantic"
+        )
+        .unsafeRunAsyncAndForget()
+
       SendSoundEffect.sendEverySound(Sound.ENTITY_PLAYER_LEVELUP, 1f, 1f)
 
       // 同時に【はじめての方へ】ページに誘導したほうがただWebサイトに誘導するよりまだ可能性がありそう
@@ -125,10 +130,14 @@ class PlayerJoinListener extends Listener {
       // 初見プレイヤー向けの Lore (説明文) を設定
       // /stick で入手できる木の棒は、簡略化された説明文にしておく。
       val stickLore = List(
-        "この棒を持って右クリックもしくは左クリックするとメニューが開きます。",
-        "メニューからはいろんな機能が使えます。試してみよう。",
-        "この棒をなくしても /stick コマンドを実行すると再入手できます。",
-        "ヒント: もしサーバー内で迷子になったら /spawn コマンドを実行することでいつでも戻れます。"
+        "この棒を持って右クリックもしくは",
+        "左クリックするとメニューが開きます。",
+        "試してみよう。",
+        "",
+        "この棒をなくしても /stick コマンドを",
+        "実行すると再入手できます。",
+        "ヒント: もしサーバー内で迷子になったら /spawn",
+        "コマンドを実行することでいつでも戻れます。"
       )
       val stick = new ItemStack(Material.STICK, 1).tap { itemStack =>
         import itemStack._
@@ -144,13 +153,13 @@ class PlayerJoinListener extends Listener {
         // 耐久Ⅲ
         .tap(_.addEnchantment(Enchantment.DURABILITY, 3))
       inv.addItem(pickaxe)
-      inv.addItem(new ItemStack(Material.DIAMOND_SPADE))
+      inv.addItem(new ItemStack(Material.DIAMOND_SHOVEL))
 
       inv.addItem(
-        new ItemStack(Material.LOG, 64, 0.toShort),
-        new ItemStack(Material.LOG, 64, 0.toShort),
-        new ItemStack(Material.LOG, 64, 2.toShort),
-        new ItemStack(Material.LOG_2, 64, 1.toShort)
+        new ItemStack(Material.OAK_LOG, 64),
+        new ItemStack(Material.OAK_LOG, 64),
+        new ItemStack(Material.BIRCH_LOG, 64),
+        new ItemStack(Material.DARK_OAK_LOG, 64)
       )
 
       inv.addItem(new ItemStack(Material.BAKED_POTATO, 64))
@@ -196,8 +205,7 @@ class PlayerJoinListener extends Listener {
         BukkitMebiusItemStackCodec.materialize(
           // **getDisplayNameは二つ名も含むのでMCIDにはgetNameが適切**
           MebiusProperty
-            .initialProperty(NormalMebius, player.getName, player.getUniqueId.toString),
-          damageValue = 0.toShort
+            .initialProperty(NormalMebius, player.getName, player.getUniqueId.toString)
         )
       )
 
@@ -215,27 +223,12 @@ class PlayerJoinListener extends Listener {
     // 整地専用サーバーの場合は上級者向けのサーバーである旨を通知
     if (SeichiAssist.seichiAssistConfig.getServerNum == 5)
       player.sendTitle(
-        s"${WHITE}ここは$BLUE${UNDERLINE}上級者向けのサーバー${WHITE}",
+        s"${WHITE}ここは$BLUE${UNDERLINE}上級者向けのサーバー$WHITE",
         s"${WHITE}始めたては他がおすすめ",
         10,
         70,
         20
       )
-
-    // エデンサーバーへ入場する際に警告を行う
-    // TODO: エデンサーバーの不具合が解消されたら削除すること
-    if (SeichiAssist.seichiAssistConfig.getServerNum == 2) {
-      player.sendMessage(
-        Array(
-          s"${RED}${BOLD}${UNDERLINE}【ご注意ください】${RESET}",
-          s"${YELLOW}${BOLD}エデンサーバーは現在、管理者の意図しないタイミングでシャットダウン(いわゆる「鯖落ち」)が起こることがあります。",
-          s"${YELLOW}${BOLD}もし鯖落ちによりアイテムの消失等が発生しても、補償はできかねます。",
-          s"${YELLOW}${BOLD}当サーバーは以上の内容をご理解の上ご利用ください。",
-          s"${YELLOW}${BOLD}不安な場合はアルカディアサーバーやヴァルハラサーバーのご利用をおすすめいたします。",
-          s"${YELLOW}${BOLD}ご迷惑をおかけいたしまして申し訳ございません。。"
-        )
-      )
-    }
   }
 
   // プレイヤーがワールドを移動したとき
@@ -249,10 +242,10 @@ class PlayerJoinListener extends Listener {
 
     // coreprotectを切る
     // inspectマップにtrueで登録されている場合
-    if (Config.inspecting.getOrDefault(p.getName, false)) {
+    if (ConfigHandler.inspecting.getOrDefault(p.getName, false)) {
       // falseに変更する
       p.sendMessage("§3CoreProtect §f- Inspector now disabled.")
-      Config.inspecting.put(p.getName, false)
+      ConfigHandler.inspecting.put(p.getName, false)
     }
 
     // アサルトスキルを切る
diff --git a/src/main/scala/com/github/unchama/seichiassist/listener/SpawnRegionProjectileInterceptor.scala b/src/main/scala/com/github/unchama/seichiassist/listener/SpawnRegionProjectileInterceptor.scala
index 5f7cb471e8..294ad05168 100644
--- a/src/main/scala/com/github/unchama/seichiassist/listener/SpawnRegionProjectileInterceptor.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/listener/SpawnRegionProjectileInterceptor.scala
@@ -1,6 +1,6 @@
 package com.github.unchama.seichiassist.listener
 
-import com.github.unchama.util.external.WorldGuardWrapper.getRegions
+import com.github.unchama.util.external.WorldGuardWrapper.getRegion
 import org.bukkit.Material._
 import org.bukkit.event.block.Action
 import org.bukkit.event.player.PlayerInteractEvent
@@ -19,10 +19,10 @@ object SpawnRegionProjectileInterceptor extends Listener {
     BOW,
     EGG,
     ENDER_PEARL,
-    EXP_BOTTLE,
-    EYE_OF_ENDER,
+    EXPERIENCE_BOTTLE,
+    ENDER_EYE,
     LINGERING_POTION,
-    SNOW_BALL,
+    SNOWBALL,
     SPLASH_POTION
   )
 
@@ -34,7 +34,7 @@ object SpawnRegionProjectileInterceptor extends Listener {
     val isRightClickEvent =
       action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK
     val isInSpawnRegion =
-      getRegions(player.getLocation).map(_.getId).exists(spawnRegionNames.contains)
+      getRegion(player.getLocation).map(_.getId).exists(spawnRegionNames.contains)
 
     // Projectileを持った状態で右クリックし、playerがいる保護がspawn保護の中であった場合はイベントをキャンセルする
     if (hasProjectile && isRightClickEvent && isInSpawnRegion) {
diff --git a/src/main/scala/com/github/unchama/seichiassist/listener/WorldRegenListener.java b/src/main/scala/com/github/unchama/seichiassist/listener/WorldRegenListener.java
index 93d27d1800..06e201cbd9 100644
--- a/src/main/scala/com/github/unchama/seichiassist/listener/WorldRegenListener.java
+++ b/src/main/scala/com/github/unchama/seichiassist/listener/WorldRegenListener.java
@@ -2,15 +2,15 @@
 
 import com.github.unchama.seichiassist.Config;
 import com.github.unchama.seichiassist.SeichiAssist;
-import com.sk89q.worldedit.BlockVector;
 import com.sk89q.worldedit.EditSession;
 import com.sk89q.worldedit.MaxChangedBlocksException;
 import com.sk89q.worldedit.WorldEdit;
-import com.sk89q.worldedit.blocks.BaseBlock;
+import com.sk89q.worldedit.bukkit.BukkitAdapter;
 import com.sk89q.worldedit.bukkit.BukkitWorld;
+import com.sk89q.worldedit.math.BlockVector3;
 import com.sk89q.worldedit.regions.CuboidRegion;
+import com.sk89q.worldguard.WorldGuard;
 import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
-import com.sk89q.worldguard.protection.managers.RegionManager;
 import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
 import com.sk89q.worldguard.protection.regions.ProtectedRegion;
 import com.wimbli.WorldBorder.CoordXZ;
@@ -20,10 +20,14 @@
 import io.monchi.regenworld.event.RegenWorldEvent;
 import org.bukkit.Bukkit;
 import org.bukkit.Location;
+import org.bukkit.Material;
 import org.bukkit.World;
 import org.bukkit.event.EventHandler;
 import org.bukkit.event.Listener;
 
+import java.util.Collection;
+import java.util.Objects;
+
 /**
  * @author Mon_chi
  */
@@ -33,8 +37,6 @@ public class WorldRegenListener implements Listener {
     private final int roadLength;
     private final int spaceHeight;
     private final int worldSize;
-    private final BaseBlock roadBlock;
-    private final BaseBlock spaceBlock;
 
     private final WorldEdit worldEdit;
     private final WorldGuardPlugin worldGuard;
@@ -46,8 +48,6 @@ public WorldRegenListener() {
         this.roadLength = config.getRoadLength();
         this.spaceHeight = config.getSpaceHeight();
         this.worldSize = config.getWorldSize();
-        this.roadBlock = new BaseBlock(config.getRoadBlockID(), config.getRoadBlockDamage());
-        this.spaceBlock = new BaseBlock(0);
 
         this.worldEdit = WorldEdit.getInstance();
         this.worldGuard = WorldGuardPlugin.inst();
@@ -73,20 +73,26 @@ public void onWorldRegen(RegenWorldEvent event) {
             com.wimbli.WorldBorder.Config.fillTask.setTaskID(task);
         }
 
-        RegionManager regionManager = worldGuard.getRegionManager(world);
-        regionManager.getRegions().keySet().stream()
-                .filter(region -> !region.equalsIgnoreCase("__global__"))
-                .forEach(regionManager::removeRegion);
+        Collection<ProtectedRegion> regions = Objects.requireNonNull(WorldGuard.getInstance().getPlatform()
+                .getRegionContainer()
+                .get(BukkitAdapter.adapt(world)))
+                .getRegions()
+                .values();
+
+        regions.forEach(region -> {
+            Objects.requireNonNull(WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(world))).removeRegion(region.getId());
+        });
+
 
         EditSession session = worldEdit.getEditSessionFactory().getEditSession(bukkitWorld, 99999999);
         try {
             // spawnの地形造成
-            setupRoadWithWorldGuard(session, world, "spawn", new BlockVector(0, roadY, 0), new BlockVector(15, roadY, 15));
+            setupRoadWithWorldGuard(session, world, "spawn", BlockVector3.at(0, roadY, 0), BlockVector3.at(15, roadY, 15));
             // 東西南北へ続くroadの地形造成
-            setupRoad(session, world, new BlockVector(16, roadY, 0), new BlockVector(15 + 16 * roadLength, roadY, 15));
-            setupRoad(session, world, new BlockVector(-1, roadY, 0), new BlockVector(-(16 * roadLength), roadY, 15));
-            setupRoad(session, world, new BlockVector(0, roadY, 16), new BlockVector(15, roadY, 15 + 16 * roadLength));
-            setupRoad(session, world, new BlockVector(0, roadY, -1), new BlockVector(15, roadY, -(16 * roadLength)));
+            setupRoad(session, world, BlockVector3.at(16, roadY, 0), BlockVector3.at(15 + 16 * roadLength, roadY, 15));
+            setupRoad(session, world, BlockVector3.at(-1, roadY, 0), BlockVector3.at(-(16 * roadLength), roadY, 15));
+            setupRoad(session, world, BlockVector3.at(0, roadY, 16), BlockVector3.at(15, roadY, 15 + 16 * roadLength));
+            setupRoad(session, world, BlockVector3.at(0, roadY, -1), BlockVector3.at(15, roadY, -(16 * roadLength)));
         } catch (MaxChangedBlocksException e) {
             e.printStackTrace();
         }
@@ -95,33 +101,24 @@ public void onWorldRegen(RegenWorldEvent event) {
     /**
      * 地形造成を行う
      *
-     * @param session
-     * @param world
-     * @param pos1
-     * @param pos2
      * @throws MaxChangedBlocksException
      */
-    private void setupRoad(EditSession session, World world, BlockVector pos1, BlockVector pos2) throws MaxChangedBlocksException {
+    private void setupRoad(EditSession session, World world, BlockVector3 pos1, BlockVector3 pos2) throws MaxChangedBlocksException {
         BukkitWorld bukkitWorld = new BukkitWorld(world);
-        session.setBlocks(new CuboidRegion(bukkitWorld, pos1, pos2), roadBlock);
-        session.setBlocks(new CuboidRegion(bukkitWorld, pos1.add(0, 1, 0), pos2.add(0, 1 + spaceHeight, 0)), spaceBlock);
+        session.setBlocks(new CuboidRegion(bukkitWorld, pos1, pos2), BukkitAdapter.adapt(Material.BEDROCK.createBlockData()));
+        session.setBlocks(new CuboidRegion(bukkitWorld, pos1.add(0, 1, 0), pos2.add(0, 1 + spaceHeight, 0)), BukkitAdapter.adapt(Material.AIR.createBlockData()));
     }
 
     /**
      * 地形造成と、地形造成を行った場所にWorldGuardRegionも設定する
      *
-     * @param session
-     * @param world
-     * @param protName
-     * @param pos1
-     * @param pos2
      * @throws MaxChangedBlocksException
      */
-    private void setupRoadWithWorldGuard(EditSession session, World world, String protName, BlockVector pos1, BlockVector pos2) throws MaxChangedBlocksException {
+    private void setupRoadWithWorldGuard(EditSession session, World world, String protName, BlockVector3 pos1, BlockVector3 pos2) throws MaxChangedBlocksException {
         BukkitWorld bukkitWorld = new BukkitWorld(world);
-        session.setBlocks(new CuboidRegion(bukkitWorld, pos1, pos2), roadBlock);
-        session.setBlocks(new CuboidRegion(bukkitWorld, pos1.add(0, 1, 0), pos2.add(0, 1 + spaceHeight, 0)), spaceBlock);
-        ProtectedRegion region = new ProtectedCuboidRegion(protName, new BlockVector(pos1.getX(), 0, pos1.getZ()), new BlockVector(pos2.getX(), 255, pos2.getZ()));
-        WorldGuardPlugin.inst().getRegionManager(world).addRegion(region);
+        session.setBlocks(new CuboidRegion(bukkitWorld, pos1, pos2), BukkitAdapter.adapt(Material.BEDROCK.createBlockData()));
+        session.setBlocks(new CuboidRegion(bukkitWorld, pos1.add(0, 1, 0), pos2.add(0, 1 + spaceHeight, 0)), BukkitAdapter.adapt(Material.AIR.createBlockData()));
+        ProtectedRegion region = new ProtectedCuboidRegion(protName, BlockVector3.at(pos1.getX(), 0, pos1.getZ()), BlockVector3.at(pos2.getX(), 255, pos2.getZ()));
+        WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(world)).addRegion(region);
     }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/listener/Y5DoubleSlabCanceller.scala b/src/main/scala/com/github/unchama/seichiassist/listener/YMinus59DoubleSlabCanceller.scala
similarity index 60%
rename from src/main/scala/com/github/unchama/seichiassist/listener/Y5DoubleSlabCanceller.scala
rename to src/main/scala/com/github/unchama/seichiassist/listener/YMinus59DoubleSlabCanceller.scala
index fd84ecbdfa..f2d85be0e5 100644
--- a/src/main/scala/com/github/unchama/seichiassist/listener/Y5DoubleSlabCanceller.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/listener/YMinus59DoubleSlabCanceller.scala
@@ -1,11 +1,11 @@
 package com.github.unchama.seichiassist.listener
 
 import com.github.unchama.seichiassist.ManagedWorld._
-import org.bukkit.Material
+import org.bukkit.block.data.`type`.Slab
 import org.bukkit.event.block.BlockPlaceEvent
 import org.bukkit.event.{EventHandler, Listener}
 
-object Y5DoubleSlabCanceller extends Listener {
+object YMinus59DoubleSlabCanceller extends Listener {
 
   /**
    * 以下の条件をすべて満たすときにブロックの設置をキャンセルし、その旨を示すメッセージを送出する
@@ -13,22 +13,22 @@ object Y5DoubleSlabCanceller extends Listener {
    *   - プレイヤーが手に持っているブロックが焼き石のハーフブロックである
    *   - 対象座標の改変後ブロックが焼き石の二段重ねハーフブロックである
    *   - 対象座標が整地ワールドを指している
-   *   - 対象ブロックのY座標が5である
+   *   - 対象ブロックのY座標が-59である
    * @see
    *   https://github.com/GiganticMinecraft/SeichiAssist/issues/775
    * @param event
    *   対象イベント
    */
   @EventHandler
-  def onPlaceDoubleSlabAtY5(event: BlockPlaceEvent): Unit = {
+  def onPlaceDoubleSlabAtYMinus59(event: BlockPlaceEvent): Unit = {
     if (!event.canBuild) return
-    if (event.getItemInHand.getType ne Material.STEP) return
-    if (event.getItemInHand.getDurability != 0) return
-    if (event.getBlockPlaced.getType ne Material.DOUBLE_STEP) return
-    if (event.getBlockPlaced.getData != 0) return
     if (!event.getBlockPlaced.getWorld.isSeichi) return
-    if (event.getBlockPlaced.getY != 5) return
-    event.setCancelled(true)
-    event.getPlayer.sendMessage("Y5のハーフブロックを二段重ねにすることはできません。")
+    if (event.getBlockPlaced.getY != -59) return
+    event.getBlockPlaced.getBlockData match {
+      case slab: Slab if slab.getType == Slab.Type.DOUBLE =>
+        event.setCancelled(true)
+        event.getPlayer.sendMessage("Y-59のハーフブロックを二段重ねにすることはできません。")
+      case _ =>
+    }
   }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/listener/invlistener/OnClickTitleMenu.scala b/src/main/scala/com/github/unchama/seichiassist/listener/invlistener/OnClickTitleMenu.scala
index 4122f4b310..bcb60755ee 100644
--- a/src/main/scala/com/github/unchama/seichiassist/listener/invlistener/OnClickTitleMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/listener/invlistener/OnClickTitleMenu.scala
@@ -57,7 +57,11 @@ object OnClickTitleMenu {
     if (topInventory.row != 4) {
       return
     }
-    val current = event.getCurrentItem
+    val current = event
+      .getCurrentItem
+      .ifNull(
+        return
+      )
 
     val player = he.asInstanceOf[Player]
     val pd = SeichiAssist.playermap(player.getUniqueId)
@@ -68,191 +72,169 @@ object OnClickTitleMenu {
     }
 
     val mat = current.getType
-    val isSkull = mat == Material.SKULL_ITEM
-    topInventory.getTitle match {
+    val isSkull = mat == Material.PLAYER_HEAD
+    view.getTitle match {
       case MenuType.HEAD.invName =>
         event.setCancelled(true)
-        mat match {
-          case Material.WATER_BUCKET =>
-            clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
-
-            val id = current.getItemMeta.getDisplayName.toInt
-            val length = Nicknames
-              .getCombinedNicknameFor(id, pd.settings.nickname.id2, pd.settings.nickname.id3)
-              .getOrElse("")
-              .length
-            if (length > MAX_LENGTH) {
-              player.sendMessage(LENGTH_LIMIT_EXCEEDED)
-            } else {
-              pd.updateNickname(id1 = id)
-              player.sendMessage(
-                "前パーツ「" + Nicknames
-                  .getHeadPartFor(pd.settings.nickname.id1)
-                  .getOrElse("") + "」をセットしました。"
-              )
-            }
-
-          case Material.GRASS =>
-            // unselect
-            clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
-            pd.updateNickname(id1 = 0)
-            player.sendMessage("前パーツの選択を解除しました。")
-
-          case Material.BARRIER =>
-            clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
-            ioCanOpenNicknameMenu.open(NickNameMenu).apply(player).unsafeRunAsyncAndForget()
-
-          case _ if isSkull && isApplicableAsNextPageButton(current) =>
-            // 次ページ
-            clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
-            val uuid = player.getUniqueId
-            val menuType = MenuInventoryData.MenuType.HEAD
-            MenuInventoryData.setHeadingIndex(
-              uuid,
-              menuType,
-              MenuInventoryData.getHeadingIndex(uuid, menuType).get + PER_PAGE
+        if (mat == Material.WATER_BUCKET) {
+          clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
+
+          val id = current.getItemMeta.getDisplayName.toInt
+          val length = Nicknames
+            .getCombinedNicknameFor(id, pd.settings.nickname.id2, pd.settings.nickname.id3)
+            .getOrElse("")
+            .length
+          if (length > MAX_LENGTH) {
+            player.sendMessage(LENGTH_LIMIT_EXCEEDED)
+          } else {
+            pd.updateNickname(id1 = id)
+            player.sendMessage(
+              "前パーツ「" + Nicknames
+                .getHeadPartFor(pd.settings.nickname.id1)
+                .getOrElse("") + "」をセットしました。"
             )
-            player.openInventory(MenuInventoryData.computeHeadPartCustomMenu(player))
-
-          case _ =>
+          }
+        } else if (mat == Material.GRASS) {
+          // unselect
+          clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
+          pd.updateNickname(id1 = 0)
+          player.sendMessage("前パーツの選択を解除しました。")
+        } else if (mat == Material.BARRIER) {
+          clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
+          ioCanOpenNicknameMenu.open(NickNameMenu).apply(player).unsafeRunAsyncAndForget()
+        } else if (isSkull && isApplicableAsNextPageButton(current)) {
+          // 次ページ
+          clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
+          val uuid = player.getUniqueId
+          val menuType = MenuInventoryData.MenuType.HEAD
+          MenuInventoryData.setHeadingIndex(
+            uuid,
+            menuType,
+            MenuInventoryData.getHeadingIndex(uuid, menuType).get + PER_PAGE
+          )
+          player.openInventory(MenuInventoryData.computeHeadPartCustomMenu(player))
         }
 
       case MenuType.MIDDLE.invName =>
         event.setCancelled(true)
-        mat match {
-          case Material.MILK_BUCKET =>
-            clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
-
-            val id = current.getItemMeta.getDisplayName.toInt
-            val length = Nicknames
-              .getCombinedNicknameFor(pd.settings.nickname.id1, id, pd.settings.nickname.id3)
-              .getOrElse("")
-              .length
-            if (length > MAX_LENGTH) {
-              player.sendMessage(LENGTH_LIMIT_EXCEEDED)
-            } else {
-              pd.updateNickname(id2 = id)
-              player.sendMessage(
-                "中パーツ「" + Nicknames
-                  .getMiddlePartFor(pd.settings.nickname.id2)
-                  .getOrElse("") + "」をセットしました。"
-              )
-            }
-
-          case Material.GRASS =>
-            clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
-            pd.updateNickname(id2 = 0)
-            player.sendMessage("中パーツの選択を解除しました。")
 
-          case Material.BARRIER =>
-            clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
-            ioCanOpenNicknameMenu.open(NickNameMenu).apply(player).unsafeRunAsyncAndForget()
-
-          case _ if isSkull && isApplicableAsNextPageButton(current) =>
-            clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
-            val uuid = player.getUniqueId
-            val menuType = MenuInventoryData.MenuType.MIDDLE
-            MenuInventoryData.setHeadingIndex(
-              uuid,
-              menuType,
-              MenuInventoryData.getHeadingIndex(uuid, menuType).get + PER_PAGE
+        if (mat == Material.MILK_BUCKET) {
+          clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
+
+          val id = current.getItemMeta.getDisplayName.toInt
+          val length = Nicknames
+            .getCombinedNicknameFor(pd.settings.nickname.id1, id, pd.settings.nickname.id3)
+            .getOrElse("")
+            .length
+          if (length > MAX_LENGTH) {
+            player.sendMessage(LENGTH_LIMIT_EXCEEDED)
+          } else {
+            pd.updateNickname(id2 = id)
+            player.sendMessage(
+              "中パーツ「" + Nicknames
+                .getMiddlePartFor(pd.settings.nickname.id2)
+                .getOrElse("") + "」をセットしました。"
             )
-            player.openInventory(MenuInventoryData.computeMiddlePartCustomMenu(player))
-
-          case _ =>
+          }
+        } else if (mat == Material.GRASS) {
+          clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
+          pd.updateNickname(id2 = 0)
+          player.sendMessage("中パーツの選択を解除しました。")
+        } else if (mat == Material.BARRIER) {
+          clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
+          ioCanOpenNicknameMenu.open(NickNameMenu).apply(player).unsafeRunAsyncAndForget()
+        } else if (isSkull && isApplicableAsNextPageButton(current)) {
+          clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
+          val uuid = player.getUniqueId
+          val menuType = MenuInventoryData.MenuType.MIDDLE
+          MenuInventoryData.setHeadingIndex(
+            uuid,
+            menuType,
+            MenuInventoryData.getHeadingIndex(uuid, menuType).get + PER_PAGE
+          )
+          player.openInventory(MenuInventoryData.computeMiddlePartCustomMenu(player))
         }
 
       case MenuType.TAIL.invName =>
         event.setCancelled(true)
-        mat match {
-          case Material.LAVA_BUCKET =>
-            clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
-
-            val id = current.getItemMeta.getDisplayName.toInt
-            val length = Nicknames
-              .getCombinedNicknameFor(pd.settings.nickname.id1, pd.settings.nickname.id2, id)
-              .getOrElse("")
-              .length
-            if (length > MAX_LENGTH) {
-              player.sendMessage(LENGTH_LIMIT_EXCEEDED)
-            } else {
-              pd.updateNickname(id3 = id)
-              player.sendMessage(
-                "後パーツ「" + Nicknames
-                  .getTailPartFor(pd.settings.nickname.id3)
-                  .getOrElse("") + "」をセットしました。"
-              )
-            }
 
-          case Material.GRASS =>
-            clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
-            pd.updateNickname(id3 = 0)
-            player.sendMessage("後パーツの選択を解除しました。")
-
-          case Material.BARRIER =>
-            clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
-            ioCanOpenNicknameMenu.open(NickNameMenu).apply(player).unsafeRunAsyncAndForget()
-
-          case _ if isSkull && isApplicableAsNextPageButton(current) =>
-            clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
-            val uuid = player.getUniqueId
-            val menuType = MenuInventoryData.MenuType.TAIL
-            MenuInventoryData.setHeadingIndex(
-              uuid,
-              menuType,
-              MenuInventoryData.getHeadingIndex(uuid, menuType).get + PER_PAGE
+        if (mat == Material.LAVA_BUCKET) {
+          clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
+
+          val id = current.getItemMeta.getDisplayName.toInt
+          val length = Nicknames
+            .getCombinedNicknameFor(pd.settings.nickname.id1, pd.settings.nickname.id2, id)
+            .getOrElse("")
+            .length
+          if (length > MAX_LENGTH) {
+            player.sendMessage(LENGTH_LIMIT_EXCEEDED)
+          } else {
+            pd.updateNickname(id3 = id)
+            player.sendMessage(
+              "後パーツ「" + Nicknames
+                .getTailPartFor(pd.settings.nickname.id3)
+                .getOrElse("") + "」をセットしました。"
             )
-            player.openInventory(MenuInventoryData.computeTailPartCustomMenu(player))
-
-          case _ =>
+          }
+        } else if (mat == Material.GRASS) {
+          clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
+          pd.updateNickname(id3 = 0)
+          player.sendMessage("後パーツの選択を解除しました。")
+        } else if (mat == Material.BARRIER) {
+          clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
+          ioCanOpenNicknameMenu.open(NickNameMenu).apply(player).unsafeRunAsyncAndForget()
+        } else if (isSkull && isApplicableAsNextPageButton(current)) {
+          clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
+          val uuid = player.getUniqueId
+          val menuType = MenuInventoryData.MenuType.TAIL
+          MenuInventoryData.setHeadingIndex(
+            uuid,
+            menuType,
+            MenuInventoryData.getHeadingIndex(uuid, menuType).get + PER_PAGE
+          )
+          player.openInventory(MenuInventoryData.computeTailPartCustomMenu(player))
         }
 
       case MenuType.SHOP.invName =>
         event.setCancelled(true)
-        mat match {
+        if (mat == Material.EMERALD_ORE) {
           // 実績ポイント最新化
-          case Material.EMERALD_ORE =>
-            clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
-            pd.recalculateAchievePoint()
-            pd.samepageflag = true
-            player.openInventory(MenuInventoryData.computePartsShopMenu(player))
-
+          clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
+          pd.recalculateAchievePoint()
+          pd.samepageflag = true
+          player.openInventory(MenuInventoryData.computePartsShopMenu(player))
+        } else if (mat == Material.BEDROCK) {
           // 購入処理
-          case Material.BEDROCK =>
-            clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
-
-            val num = current.getItemMeta.getDisplayName.toInt
-            val isHead = num < 9900
-            val required = if (isHead) 20 else 35
-            val getPart = if (isHead) { num => Nicknames.getHeadPartFor(num) }
-            else { num => Nicknames.getMiddlePartFor(num) }
-
-            if (pd.achievePoint.left >= required) {
-              pd.TitleFlags.addOne(num)
-              pd.consumeAchievePoint(required)
-              player.sendMessage("パーツ「" + getPart(num).getOrElse("") + "」を購入しました。")
-              pd.samepageflag = true
-              player.openInventory(MenuInventoryData.computePartsShopMenu(player))
-            } else {
-              player.sendMessage("実績ポイントが不足しています。")
-            }
-
-          case Material.BARRIER =>
-            clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
-            ioCanOpenNicknameMenu.open(NickNameMenu).apply(player).unsafeRunAsyncAndForget()
-
-          case _ if isSkull && isApplicableAsNextPageButton(current) =>
-            clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
-            val uuid = player.getUniqueId
-            val menuType = MenuInventoryData.MenuType.SHOP
-            MenuInventoryData.setHeadingIndex(
-              uuid,
-              menuType,
-              MenuInventoryData.getHeadingIndex(uuid, menuType).get + PER_PAGE
-            )
+          clickedSound(player, Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1.0f)
+
+          val num = current.getItemMeta.getDisplayName.toInt
+          val isHead = num < 9900
+          val required = if (isHead) 20 else 35
+          val getPart = if (isHead) { num => Nicknames.getHeadPartFor(num) }
+          else { num => Nicknames.getMiddlePartFor(num) }
+
+          if (pd.achievePoint.left >= required) {
+            pd.TitleFlags.addOne(num)
+            pd.consumeAchievePoint(required)
+            player.sendMessage("パーツ「" + getPart(num).getOrElse("") + "」を購入しました。")
+            pd.samepageflag = true
             player.openInventory(MenuInventoryData.computePartsShopMenu(player))
-
-          case _ =>
+          } else {
+            player.sendMessage("実績ポイントが不足しています。")
+          }
+        } else if (mat == Material.BARRIER) {
+          clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
+          ioCanOpenNicknameMenu.open(NickNameMenu).apply(player).unsafeRunAsyncAndForget()
+        } else if (isSkull && isApplicableAsNextPageButton(current)) {
+          clickedSound(player, Sound.BLOCK_FENCE_GATE_OPEN, 0.1f)
+          val uuid = player.getUniqueId
+          val menuType = MenuInventoryData.MenuType.SHOP
+          MenuInventoryData.setHeadingIndex(
+            uuid,
+            menuType,
+            MenuInventoryData.getHeadingIndex(uuid, menuType).get + PER_PAGE
+          )
+          player.openInventory(MenuInventoryData.computePartsShopMenu(player))
         }
 
       // それ以外のインベントリの名前だった場合何もしない!
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/BuildMainMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/BuildMainMenu.scala
index f655e40618..f6d55c8841 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/BuildMainMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/BuildMainMenu.scala
@@ -21,6 +21,7 @@ import com.github.unchama.seichiassist.subsystems.managedfly.domain.{
   NotFlying,
   RemainingFlyDuration
 }
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.targetedeffect.commandsender.MessageEffect
 import com.github.unchama.targetedeffect.player.PlayerEffects.{
   closeInventoryEffect,
@@ -39,7 +40,8 @@ import org.bukkit.inventory.ItemFlag
 import org.bukkit.{Material, Sound}
 
 private case class ButtonComputations(player: Player)(
-  implicit ioOnMainThread: OnMinecraftServerThread[IO]
+  implicit ioOnMainThread: OnMinecraftServerThread[IO],
+  playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
 ) {
 
   import BuildMainMenu._
@@ -207,7 +209,7 @@ private case class ButtonComputations(player: Player)(
       IO {
         val openerData = BuildAssist.instance.temporaryData(getUniqueId)
 
-        val iconItemStack = new IconItemStackBuilder(Material.WOOD)
+        val iconItemStack = new IconItemStackBuilder(Material.OAK_PLANKS)
           .title(s"$YELLOW${EMPHASIZE}直列設置: ${BuildAssist.line_up_str(openerData.line_up_flg)}")
           .lore(
             s"$RESET${GRAY}オフハンドに木の棒、メインハンドに設置したいブロックを持って",
@@ -279,7 +281,7 @@ private case class ButtonComputations(player: Player)(
   def computeButtonToOpenMenuToCraftItemsWhereMineStack(
     implicit canOpenMassCraftMenu: CanOpen[IO, MineStackMassCraftMenu]
   ): IO[Button] = IO {
-    val iconItemStackBuilder = new IconItemStackBuilder(Material.WORKBENCH)
+    val iconItemStackBuilder = new IconItemStackBuilder(Material.CRAFTING_TABLE)
       .title(s"$YELLOW${EMPHASIZE}MineStackブロック一括クラフト画面へ")
       .lore(s"$RESET$DARK_RED${UNDERLINE}クリックで移動")
       .build()
@@ -398,7 +400,8 @@ object BuildMainMenu extends Menu {
     implicit val flyApi: ManagedFlyApi[SyncIO, Player],
     val ioOnMainThread: OnMinecraftServerThread[IO],
     val canOpenBlockPlacementSkillMenu: CanOpen[IO, BlockPlacementSkillMenu.type],
-    val canOpenMassCraftMenu: CanOpen[IO, MineStackMassCraftMenu]
+    val canOpenMassCraftMenu: CanOpen[IO, MineStackMassCraftMenu],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
   val EMPHASIZE = s"$UNDERLINE$BOLD"
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/CommonButtons.scala b/src/main/scala/com/github/unchama/seichiassist/menus/CommonButtons.scala
index fddb7593ee..d265a6f2b1 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/CommonButtons.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/CommonButtons.scala
@@ -9,6 +9,8 @@ import com.github.unchama.seichiassist.SkullOwners
 import com.github.unchama.seichiassist.effects.player.CommonSoundEffects
 import com.github.unchama.seichiassist.menus.ColorScheme.{clickResultDescription, navigation}
 import com.github.unchama.seichiassist.menus.stickmenu.{FirstPage, StickMenu}
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
+import org.bukkit.entity.Player
 
 /**
  * メニューUIに頻繁に現れるような[Button]を生成する、または定数として持っているオブジェクト.
@@ -33,7 +35,10 @@ object CommonButtons {
       )
     )
 
-  def openStickMenu(implicit canOpenStickMenu: CanOpen[IO, FirstPage.type]): Button = {
+  def openStickMenu(
+    implicit canOpenStickMenu: CanOpen[IO, FirstPage.type],
+    playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
+  ): Button = {
     transferButton(
       new SkullItemStackBuilder(SkullOwners.MHF_ArrowLeft),
       "木の棒メニューホームへ",
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/RegionMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/RegionMenu.scala
index e8d1a01e54..126952108e 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/RegionMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/RegionMenu.scala
@@ -15,7 +15,8 @@ import com.github.unchama.seichiassist.menus.gridregion.GridRegionMenu
 import com.github.unchama.seichiassist.subsystems.gridregion.GridRegionAPI
 import com.github.unchama.targetedeffect.commandsender.MessageEffect
 import com.github.unchama.targetedeffect.player.{CommandEffect, FocusedSoundEffect}
-import com.github.unchama.util.external.ExternalPlugins
+import com.sk89q.worldedit.WorldEdit
+import com.sk89q.worldedit.bukkit.BukkitAdapter
 import org.bukkit.ChatColor._
 import org.bukkit.entity.Player
 import org.bukkit.event.inventory.InventoryType
@@ -69,34 +70,34 @@ object RegionMenu extends Menu {
     val computeButtonToClaimRegion: IO[Button] = for {
       regionCount <- gridRegionAPI.regionCount(player)
     } yield {
-      val selection = ExternalPlugins.getWorldEdit.getSelection(player)
-
+      val session = WorldEdit.getInstance().getSessionManager.get(BukkitAdapter.adapt(player))
+      val world = BukkitAdapter.adapt(player.getWorld)
+      val isSelected = session.isSelectionDefined(world)
       val playerHasPermission = player.hasPermission("worldguard.region.claim")
-      val isSelectionNull = selection == null
+
+      val selectionOpt = Option.when(isSelected)(session.getSelection(world))
       val selectionHasEnoughSpace =
-        if (!isSelectionNull)
-          selection.getLength >= 10 && selection.getWidth >= 10
-        else false
+        selectionOpt.exists(selection => selection.getLength >= 10 && selection.getWidth >= 10)
 
-      val canMakeRegion = playerHasPermission && !isSelectionNull && selectionHasEnoughSpace
+      val canMakeRegion = playerHasPermission && !isSelected && selectionHasEnoughSpace
 
       val iconItemStack = {
-
         val lore = {
-          if (!playerHasPermission)
+          if (!playerHasPermission) {
             Seq(s"${RED}このワールドでは", s"${RED}保護を作成できません")
-          else if (isSelectionNull)
+          } else if (!isSelected) {
             Seq(s"${RED}範囲指定されていません", s"${RED}先に木の斧で2か所クリックしてネ")
-          else if (!selectionHasEnoughSpace)
+          } else if (!selectionHasEnoughSpace) {
             Seq(s"${RED}選択された範囲が狭すぎます", s"${RED}一辺当たり最低10ブロック以上にしてネ")
-          else
+          } else {
             Seq(s"$DARK_GREEN${UNDERLINE}範囲指定されています", s"$DARK_GREEN${UNDERLINE}クリックすると保護を作成します")
+          }
         } ++ {
           if (playerHasPermission)
             Seq(
               s"${GRAY}Y座標は自動で全範囲保護されます",
               s"${YELLOW}A new region has been claimed",
-              s"${YELLOW}named '${getName}_$regionCount'.",
+              s"${YELLOW}named '${getName}_${regionCount.value}'.",
               s"${GRAY}と出れば保護設定完了です",
               s"${RED}赤色で別の英文が出た場合",
               s"${GRAY}保護の設定に失敗しています",
@@ -108,7 +109,7 @@ object RegionMenu extends Menu {
         }
 
         import scala.util.chaining._
-        new IconItemStackBuilder(Material.GOLD_AXE)
+        new IconItemStackBuilder(Material.GOLDEN_AXE)
           .tap { b => if (canMakeRegion) b.enchanted() }
           .title(s"$YELLOW$UNDERLINE${BOLD}保護の作成")
           .lore(lore.toList)
@@ -120,7 +121,7 @@ object RegionMenu extends Menu {
         action.FilteredButtonEffect(ClickEventFilter.LEFT_CLICK)(_ =>
           if (!playerHasPermission)
             MessageEffect(s"${RED}このワールドでは保護を作成できません")
-          else if (isSelectionNull)
+          else if (!isSelected)
             SequentialEffect(
               MessageEffect(s"${RED}先に木の斧で範囲を指定してからこのボタンを押してください"),
               FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 0.5f)
@@ -133,7 +134,7 @@ object RegionMenu extends Menu {
           else
             SequentialEffect(
               CommandEffect("/expand vert"),
-              CommandEffect(s"rg claim ${player.getName}_$regionCount"),
+              CommandEffect(s"rg claim ${player.getName}_${regionCount.value}"),
               gridRegionAPI.createAndClaimRegionSelectedOnWorldGuard,
               CommandEffect("/sel"),
               FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 1f)
@@ -153,7 +154,7 @@ object RegionMenu extends Menu {
         s"$GREEN④メニューの${YELLOW}金の斧${GREEN}をクリック"
       )
 
-      val iconItemStack = new IconItemStackBuilder(Material.WOOD_AXE)
+      val iconItemStack = new IconItemStackBuilder(Material.WOODEN_AXE)
         .title(s"$YELLOW$UNDERLINE${BOLD}保護設定用の木の斧を召喚")
         .lore(
           wandUsage ++ List(
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/ServerSwitchMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/ServerSwitchMenu.scala
index f037604ab3..f338920141 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/ServerSwitchMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/ServerSwitchMenu.scala
@@ -7,6 +7,7 @@ import com.github.unchama.menuinventory.slot.button.Button
 import com.github.unchama.menuinventory.slot.button.action.LeftClickButtonEffect
 import com.github.unchama.menuinventory.{ChestSlotRef, Menu, MenuFrame, MenuSlotLayout}
 import com.github.unchama.seichiassist.menus.stickmenu.FirstPage
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.targetedeffect._
 import com.github.unchama.targetedeffect.player.PlayerEffects._
 import org.bukkit.ChatColor._
@@ -53,7 +54,7 @@ object ServerSwitchMenu extends Menu {
         )
 
     case object EDEN
-        extends Server(s"$YELLOW${BOLD}エデン", "s2", ChestSlotRef(0, 1), Material.DIAMOND_SPADE)
+        extends Server(s"$YELLOW${BOLD}エデン", "s2", ChestSlotRef(0, 1), Material.DIAMOND_SHOVEL)
 
     case object VALHALLA
         extends Server(s"$YELLOW${BOLD}ヴァルハラ", "s3", ChestSlotRef(0, 2), Material.DIAMOND_AXE)
@@ -71,7 +72,10 @@ object ServerSwitchMenu extends Menu {
   import com.github.unchama.menuinventory.syntax._
   import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts.onMainThread
 
-  class Environment(implicit val ioCanOpenStickMenu: IO CanOpen FirstPage.type)
+  class Environment(
+    implicit val ioCanOpenStickMenu: IO CanOpen FirstPage.type,
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
+  )
 
   /**
    * メニューのサイズとタイトルに関する情報
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/TopLevelRouter.scala b/src/main/scala/com/github/unchama/seichiassist/menus/TopLevelRouter.scala
index b31e314295..c7b44baa6c 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/TopLevelRouter.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/TopLevelRouter.scala
@@ -15,7 +15,7 @@ import com.github.unchama.seichiassist.menus.home.{ConfirmationMenuEnvironment,
 import com.github.unchama.seichiassist.menus.minestack.{
   CategorizedMineStackMenu,
   MineStackMainMenu,
-  MineStackSelectItemColorMenu
+  MineStackSelectItemKindMenu
 }
 import com.github.unchama.seichiassist.menus.nicknames.NickNameMenu
 import com.github.unchama.seichiassist.menus.ranking.{RankingMenu, RankingRootMenu}
@@ -48,6 +48,7 @@ import com.github.unchama.seichiassist.subsystems.gridregion.GridRegionAPI
 import com.github.unchama.seichiassist.subsystems.home.HomeReadAPI
 import com.github.unchama.seichiassist.subsystems.mana.ManaApi
 import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.ranking.api.AssortedRankingApi
 import com.github.unchama.seichiassist.subsystems.ranking.domain.values.{LoginTime, VoteCount}
 import com.github.unchama.seichiassist.subsystems.sharedinventory.SharedInventoryAPI
@@ -102,7 +103,8 @@ object TopLevelRouter {
     consumeGachaTicketAPI: ConsumeGachaTicketAPI[IO, Player],
     fairySpeechAPI: FairySpeechAPI[IO, Player],
     gridRegionAPI: GridRegionAPI[IO, Player, Location],
-    breakSkillTargetConfigAPI: BreakSkillTargetConfigAPI[IO, Player]
+    breakSkillTargetConfigAPI: BreakSkillTargetConfigAPI[IO, Player],
+    playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   ): TopLevelRouter[IO] = new TopLevelRouter[IO] {
     import assortedRankingApi._
 
@@ -134,9 +136,8 @@ object TopLevelRouter {
       new AchievementGroupMenu.Environment
     implicit lazy val passiveSkillMenuEnv: PassiveSkillMenu.Environment =
       new PassiveSkillMenu.Environment
-    implicit lazy val mineStackSelectItemColorMenuEnv
-      : MineStackSelectItemColorMenu.Environment =
-      new MineStackSelectItemColorMenu.Environment
+    implicit lazy val mineStackSelectItemColorMenuEnv: MineStackSelectItemKindMenu.Environment =
+      new MineStackSelectItemKindMenu.Environment
 
     implicit lazy val seichiRankingMenuEnv: RankingMenu[SeichiAmountData]#Environment =
       new RankingMenu.Environment
@@ -163,7 +164,7 @@ object TopLevelRouter {
 
     implicit lazy val ioCanOpenNickNameMenu: IO CanOpen NickNameMenu.type = _.open
 
-    implicit lazy val ioCanOpenSelectItemColorMenu: IO CanOpen MineStackSelectItemColorMenu =
+    implicit lazy val ioCanOpenSelectItemColorMenu: IO CanOpen MineStackSelectItemKindMenu =
       _.open
     implicit lazy val ioCanOpenAchievementGroupMenu: IO CanOpen AchievementGroupMenu = _.open
     implicit lazy val ioCanOpenHomeConfirmationMenu
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/VoteMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/VoteMenu.scala
index 14b414cf4c..90897b0a1c 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/VoteMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/VoteMenu.scala
@@ -12,6 +12,7 @@ import com.github.unchama.menuinventory.{ChestSlotRef, Menu, MenuFrame, MenuSlot
 import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts
 import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts.onMainThread
 import com.github.unchama.seichiassist.menus.stickmenu.FirstPage
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.vote.VoteAPI
 import com.github.unchama.seichiassist.subsystems.vote.subsystems.fairy.FairyAPI
 import com.github.unchama.seichiassist.subsystems.vote.subsystems.fairy.domain.property.FairyAppleConsumeStrategy.{
@@ -46,7 +47,8 @@ object VoteMenu extends Menu {
     implicit val voteAPI: VoteAPI[IO, Player],
     val fairyAPI: FairyAPI[IO, SyncIO, Player],
     val ioCanOpenFirstPage: IO CanOpen FirstPage.type,
-    val fairySpeechAPI: FairySpeechAPI[IO, Player]
+    val fairySpeechAPI: FairySpeechAPI[IO, Player],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
   /**
@@ -149,7 +151,7 @@ object VoteMenu extends Menu {
     }
 
     val showVoteURLButton: Button = Button(
-      new IconItemStackBuilder(Material.BOOK_AND_QUILL)
+      new IconItemStackBuilder(Material.WRITABLE_BOOK)
         .title(s"$YELLOW$UNDERLINE${BOLD}投票ページにアクセス")
         .lore(
           List(
@@ -181,7 +183,7 @@ object VoteMenu extends Menu {
         fairySummonCost <- fairyAPI.fairySummonCost(player)
       } yield {
         Button(
-          new IconItemStackBuilder(Material.WATCH)
+          new IconItemStackBuilder(Material.CLOCK)
             .title(s"$AQUA$UNDERLINE${BOLD}マナ妖精 時間設定")
             .lore(
               List(
@@ -288,7 +290,7 @@ object VoteMenu extends Menu {
           LeftClickButtonEffect {
             SequentialEffect(
               FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 1f),
-              DeferredEffect(IO(fairySpeechAPI.togglePlaySoundOnSpeech))
+              fairySpeechAPI.togglePlaySoundOnSpeech
             )
           }
         )
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/achievement/AchievementCategoryMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/achievement/AchievementCategoryMenu.scala
index 587499d69b..fedf88062a 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/achievement/AchievementCategoryMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/achievement/AchievementCategoryMenu.scala
@@ -20,6 +20,7 @@ import com.github.unchama.seichiassist.menus.achievement.AchievementCategoryMenu
 }
 import com.github.unchama.seichiassist.menus.achievement.group.AchievementGroupMenu
 import com.github.unchama.seichiassist.menus.{ColorScheme, CommonButtons}
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import org.bukkit.ChatColor._
 import org.bukkit.Material
 import org.bukkit.entity.Player
@@ -37,12 +38,12 @@ object AchievementCategoryMenu {
         ChestSlotRef(1, 5) -> (BrokenBlockRanking, Material.DIAMOND_PICKAXE)
       )
     case Building =>
-      Map(ChestSlotRef(1, 4) -> (PlacedBlockAmount, Material.BIRCH_WOOD_STAIRS))
+      Map(ChestSlotRef(1, 4) -> (PlacedBlockAmount, Material.BIRCH_STAIRS))
     case Login =>
       Map(
         ChestSlotRef(1, 1) -> (PlayTime, Material.COMPASS),
         ChestSlotRef(1, 3) -> (TotalLogins, Material.BOOK),
-        ChestSlotRef(1, 5) -> (ConsecutiveLogins, Material.BOOK_AND_QUILL),
+        ChestSlotRef(1, 5) -> (ConsecutiveLogins, Material.WRITABLE_BOOK),
         ChestSlotRef(1, 7) -> (Anniversaries, Material.NETHER_STAR)
       )
     case Challenges =>
@@ -53,8 +54,8 @@ object AchievementCategoryMenu {
     case Specials =>
       Map(
         ChestSlotRef(1, 2) -> (OfficialEvent, Material.BLAZE_POWDER),
-        ChestSlotRef(1, 4) -> (VoteCounts, Material.YELLOW_FLOWER),
-        ChestSlotRef(1, 6) -> (Secrets, Material.DIAMOND_BARDING)
+        ChestSlotRef(1, 4) -> (VoteCounts, Material.DANDELION),
+        ChestSlotRef(1, 6) -> (Secrets, Material.DIAMOND_HORSE_ARMOR)
       )
   }
 
@@ -80,7 +81,8 @@ object AchievementCategoryMenu {
 
   class Environment(
     implicit val ioCanOpenAchievementMainMenu: IO CanOpen AchievementMenu.type,
-    val ioCanOpenAchievementGroupMenu: IO CanOpen AchievementGroupMenu
+    val ioCanOpenAchievementGroupMenu: IO CanOpen AchievementGroupMenu,
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/achievement/AchievementMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/achievement/AchievementMenu.scala
index fe318872ad..332a2c70bd 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/achievement/AchievementMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/achievement/AchievementMenu.scala
@@ -14,6 +14,7 @@ import com.github.unchama.seichiassist.effects.player.CommonSoundEffects
 import com.github.unchama.seichiassist.menus.nicknames.NickNameMenu
 import com.github.unchama.seichiassist.menus.stickmenu.FirstPage
 import com.github.unchama.seichiassist.menus.{ColorScheme, CommonButtons}
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.vote.VoteAPI
 import com.github.unchama.targetedeffect.player.FocusedSoundEffect
 import com.github.unchama.targetedeffect.{SequentialEffect, TargetedEffect}
@@ -31,7 +32,8 @@ object AchievementMenu extends Menu {
     val ioCanOpenCategoryMenu: IO CanOpen AchievementCategoryMenu,
     val ioOnMainThread: OnMinecraftServerThread[IO],
     val voteAPI: VoteAPI[IO, Player],
-    val ioCanOpenNickNameMenu: IO CanOpen NickNameMenu.type
+    val ioCanOpenNickNameMenu: IO CanOpen NickNameMenu.type,
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
   override val frame: MenuFrame = MenuFrame(4.chestRows, s"$DARK_PURPLE${BOLD}実績・二つ名システム")
@@ -40,11 +42,11 @@ object AchievementMenu extends Menu {
 
   val categoryLayout: Map[Int, AchievementCategoryRepr] =
     Map(
-      ChestSlotRef(1, 1) -> (BrokenBlock, Material.GOLD_PICKAXE),
+      ChestSlotRef(1, 1) -> (BrokenBlock, Material.GOLDEN_PICKAXE),
       ChestSlotRef(1, 3) -> (Building, Material.GLASS),
       ChestSlotRef(1, 5) -> (Login, Material.COMPASS),
       ChestSlotRef(1, 7) -> (Challenges, Material.BLAZE_POWDER),
-      ChestSlotRef(2, 4) -> (Specials, Material.EYE_OF_ENDER)
+      ChestSlotRef(2, 4) -> (Specials, Material.ENDER_EYE)
     )
 
   def buttonFor(
@@ -88,7 +90,7 @@ object AchievementMenu extends Menu {
       categoryLayout.view.mapValues(category => buttonFor(category)).toMap
 
     val toggleTitleToPlayerLevelButton = Button(
-      new IconItemStackBuilder(Material.REDSTONE_TORCH_ON)
+      new IconItemStackBuilder(Material.REDSTONE_TORCH)
         .title(ColorScheme.navigation("整地Lvを表示"))
         .lore(
           List(
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/achievement/group/AchievementGroupMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/achievement/group/AchievementGroupMenu.scala
index a9839f17b5..0d75390bfe 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/achievement/group/AchievementGroupMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/achievement/group/AchievementGroupMenu.scala
@@ -13,6 +13,7 @@ import com.github.unchama.seichiassist.achievement.hierarchy.AchievementGroup._
 import com.github.unchama.seichiassist.menus.achievement.AchievementCategoryMenu
 import com.github.unchama.seichiassist.menus.achievement.group.AchievementGroupMenu.sequentialEntriesIn
 import com.github.unchama.seichiassist.menus.{ColorScheme, CommonButtons}
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.targetedeffect.TargetedEffect
 import org.bukkit.entity.Player
 
@@ -20,7 +21,8 @@ object AchievementGroupMenu {
 
   class Environment(
     implicit val ioCanOpenGroupMenu: IO CanOpen AchievementGroupMenu,
-    val ioCanOpenCategoryMenu: IO CanOpen AchievementCategoryMenu
+    val ioCanOpenCategoryMenu: IO CanOpen AchievementCategoryMenu,
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
   val sequentialEntriesIn: AchievementGroup => List[GroupMenuEntry] = CachedFunction {
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/achievement/group/AchievementGroupMenuButtons.scala b/src/main/scala/com/github/unchama/seichiassist/menus/achievement/group/AchievementGroupMenuButtons.scala
index 02a6355957..535d6fc3b7 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/achievement/group/AchievementGroupMenuButtons.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/achievement/group/AchievementGroupMenuButtons.scala
@@ -19,6 +19,7 @@ import com.github.unchama.seichiassist.achievement.{
   NicknameMapping,
   SeichiAchievement
 }
+import com.github.unchama.seichiassist.achievement.hierarchy.AchievementGroup
 import com.github.unchama.seichiassist.menus.ColorScheme
 import com.github.unchama.targetedeffect.commandsender.MessageEffect
 import com.github.unchama.targetedeffect.player.FocusedSoundEffect
@@ -124,7 +125,13 @@ object AchievementGroupMenuButtons {
                                 .playermap(player.getUniqueId)
                                 .TitleFlags
                                 .addOne(achievement.id)
-                              player.sendMessage(s"実績No${achievement.id}を解除しました!おめでとうございます!")
+                              val displayGroupName =
+                                AchievementGroup
+                                  .getGroupNameByEntryId(achievement.id)
+                                  .getOrElse("未実装")
+                              player.sendMessage(
+                                s"[${displayGroupName}]実績No${achievement.id}を解除しました!おめでとうございます!"
+                              )
                             }
                             else {
                               MessageEffect(s"${RED}実績No${achievement.id}は条件を満たしていません。")(player)
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/gridregion/GridRegionMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/gridregion/GridRegionMenu.scala
index ed58f828e9..630ee03d79 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/gridregion/GridRegionMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/gridregion/GridRegionMenu.scala
@@ -80,7 +80,7 @@ object GridRegionMenu extends Menu {
       for {
         currentLengthChangePerClick <- gridRegionAPI.lengthChangePerClick(player)
       } yield {
-        val iconItemStack = new IconItemStackBuilder(Material.STAINED_GLASS_PANE, 1)
+        val iconItemStack = new IconItemStackBuilder(Material.WHITE_STAINED_GLASS_PANE)
           .title(s"${GREEN}拡張単位の変更")
           .lore(
             List(
@@ -143,11 +143,15 @@ object GridRegionMenu extends Menu {
           case HorizontalAxisAlignedSubjectiveDirection.Right  => "右へ"
         }
 
-        val stainedGlassPaneDurability = relativeDirection match {
-          case HorizontalAxisAlignedSubjectiveDirection.Ahead  => 14
-          case HorizontalAxisAlignedSubjectiveDirection.Left   => 10
-          case HorizontalAxisAlignedSubjectiveDirection.Behind => 13
-          case HorizontalAxisAlignedSubjectiveDirection.Right  => 5
+        val material = relativeDirection match {
+          case HorizontalAxisAlignedSubjectiveDirection.Ahead =>
+            Material.RED_STAINED_GLASS_PANE
+          case HorizontalAxisAlignedSubjectiveDirection.Behind =>
+            Material.GREEN_STAINED_GLASS_PANE
+          case HorizontalAxisAlignedSubjectiveDirection.Left =>
+            Material.PURPLE_STAINED_GLASS_PANE
+          case HorizontalAxisAlignedSubjectiveDirection.Right =>
+            Material.YELLOW_STAINED_GLASS_PANE
         }
 
         def updateCurrentRegionShapeTo(
@@ -169,10 +173,10 @@ object GridRegionMenu extends Menu {
         }
 
         Button(
-          new IconItemStackBuilder(
-            Material.STAINED_GLASS_PANE,
-            stainedGlassPaneDurability.toShort
-          ).title(s"$DARK_GREEN${relativeDirectionString}ユニット増やす/減らす").lore(lore).build(),
+          new IconItemStackBuilder(material)
+            .title(s"$DARK_GREEN${relativeDirectionString}ユニット増やす/減らす")
+            .lore(lore)
+            .build(),
           LeftClickButtonEffect(updateCurrentRegionShapeTo(expandedShape)),
           RightClickButtonEffect(updateCurrentRegionShapeTo(contractedShape))
         )
@@ -194,7 +198,7 @@ object GridRegionMenu extends Menu {
     }
 
     val resetSettingButton: Button = {
-      val itemStack = new IconItemStackBuilder(Material.STAINED_GLASS_PANE, 4)
+      val itemStack = new IconItemStackBuilder(Material.YELLOW_STAINED_GLASS_PANE)
         .title(s"${RED}全設定リセット")
         .lore(List(s"$RED${UNDERLINE}取り扱い注意!!"))
         .build()
@@ -225,10 +229,10 @@ object GridRegionMenu extends Menu {
           s"${GRAY}右方向:${showRegionShapeDimension(shape.right)}",
           s"${GRAY}左方向:${showRegionShapeDimension(shape.left)}",
           s"${GRAY}保護ユニット数:$AQUA${shape.regionUnits.count}",
-          s"${GRAY}保護ユニット上限値:$RED${gridRegionAPI.regionUnitLimit(worldName).limit}"
+          s"${GRAY}保護ユニット上限値:$RED${gridRegionAPI.regionUnitLimit(worldName).limit.count}"
         )
 
-        val itemStack = new IconItemStackBuilder(Material.STAINED_GLASS_PANE, 11)
+        val itemStack = new IconItemStackBuilder(Material.BLUE_STAINED_GLASS_PANE)
           .title(s"${DARK_GREEN}設定")
           .lore(lore)
           .build()
@@ -245,7 +249,7 @@ object GridRegionMenu extends Menu {
         canCreateRegionResult match {
           case RegionCreationResult.Success =>
             Button(
-              new IconItemStackBuilder(Material.WOOL, 11)
+              new IconItemStackBuilder(Material.LIGHT_BLUE_WOOL)
                 .title(s"${GREEN}保護作成")
                 .lore(List(s"${DARK_GREEN}保護作成可能です", s"$RED${UNDERLINE}クリックで作成"))
                 .build(),
@@ -257,14 +261,14 @@ object GridRegionMenu extends Menu {
             )
           case RegionCreationResult.WorldProhibitsRegionCreation =>
             Button(
-              new IconItemStackBuilder(Material.WOOL, 14)
+              new IconItemStackBuilder(Material.RED_WOOL)
                 .title(s"${RED}保護作成")
                 .lore(List(s"$RED${UNDERLINE}このワールドでは保護を作成できません"))
                 .build()
             )
           case RegionCreationResult.Error =>
             Button(
-              new IconItemStackBuilder(Material.WOOL, 1)
+              new IconItemStackBuilder(Material.RED_WOOL)
                 .title(s"${RED}以下の原因により保護の作成できません")
                 .lore(
                   List(
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/home/HomeMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/home/HomeMenu.scala
index f899665d95..2af33b9774 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/home/HomeMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/home/HomeMenu.scala
@@ -14,6 +14,7 @@ import com.github.unchama.seichiassist.menus.CommonButtons
 import com.github.unchama.seichiassist.menus.stickmenu.FirstPage
 import com.github.unchama.seichiassist.subsystems.home.HomeReadAPI
 import com.github.unchama.seichiassist.subsystems.home.domain.{Home, HomeId}
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.{ManagedWorld, SkullOwners}
 import com.github.unchama.targetedeffect._
 import com.github.unchama.targetedeffect.player.PlayerEffects._
@@ -31,7 +32,8 @@ object HomeMenu {
     implicit val ioCanOpenHome: IO CanOpen HomeMenu,
     val ioCanOpenHomeRemoveConfirmationMenu: IO CanOpen HomeRemoveConfirmationMenu,
     implicit val homeReadAPI: HomeReadAPI[IO],
-    implicit val asyncShift: NonServerThreadContextShift[IO]
+    implicit val asyncShift: NonServerThreadContextShift[IO],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
 }
@@ -168,8 +170,9 @@ case class HomeMenuButtonComputations(player: Player)(
         val commandInfo =
           List(s"$DARK_RED${UNDERLINE}クリックで名称変更", s"${DARK_GRAY}command->[/home name $homeId]")
 
-        val coordinates = List(s"$GRAY$worldName x:${Math.floor(location.x)} y:${Math
-            .floor(location.y)} z:${Math.floor(location.z)}")
+        val coordinates = List(
+          s"$GRAY$worldName x:${Math.floor(location.x)} y:${Math.floor(location.y)} z:${Math.floor(location.z)}"
+        )
         nameStatus ++ commandInfo ++ coordinates
       })
       Button(
@@ -200,7 +203,7 @@ case class HomeMenuButtonComputations(player: Player)(
       homeOpt <- homeReadAPI.get(player.getUniqueId, homeId)
     } yield {
       Button(
-        new IconItemStackBuilder(Material.BED)
+        new IconItemStackBuilder(Material.WHITE_BED)
           .title(s"$YELLOW$UNDERLINE${BOLD}ホームポイント${homeNumber}を設定")
           .lore(
             List(
@@ -231,7 +234,7 @@ case class HomeMenuButtonComputations(player: Player)(
       homeOpt <- homeReadAPI.get(player.getUniqueId, homeId)
     } yield {
       Button(
-        new IconItemStackBuilder(Material.WOOL, 14)
+        new IconItemStackBuilder(Material.RED_WOOL)
           .title(s"$RED$UNDERLINE${BOLD}ホームポイント${homeNumber}を削除")
           .lore(
             List(
@@ -242,7 +245,7 @@ case class HomeMenuButtonComputations(player: Player)(
           )
           .build(),
         LeftClickButtonEffect {
-          FocusedSoundEffect(Sound.BLOCK_ENDERCHEST_CLOSE, 1f, 0.1f)
+          FocusedSoundEffect(Sound.BLOCK_ENDER_CHEST_CLOSE, 1f, 0.1f)
           SequentialEffect(
             environment
               .ioCanOpenHomeRemoveConfirmationMenu
@@ -272,7 +275,7 @@ case class HomeChangeConfirmationMenu(changeHomeNumber: Int, homeName: String =
 
   val changeButton: Button =
     Button(
-      new IconItemStackBuilder(Material.WOOL, durability = 5).title(s"${GREEN}変更する").build(),
+      new IconItemStackBuilder(Material.LIME_WOOL).title(s"${GREEN}変更する").build(),
       LeftClickButtonEffect {
         SequentialEffect(
           FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 1f),
@@ -284,7 +287,7 @@ case class HomeChangeConfirmationMenu(changeHomeNumber: Int, homeName: String =
 
   def cancelButton(implicit environment: Environment): Button =
     Button(
-      new IconItemStackBuilder(Material.WOOL, durability = 14).title(s"${RED}変更しない").build(),
+      new IconItemStackBuilder(Material.RED_WOOL).title(s"${RED}変更しない").build(),
       LeftClickButtonEffect {
         FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 1f)
         environment.ioCanOpenHomeMenu.open(new HomeMenu)
@@ -324,7 +327,7 @@ case class HomeRemoveConfirmationMenu(removeHomeNumber: Int, homeName: String =
 
   val removeButton: Button =
     Button(
-      new IconItemStackBuilder(Material.WOOL, durability = 5).title(s"${GREEN}削除する").build(),
+      new IconItemStackBuilder(Material.LIME_WOOL).title(s"${GREEN}削除する").build(),
       LeftClickButtonEffect {
         SequentialEffect(
           FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 1f),
@@ -336,7 +339,7 @@ case class HomeRemoveConfirmationMenu(removeHomeNumber: Int, homeName: String =
 
   def cancelButton(implicit environment: Environment): Button =
     Button(
-      new IconItemStackBuilder(Material.WOOL, durability = 14).title(s"${RED}変更しない").build(),
+      new IconItemStackBuilder(Material.RED_WOOL).title(s"${RED}変更しない").build(),
       LeftClickButtonEffect {
         FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 1f)
         environment.ioCanOpenHomeMenu.open(new HomeMenu)
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/minestack/CategorizedMineStackMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/minestack/CategorizedMineStackMenu.scala
index 3df3df405d..e79c4b3fb4 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/minestack/CategorizedMineStackMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/minestack/CategorizedMineStackMenu.scala
@@ -12,6 +12,7 @@ import com.github.unchama.seichiassist.menus.CommonButtons
 import com.github.unchama.seichiassist.subsystems.gachaprize.GachaPrizeAPI
 import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
 import com.github.unchama.seichiassist.subsystems.minestack.domain.minestackobject.MineStackObjectCategory
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.targetedeffect.{DeferredEffect, TargetedEffect}
 import org.bukkit.ChatColor._
 import org.bukkit.entity.Player
@@ -22,10 +23,11 @@ object CategorizedMineStackMenu {
   class Environment(
     implicit val ioCanOpenMineStackMainMenu: IO CanOpen MineStackMainMenu.type,
     val ioCanOpenCategorizedMenu: IO CanOpen CategorizedMineStackMenu,
-    val ioCanOpenSelectItemColorMenu: IO CanOpen MineStackSelectItemColorMenu,
+    val ioCanOpenSelectItemColorMenu: IO CanOpen MineStackSelectItemKindMenu,
     val onMainThread: OnMinecraftServerThread[IO],
     val mineStackAPI: MineStackAPI[IO, Player, ItemStack],
-    implicit val gachaPrizeAPI: GachaPrizeAPI[IO, ItemStack, Player]
+    implicit val gachaPrizeAPI: GachaPrizeAPI[IO, ItemStack, Player],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
 }
@@ -52,7 +54,8 @@ case class CategorizedMineStackMenu(category: MineStackObjectCategory, pageIndex
   )
 
   private def mineStackMainMenuButtonSection(
-    implicit ioCanOpenMineStackMainMenu: IO CanOpen MineStackMainMenu.type
+    implicit ioCanOpenMineStackMainMenu: IO CanOpen MineStackMainMenu.type,
+    playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   ): Seq[(Int, Button)] =
     Seq(
       ChestSlotRef(5, 0) -> CommonButtons.transferButton(
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/minestack/MineStackButtons.scala b/src/main/scala/com/github/unchama/seichiassist/menus/minestack/MineStackButtons.scala
index 5a2d1ba2fb..19a7bfca12 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/minestack/MineStackButtons.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/minestack/MineStackButtons.scala
@@ -12,7 +12,7 @@ import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
 import com.github.unchama.seichiassist.subsystems.minestack.domain.minestackobject.{
   MineStackObject,
   MineStackObjectGroup,
-  MineStackObjectWithColorVariants
+  MineStackObjectWithKindVariants
 }
 import com.github.unchama.seichiassist.util.InventoryOperations.grantItemStacksEffect
 import com.github.unchama.targetedeffect.commandsender.MessageEffect
@@ -38,7 +38,7 @@ private[minestack] case class MineStackButtons(player: Player)(
     mineStackObjectGroup match {
       case Left(mineStackObject) =>
         mineStackObject
-      case Right(MineStackObjectWithColorVariants(representative, _)) =>
+      case Right(MineStackObjectWithKindVariants(representative, _)) =>
         representative
     }
   }
@@ -69,7 +69,7 @@ private[minestack] case class MineStackButtons(player: Player)(
     val mineStackObject = mineStackObjectGroup match {
       case Left(mineStackObject) =>
         mineStackObject
-      case Right(MineStackObjectWithColorVariants(representative, _)) =>
+      case Right(MineStackObjectWithKindVariants(representative, _)) =>
         representative
     }
 
@@ -94,17 +94,17 @@ private[minestack] case class MineStackButtons(player: Player)(
             }
 
             setLore {
-              val itemDetail = List(s"$RESET$GREEN${stackedAmount.formatted("%,d")}個")
               val operationDetail =
                 if (mineStackObjectGroup.isRight) {
-                  List(s"$RESET${DARK_GREEN}クリックで色選択画面を開きます。")
+                  List(s"$RESET${DARK_GREEN}クリックで種類選択画面を開きます。")
                 } else {
                   List(
+                    s"$RESET$GREEN${String.format("%,d", stackedAmount)}個",
                     s"$RESET$DARK_RED${UNDERLINE}左クリックで1スタック取り出し",
                     s"$RESET$DARK_AQUA${UNDERLINE}右クリックで1個取り出し"
                   )
                 }
-              (itemDetail ++ operationDetail).asJava
+              operationDetail.asJava
             }
 
             setAmount(1)
@@ -120,7 +120,7 @@ private[minestack] case class MineStackButtons(player: Player)(
     oldPage: Int
   )(
     implicit onMainThread: OnMinecraftServerThread[IO],
-    canOpenCategorizedMineStackMenu: IO CanOpen MineStackSelectItemColorMenu
+    canOpenCategorizedMineStackMenu: IO CanOpen MineStackSelectItemKindMenu
   ): IO[Button] = RecomputedButton {
     for {
       itemStack <- getMineStackObjectIconItemStack(mineStackObjectGroup)
@@ -152,7 +152,7 @@ private[minestack] case class MineStackButtons(player: Player)(
     oldPage: Int
   )(
     implicit onMainThread: OnMinecraftServerThread[IO],
-    canOpenMineStackSelectItemColorMenu: IO CanOpen MineStackSelectItemColorMenu
+    canOpenMineStackSelectItemColorMenu: IO CanOpen MineStackSelectItemKindMenu
   ): Kleisli[IO, Player, Unit] = {
     mineStackObjectGroup match {
       case Left(mineStackObject) =>
@@ -168,7 +168,7 @@ private[minestack] case class MineStackButtons(player: Player)(
         )
       case Right(mineStackObjectWithColorVariants) =>
         canOpenMineStackSelectItemColorMenu.open(
-          MineStackSelectItemColorMenu(mineStackObjectWithColorVariants, oldPage)
+          MineStackSelectItemKindMenu(mineStackObjectWithColorVariants, oldPage)
         )
     }
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/minestack/MineStackMainMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/minestack/MineStackMainMenu.scala
index dadbab3c2c..f6800b8c2c 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/minestack/MineStackMainMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/minestack/MineStackMainMenu.scala
@@ -13,6 +13,7 @@ import com.github.unchama.seichiassist.subsystems.gachaprize.GachaPrizeAPI
 import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
 import com.github.unchama.seichiassist.subsystems.minestack.domain.minestackobject.MineStackObjectCategory
 import com.github.unchama.seichiassist.subsystems.minestack.domain.minestackobject.MineStackObjectCategory._
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import org.bukkit.ChatColor._
 import org.bukkit.Material
 import org.bukkit.entity.Player
@@ -28,7 +29,8 @@ object MineStackMainMenu extends Menu {
     implicit val ioCanOpenFirstPage: IO CanOpen FirstPage.type,
     implicit val ioCanOpenCategorizedMineStackMenu: IO CanOpen CategorizedMineStackMenu,
     implicit val gachaPrizeAPI: GachaPrizeAPI[IO, ItemStack, Player],
-    implicit val mineStackAPI: MineStackAPI[IO, Player, ItemStack]
+    implicit val mineStackAPI: MineStackAPI[IO, Player, ItemStack],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
   override val frame: MenuFrame = MenuFrame(6.chestRows, s"$DARK_PURPLE${BOLD}MineStackメインメニュー")
@@ -39,8 +41,8 @@ object MineStackMainMenu extends Menu {
     def iconMaterialFor(category: MineStackObjectCategory): Material = category match {
       case ORES                        => Material.DIAMOND_ORE
       case MOB_DROP                    => Material.ENDER_PEARL
-      case AGRICULTURAL                => Material.SEEDS
-      case BUILDING                    => Material.SMOOTH_BRICK
+      case AGRICULTURAL                => Material.WHEAT_SEEDS
+      case BUILDING                    => Material.STONE_BRICKS
       case REDSTONE_AND_TRANSPORTATION => Material.REDSTONE
       case GACHA_PRIZES                => Material.GOLDEN_APPLE
     }
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/minestack/MineStackSelectItemColorMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/minestack/MineStackSelectItemColorMenu.scala
deleted file mode 100644
index 4b150c03a2..0000000000
--- a/src/main/scala/com/github/unchama/seichiassist/menus/minestack/MineStackSelectItemColorMenu.scala
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.github.unchama.seichiassist.menus.minestack
-
-import cats.effect.IO
-import cats.implicits.toTraverseOps
-import com.github.unchama.itemstackbuilder.SkullItemStackBuilder
-import com.github.unchama.menuinventory.router.CanOpen
-import com.github.unchama.menuinventory.{ChestSlotRef, Menu, MenuFrame, MenuSlotLayout}
-import com.github.unchama.seichiassist.SkullOwners
-import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts.onMainThread
-import com.github.unchama.seichiassist.menus.CommonButtons
-import com.github.unchama.seichiassist.subsystems.gachaprize.GachaPrizeAPI
-import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
-import com.github.unchama.seichiassist.subsystems.minestack.domain.minestackobject.MineStackObjectWithColorVariants
-import eu.timepit.refined.auto._
-import org.bukkit.ChatColor.{BOLD, DARK_BLUE}
-import org.bukkit.entity.Player
-import org.bukkit.inventory.ItemStack
-
-object MineStackSelectItemColorMenu {
-
-  class Environment(
-    implicit val canOpenCategorizedMineStackMenu: CanOpen[IO, CategorizedMineStackMenu],
-    implicit val mineStackAPI: MineStackAPI[IO, Player, ItemStack],
-    implicit val gachaPrizeAPI: GachaPrizeAPI[IO, ItemStack, Player]
-  )
-
-}
-
-case class MineStackSelectItemColorMenu(
-  group: MineStackObjectWithColorVariants[ItemStack],
-  oldPage: Int
-) extends Menu {
-
-  import com.github.unchama.menuinventory.syntax._
-
-  override type Environment = MineStackSelectItemColorMenu.Environment
-  override val frame: MenuFrame =
-    MenuFrame(6.chestRows, s"$DARK_BLUE${BOLD}MineStack(アイテム色選択)")
-
-  override def computeMenuLayout(
-    player: Player
-  )(implicit environment: Environment): IO[MenuSlotLayout] = {
-    import environment._
-    val buttonMapping = (List(group.representative) ++ group.coloredVariants).zipWithIndex.map {
-      case (inListMineStackObj, index) =>
-        index -> MineStackButtons(player).getMineStackObjectButtonOf(inListMineStackObj)
-    } ++ List(
-      ChestSlotRef(5, 0) -> IO(
-        CommonButtons.transferButton(
-          new SkullItemStackBuilder(SkullOwners.MHF_ArrowUp),
-          s"MineStack${oldPage + 1}ページ目へ",
-          CategorizedMineStackMenu(group.category, oldPage)
-        )
-      )
-    )
-    for {
-      mapping <- buttonMapping.traverse(_.sequence)
-    } yield MenuSlotLayout(mapping: _*)
-
-  }
-
-}
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/minestack/MineStackSelectItemKindMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/minestack/MineStackSelectItemKindMenu.scala
new file mode 100644
index 0000000000..3cc2017e4a
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/minestack/MineStackSelectItemKindMenu.scala
@@ -0,0 +1,110 @@
+package com.github.unchama.seichiassist.menus.minestack
+
+import cats.effect.IO
+import cats.implicits.toTraverseOps
+import com.github.unchama.itemstackbuilder.{SkullItemStackBuilder, SkullOwnerReference}
+import com.github.unchama.menuinventory.router.CanOpen
+import com.github.unchama.menuinventory.{ChestSlotRef, Menu, MenuFrame, MenuSlotLayout}
+import com.github.unchama.seichiassist.SkullOwners
+import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts.onMainThread
+import com.github.unchama.seichiassist.menus.CommonButtons
+import com.github.unchama.seichiassist.subsystems.gachaprize.GachaPrizeAPI
+import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
+import com.github.unchama.seichiassist.subsystems.minestack.domain.minestackobject.MineStackObjectWithKindVariants
+import eu.timepit.refined.auto._
+import org.bukkit.ChatColor.{BOLD, DARK_BLUE}
+import org.bukkit.entity.Player
+import org.bukkit.inventory.ItemStack
+import com.github.unchama.menuinventory.slot.button.Button
+import com.github.unchama.generic.MapExtra
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
+
+object MineStackSelectItemKindMenu {
+
+  class Environment(
+    implicit val canOpenCategorizedMineStackMenu: CanOpen[IO, CategorizedMineStackMenu],
+    implicit val canOpenSelectItemKindMenu: CanOpen[IO, MineStackSelectItemKindMenu],
+    implicit val mineStackAPI: MineStackAPI[IO, Player, ItemStack],
+    implicit val gachaPrizeAPI: GachaPrizeAPI[IO, ItemStack, Player],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
+  )
+
+}
+
+case class MineStackSelectItemKindMenu(
+  group: MineStackObjectWithKindVariants[ItemStack],
+  oldPage: Int,
+  pageIndex: Int = 0
+) extends Menu {
+
+  import com.github.unchama.menuinventory.syntax._
+
+  override type Environment = MineStackSelectItemKindMenu.Environment
+  override val frame: MenuFrame =
+    MenuFrame(6.chestRows, s"$DARK_BLUE${BOLD}MineStack(アイテム種類選択)")
+
+  /**
+   * マインスタックオブジェクトボタンを置くセクションの行数
+   */
+  private val objectSectionRows = 5
+
+  // ページ操作等のボタンを含むレイアウトセクション
+  def uiOperationSection(
+    totalNumberOfPages: Int
+  )(page: Int)(implicit environment: Environment): Seq[(Int, Button)] = {
+    import environment._
+
+    def buttonToTransferTo(pageIndex: Int, skullOwnerReference: SkullOwnerReference): Button =
+      CommonButtons.transferButton(
+        new SkullItemStackBuilder(skullOwnerReference),
+        s"MineStack(アイテム種類選択)${pageIndex + 1}ページ目へ",
+        MineStackSelectItemKindMenu(group, oldPage, pageIndex)
+      )
+
+    val previousPageButtonSection =
+      MapExtra.when(page > 0)(
+        Map(ChestSlotRef(5, 7) -> buttonToTransferTo(page - 1, SkullOwners.MHF_ArrowUp))
+      )
+
+    val nextPageButtonSection =
+      MapExtra.when(page + 1 < totalNumberOfPages)(
+        Map(ChestSlotRef(5, 8) -> buttonToTransferTo(page + 1, SkullOwners.MHF_ArrowDown))
+      )
+
+    (previousPageButtonSection ++ nextPageButtonSection).toSeq
+  }
+
+  override def computeMenuLayout(
+    player: Player
+  )(implicit environment: Environment): IO[MenuSlotLayout] = {
+    import environment._
+    val mineStackObjectPerPage = objectSectionRows.chestRows.slotCount
+
+    val buttonMapping = (List(group.representative) ++ group.kindVariants)
+      .slice(
+        mineStackObjectPerPage * pageIndex,
+        mineStackObjectPerPage * pageIndex + mineStackObjectPerPage
+      )
+      .zipWithIndex
+      .map {
+        case (inListMineStackObj, index) =>
+          index -> MineStackButtons(player).getMineStackObjectButtonOf(inListMineStackObj)
+      } ++ List(
+      ChestSlotRef(5, 0) -> IO(
+        CommonButtons.transferButton(
+          new SkullItemStackBuilder(SkullOwners.MHF_ArrowUp),
+          s"MineStack${oldPage + 1}ページ目へ",
+          CategorizedMineStackMenu(group.category, oldPage)
+        )
+      )
+    )
+
+    val totalNumberOfPages = Math.ceil((group.kindVariants.length + 1) / 45.0).toInt
+
+    for {
+      mapping <- buttonMapping.traverse(_.sequence)
+    } yield MenuSlotLayout(mapping ++ uiOperationSection(totalNumberOfPages)(pageIndex): _*)
+
+  }
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/nicknames/NickNameMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/nicknames/NickNameMenu.scala
index 79d30d4de4..6304b22081 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/nicknames/NickNameMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/nicknames/NickNameMenu.scala
@@ -19,6 +19,7 @@ import com.github.unchama.seichiassist.achievement.Nicknames
 import com.github.unchama.seichiassist.data.MenuInventoryData
 import com.github.unchama.seichiassist.menus.CommonButtons
 import com.github.unchama.seichiassist.menus.achievement.AchievementMenu
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.vote.VoteAPI
 import com.github.unchama.targetedeffect.{SequentialEffect, UnfocusedEffect}
 import com.github.unchama.targetedeffect.player.FocusedSoundEffect
@@ -33,7 +34,8 @@ object NickNameMenu extends Menu {
     implicit val ioCanOpenAchievementMenu: IO CanOpen AchievementMenu.type,
     implicit val layoutPreparationContext: LayoutPreparationContext,
     implicit val onMinecraftServerThread: OnMinecraftServerThread[IO],
-    implicit val voteAPI: VoteAPI[IO, Player]
+    implicit val voteAPI: VoteAPI[IO, Player],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
   override val frame: MenuFrame = MenuFrame(4.chestRows, s"$DARK_PURPLE${BOLD}二つ名組み合わせシステム")
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/ranking/RankingMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/ranking/RankingMenu.scala
index 8b45a77a6b..f7bfb6baa6 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/ranking/RankingMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/ranking/RankingMenu.scala
@@ -10,6 +10,7 @@ import com.github.unchama.seichiassist.SkullOwners
 import com.github.unchama.seichiassist.menus.CommonButtons
 import com.github.unchama.seichiassist.subsystems.breakcount.domain.SeichiAmountData
 import com.github.unchama.seichiassist.subsystems.buildcount.domain.playerdata.BuildAmountData
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.ranking.api.RankingProvider
 import com.github.unchama.seichiassist.subsystems.ranking.domain.values.{LoginTime, VoteCount}
 import com.github.unchama.seichiassist.subsystems.ranking.domain.{
@@ -25,7 +26,8 @@ object RankingMenu {
   class Environment[R](
     implicit val rankingApi: RankingProvider[IO, R],
     val ioCanOpenRankingMenuItself: IO CanOpen RankingMenu[R],
-    val ioCanOpenRankingRootMenu: IO CanOpen RankingRootMenu.type
+    val ioCanOpenRankingRootMenu: IO CanOpen RankingRootMenu.type,
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
 }
@@ -157,10 +159,14 @@ case class RankingMenu[R](template: RankingMenuTemplate[R], pageIndex: Int = 0)
     goBackToStickMenuSection ++ previousPageButtonSection ++ nextPageButtonSection
   }
 
-  private def rankingSection(ranking: Ranking[R]): Seq[(Int, Button)] = {
+  private def rankingSection(
+    ranking: Ranking[R]
+  )(implicit environment: Environment): Seq[(Int, Button)] = {
+    import environment.playerHeadSkinAPI
+
     def entry(position: Int, record: RankingRecord[R]): Button = {
       Button(
-        new SkullItemStackBuilder(record.playerName)
+        new SkullItemStackBuilder(record.uuid)
           .title(s"$YELLOW$BOLD${position}位:$WHITE${record.playerName}")
           .lore(template.recordDataLore(record.value))
           .build()
@@ -178,7 +184,11 @@ case class RankingMenu[R](template: RankingMenuTemplate[R], pageIndex: Int = 0)
       }
   }
 
-  private def totalAmountSection(ranking: Ranking[R]): Seq[(Int, Button)] = {
+  private def totalAmountSection(
+    ranking: Ranking[R]
+  )(implicit environment: Environment): Seq[(Int, Button)] = {
+    import environment.playerHeadSkinAPI
+
     Seq(
       ChestSlotRef(5, 4) ->
         Button(
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/ranking/RankingRootMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/ranking/RankingRootMenu.scala
index 9ac4dc2f5f..23e9171b6e 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/ranking/RankingRootMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/ranking/RankingRootMenu.scala
@@ -12,6 +12,7 @@ import com.github.unchama.seichiassist.menus.CommonButtons
 import com.github.unchama.seichiassist.menus.stickmenu.FirstPage
 import com.github.unchama.seichiassist.subsystems.breakcount.domain.SeichiAmountData
 import com.github.unchama.seichiassist.subsystems.buildcount.domain.playerdata.BuildAmountData
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.ranking.domain.values.{LoginTime, VoteCount}
 import eu.timepit.refined.auto._
 import org.bukkit.ChatColor._
@@ -25,7 +26,8 @@ object RankingRootMenu extends Menu {
     val ioCanOpenSeichiRankingMenu: IO CanOpen RankingMenu[SeichiAmountData],
     val ioCanOpenBuildRankingMenu: IO CanOpen RankingMenu[BuildAmountData],
     val ioCanOpenLoginTimeRankingMenu: IO CanOpen RankingMenu[LoginTime],
-    val ioCanOpenVoteCountRankingMenu: IO CanOpen RankingMenu[VoteCount]
+    val ioCanOpenVoteCountRankingMenu: IO CanOpen RankingMenu[VoteCount],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
   override val frame: MenuFrame = MenuFrame(4.chestRows, s"$DARK_PURPLE${BOLD}ランキング")
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/skill/ActiveSkillEffectMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/skill/ActiveSkillEffectMenu.scala
index bcef47f214..d66da57d1f 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/skill/ActiveSkillEffectMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/skill/ActiveSkillEffectMenu.scala
@@ -19,6 +19,7 @@ import com.github.unchama.seichiassist.seichiskill.effect.{
 import com.github.unchama.seichiassist.subsystems.vote.VoteAPI
 import com.github.unchama.seichiassist.subsystems.vote.domain.EffectPoint
 import com.github.unchama.seichiassist.subsystems.donate.DonatePremiumPointAPI
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.{SeichiAssist, SkullOwners}
 import com.github.unchama.targetedeffect.commandsender.MessageEffect
 import com.github.unchama.targetedeffect.player.FocusedSoundEffect
@@ -39,7 +40,8 @@ object ActiveSkillEffectMenu extends Menu {
     val ioCanOpenTransactionHistoryMenu: IO CanOpen PremiumPointTransactionHistoryMenu,
     val ioOnMainThread: OnMinecraftServerThread[IO],
     val voteAPI: VoteAPI[IO, Player],
-    val donateAPI: DonatePremiumPointAPI[IO]
+    val donateAPI: DonatePremiumPointAPI[IO],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
   override val frame: MenuFrame = MenuFrame(6.chestRows, s"$DARK_PURPLE${BOLD}整地スキルエフェクト選択")
@@ -237,7 +239,8 @@ object ActiveSkillEffectMenu extends Menu {
       )
 
     def goBackToSkillMenuButton(
-      implicit ioCanOpenActiveSkillMenu: IO CanOpen ActiveSkillMenu.type
+      implicit ioCanOpenActiveSkillMenu: IO CanOpen ActiveSkillMenu.type,
+      playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
     ): Button =
       CommonButtons.transferButton(
         new SkullItemStackBuilder(SkullOwners.MHF_ArrowLeft),
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/skill/ActiveSkillMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/skill/ActiveSkillMenu.scala
index 7ad8f10c9b..7f0b7aa1ed 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/skill/ActiveSkillMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/skill/ActiveSkillMenu.scala
@@ -3,7 +3,6 @@ package com.github.unchama.seichiassist.menus.skill
 import cats.data.Kleisli
 import cats.effect.concurrent.Ref
 import cats.effect.{ConcurrentEffect, IO, SyncIO}
-import com.github.unchama.concurrent.NonServerThreadContextShift
 import com.github.unchama.generic.effect.concurrent.TryableFiber
 import com.github.unchama.itemstackbuilder.{
   AbstractItemStackBuilder,
@@ -28,6 +27,7 @@ import com.github.unchama.seichiassist.seichiskill.assault.AssaultRoutine
 import com.github.unchama.seichiassist.subsystems.breakcount.BreakCountAPI
 import com.github.unchama.seichiassist.subsystems.discordnotification.DiscordNotificationAPI
 import com.github.unchama.seichiassist.subsystems.mana.ManaApi
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.util.SendMessageEffect
 import com.github.unchama.targetedeffect.SequentialEffect
 import com.github.unchama.targetedeffect.TargetedEffect.emptyEffect
@@ -61,7 +61,8 @@ object ActiveSkillMenu extends Menu {
     val ioCanOpenActiveSkillEffectMenu: IO CanOpen ActiveSkillEffectMenu.type,
     val ioCanOpenFirstPage: IO CanOpen FirstPage.type,
     val ioOnMainThread: OnMinecraftServerThread[IO],
-    val globalNotification: DiscordNotificationAPI[IO]
+    val globalNotification: DiscordNotificationAPI[IO],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
   override val frame: MenuFrame = MenuFrame(5.chestRows, s"$DARK_PURPLE${BOLD}整地スキル選択")
@@ -155,7 +156,7 @@ object ActiveSkillMenu extends Menu {
         case skill: ActiveSkill =>
           skill match {
             case SeichiSkill.DualBreak =>
-              new IconItemStackBuilder(Material.GRASS)
+              new IconItemStackBuilder(Material.GRASS_BLOCK)
             case SeichiSkill.TrialBreak =>
               new IconItemStackBuilder(Material.STONE)
             case SeichiSkill.Explosion =>
@@ -178,11 +179,11 @@ object ActiveSkillMenu extends Menu {
             case SeichiSkill.Thunderstorm =>
               new IconItemStackBuilder(Material.MINECART)
             case SeichiSkill.StarlightBreaker =>
-              new IconItemStackBuilder(Material.STORAGE_MINECART)
+              new IconItemStackBuilder(Material.CHEST_MINECART)
             case SeichiSkill.EarthDivide =>
-              new IconItemStackBuilder(Material.POWERED_MINECART)
+              new IconItemStackBuilder(Material.FURNACE_MINECART)
             case SeichiSkill.HeavenGaeBolg =>
-              new IconItemStackBuilder(Material.EXPLOSIVE_MINECART)
+              new IconItemStackBuilder(Material.TNT_MINECART)
             case SeichiSkill.Decision =>
               new IconItemStackBuilder(Material.HOPPER_MINECART)
 
@@ -210,9 +211,9 @@ object ActiveSkillMenu extends Menu {
             case SeichiSkill.LavaCondensation =>
               new IconItemStackBuilder(Material.NETHERRACK)
             case SeichiSkill.MoerakiBoulders =>
-              new IconItemStackBuilder(Material.NETHER_BRICK)
+              new IconItemStackBuilder(Material.NETHER_BRICKS)
             case SeichiSkill.Eldfell =>
-              new IconItemStackBuilder(Material.MAGMA)
+              new IconItemStackBuilder(Material.MAGMA_BLOCK)
             case SeichiSkill.VenderBlizzard =>
               new IconItemStackBuilder(Material.NETHER_STAR)
             case SeichiSkill.AssaultArmor =>
@@ -282,9 +283,7 @@ object ActiveSkillMenu extends Menu {
       }
     }
 
-    def seichiSkillButton[F[
-      _
-    ]: ConcurrentEffect: NonServerThreadContextShift: DiscordNotificationAPI](
+    def seichiSkillButton[F[_]: ConcurrentEffect: DiscordNotificationAPI](
       state: SkillSelectionState,
       skill: SeichiSkill
     )(implicit environment: Environment): Button = {
@@ -380,12 +379,12 @@ object ActiveSkillMenu extends Menu {
                                   .sendPlainText(notificationMessage)
                                   .toIO
                               ),
-                              Kleisli.liftF(IO {
-                                SendMessageEffect.sendMessageToEveryoneIgnoringPreference(
+                              Kleisli.liftF(
+                                SendMessageEffect.sendMessageToEveryoneIgnoringPreferenceIO(
                                   s"$GOLD$BOLD$notificationMessage"
                                 )
-                              }),
-                              BroadcastSoundEffect(Sound.ENTITY_ENDERDRAGON_DEATH, 1.0f, 1.2f)
+                              ),
+                              BroadcastSoundEffect(Sound.ENTITY_ENDER_DRAGON_DEATH, 1.0f, 1.2f)
                             )
                           )
                         } else (unlockedState, emptyEffect)
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/skill/PassiveSkillMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/skill/PassiveSkillMenu.scala
index a2034882b7..f9eed5e419 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/skill/PassiveSkillMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/skill/PassiveSkillMenu.scala
@@ -13,6 +13,7 @@ import com.github.unchama.seichiassist.menus.stickmenu.FirstPage
 import com.github.unchama.seichiassist.subsystems.breakcount.BreakCountAPI
 import com.github.unchama.seichiassist.subsystems.breakskilltargetconfig.BreakSkillTargetConfigAPI
 import com.github.unchama.seichiassist.subsystems.breakskilltargetconfig.domain.BreakSkillTargetConfigKey
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.targetedeffect._
 import com.github.unchama.targetedeffect.commandsender.MessageEffect
 import com.github.unchama.targetedeffect.player.FocusedSoundEffect
@@ -33,7 +34,8 @@ object PassiveSkillMenu extends Menu {
   class Environment(
     implicit val breakCountApi: BreakCountAPI[IO, SyncIO, Player],
     implicit val breakSkillTargetConfigAPI: BreakSkillTargetConfigAPI[IO, Player],
-    val ioCanOpenFirstPage: IO CanOpen FirstPage.type
+    val ioCanOpenFirstPage: IO CanOpen FirstPage.type,
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
   /**
@@ -260,7 +262,8 @@ object PassiveSkillMenu extends Menu {
             } else {
               List(
                 s"${GRAY}MOBの魂を${openerData.giganticBerserk.requiredExpToNextLevel()}回吸収すると更なる力が得られる",
-                s"$GRAY${openerData.giganticBerserk.exp}/${openerData.giganticBerserk.requiredExpToNextLevel()}"
+                s"$GRAY${openerData.giganticBerserk.exp}/${openerData.giganticBerserk.requiredExpToNextLevel()}",
+                s"${GRAY}MOB討伐総数:${openerData.giganticBerserk.totalNumberOfKilledEnemies}"
               )
             }
             val probability = 100 * openerData.giganticBerserk.manaRegenerationProbability()
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/skill/PremiumPointTransactionHistoryMenu.scala b/src/main/scala/com/github/unchama/seichiassist/menus/skill/PremiumPointTransactionHistoryMenu.scala
index a28fe5ab69..3b9eaa6f21 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/skill/PremiumPointTransactionHistoryMenu.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/skill/PremiumPointTransactionHistoryMenu.scala
@@ -13,6 +13,7 @@ import com.github.unchama.seichiassist.SkullOwners
 import com.github.unchama.seichiassist.menus.CommonButtons
 import com.github.unchama.seichiassist.subsystems.donate.DonatePremiumPointAPI
 import com.github.unchama.seichiassist.subsystems.donate.domain.{Obtained, Used}
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import net.md_5.bungee.api.ChatColor._
 import org.bukkit.ChatColor.{GOLD, GREEN, RESET}
 import org.bukkit.Material
@@ -23,7 +24,8 @@ object PremiumPointTransactionHistoryMenu {
   class Environment(
     implicit val ioCanOpenActiveSkillEffectMenu: IO CanOpen ActiveSkillEffectMenu.type,
     val ioCanOpenTransactionHistoryMenu: IO CanOpen PremiumPointTransactionHistoryMenu,
-    val donateAPI: DonatePremiumPointAPI[IO]
+    val donateAPI: DonatePremiumPointAPI[IO],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
 }
@@ -37,13 +39,16 @@ case class PremiumPointTransactionHistoryMenu(pageNumber: Int) extends Menu {
   override val frame: MenuFrame = MenuFrame(4.chestRows, s"$BLUE${BOLD}プレミアムエフェクト購入履歴")
 
   def buttonToTransferTo(pageNumber: Int, skullOwnerReference: SkullOwnerReference)(
-    implicit ioCanOpenTransactionHistoryMenu: IO CanOpen PremiumPointTransactionHistoryMenu
-  ): Button =
+    implicit environment: Environment
+  ): Button = {
+    import environment._
+
     CommonButtons.transferButton(
       new SkullItemStackBuilder(skullOwnerReference),
       s"${pageNumber}ページ目へ",
       PremiumPointTransactionHistoryMenu(pageNumber)
     )
+  }
 
   def computeDynamicParts(player: Player)(
     implicit environment: PremiumPointTransactionHistoryMenu.Environment
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/stickmenu/FirstPage.scala b/src/main/scala/com/github/unchama/seichiassist/menus/stickmenu/FirstPage.scala
index 8724203955..88d3ddd579 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/stickmenu/FirstPage.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/stickmenu/FirstPage.scala
@@ -8,7 +8,8 @@ import com.github.unchama.menuinventory.router.CanOpen
 import com.github.unchama.menuinventory.slot.button.action.{
   ClickEventFilter,
   FilteredButtonEffect,
-  LeftClickButtonEffect
+  LeftClickButtonEffect,
+  RightClickButtonEffect
 }
 import com.github.unchama.menuinventory.slot.button.{Button, RecomputedButton, action}
 import com.github.unchama.seichiassist.data.descrptions.PlayerStatsLoreGenerator
@@ -44,6 +45,7 @@ import com.github.unchama.seichiassist.subsystems.gachapoint.GachaPointApi
 import com.github.unchama.seichiassist.subsystems.ranking.api.RankingProvider
 import com.github.unchama.seichiassist.task.CoolDownTask
 import com.github.unchama.seichiassist.ManagedWorld._
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.vote.VoteAPI
 import com.github.unchama.seichiassist.{SeichiAssist, SkullOwners, util}
 import com.github.unchama.targetedeffect.TargetedEffect.emptyEffect
@@ -94,7 +96,8 @@ object FirstPage extends Menu {
     val ioCanOpenVoteMenu: IO CanOpen VoteMenu.type,
     val enderChestAccessApi: AnywhereEnderChestAPI[IO],
     val gachaTicketAPI: GachaTicketAPI[IO],
-    val voteAPI: VoteAPI[IO, Player]
+    val voteAPI: VoteAPI[IO, Player],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
   override val frame: MenuFrame =
@@ -165,6 +168,7 @@ object FirstPage extends Menu {
   private case class ButtonComputations(player: Player)(implicit environment: Environment) {
 
     import player._
+    import environment._
 
     val computeStatsButton: IO[Button] = RecomputedButton {
       val openerData = SeichiAssist.playermap(getUniqueId)
@@ -279,14 +283,13 @@ object FirstPage extends Menu {
     val computeRegionMenuButton: IO[Button] = IO {
       val (buttonLore, effect) = {
         val world = getWorld
-        val regionManager = WorldGuardWrapper.getRegionManager(world)
 
-        if (regionManager.isEmpty) {
+        if (!WorldGuardWrapper.canProtectionWorld(world)) {
           (List(s"${GRAY}このワールドでは土地の保護は行なえません"), LeftClickButtonEffect(emptyEffect))
         } else {
-          val maxRegionCount = WorldGuardWrapper.getMaxRegionCount(player, world)
+          val maxRegionCount = WorldGuardWrapper.getWorldMaxRegion(world)
           val currentPlayerRegionCount =
-            WorldGuardWrapper.getRegionCountOfPlayer(player, world)
+            WorldGuardWrapper.getMaxRegion(player, world)
 
           (
             List(
@@ -370,7 +373,7 @@ object FirstPage extends Menu {
             s"$RESET$DARK_GREEN${UNDERLINE}クリックで開く"
           )
 
-          new IconItemStackBuilder(Material.ENDER_PORTAL_FRAME)
+          new IconItemStackBuilder(Material.END_PORTAL_FRAME)
             .title(s"$YELLOW$UNDERLINE${BOLD}4次元ポケットを開く")
             .lore(loreHeading ++ loreAnnotation)
             .build()
@@ -405,10 +408,10 @@ object FirstPage extends Menu {
           environment.enderChestAccessApi.openEnderChestOrNotifyInsufficientLevel.flatMap {
             case Right(_) =>
               // 開くのに成功した場合の音
-              FocusedSoundEffect(Sound.BLOCK_GRASS_PLACE, 1.0f, 0.1f)
+              FocusedSoundEffect(Sound.BLOCK_ENDER_CHEST_OPEN, 1.0f, 1.0f)
             case Left(_) =>
               // 開くのに失敗した場合の音
-              FocusedSoundEffect(Sound.BLOCK_ENDERCHEST_OPEN, 1.0f, 1.0f)
+              FocusedSoundEffect(Sound.BLOCK_GRASS_PLACE, 1.0f, 0.1f)
           }
         )
       )
@@ -517,8 +520,11 @@ object FirstPage extends Menu {
     }
 
     val computeGachaTicketButton: IO[Button] = {
-      val effect: FilteredButtonEffect = LeftClickButtonEffect(
-        environment.gachaPointApi.receiveBatch
+      val leftClickEffect: FilteredButtonEffect = LeftClickButtonEffect(
+        environment.gachaPointApi.receiveLargeBatch
+      )
+      val rightClickEffect: FilteredButtonEffect = RightClickButtonEffect(
+        environment.gachaPointApi.receiveSmallBatch
       )
 
       val computeItemStack: IO[ItemStack] =
@@ -532,8 +538,10 @@ object FirstPage extends Menu {
 
             val requiredToNextTicket =
               s"$RESET${AQUA}次のガチャ券まで:${point.amountUntilNextGachaTicket.amount}ブロック"
+            val receiveGachaTicketDescription =
+              s"$RESET${GRAY}左クリックで最大9st、右クリックで最大1stのガチャ券を受け取ります"
 
-            List(gachaTicketStatus, requiredToNextTicket)
+            List(gachaTicketStatus, requiredToNextTicket, receiveGachaTicketDescription)
           }
 
           new SkullItemStackBuilder(SkullOwners.unchama)
@@ -543,7 +551,7 @@ object FirstPage extends Menu {
         }
 
       val computeButton: IO[Button] = computeItemStack.map { itemStack =>
-        Button(itemStack, effect)
+        Button(itemStack, leftClickEffect, rightClickEffect)
       }
 
       RecomputedButton(computeButton)
@@ -616,7 +624,10 @@ object FirstPage extends Menu {
       )
     }
 
-    def secondPageButton(implicit ioCanOpenSecondPage: IO CanOpen SecondPage.type): Button =
+    def secondPageButton(
+      implicit ioCanOpenSecondPage: IO CanOpen SecondPage.type,
+      playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
+    ): Button =
       CommonButtons.transferButton(
         new SkullItemStackBuilder(SkullOwners.MHF_ArrowRight),
         "2ページ目へ",
@@ -657,7 +668,7 @@ object FirstPage extends Menu {
 
     def homePointMenuButton(implicit ioCanOpenHomeMenu: IO CanOpen HomeMenu): Button = {
       val iconItemStack =
-        new IconItemStackBuilder(Material.BED)
+        new IconItemStackBuilder(Material.WHITE_BED)
           .title(s"$YELLOW$UNDERLINE${BOLD}ホームメニューを開く")
           .lore(List(s"$RESET${GRAY}ホームポイントに関するメニュー", s"$RESET$DARK_RED${UNDERLINE}クリックで開く"))
           .build()
@@ -673,7 +684,7 @@ object FirstPage extends Menu {
 
     val fastCraftButton: Button = {
       val iconItemStack =
-        new IconItemStackBuilder(Material.WORKBENCH)
+        new IconItemStackBuilder(Material.CRAFTING_TABLE)
           .title(s"$YELLOW$UNDERLINE${BOLD}FastCraft機能")
           .lore(
             List(
diff --git a/src/main/scala/com/github/unchama/seichiassist/menus/stickmenu/SecondPage.scala b/src/main/scala/com/github/unchama/seichiassist/menus/stickmenu/SecondPage.scala
index 00963b7a50..3b292fde92 100644
--- a/src/main/scala/com/github/unchama/seichiassist/menus/stickmenu/SecondPage.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/menus/stickmenu/SecondPage.scala
@@ -22,6 +22,7 @@ import com.github.unchama.seichiassist.subsystems.gacha.GachaDrawAPI
 import com.github.unchama.seichiassist.subsystems.gacha.subsystems.consumegachaticket.ConsumeGachaTicketAPI
 import com.github.unchama.seichiassist.subsystems.gachapoint.GachaPointApi
 import com.github.unchama.seichiassist.subsystems.gachapoint.domain.gachapoint.GachaPoint
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.seasonalevents.anniversary.Anniversary
 import com.github.unchama.seichiassist.subsystems.seasonalevents.anniversary.AnniversaryItemData.anniversaryPlayerHead
 import com.github.unchama.seichiassist.subsystems.seasonalevents.christmas.Christmas
@@ -62,7 +63,8 @@ object SecondPage extends Menu {
     val sharedInventoryAPI: SharedInventoryAPI[IO, Player],
     val gachaDrawAPI: GachaDrawAPI[IO, Player],
     val gachaPointAPI: GachaPointApi[IO, SyncIO, Player],
-    val consumeGachaTicketAPI: ConsumeGachaTicketAPI[IO, Player]
+    val consumeGachaTicketAPI: ConsumeGachaTicketAPI[IO, Player],
+    implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   )
 
   override val frame: MenuFrame =
@@ -105,7 +107,8 @@ object SecondPage extends Menu {
   }
 
   private case class ButtonComputations(player: Player)(
-    implicit sharedInventoryAPI: SharedInventoryAPI[IO, Player]
+    implicit sharedInventoryAPI: SharedInventoryAPI[IO, Player],
+    playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   ) {
 
     import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts.layoutPreparationContext
@@ -489,17 +492,18 @@ object SecondPage extends Menu {
     }
 
     val JMSNavigationButton: Button = {
-      val iconItemStack = new IconItemStackBuilder(Material.SIGN)
-        .title(s"$YELLOW$UNDERLINE${BOLD}JapanMinecraftServerリンク")
-        .lore(
-          List(
-            s"$RESET${DARK_GRAY}クリックするとチャット欄に",
-            s"$RESET${DARK_GRAY}URLが表示されますので",
-            s"$RESET${DARK_GRAY}Tキーを押してから",
-            s"$RESET${DARK_GRAY}そのURLをクリックしてください"
+      val iconItemStack =
+        new IconItemStackBuilder(Material.OAK_SIGN) // 1.16からSIGNが素材ごとに別れたので、オークに決めうちしておく
+          .title(s"$YELLOW$UNDERLINE${BOLD}JapanMinecraftServerリンク")
+          .lore(
+            List(
+              s"$RESET${DARK_GRAY}クリックするとチャット欄に",
+              s"$RESET${DARK_GRAY}URLが表示されますので",
+              s"$RESET${DARK_GRAY}Tキーを押してから",
+              s"$RESET${DARK_GRAY}そのURLをクリックしてください"
+            )
           )
-        )
-        .build()
+          .build()
 
       Button(
         iconItemStack,
@@ -514,7 +518,7 @@ object SecondPage extends Menu {
     }
 
     val appleConversionButton: Button = {
-      val iconItemStack = new IconItemStackBuilder(Material.GOLDEN_APPLE, durability = 1)
+      val iconItemStack = new IconItemStackBuilder(Material.GOLDEN_APPLE)
         .title(s"$YELLOW$UNDERLINE${BOLD}GT景品→椎名林檎変換システム")
         .lore(
           List(
diff --git a/src/main/scala/com/github/unchama/seichiassist/seichiskill/BlockSearching.scala b/src/main/scala/com/github/unchama/seichiassist/seichiskill/BlockSearching.scala
index 9f97c27841..304a22c10b 100644
--- a/src/main/scala/com/github/unchama/seichiassist/seichiskill/BlockSearching.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/seichiskill/BlockSearching.scala
@@ -5,8 +5,10 @@ import com.github.unchama.seichiassist.MaterialSets
 import com.github.unchama.seichiassist.MaterialSets.BlockBreakableBySkill
 import com.github.unchama.seichiassist.data.XYZTuple
 import com.github.unchama.seichiassist.util.BreakUtil
+import com.github.unchama.util.external.ExternalPlugins
 import org.bukkit.Material
 import org.bukkit.block.Block
+import org.bukkit.block.data.Waterlogged
 import org.bukkit.entity.Player
 
 import scala.collection.{Set, mutable}
@@ -37,18 +39,35 @@ object BlockSearching {
     relativeVectors.collect {
       case XYZTuple(x, y, z) =>
         val targetBlock = referencePoint.getRelative(x, y, z)
+        val waterloggedMaterials = Set(
+          Material.WATER,
+          Material.BUBBLE_COLUMN,
+          Material.TALL_SEAGRASS,
+          Material.SEAGRASS,
+          Material.KELP,
+          Material.KELP_PLANT
+        )
 
-        if (BreakUtil.canBreakWithSkill(player, targetBlock, lockedBlocks))
-          targetBlock.getType match {
-            case Material.STATIONARY_LAVA | Material.LAVA =>
-              lavaBlocks.add(targetBlock)
-            case Material.STATIONARY_WATER | Material.WATER =>
-              waterBlocks.add(targetBlock)
-            case _ =>
-              MaterialSets
-                .refineBlock(targetBlock, MaterialSets.materials)
-                .foreach(b => solidBlocks.add(b))
+        if (BreakUtil.canBreakWithSkill(player, targetBlock, lockedBlocks)) {
+          if (targetBlock.getType == Material.LAVA) {
+            lavaBlocks.add(targetBlock)
+          } else if (
+            waterloggedMaterials.contains(targetBlock.getType) || (targetBlock
+              .getBlockData
+              .isInstanceOf[Waterlogged] && ExternalPlugins
+              .getCoreProtectWrapper
+              .isNotEditedBlock(targetBlock) && targetBlock
+              .getBlockData
+              .asInstanceOf[Waterlogged]
+              .isWaterlogged)
+          ) {
+            waterBlocks.add(targetBlock)
+          } else {
+            MaterialSets
+              .refineBlock(targetBlock, MaterialSets.materials)
+              .foreach(b => solidBlocks.add(b))
           }
+        }
     }
 
     Result(solidBlocks.toList, waterBlocks.toList, lavaBlocks.toList)
@@ -63,10 +82,7 @@ object BlockSearching {
     targetBlock =>
       val blockMaterials = Set(referenceBlock.getType, targetBlock.getType)
 
-      val identifications = List(
-        Set(Material.DIRT, Material.GRASS),
-        Set(Material.REDSTONE_ORE, Material.GLOWING_REDSTONE_ORE)
-      )
+      val identifications = List(Set(Material.DIRT, Material.GRASS), Set(Material.REDSTONE_ORE))
 
       // マテリアルが同一視により等しくなるかどうか
       blockMaterials.size == 1 || identifications.exists(blockMaterials.subsetOf)
diff --git a/src/main/scala/com/github/unchama/seichiassist/seichiskill/SkillRange.scala b/src/main/scala/com/github/unchama/seichiassist/seichiskill/SkillRange.scala
index d5731b0b78..f5ff56819f 100644
--- a/src/main/scala/com/github/unchama/seichiassist/seichiskill/SkillRange.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/seichiskill/SkillRange.scala
@@ -41,24 +41,22 @@ object AssaultSkillRange {
   }
 
   case class Water(effectChunkSize: XYZTuple) extends AssaultSkillRange {
-    override val blockMaterialConversion: Material => Material = {
-      case Material.WATER => Material.ICE
-      case x              => x
+    override val blockMaterialConversion: Material => Material = { m =>
+      if (m == Material.WATER || m == Material.BUBBLE_COLUMN) Material.ICE else m
     }
   }
 
   case class Lava(effectChunkSize: XYZTuple) extends AssaultSkillRange {
-    override val blockMaterialConversion: Material => Material = {
-      case Material.LAVA => Material.MAGMA
-      case x             => x
+    override val blockMaterialConversion: Material => Material = { m =>
+      if (m == Material.LAVA) Material.MAGMA_BLOCK else m
     }
   }
 
   case class Liquid(effectChunkSize: XYZTuple) extends AssaultSkillRange {
-    override val blockMaterialConversion: Material => Material = {
-      case Material.WATER => Material.ICE
-      case Material.LAVA  => Material.MAGMA
-      case x              => x
+    override val blockMaterialConversion: Material => Material = { m =>
+      if (m == Material.WATER || m == Material.BUBBLE_COLUMN) Material.ICE
+      else if (m == Material.LAVA) Material.MAGMA_BLOCK
+      else m
     }
   }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/seichiskill/assault/AssaultRoutine.scala b/src/main/scala/com/github/unchama/seichiassist/seichiskill/assault/AssaultRoutine.scala
index 190aee7bab..e3a8ac2324 100644
--- a/src/main/scala/com/github/unchama/seichiassist/seichiskill/assault/AssaultRoutine.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/seichiskill/assault/AssaultRoutine.scala
@@ -18,6 +18,7 @@ import com.github.unchama.seichiassist.{DefaultEffectEnvironment, MaterialSets,
 import org.bukkit.ChatColor._
 import org.bukkit.enchantments.Enchantment
 import org.bukkit.entity.Player
+import org.bukkit.inventory.meta.Damageable
 import org.bukkit.{GameMode, Location, Material, Sound}
 
 object AssaultRoutine {
@@ -141,7 +142,7 @@ object AssaultRoutine {
 
       // 減る耐久値の計算
       val durability =
-        (toolToBeUsed.getDurability +
+        (toolToBeUsed.getItemMeta.asInstanceOf[Damageable].getDamage +
           BreakUtil.calcDurability(
             toolToBeUsed.getEnchantmentLevel(Enchantment.DURABILITY),
             breakTargets
@@ -161,7 +162,11 @@ object AssaultRoutine {
       }
 
       // 耐久値を減らす
-      if (!toolToBeUsed.getItemMeta.isUnbreakable) toolToBeUsed.setDurability(durability)
+      if (!toolToBeUsed.getItemMeta.isUnbreakable) {
+        val meta = toolToBeUsed.getItemMeta
+        meta.asInstanceOf[Damageable].setDamage(durability)
+        toolToBeUsed.setItemMeta(meta)
+      }
 
       // ブロックを書き換える
       if (shouldBreakAllBlocks) {
@@ -178,7 +183,7 @@ object AssaultRoutine {
         )
       } else {
         if (shouldRemoveOrCondenseWater) foundWaters.foreach(_.setType(Material.PACKED_ICE))
-        if (shouldRemoveOrCondenseLava) foundLavas.foreach(_.setType(Material.MAGMA))
+        if (shouldRemoveOrCondenseLava) foundLavas.foreach(_.setType(Material.MAGMA_BLOCK))
       }
 
       Some(newState)
diff --git a/src/main/scala/com/github/unchama/seichiassist/seichiskill/effect/ActiveSkillEffect.scala b/src/main/scala/com/github/unchama/seichiassist/seichiskill/effect/ActiveSkillEffect.scala
index b8b8775ab8..74a13cbd83 100644
--- a/src/main/scala/com/github/unchama/seichiassist/seichiskill/effect/ActiveSkillEffect.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/seichiskill/effect/ActiveSkillEffect.scala
@@ -22,7 +22,6 @@ import enumeratum.{Enum, EnumEntry}
 import org.bukkit.ChatColor._
 import org.bukkit._
 import org.bukkit.entity.{Chicken, Player}
-import org.bukkit.material.Wool
 
 import scala.util.Random
 
@@ -128,10 +127,12 @@ sealed abstract class ActiveSkillNormalEffect(
             tool,
             isSkillDualBreakOrTrialBreak
           )
-          _ <- IO {
-            explosionLocations.foreach(coordinates =>
-              world.createExplosion(coordinates.toLocation(world), 0f, false)
-            )
+          _ <- ioOnMainThread.runAction {
+            SyncIO {
+              explosionLocations.foreach(coordinates =>
+                world.createExplosion(coordinates.toLocation(world), 0f, false)
+              )
+            }
           }
         } yield ()
 
@@ -248,7 +249,7 @@ object ActiveSkillNormalEffect extends Enum[ActiveSkillNormalEffect] {
         s"${DARK_RED}メテオ",
         "隕石を落とす",
         100,
-        Material.FIREBALL
+        Material.FIRE_CHARGE
       )
 
 }
@@ -277,27 +278,28 @@ sealed abstract class ActiveSkillPremiumEffect(
 
     this match {
       case ActiveSkillPremiumEffect.MAGIC =>
-        val colors = Array(DyeColor.RED, DyeColor.BLUE, DyeColor.YELLOW, DyeColor.GREEN)
+        val colors = Array(
+          Material.RED_WOOL,
+          Material.BLUE_WOOL,
+          Material.YELLOW_WOOL,
+          Material.GREEN_WOOL
+        )
 
         // 破壊するブロックの中心位置
         val centerBreak: Location = standard + ((breakArea.begin + breakArea.end) / 2)
 
         for {
-          randomColor <- IO { colors(Random.nextInt(colors.length)) }
+          randomWool <- IO { colors(Random.nextInt(colors.length)) }
           _ <- BreakUtil.massBreakBlock(
             player,
             breakBlocks,
             standard,
             tool,
             shouldPlayBreakSound = false,
-            Material.WOOL
+            randomWool
           )
           _ <- IO {
-            breakBlocks.foreach { b =>
-              val state = b.getState
-              state.getData.asInstanceOf[Wool].setColor(randomColor)
-              state.update()
-            }
+            breakBlocks.foreach(_.setType(randomWool))
           }
 
           period <- IO { if (SeichiAssist.DEBUG) 100 else 10 }
@@ -351,7 +353,7 @@ case object ActiveSkillPremiumEffect extends Enum[ActiveSkillPremiumEffect] {
         s"$RED$UNDERLINE${BOLD}マジック",
         "鶏が出る手品",
         10,
-        Material.RED_ROSE
+        Material.POPPY
       )
 
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/seichiskill/effect/arrow/ArrowEffects.scala b/src/main/scala/com/github/unchama/seichiassist/seichiskill/effect/arrow/ArrowEffects.scala
index a4b55429a7..dcf189630c 100644
--- a/src/main/scala/com/github/unchama/seichiassist/seichiskill/effect/arrow/ArrowEffects.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/seichiskill/effect/arrow/ArrowEffects.scala
@@ -7,6 +7,7 @@ import com.github.unchama.seichiassist.SeichiAssist
 import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts
 import com.github.unchama.targetedeffect.player.FocusedSoundEffect
 import com.github.unchama.util.effect.BukkitResources
+import org.bukkit.entity.AbstractArrow.PickupStatus
 import org.bukkit.entity._
 import org.bukkit.inventory.ItemStack
 import org.bukkit.inventory.meta.PotionMeta
@@ -28,9 +29,10 @@ object ArrowEffects {
   def normalArrowEffect(
     implicit mainThread: OnMinecraftServerThread[IO]
   ): TargetedEffect[Player] =
-    arrowEffect[Arrow](
+    arrowEffect[AbstractArrow](
       ProjectileSpawnConfiguration(1.0, (0.0, 1.6, 0.0)),
-      Some(Sound.ENTITY_ARROW_SHOOT)
+      Some(Sound.ENTITY_ARROW_SHOOT),
+      _.setPickupStatus(PickupStatus.DISALLOWED)
     )
 
   def singleArrowBlizzardEffect(
@@ -65,10 +67,13 @@ object ArrowEffects {
   def singleArrowMeteoEffect(
     implicit mainThread: OnMinecraftServerThread[IO]
   ): TargetedEffect[Player] =
-    arrowEffect[Arrow](
+    arrowEffect[AbstractArrow](
       ProjectileSpawnConfiguration(1.0, (0.0, 1.6, 0.0)),
       Some(Sound.ENTITY_ARROW_SHOOT),
-      _.setGlowing(true)
+      { arrow =>
+        arrow.setGlowing(true)
+        arrow.setPickupStatus(PickupStatus.DISALLOWED)
+      }
     )
 
   def singleArrowExplosionEffect(
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/anywhereender/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/anywhereender/System.scala
index 0a1f997474..f50b67d17e 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/anywhereender/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/anywhereender/System.scala
@@ -1,6 +1,5 @@
 package com.github.unchama.seichiassist.subsystems.anywhereender
 
-import cats.Functor
 import cats.data.Kleisli
 import cats.effect.{Effect, IO, LiftIO}
 import com.github.unchama.generic.ContextCoercion
@@ -25,9 +24,7 @@ object System {
   import ContextCoercion._
   import cats.implicits._
 
-  def wired[F[_]: BreakCountReadAPI[IO, *[_], Player]: Functor: ContextCoercion[*[_], G], G[
-    _
-  ]: Effect](
+  def wired[F[_]: BreakCountReadAPI[IO, *[_], Player]: ContextCoercion[*[_], G], G[_]: Effect](
     configuration: SystemConfiguration
   )(implicit onMainThread: OnMinecraftServerThread[IO]): System[G] = new System[G] {
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/autosave/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/autosave/System.scala
index c3cb3d3782..93baa0ae1c 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/autosave/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/autosave/System.scala
@@ -1,7 +1,7 @@
 package com.github.unchama.seichiassist.subsystems.autosave
 
 import cats.effect.{Sync, Timer}
-import com.github.unchama.minecraft.actions.OnMinecraftServerThread
+import com.github.unchama.minecraft.actions.{GetConnectedPlayers, OnMinecraftServerThread}
 import com.github.unchama.seichiassist.subsystems.autosave.application.{
   CanNotifySaves,
   CanSaveWorlds,
@@ -12,16 +12,17 @@ import com.github.unchama.seichiassist.subsystems.autosave.bukkit.instances.{
   SyncCanNotifyBukkitSaves,
   SyncCanSaveBukkitWorlds
 }
+import org.bukkit.entity.Player
 
 object System {
-  def backgroundProcess[F[_]: Sync: Timer: OnMinecraftServerThread, G[_]](
+  def backgroundProcess[F[_]: Sync: Timer: OnMinecraftServerThread](
+    implicit getConnectedPlayers: GetConnectedPlayers[F, Player],
     configuration: SystemConfiguration
   ): F[Nothing] = {
 
-    implicit val _configuration: SystemConfiguration = configuration
-
     implicit val _canSaveWorlds: CanSaveWorlds[F] = SyncCanSaveBukkitWorlds[F]
-    implicit val _canNotifySaves: CanNotifySaves[F] = SyncCanNotifyBukkitSaves[F]
+    implicit val _canNotifySaves: CanNotifySaves[F] =
+      SyncCanNotifyBukkitSaves[F]
 
     WorldSaveRoutine()
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/autosave/bukkit/instances/SyncCanNotifyBukkitSaves.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/autosave/bukkit/instances/SyncCanNotifyBukkitSaves.scala
index 88e7cc3950..c86feb9364 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/autosave/bukkit/instances/SyncCanNotifyBukkitSaves.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/autosave/bukkit/instances/SyncCanNotifyBukkitSaves.scala
@@ -1,17 +1,24 @@
 package com.github.unchama.seichiassist.subsystems.autosave.bukkit.instances
 
 import cats.effect.Sync
-import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts.onMainThread
+import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.subsystems.autosave.application.CanNotifySaves
 import com.github.unchama.seichiassist.util.SendMessageEffect
 import org.bukkit.Bukkit
+import org.bukkit.entity.Player
+import com.github.unchama.minecraft.actions.GetConnectedPlayers
 
 object SyncCanNotifyBukkitSaves {
 
-  def apply[F[_]: Sync]: CanNotifySaves[F] = (message: String) =>
-    Sync[F].delay {
-      SendMessageEffect.sendMessageToEveryoneIgnoringPreference(message)
-      Bukkit.getLogger.info(message)
-    }
+  import cats.implicits._
+
+  def apply[F[_]: Sync: OnMinecraftServerThread](
+    implicit getConnectedPlayers: GetConnectedPlayers[F, Player]
+  ): CanNotifySaves[F] =
+    (message: String) =>
+      for {
+        _ <- SendMessageEffect.sendMessageToEveryoneIgnoringPreferenceM[String, F](message)
+        _ <- Sync[F].delay(Bukkit.getLogger.info(message))
+      } yield ()
 
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/autosave/bukkit/instances/SyncCanSaveBukkitWorlds.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/autosave/bukkit/instances/SyncCanSaveBukkitWorlds.scala
index 1a1e6188d8..f5c505d5a5 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/autosave/bukkit/instances/SyncCanSaveBukkitWorlds.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/autosave/bukkit/instances/SyncCanSaveBukkitWorlds.scala
@@ -1,6 +1,6 @@
 package com.github.unchama.seichiassist.subsystems.autosave.bukkit.instances
 
-import cats.effect.{Sync, SyncIO}
+import cats.effect.SyncIO
 import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.subsystems.autosave.application.CanSaveWorlds
 import org.bukkit.{Bukkit, World}
@@ -10,7 +10,7 @@ import scala.annotation.tailrec
 
 object SyncCanSaveBukkitWorlds {
 
-  def apply[F[_]: Sync: OnMinecraftServerThread]: CanSaveWorlds[F] = new CanSaveWorlds[F] {
+  def apply[F[_]: OnMinecraftServerThread]: CanSaveWorlds[F] = new CanSaveWorlds[F] {
     val save: SyncIO[Unit] = SyncIO {
       def saveWorld(world: World): Unit = {
         // WARNを防ぐためMinecraftサーバーデフォルトの自動セーブは無効化
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/blockliquidstream/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/blockliquidstream/System.scala
new file mode 100644
index 0000000000..b6907fe2d2
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/blockliquidstream/System.scala
@@ -0,0 +1,15 @@
+package com.github.unchama.seichiassist.subsystems.blockliquidstream
+
+import com.github.unchama.seichiassist.meta.subsystem.Subsystem
+import com.github.unchama.seichiassist.subsystems.blockliquidstream.bukkit.LiquidStreamListener
+import org.bukkit.event.Listener
+
+object System {
+
+  def wired[F[_]]: Subsystem[F] = {
+    new Subsystem[F] {
+      override val listeners: Seq[Listener] = Seq(new LiquidStreamListener)
+    }
+  }
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/blockliquidstream/bukkit/LiquidStreamListener.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/blockliquidstream/bukkit/LiquidStreamListener.scala
new file mode 100644
index 0000000000..43e9231333
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/blockliquidstream/bukkit/LiquidStreamListener.scala
@@ -0,0 +1,28 @@
+package com.github.unchama.seichiassist.subsystems.blockliquidstream.bukkit
+
+import org.bukkit.block.data.Waterlogged
+import org.bukkit.event.block.BlockFromToEvent
+import org.bukkit.event.{EventHandler, EventPriority, Listener}
+import org.bukkit.block.Block
+import com.github.unchama.seichiassist.ManagedWorld._
+
+class LiquidStreamListener extends Listener {
+
+  @EventHandler(priority = EventPriority.HIGHEST)
+  def onBlockMove(event: BlockFromToEvent): Unit = {
+    event.setCancelled(isLiquidStream(event.getBlock))
+  }
+
+  private def isLiquidStream(block: Block): Boolean = {
+    val world = block.getWorld
+
+    if (world.isNotSeichi) return false
+    val blockData = block.getBlockData
+
+    blockData match {
+      case waterlogged: Waterlogged if !block.isLiquid && !waterlogged.isWaterlogged => false
+      case _                                                                         => true
+    }
+  }
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/bookedachivement/bukkit/command/AchievementCommand.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/bookedachivement/bukkit/command/AchievementCommand.scala
index b459659a79..50e547825f 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/bookedachivement/bukkit/command/AchievementCommand.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/bookedachivement/bukkit/command/AchievementCommand.scala
@@ -75,6 +75,7 @@ object AchievementCommand {
     )
   )
 
+  // TODO: パーサーを分けるべき
   def executor[F[_]: ConcurrentEffect](
     implicit service: AchievementBookingService[F]
   ): TabExecutor = ContextualExecutorBuilder
@@ -149,7 +150,7 @@ object AchievementCommand {
         }.combineAll
       }
 
-      execution()
+      execution().flatMap(_.apply(sender))
     }
     .asNonBlockingTabExecutor()
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/bookedachivement/infrastructure/JdbcBookedAchievementPersistenceRepository.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/bookedachivement/infrastructure/JdbcBookedAchievementPersistenceRepository.scala
index cf318220e4..b8d8db6729 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/bookedachivement/infrastructure/JdbcBookedAchievementPersistenceRepository.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/bookedachivement/infrastructure/JdbcBookedAchievementPersistenceRepository.scala
@@ -26,7 +26,6 @@ class JdbcBookedAchievementPersistenceRepository[F[_]](implicit SyncContext: Syn
               | values (${key.toString}, $achievementId, ${operation.toString})"""
           .stripMargin
           .update()
-          .apply()
       }
     }
   }
@@ -49,7 +48,6 @@ class JdbcBookedAchievementPersistenceRepository[F[_]](implicit SyncContext: Syn
             )
           }
           .toList()
-          .apply()
       }
     }
   }
@@ -64,7 +62,6 @@ class JdbcBookedAchievementPersistenceRepository[F[_]](implicit SyncContext: Syn
               | where player_uuid = ${key.toString} and completed_at is null"""
           .stripMargin
           .update()
-          .apply()
       }
     }
   }
@@ -79,7 +76,6 @@ class JdbcBookedAchievementPersistenceRepository[F[_]](implicit SyncContext: Syn
           sql"select (uuid) from playerdata where name = $playerName"
             .map { rs => rs.string("uuid") }
             .toList()
-            .apply()
             .head
         )
       }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/application/actions/IncrementSeichiExp.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/application/actions/IncrementSeichiExp.scala
index 0eb97809c1..4869d51fe4 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/application/actions/IncrementSeichiExp.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/application/actions/IncrementSeichiExp.scala
@@ -5,7 +5,6 @@ import cats.effect.concurrent.Ref
 import cats.effect.{Effect, Sync}
 import com.github.unchama.datarepository.KeyedDataRepository
 import com.github.unchama.fs2.workaround.fs3.Fs3Topic
-import com.github.unchama.generic.ContextCoercion
 import com.github.unchama.generic.effect.EffectExtra
 import com.github.unchama.seichiassist.subsystems.breakcount.domain.SeichiAmountData
 import com.github.unchama.seichiassist.subsystems.breakcount.domain.level.SeichiExpAmount
@@ -27,9 +26,7 @@ object IncrementSeichiExp {
   /**
    * 与えられたデータレポジトリと更新を流すトピックを用いてプレーヤーの整地量を増加させるような 代数を作成する。
    */
-  def using[F[_]: Sync: ClassifyPlayerWorld[*[_], Player], G[_]: Effect: ContextCoercion[F, *[
-    _
-  ]], Player](
+  def using[F[_]: Sync: ClassifyPlayerWorld[*[_], Player], G[_]: Effect, Player](
     dataRepository: KeyedDataRepository[Player, Ref[F, SeichiAmountData]],
     dataTopic: Fs3Topic[G, Option[(Player, SeichiAmountData)]]
   ): IncrementSeichiExp[F, Player] =
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/domain/level/SeichiExpAmount.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/domain/level/SeichiExpAmount.scala
index 73def02d89..d2b60991e1 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/domain/level/SeichiExpAmount.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/domain/level/SeichiExpAmount.scala
@@ -17,7 +17,7 @@ case class SeichiExpAmount private (amount: BigDecimal) extends AnyVal {
 
   def subtract(a: SeichiExpAmount): SeichiExpAmount = mapAmount(_ - a.amount)
 
-  def formatted: String = amount.toLong.formatted("%,d")
+  def formatted: String = String.format("%,d", amount.longValue)
 }
 
 object SeichiExpAmount {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/infrastructure/JdbcSeichiAmountDataPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/infrastructure/JdbcSeichiAmountDataPersistence.scala
index 8ef24a54dd..f6be481b3e 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/infrastructure/JdbcSeichiAmountDataPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/infrastructure/JdbcSeichiAmountDataPersistence.scala
@@ -23,7 +23,6 @@ class JdbcSeichiAmountDataPersistence[F[_]](implicit F: Sync[F])
             )
           }
           .first()
-          .apply()
       }
     }
 
@@ -32,7 +31,6 @@ class JdbcSeichiAmountDataPersistence[F[_]](implicit F: Sync[F])
       DB.localTx { implicit session =>
         sql"update playerdata set totalbreaknum = ${value.expAmount.amount} where uuid = ${key.toString}"
           .update()
-          .apply()
       }
     }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/subsystems/notification/bukkit/actions/BukkitNotifyLevelUp.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/subsystems/notification/bukkit/actions/BukkitNotifyLevelUp.scala
index b8337299bd..47563698cd 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/subsystems/notification/bukkit/actions/BukkitNotifyLevelUp.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcount/subsystems/notification/bukkit/actions/BukkitNotifyLevelUp.scala
@@ -15,20 +15,19 @@ import com.github.unchama.seichiassist.subsystems.breakcount.subsystems.notifica
 import com.github.unchama.seichiassist.subsystems.discordnotification.DiscordNotificationAPI
 import com.github.unchama.seichiassist.util.{
   LaunchFireWorksEffect,
-  PlayerSendable,
   SendMessageEffect,
   SendSoundEffect
 }
 import org.bukkit.ChatColor.{BOLD, GOLD}
 import org.bukkit.Sound
 import org.bukkit.entity.Player
+import com.github.unchama.seichiassist.util.PlayerSendable._
 
 //FIXME ファイル名とやっていることが違うようになっているので修正するべき。
 //例えば、10億の倍数到達時の通知はLevelUp時の通知ではない
 //また、BukkitNotifyLevelUpなのにdiffの展開やいつメッセージを出すかなどを扱うべきでない。
 object BukkitNotifyLevelUp {
 
-  import PlayerSendable.forString
   import cats.implicits._
 
   def apply[F[_]: OnMinecraftServerThread: ConcurrentEffect: DiscordNotificationAPI]
@@ -44,17 +43,21 @@ object BukkitNotifyLevelUp {
             .expAmount
             .amount >= nextTenBillion
         ) {
+          // TODO: ここのSyncIOを剥がせそう
           OnMinecraftServerThread[F].runAction(SyncIO {
             val notificationMessage =
               s"${player.getName}の総整地量が${(newBreakAmount.expAmount.amount / 100000000).toInt}億に到達しました!"
-            SendMessageEffect.sendMessageToEveryoneIgnoringPreference(
-              s"$GOLD$BOLD$notificationMessage"
-            )(forString[IO])
+
+            SendMessageEffect
+              .sendMessageToEveryoneIgnoringPreferenceIO(s"$GOLD$BOLD$notificationMessage")(
+                forString[IO]
+              )
+              .unsafeRunAsyncAndForget()
             DiscordNotificationAPI[F]
               .sendPlainText(notificationMessage)
               .toIO
               .unsafeRunAsyncAndForget()
-            SendSoundEffect.sendEverySound(Sound.ENTITY_ENDERDRAGON_DEATH, 1.0f, 1.2f)
+            SendSoundEffect.sendEverySound(Sound.ENTITY_ENDER_DRAGON_DEATH, 1.0f, 1.2f)
           })
         } else Applicative[F].unit
       }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcountbar/application/ExpBarSynchronizationRepositoryTemplate.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcountbar/application/ExpBarSynchronizationRepositoryTemplate.scala
index 4d5e1b8ed9..2da81fedcb 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcountbar/application/ExpBarSynchronizationRepositoryTemplate.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcountbar/application/ExpBarSynchronizationRepositoryTemplate.scala
@@ -73,7 +73,7 @@ object ExpBarSynchronizationRepositoryTemplate {
       } yield (bossBar, fiberPromise)
     }
 
-  def finalization[G[_]: Sync, F[_]: ConcurrentEffect: ContextCoercion[G, *[_]], Player]
+  def finalization[G[_]: Sync, F[_]: ConcurrentEffect, Player]
     : RepositoryFinalization[G, Player, RepositoryValueType[F, Player]] =
     RepositoryFinalization.withoutAnyPersistence {
       case (_, (_, fiberPromise)) =>
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcountbar/infrastructure/JdbcBreakCountBarVisibilityPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcountbar/infrastructure/JdbcBreakCountBarVisibilityPersistence.scala
index 5f12a59787..546ea08c18 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcountbar/infrastructure/JdbcBreakCountBarVisibilityPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakcountbar/infrastructure/JdbcBreakCountBarVisibilityPersistence.scala
@@ -24,7 +24,6 @@ class JdbcBreakCountBarVisibilityPersistence[F[_]](implicit F: Sync[F])
             }
           }
           .first()
-          .apply()
       }
     }
 
@@ -33,7 +32,6 @@ class JdbcBreakCountBarVisibilityPersistence[F[_]](implicit F: Sync[F])
       DB.localTx { implicit session =>
         sql"update playerdata set expvisible = ${value == BreakCountBarVisibility.Shown} where uuid = ${key.toString}"
           .update()
-          .apply()
       }
     }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakskilltargetconfig/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakskilltargetconfig/System.scala
index 08ded6514f..5e2e56eee5 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakskilltargetconfig/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakskilltargetconfig/System.scala
@@ -1,7 +1,7 @@
 package com.github.unchama.seichiassist.subsystems.breakskilltargetconfig
 
 import cats.data.Kleisli
-import cats.effect.{Sync, SyncEffect}
+import cats.effect.SyncEffect
 import com.github.unchama.datarepository.bukkit.player.BukkitRepositoryControls
 import com.github.unchama.generic.ContextCoercion
 import com.github.unchama.seichiassist.meta.subsystem.Subsystem
@@ -21,7 +21,7 @@ object System {
 
   import cats.implicits._
 
-  def wired[F[_]: Sync, G[_]: SyncEffect: ContextCoercion[*[_], F]]: G[System[F, Player]] = {
+  def wired[F[_], G[_]: SyncEffect: ContextCoercion[*[_], F]]: G[System[F, Player]] = {
     implicit val breakSkillTargetConfigPersistence: BreakSkillTargetConfigPersistence[G] =
       new JdbcBreakSkillTargetConfigPersistence[G]
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakskilltargetconfig/persistence/JdbcBreakSkillTargetConfigPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakskilltargetconfig/persistence/JdbcBreakSkillTargetConfigPersistence.scala
index 2ed07fa43d..5270f088e5 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/breakskilltargetconfig/persistence/JdbcBreakSkillTargetConfigPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/breakskilltargetconfig/persistence/JdbcBreakSkillTargetConfigPersistence.scala
@@ -22,7 +22,6 @@ class JdbcBreakSkillTargetConfigPersistence[F[_]: Sync]
           }
         }
         .toList()
-        .apply()
         .flatten
         .toMap
     }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/BuildCountAPI.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/BuildCountAPI.scala
index 107dde5198..9116673b67 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/BuildCountAPI.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/BuildCountAPI.scala
@@ -16,15 +16,11 @@ trait BuildCountAPI[F[_], G[_], Player] {
 
   implicit val incrementBuildExpWhenBuiltByHand: IncrementBuildExpWhenBuiltByHand[G, Player]
 
-  implicit val incrementBuildExpWhenBuiltWithSkill: IncrementBuildExpWhenBuiltWithSkill[
-    G,
-    Player
-  ]
-
-  implicit val playerBuildAmountRepository: KeyedDataRepository[
-    Player,
-    ReadOnlyRef[G, BuildAmountData]
-  ]
+  implicit val incrementBuildExpWhenBuiltWithSkill
+    : IncrementBuildExpWhenBuiltWithSkill[G, Player]
+
+  implicit val playerBuildAmountRepository
+    : KeyedDataRepository[Player, ReadOnlyRef[G, BuildAmountData]]
 
   val buildAmountUpdates: fs2.Stream[F, (Player, BuildAmountData)]
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/System.scala
index b85f72cca1..2c3995209c 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/System.scala
@@ -1,7 +1,6 @@
 package com.github.unchama.seichiassist.subsystems.buildcount
 
 import cats.effect.{Clock, ConcurrentEffect, SyncEffect}
-import com.github.unchama.concurrent.NonServerThreadContextShift
 import com.github.unchama.datarepository.KeyedDataRepository
 import com.github.unchama.datarepository.bukkit.player.BukkitRepositoryControls
 import com.github.unchama.datarepository.template.RepositoryDefinition
@@ -9,7 +8,7 @@ import com.github.unchama.fs2.workaround.fs3.Fs3Topic
 import com.github.unchama.generic.ContextCoercion
 import com.github.unchama.generic.effect.concurrent.ReadOnlyRef
 import com.github.unchama.generic.ratelimiting.RateLimiter
-import com.github.unchama.minecraft.actions.OnMinecraftServerThread
+import com.github.unchama.minecraft.actions.{GetConnectedPlayers, OnMinecraftServerThread}
 import com.github.unchama.seichiassist.meta.subsystem.Subsystem
 import com.github.unchama.seichiassist.subsystems.buildcount.application.actions.{
   ClassifyPlayerWorld,
@@ -53,10 +52,11 @@ object System {
 
   def wired[F[
     _
-  ]: OnMinecraftServerThread: ConcurrentEffect: NonServerThreadContextShift: ErrorLogger: DiscordNotificationAPI, G[
+  ]: OnMinecraftServerThread: ConcurrentEffect: ErrorLogger: DiscordNotificationAPI, G[
     _
   ]: SyncEffect: ContextCoercion[*[_], F]: Clock](
-    implicit configuration: Configuration
+    implicit configuration: Configuration,
+    getConnectedPlayers: GetConnectedPlayers[F, Player]
   ): F[System[F, G]] = {
     implicit val expMultiplier: BuildExpMultiplier = configuration.multipliers
     implicit val persistence: JdbcBuildAmountDataPersistence[G] =
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/application/actions/IncrementBuildExpWhenBuiltByHand.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/application/actions/IncrementBuildExpWhenBuiltByHand.scala
index 2170bbaeed..aedb816544 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/application/actions/IncrementBuildExpWhenBuiltByHand.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/application/actions/IncrementBuildExpWhenBuiltByHand.scala
@@ -5,7 +5,6 @@ import cats.effect.concurrent.Ref
 import cats.effect.{Effect, Sync}
 import com.github.unchama.datarepository.KeyedDataRepository
 import com.github.unchama.fs2.workaround.fs3.Fs3Topic
-import com.github.unchama.generic.ContextCoercion
 import com.github.unchama.generic.effect.EffectExtra
 import com.github.unchama.generic.ratelimiting.RateLimiter
 import com.github.unchama.seichiassist.subsystems.buildcount.application.BuildExpMultiplier
@@ -31,10 +30,7 @@ object IncrementBuildExpWhenBuiltByHand {
     implicit ev: IncrementBuildExpWhenBuiltByHand[F, Player]
   ): IncrementBuildExpWhenBuiltByHand[F, Player] = ev
 
-  def using[F[_]: ClassifyPlayerWorld[*[_], Player], G[_]: Effect: ContextCoercion[
-    F,
-    *[_]
-  ], Player](
+  def using[F[_]: ClassifyPlayerWorld[*[_], Player], G[_]: Effect, Player](
     rateLimiterRepository: KeyedDataRepository[Player, RateLimiter[F, BuildExpAmount]],
     dataRepository: KeyedDataRepository[Player, Ref[F, BuildAmountData]],
     dataTopic: Fs3Topic[G, (Player, BuildAmountData)]
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/application/application/RateLimiterRepositoryDefinitions.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/application/application/RateLimiterRepositoryDefinitions.scala
index a6c5b3311c..2418f1873a 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/application/application/RateLimiterRepositoryDefinitions.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/application/application/RateLimiterRepositoryDefinitions.scala
@@ -59,8 +59,7 @@ object RateLimiterRepositoryDefinitions {
   }
 
   def finalization[F[_]: Sync: JavaTime, Player: HasUuid](
-    implicit config: Configuration,
-    persistence: BuildAmountRateLimitPersistence[F]
+    implicit persistence: BuildAmountRateLimitPersistence[F]
   ): RepositoryFinalization[F, Player, RateLimiter[F, BuildExpAmount]] =
     RepositoryFinalization.withoutAnyFinalization {
       case (p, rateLimiter) =>
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/infrastructure/JdbcBuildAmountDataPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/infrastructure/JdbcBuildAmountDataPersistence.scala
index bb8a1d12b6..2339238309 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/infrastructure/JdbcBuildAmountDataPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/infrastructure/JdbcBuildAmountDataPersistence.scala
@@ -24,7 +24,6 @@ class JdbcBuildAmountDataPersistence[F[_]](implicit F: Sync[F])
             BuildAmountData(exp)
           }
           .first()
-          .apply()
       }
     }
 
@@ -34,7 +33,6 @@ class JdbcBuildAmountDataPersistence[F[_]](implicit F: Sync[F])
         sql"update playerdata set build_count = ${value.expAmount.amount} where uuid = ${key.toString}"
           .stripMargin
           .update()
-          .apply()
       }
     }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/infrastructure/JdbcBuildAmountRateLimitPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/infrastructure/JdbcBuildAmountRateLimitPersistence.scala
index 3f7f1d8046..4e523046ed 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/infrastructure/JdbcBuildAmountRateLimitPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/infrastructure/JdbcBuildAmountRateLimitPersistence.scala
@@ -1,7 +1,6 @@
 package com.github.unchama.seichiassist.subsystems.buildcount.infrastructure
 
 import cats.effect.Sync
-import com.github.unchama.seichiassist.subsystems.buildcount.application.Configuration
 import com.github.unchama.seichiassist.subsystems.buildcount.domain.BuildAmountRateLimiterSnapshot
 import com.github.unchama.seichiassist.subsystems.buildcount.domain.explevel.BuildExpAmount
 import com.github.unchama.seichiassist.subsystems.buildcount.domain.playerdata.BuildAmountRateLimitPersistence
@@ -10,8 +9,7 @@ import scalikejdbc._
 import java.util.UUID
 
 class JdbcBuildAmountRateLimitPersistence[SyncContext[_]](
-  implicit SyncContext: Sync[SyncContext],
-  config: Configuration
+  implicit SyncContext: Sync[SyncContext]
 ) extends BuildAmountRateLimitPersistence[SyncContext] {
 
   override def read(key: UUID): SyncContext[Option[BuildAmountRateLimiterSnapshot]] =
@@ -26,7 +24,6 @@ class JdbcBuildAmountRateLimitPersistence[SyncContext[_]](
             BuildAmountRateLimiterSnapshot(exp, ldt)
           }
           .first()
-          .apply()
       }
     }
 
@@ -40,7 +37,7 @@ class JdbcBuildAmountRateLimitPersistence[SyncContext[_]](
              |  on duplicate key update
              |    available_permission = ${value.amount.toPlainString},
              |    record_date = ${value.recordTime}
-             |""".stripMargin.update().apply()
+             |""".stripMargin.update()
       }
     }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/subsystems/notification/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/subsystems/notification/System.scala
index 02532af23e..86741a7835 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/subsystems/notification/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/subsystems/notification/System.scala
@@ -2,7 +2,7 @@ package com.github.unchama.seichiassist.subsystems.buildcount.subsystems.notific
 
 import cats.effect.Concurrent
 import com.github.unchama.generic.effect.stream.StreamExtra
-import com.github.unchama.minecraft.actions.OnMinecraftServerThread
+import com.github.unchama.minecraft.actions.{GetConnectedPlayers, OnMinecraftServerThread}
 import com.github.unchama.seichiassist.subsystems.buildcount.BuildCountAPI
 import com.github.unchama.seichiassist.subsystems.buildcount.subsystems.notification.application.actions.{
   NotifyBuildAmountThreshold,
@@ -22,7 +22,7 @@ object System {
     _
   ]: Concurrent: ErrorLogger: OnMinecraftServerThread: DiscordNotificationAPI, G[_], A](
     buildCountReadAPI: BuildCountAPI[F, G, Player]
-  ): F[A] = {
+  )(implicit getConnectedPlayers: GetConnectedPlayers[F, Player]): F[A] = {
     val notifyLevelUp: NotifyLevelUp[F, Player] = BukkitNotifyLevelUp[F]
     val notifyBuildAmountThreshold: NotifyBuildAmountThreshold[F, Player] =
       BukkitNotifyBuildAmountThreshold[F]
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/subsystems/notification/bukkit/actions/BukkitNotifyBuildAmountThreshold.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/subsystems/notification/bukkit/actions/BukkitNotifyBuildAmountThreshold.scala
index a2c53c7a15..325279cef1 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/subsystems/notification/bukkit/actions/BukkitNotifyBuildAmountThreshold.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/subsystems/notification/bukkit/actions/BukkitNotifyBuildAmountThreshold.scala
@@ -1,23 +1,24 @@
 package com.github.unchama.seichiassist.subsystems.buildcount.subsystems.notification.bukkit.actions
 
-import cats.effect.{IO, Sync}
+import cats.effect.Sync
 import com.github.unchama.generic.Diff
-import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts.onMainThread
+import com.github.unchama.minecraft.actions.{GetConnectedPlayers, OnMinecraftServerThread}
 import com.github.unchama.seichiassist.subsystems.buildcount.domain.playerdata.BuildAmountData
 import com.github.unchama.seichiassist.subsystems.buildcount.subsystems.notification.application.actions.NotifyBuildAmountThreshold
 import com.github.unchama.seichiassist.subsystems.discordnotification.DiscordNotificationAPI
-import com.github.unchama.seichiassist.util.{PlayerSendable, SendMessageEffect, SendSoundEffect}
+import com.github.unchama.seichiassist.util.{SendMessageEffect, SendSoundEffect}
 import org.bukkit.ChatColor.{BOLD, GOLD}
 import org.bukkit.Sound
 import org.bukkit.entity.Player
 
 object BukkitNotifyBuildAmountThreshold {
 
-  import PlayerSendable.forString
   import cats.implicits._
 
   // TODO: BukkitNotifyLevelUpなのにdiffの展開やいつメッセージを出すかなどを扱うべきでない。
-  def apply[F[_]: Sync: DiscordNotificationAPI]: NotifyBuildAmountThreshold[F, Player] = {
+  def apply[F[_]: Sync: DiscordNotificationAPI: OnMinecraftServerThread: GetConnectedPlayers[*[
+    _
+  ], Player]]: NotifyBuildAmountThreshold[F, Player] = {
     new NotifyBuildAmountThreshold[F, Player] {
       override def ofBuildAmountTo(player: Player)(diff: Diff[BuildAmountData]): F[Unit] = {
         val Diff(oldBuildAmount, newBuildAmount) = diff
@@ -46,11 +47,10 @@ object BukkitNotifyBuildAmountThreshold {
           val notificationMessage =
             s"${player.getName}の総建築量が${newBuildAmountDisplay}に到達しました!"
 
-          Sync[F].delay {
-            SendMessageEffect.sendMessageToEveryoneIgnoringPreference(
-              s"$GOLD$BOLD$notificationMessage"
-            )(forString[IO])
-            SendSoundEffect.sendEverySound(Sound.ENTITY_ENDERDRAGON_DEATH, 1.0f, 1.2f)
+          SendMessageEffect.sendMessageToEveryoneIgnoringPreferenceM[String, F](
+            s"$GOLD$BOLD$notificationMessage"
+          ) >> Sync[F].delay {
+            SendSoundEffect.sendEverySound(Sound.ENTITY_ENDER_DRAGON_DEATH, 1.0f, 1.2f)
           } >> DiscordNotificationAPI[F].sendPlainText(notificationMessage)
         } else Sync[F].unit
       }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/subsystems/notification/bukkit/actions/BukkitNotifyLevelUp.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/subsystems/notification/bukkit/actions/BukkitNotifyLevelUp.scala
index 69d165e8ee..7695570b28 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/subsystems/notification/bukkit/actions/BukkitNotifyLevelUp.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/buildcount/subsystems/notification/bukkit/actions/BukkitNotifyLevelUp.scala
@@ -1,30 +1,29 @@
 package com.github.unchama.seichiassist.subsystems.buildcount.subsystems.notification.bukkit.actions
 
-import cats.effect.{IO, Sync}
+import cats.effect.Sync
 import com.github.unchama.generic.Diff
-import com.github.unchama.minecraft.actions.OnMinecraftServerThread
-import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts.onMainThread
+import com.github.unchama.minecraft.actions.{GetConnectedPlayers, OnMinecraftServerThread}
 import com.github.unchama.seichiassist.subsystems.buildcount.domain.explevel.{
   BuildAssistExpTable,
   BuildLevel
 }
 import com.github.unchama.seichiassist.subsystems.buildcount.subsystems.notification.application.actions.NotifyLevelUp
 import com.github.unchama.seichiassist.subsystems.discordnotification.DiscordNotificationAPI
-import com.github.unchama.seichiassist.util.SendMessageEffect.sendMessageToEveryoneIgnoringPreference
+import com.github.unchama.seichiassist.util.SendMessageEffect.sendMessageToEveryoneIgnoringPreferenceM
 import com.github.unchama.seichiassist.util.SendSoundEffect.sendEverySound
-import com.github.unchama.seichiassist.util.{LaunchFireWorksEffect, PlayerSendable}
+import com.github.unchama.seichiassist.util.LaunchFireWorksEffect
 import org.bukkit.ChatColor.GOLD
 import org.bukkit.Sound
 import org.bukkit.entity.Player
 
 object BukkitNotifyLevelUp {
 
-  import PlayerSendable.forString
   import cats.implicits._
 
   // TODO: BukkitNotifyLevelUpなのにdiffの展開やいつメッセージを出すかなどを扱うべきでない。
-  def apply[F[_]: Sync: OnMinecraftServerThread: DiscordNotificationAPI]
-    : NotifyLevelUp[F, Player] = {
+  def apply[F[_]: Sync: OnMinecraftServerThread: DiscordNotificationAPI: GetConnectedPlayers[*[
+    _
+  ], Player]]: NotifyLevelUp[F, Player] = {
     new NotifyLevelUp[F, Player] {
       override def ofBuildLevelTo(player: Player)(diff: Diff[BuildLevel]): F[Unit] = {
         val Diff(oldLevel, newLevel) = diff
@@ -32,11 +31,12 @@ object BukkitNotifyLevelUp {
           val messageLevelMaxGlobal = s"$GOLD${player.getName}の建築レベルが最大Lvに到達したよ(`・ω・´)"
           val messageLevelMaxDiscord = s"${player.getName}の建築レベルが最大Lvに到達したよ(`・ω・´)"
           val messageLevelMaxPlayer = s"${GOLD}最大Lvに到達したよ(`・ω・´)"
-          Sync[F].delay {
-            sendMessageToEveryoneIgnoringPreference(messageLevelMaxGlobal)(forString[IO])
-            player.sendMessage(messageLevelMaxPlayer)
-            sendEverySound(Sound.ENTITY_ENDERDRAGON_DEATH, 1.0f, 1.2f)
-          } >> LaunchFireWorksEffect.launchFireWorks[F](
+
+          sendMessageToEveryoneIgnoringPreferenceM[String, F](messageLevelMaxGlobal) >> Sync[F]
+            .delay {
+              player.sendMessage(messageLevelMaxPlayer)
+              sendEverySound(Sound.ENTITY_ENDER_DRAGON_DEATH, 1.0f, 1.2f)
+            } >> LaunchFireWorksEffect.launchFireWorks[F](
             player.getLocation
           ) >> DiscordNotificationAPI[F].sendPlainText(messageLevelMaxDiscord)
         } else if (oldLevel < newLevel) {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/canceldamagebyfallingblocks/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/canceldamagebyfallingblocks/System.scala
new file mode 100644
index 0000000000..0b995a87cb
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/canceldamagebyfallingblocks/System.scala
@@ -0,0 +1,15 @@
+package com.github.unchama.seichiassist.subsystems.canceldamagebyfallingblocks
+
+import com.github.unchama.seichiassist.meta.subsystem.Subsystem
+import com.github.unchama.seichiassist.subsystems.canceldamagebyfallingblocks.bukkit.listeners.PlayerDamageByBlockEvents
+import org.bukkit.event.Listener
+
+object System {
+
+  def wired[F[_]]: Subsystem[F] = {
+    new Subsystem[F] {
+      override val listeners: Seq[Listener] = Seq(PlayerDamageByBlockEvents)
+    }
+  }
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/canceldamagebyfallingblocks/bukkit/listeners/PlayerDamageByBlockEvents.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/canceldamagebyfallingblocks/bukkit/listeners/PlayerDamageByBlockEvents.scala
new file mode 100644
index 0000000000..aafe84e885
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/canceldamagebyfallingblocks/bukkit/listeners/PlayerDamageByBlockEvents.scala
@@ -0,0 +1,22 @@
+package com.github.unchama.seichiassist.subsystems.canceldamagebyfallingblocks.bukkit.listeners
+
+import org.bukkit.entity.Player
+import org.bukkit.event.entity.EntityDamageEvent
+import org.bukkit.event.entity.EntityDamageEvent.DamageCause
+import org.bukkit.event.{EventHandler, Listener}
+import com.github.unchama.seichiassist.ManagedWorld._
+
+object PlayerDamageByBlockEvents extends Listener {
+
+  @EventHandler
+  def onDamage(e: EntityDamageEvent): Unit = {
+    e.getEntity match {
+      // 整地ワールドではブロックの落下ダメージを無効化する
+      case player: Player
+          if e.getCause == DamageCause.FALLING_BLOCK && player.getWorld.isSeichi =>
+        e.setDamage(0.0)
+      case _ =>
+    }
+  }
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/chatratelimiter/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/chatratelimiter/System.scala
index f56d0bce5e..7ce30513dc 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/chatratelimiter/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/chatratelimiter/System.scala
@@ -9,15 +9,13 @@ import com.github.unchama.seichiassist.subsystems.breakcount.BreakCountReadAPI
 import com.github.unchama.seichiassist.subsystems.chatratelimiter.application.ChatRateLimitRepositoryDefinition
 import com.github.unchama.seichiassist.subsystems.chatratelimiter.bukkit.listeners.RateLimitCheckListener
 import com.github.unchama.seichiassist.subsystems.chatratelimiter.domain.ObtainChatPermission
-import io.chrisdavenport.log4cats.ErrorLogger
 import org.bukkit.entity.Player
 import org.bukkit.event.Listener
 
 object System {
-  def wired[F[_]: ConcurrentEffect: ErrorLogger, G[_]: SyncEffect: ContextCoercion[
-    *[_],
-    F
-  ]: Timer](implicit breakCountAPI: BreakCountReadAPI[F, G, Player]): F[Subsystem[F]] = {
+  def wired[F[_]: ConcurrentEffect, G[_]: SyncEffect: ContextCoercion[*[_], F]: Timer](
+    implicit breakCountAPI: BreakCountReadAPI[F, G, Player]
+  ): F[Subsystem[F]] = {
     val repository = ChatRateLimitRepositoryDefinition.inSyncContext[G, Player]
 
     for {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/discordnotification/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/discordnotification/System.scala
index f4e84a3810..1e078261c2 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/discordnotification/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/discordnotification/System.scala
@@ -6,20 +6,18 @@ import com.github.unchama.seichiassist.subsystems.discordnotification.infrastruc
   DefaultDiscordNotificationSender,
   WebhookDiscordNotificationSender
 }
-import io.chrisdavenport.log4cats.Logger
 
 trait System[F[_]] extends Subsystem[F] {
   implicit val globalNotification: DiscordNotificationAPI[F]
 }
 
 object System {
-  def wired[F[_]: Sync: ContextShift: Logger: LiftIO](
-    configuration: SystemConfiguration
-  ): System[F] = new System[F] {
-    implicit override val globalNotification: DiscordNotificationAPI[F] = {
-      WebhookDiscordNotificationSender
-        .tryCreate(configuration.webhookUrl)
-        .getOrElse(new DefaultDiscordNotificationSender)
+  def wired[F[_]: Sync: ContextShift: LiftIO](configuration: SystemConfiguration): System[F] =
+    new System[F] {
+      implicit override val globalNotification: DiscordNotificationAPI[F] = {
+        WebhookDiscordNotificationSender
+          .tryCreate(configuration.webhookUrl)
+          .getOrElse(new DefaultDiscordNotificationSender)
+      }
     }
-  }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/discordnotification/infrastructure/DefaultDiscordNotificationSender.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/discordnotification/infrastructure/DefaultDiscordNotificationSender.scala
index 7950ecd446..5036a6d4e3 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/discordnotification/infrastructure/DefaultDiscordNotificationSender.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/discordnotification/infrastructure/DefaultDiscordNotificationSender.scala
@@ -3,13 +3,11 @@ package com.github.unchama.seichiassist.subsystems.discordnotification.infrastru
 import cats.effect.LiftIO
 import com.github.unchama.seichiassist.SeichiAssist
 import com.github.unchama.seichiassist.subsystems.discordnotification.DiscordNotificationAPI
-import io.chrisdavenport.log4cats.Logger
 
 /**
  * この実装は[[sendPlainText]]が呼ばれるたびに警告をロガーに流す以外は何もしない。
  */
-final class DefaultDiscordNotificationSender[F[_]: Logger: LiftIO]
-    extends DiscordNotificationAPI[F] {
+final class DefaultDiscordNotificationSender[F[_]: LiftIO] extends DiscordNotificationAPI[F] {
   override def sendPlainText(message: String): F[Unit] = {
     SeichiAssist
       .instance
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/discordnotification/infrastructure/WebhookDiscordNotificationSender.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/discordnotification/infrastructure/WebhookDiscordNotificationSender.scala
index cbe745cf0e..237981483a 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/discordnotification/infrastructure/WebhookDiscordNotificationSender.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/discordnotification/infrastructure/WebhookDiscordNotificationSender.scala
@@ -2,7 +2,6 @@ package com.github.unchama.seichiassist.subsystems.discordnotification.infrastru
 
 import cats.effect.{ContextShift, Sync}
 import com.github.unchama.seichiassist.subsystems.discordnotification.DiscordNotificationAPI
-import io.chrisdavenport.log4cats.Logger
 
 import java.io.IOException
 import java.net.{HttpURLConnection, MalformedURLException, URL}
@@ -24,14 +23,14 @@ class WebhookDiscordNotificationSender[F[_]: Sync: ContextShift] private (webhoo
         import io.circe.generic.auto._
         import io.circe.syntax._
         val markdownSafeMessage = message
-          .replaceAllLiterally("\\", "\\\\")
-          .replaceAllLiterally("_", "\\_")
-          .replaceAllLiterally("*", "\\*")
-          .replaceAllLiterally("`", "\\`")
-          .replaceAllLiterally("|", "\\|")
-          .replaceAllLiterally("@", "\\@")
-          .replaceAllLiterally("~", "\\~")
-          .replaceAllLiterally(":", "\\:")
+          .replace("\\", "\\\\")
+          .replace("_", "\\_")
+          .replace("*", "\\*")
+          .replace("`", "\\`")
+          .replace("|", "\\|")
+          .replace("@", "\\@")
+          .replace("~", "\\~")
+          .replace(":", "\\:")
 
         val json =
           WebhookDiscordNotificationSender.PlainMessage(markdownSafeMessage).asJson.noSpaces
@@ -76,7 +75,7 @@ object WebhookDiscordNotificationSender {
    * @return
    *   初期化に成功した場合はSome、初期化中に特定の例外が送出された場合はNone。マスクされない例外が送出されたときは、再送出する。
    */
-  def tryCreate[F[_]: Sync: ContextShift: Logger](
+  def tryCreate[F[_]: Sync: ContextShift](
     webhookURL: String
   ): Option[WebhookDiscordNotificationSender[F]] = {
     try {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/donate/bukkit/commands/DonationCommand.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/donate/bukkit/commands/DonationCommand.scala
index db33f0340e..63101baebe 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/donate/bukkit/commands/DonationCommand.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/donate/bukkit/commands/DonationCommand.scala
@@ -1,6 +1,6 @@
 package com.github.unchama.seichiassist.subsystems.donate.bukkit.commands
 
-import cats.effect.ConcurrentEffect.ops.toAllConcurrentEffectOps
+import cats.data.Kleisli
 import cats.effect.{ConcurrentEffect, Sync}
 import com.github.unchama.contextualexecutor.ContextualExecutor
 import com.github.unchama.contextualexecutor.builder.{ContextualExecutorBuilder, Parsers}
@@ -12,7 +12,7 @@ import com.github.unchama.seichiassist.subsystems.donate.domain.{
   PlayerName
 }
 import com.github.unchama.targetedeffect.UnfocusedEffect
-import com.github.unchama.targetedeffect.commandsender.MessageEffect
+import com.github.unchama.targetedeffect.commandsender.{MessageEffect, MessageEffectF}
 import org.bukkit.ChatColor._
 import org.bukkit.command.TabExecutor
 import shapeless.HNil
@@ -31,7 +31,7 @@ class DonationCommand[F[_]: ConcurrentEffect](
       .beginConfiguration
       .thenParse(Parsers.identity)
       .thenParse(Parsers.integer(MessageEffect(s"${RED}付与するプレミアムエフェクトポイントは整数で指定してください。")))
-      .buildWithExecutionF { context =>
+      .buildWithExecutionCSEffect { context =>
         import shapeless.::
 
         val rawName :: rawDonatePoint :: HNil = context.args.parsed
@@ -40,29 +40,31 @@ class DonationCommand[F[_]: ConcurrentEffect](
 
         val dateRegex = "[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])".r
         val dateOpt = context.args.yetToBeParsed.headOption
-        val isMatchedPattern = dateOpt.forall(date => dateRegex.matches(date))
+        val isMatchedPattern = dateOpt.forall(dateRegex.matches)
 
-        val eff = for {
-          date <- Sync[F].delay {
+        (for {
+          date <- Kleisli.liftF(Sync[F].delay {
             dateOpt match {
               case Some(date) if isMatchedPattern =>
                 val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
                 LocalDate.parse(date, dateTimeFormatter)
               case _ => LocalDate.now()
             }
-          }
-          _ <- donatePersistence
-            .addDonatePremiumEffectPoint(playerName, Obtained(donatePoint, date))
-            .whenA(isMatchedPattern)
+          })
+          _ <- Kleisli.liftF(
+            donatePersistence
+              .addDonatePremiumEffectPoint(playerName, Obtained(donatePoint, date))
+              .whenA(isMatchedPattern)
+          )
         } yield {
-          if (!isMatchedPattern)
-            MessageEffect(s"${RED}購入日はyyyy-MM-ddの形式で指定してください。")
-          else
-            MessageEffect(
+          if (isMatchedPattern) {
+            MessageEffectF(
               s"$GREEN${playerName.name}に${donatePoint.value}のプレミアムエフェクトポイントを付与しました。"
             )
-        }
-        eff.toIO
+          } else {
+            MessageEffectF(s"${RED}購入日はyyyy-MM-ddの形式で指定してください。")
+          }
+        }).flatten
       }
 
   private val commandDescriptionExecutor: ContextualExecutor =
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/donate/infrastructure/JdbcDonatePersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/donate/infrastructure/JdbcDonatePersistence.scala
index 01fa757d4e..75f2f194e8 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/donate/infrastructure/JdbcDonatePersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/donate/infrastructure/JdbcDonatePersistence.scala
@@ -26,7 +26,7 @@ class JdbcDonatePersistence[F[_]: Sync] extends DonatePersistence[F] {
            | VALUES 
            | ((SELECT uuid FROM playerdata WHERE name = ${playerName.name}),
            | ${obtainedPremiumEffectPoint.effectPoint.value},
-           | ${obtainedPremiumEffectPoint.purchaseDate})""".stripMargin.execute().apply()
+           | ${obtainedPremiumEffectPoint.purchaseDate})""".stripMargin.execute()
     }
   }
 
@@ -38,7 +38,6 @@ class JdbcDonatePersistence[F[_]: Sync] extends DonatePersistence[F] {
       DB.localTx { implicit session =>
         sql"INSERT INTO donate_usage_history (uuid, effect_name, use_points) VALUES (${uuid.toString}, ${effect.entryName}, ${effect.usePoint})"
           .execute()
-          .apply()
       }
     }
 
@@ -51,7 +50,7 @@ class JdbcDonatePersistence[F[_]: Sync] extends DonatePersistence[F] {
                | WHERE uuid = ${uuid.toString}) - (
                | SELECT COALESCE(SUM(use_points), 0) AS sum_use_points FROM donate_usage_history 
                | WHERE uuid = ${uuid.toString}) AS currentPremiumEffectPoints
-             """.stripMargin.map(_.int("currentPremiumEffectPoints")).single().apply()
+             """.stripMargin.map(_.int("currentPremiumEffectPoints")).single()
         DonatePremiumEffectPoint(premiumEffectPointsOpt.get)
       }
     }
@@ -65,8 +64,7 @@ class JdbcDonatePersistence[F[_]: Sync] extends DonatePersistence[F] {
           .map(rs =>
             Obtained(DonatePremiumEffectPoint(rs.int("get_points")), rs.localDate("timestamp"))
           )
-          .list
-          .apply()
+          .list()
           .toVector
       }
     }
@@ -83,8 +81,7 @@ class JdbcDonatePersistence[F[_]: Sync] extends DonatePersistence[F] {
             ActiveSkillPremiumEffect.withName(rs.string("effect_name"))
           )
         )
-        .list
-        .apply()
+        .list()
         .toVector
     }
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/dragonnighttime/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/dragonnighttime/System.scala
index 10cb78c9c2..5d286979de 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/dragonnighttime/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/dragonnighttime/System.scala
@@ -2,13 +2,16 @@ package com.github.unchama.seichiassist.subsystems.dragonnighttime
 
 import cats.effect.{Concurrent, Timer}
 import com.github.unchama.generic.ContextCoercion
+import com.github.unchama.minecraft.actions.{GetConnectedPlayers, OnMinecraftServerThread}
 import com.github.unchama.seichiassist.subsystems.dragonnighttime.application._
 import com.github.unchama.seichiassist.subsystems.dragonnighttime.bukkit.instances._
 import com.github.unchama.seichiassist.subsystems.fastdiggingeffect.FastDiggingEffectWriteApi
 import com.github.unchama.seichiassist.subsystems.mana.ManaApi
 
 object System {
-  def backgroundProcess[F[_]: Concurrent: Timer, G[_]: ContextCoercion[*[_], F], Player](
+  def backgroundProcess[F[_]: Concurrent: Timer: OnMinecraftServerThread: GetConnectedPlayers[*[
+    _
+  ], org.bukkit.entity.Player], G[_]: ContextCoercion[*[_], F], Player](
     implicit fastDiggingEffectApi: FastDiggingEffectWriteApi[F, Player],
     manaApi: ManaApi[F, G, Player]
   ): F[Nothing] = {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/dragonnighttime/bukkit/instances/SyncCanBroadcastOnBukkit.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/dragonnighttime/bukkit/instances/SyncCanBroadcastOnBukkit.scala
index aa16c0e760..20c1874748 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/dragonnighttime/bukkit/instances/SyncCanBroadcastOnBukkit.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/dragonnighttime/bukkit/instances/SyncCanBroadcastOnBukkit.scala
@@ -1,15 +1,20 @@
 package com.github.unchama.seichiassist.subsystems.dragonnighttime.bukkit.instances
 
 import cats.effect.Sync
-import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts.onMainThread
+import com.github.unchama.minecraft.actions.{GetConnectedPlayers, OnMinecraftServerThread}
 import com.github.unchama.seichiassist.subsystems.dragonnighttime.application.CanBroadcast
 import com.github.unchama.seichiassist.util.SendMessageEffect
 import org.bukkit.Bukkit
+import org.bukkit.entity.Player
 
 object SyncCanBroadcastOnBukkit {
-  def apply[F[_]: Sync]: CanBroadcast[F] = (message: String) =>
-    Sync[F].delay {
-      SendMessageEffect.sendMessageToEveryoneIgnoringPreference(message)
-      Bukkit.getLogger.info(message)
-    }
+  import cats.implicits._
+
+  def apply[F[_]: Sync: OnMinecraftServerThread: GetConnectedPlayers[*[_], Player]]
+    : CanBroadcast[F] = (message: String) => {
+    for {
+      _ <- SendMessageEffect.sendMessageToEveryoneIgnoringPreferenceM[String, F](message)
+      _ <- Sync[F].delay(Bukkit.getLogger.info(message))
+    } yield ()
+  }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/elevator/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/elevator/System.scala
new file mode 100644
index 0000000000..edbe85e27b
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/elevator/System.scala
@@ -0,0 +1,25 @@
+package com.github.unchama.seichiassist.subsystems.elevator
+
+import cats.effect.ConcurrentEffect
+import com.github.unchama.generic.effect.unsafe.EffectEnvironment
+import com.github.unchama.seichiassist.meta.subsystem.Subsystem
+import com.github.unchama.seichiassist.subsystems.elevator.application.actions.FindTeleportLocation
+import com.github.unchama.seichiassist.subsystems.elevator.bukkit.actions.BukkitFindTeleportLocation
+import com.github.unchama.seichiassist.subsystems.elevator.bukkit.listeners.ElevatorEventsListener
+import org.bukkit.Location
+import org.bukkit.event.Listener
+
+object System {
+
+  def wired[F[_]: ConcurrentEffect](
+    implicit effectEnvironment: EffectEnvironment
+  ): Subsystem[F] = {
+    implicit val findTeleportLocation: FindTeleportLocation[F, Location] =
+      new BukkitFindTeleportLocation[F]
+
+    new Subsystem[F] {
+      override val listeners: Seq[Listener] = Seq(new ElevatorEventsListener[F])
+    }
+  }
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/elevator/application/actions/FindTeleportLocation.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/elevator/application/actions/FindTeleportLocation.scala
new file mode 100644
index 0000000000..35743f4bea
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/elevator/application/actions/FindTeleportLocation.scala
@@ -0,0 +1,25 @@
+package com.github.unchama.seichiassist.subsystems.elevator.application.actions
+
+trait FindTeleportLocation[F[_], Location] {
+
+  /**
+   * @return `currentLocation`がテレポート元として正しいかどうかを判定する作用
+   */
+  def currentLocationTeleportFromAsCorrectIs(currentLocation: Location): F[Boolean]
+
+  /**
+   * @return `targetLocation`がテレポート先として正しいかどうかを判定する作用
+   */
+  def isTeleportTargetLocation(targetLocation: Location): F[Boolean]
+
+  /**
+   * @return `currentLocation`より上のテレポート対象となる[[Location]]を探す作用
+   */
+  def findUpperLocation(currentLocation: Location): F[Option[Location]]
+
+  /**
+   * @return `currentLocation`より下のテレポート対象となる[[Location]]を探す作用
+   */
+  def findLowerLocation(currentLocation: Location): F[Option[Location]]
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/elevator/bukkit/actions/BukkitFindTeleportLocation.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/elevator/bukkit/actions/BukkitFindTeleportLocation.scala
new file mode 100644
index 0000000000..e1b390f31c
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/elevator/bukkit/actions/BukkitFindTeleportLocation.scala
@@ -0,0 +1,61 @@
+package com.github.unchama.seichiassist.subsystems.elevator.bukkit.actions
+
+import cats.effect.Sync
+import com.github.unchama.seichiassist.subsystems.elevator.application.actions.FindTeleportLocation
+import org.bukkit.Location
+import org.bukkit.Material
+
+class BukkitFindTeleportLocation[F[_]: Sync] extends FindTeleportLocation[F, Location] {
+
+  override def currentLocationTeleportFromAsCorrectIs(currentLocation: Location): F[Boolean] =
+    Sync[F].delay {
+      currentLocation
+        .clone()
+        .add(0, -1, 0)
+        .getBlock
+        .getType == Material.IRON_BLOCK && currentLocation
+        .getBlock
+        .getType == Material.HEAVY_WEIGHTED_PRESSURE_PLATE
+    }
+
+  override def isTeleportTargetLocation(targetLocation: Location): F[Boolean] = Sync[F].delay {
+    targetLocation
+      .clone()
+      .add(0, -1, 0)
+      .getBlock
+      .getType == Material.IRON_BLOCK && targetLocation
+      .getBlock
+      .getType == Material.HEAVY_WEIGHTED_PRESSURE_PLATE && targetLocation
+      .clone()
+      .add(0, 1, 0)
+      .getBlock
+      .getType == Material.AIR
+  }
+
+  import cats.implicits._
+
+  override def findUpperLocation(currentLocation: Location): F[Option[Location]] = {
+    (currentLocation.getY.toInt + 1 until currentLocation.getWorld.getMaxHeight)
+      .toVector
+      .map { y =>
+        val location = currentLocation.clone()
+        location.setY(y)
+
+        location
+      }
+      .findM(isTeleportTargetLocation)
+  }
+
+  override def findLowerLocation(currentLocation: Location): F[Option[Location]] = {
+    (currentLocation.getY.toInt - 1 until currentLocation.getWorld.getMinHeight by -1)
+      .toVector
+      .map { y =>
+        val location = currentLocation.clone()
+        location.setY(y)
+
+        location
+      }
+      .findM(isTeleportTargetLocation)
+  }
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/elevator/bukkit/listeners/ElevatorEventsListener.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/elevator/bukkit/listeners/ElevatorEventsListener.scala
new file mode 100644
index 0000000000..9bce467fa3
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/elevator/bukkit/listeners/ElevatorEventsListener.scala
@@ -0,0 +1,60 @@
+package com.github.unchama.seichiassist.subsystems.elevator.bukkit.listeners
+
+import cats.effect.{ConcurrentEffect, Sync}
+import com.github.unchama.generic.ApplicativeExtra
+import com.github.unchama.generic.effect.unsafe.EffectEnvironment
+import com.github.unchama.seichiassist.subsystems.elevator.application.actions.FindTeleportLocation
+import org.bukkit.Location
+import org.bukkit.event.player.{PlayerMoveEvent, PlayerToggleSneakEvent}
+import org.bukkit.event.{EventHandler, Listener}
+
+class ElevatorEventsListener[F[_]: ConcurrentEffect](
+  implicit findTeleportLocation: FindTeleportLocation[F, Location],
+  effectEnvironment: EffectEnvironment
+) extends Listener {
+
+  import cats.implicits._
+
+  @EventHandler
+  def onJump(e: PlayerMoveEvent): Unit = {
+    val player = e.getPlayer
+    val currentLocation = player.getLocation
+
+    if (player.isFlying || e.getFrom.getY >= e.getTo.getY) return
+
+    val teleportEffect = for {
+      currentLocationIsCorrectTeleportLocation <- findTeleportLocation
+        .currentLocationTeleportFromAsCorrectIs(currentLocation)
+      teleportTargetLocation <- ApplicativeExtra.whenAOrElse(
+        currentLocationIsCorrectTeleportLocation
+      )(findTeleportLocation.findUpperLocation(currentLocation), None)
+      _ <- teleportTargetLocation.traverse { location =>
+        Sync[F].delay(player.teleport(location))
+      }
+    } yield ()
+
+    effectEnvironment.unsafeRunEffectAsync("エレベータの上昇処理を行う", teleportEffect)
+  }
+
+  @EventHandler
+  def onSneak(e: PlayerToggleSneakEvent): Unit = {
+    val player = e.getPlayer
+    val currentLocation = player.getLocation
+
+    if (!player.isSneaking) return
+
+    val teleportEffect = for {
+      currentLocationIsCorrectTeleportLocation <- findTeleportLocation
+        .currentLocationTeleportFromAsCorrectIs(currentLocation)
+      teleportTargetLocation <- ApplicativeExtra.whenAOrElse(
+        currentLocationIsCorrectTeleportLocation
+      )(findTeleportLocation.findLowerLocation(currentLocation), None)
+      _ <- teleportTargetLocation.traverse { location =>
+        Sync[F].delay(player.teleport(location))
+      }
+    } yield ()
+
+    effectEnvironment.unsafeRunEffectAsync("エレベータの降下処理を行う", teleportEffect)
+  }
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/expbottlestack/bukkit/listeners/ExpBottleStackUsageController.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/expbottlestack/bukkit/listeners/ExpBottleStackUsageController.scala
index 5cce9248f3..1776eee635 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/expbottlestack/bukkit/listeners/ExpBottleStackUsageController.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/expbottlestack/bukkit/listeners/ExpBottleStackUsageController.scala
@@ -46,7 +46,7 @@ class ExpBottleStackUsageController[F[_]: Effect, G[_]: SyncEffect](
     if (
       player.isSneaking
       && playerInventory.getItemInMainHand != null
-      && playerInventory.getItemInMainHand.getType == Material.EXP_BOTTLE
+      && playerInventory.getItemInMainHand.getType == Material.EXPERIENCE_BOTTLE
       && (action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK)
     ) {
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/FastDiggingEffectApi.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/FastDiggingEffectApi.scala
index 2fe77ede3d..e9ca3fb02b 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/FastDiggingEffectApi.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/FastDiggingEffectApi.scala
@@ -63,18 +63,14 @@ trait FastDiggingSettingsReadApi[F[_], Player] {
   /**
    * 採掘速度上昇抑制の設定をプレーヤーごとに保持するデータレポジトリ。
    */
-  val currentSuppressionSettings: KeyedDataRepository[
-    Player,
-    ReadOnlyRef[F, FastDiggingEffectSuppressionState]
-  ]
+  val currentSuppressionSettings
+    : KeyedDataRepository[Player, ReadOnlyRef[F, FastDiggingEffectSuppressionState]]
 
   /**
    * 採掘速度上昇効果の統計を受け取るかどうかの設定をプレーヤーごとに保持するデータレポジトリ。
    */
-  val currentStatsSettings: KeyedDataRepository[
-    Player,
-    ReadOnlyRef[F, FastDiggingEffectStatsSettings]
-  ]
+  val currentStatsSettings
+    : KeyedDataRepository[Player, ReadOnlyRef[F, FastDiggingEffectStatsSettings]]
 
 }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/application/process/PlayerCountEffectSynchronization.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/application/process/PlayerCountEffectSynchronization.scala
index 0f9c2d60c1..50009bd66e 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/application/process/PlayerCountEffectSynchronization.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/application/process/PlayerCountEffectSynchronization.scala
@@ -2,7 +2,6 @@ package com.github.unchama.seichiassist.subsystems.fastdiggingeffect.application
 
 import cats.effect.{ConcurrentEffect, Timer}
 import com.github.unchama.minecraft.actions.GetConnectedPlayers
-import com.github.unchama.minecraft.algebra.HasUuid
 import com.github.unchama.seichiassist.domain.actions.GetNetworkConnectionCount
 import com.github.unchama.seichiassist.subsystems.fastdiggingeffect.FastDiggingEffectApi
 import com.github.unchama.seichiassist.subsystems.fastdiggingeffect.application.Configuration
@@ -21,7 +20,7 @@ object PlayerCountEffectSynchronization {
   def using[F[_]: ConcurrentEffect: Timer: GetConnectedPlayers[
     *[_],
     Player
-  ]: GetNetworkConnectionCount, Player: HasUuid](
+  ]: GetNetworkConnectionCount, Player](
     implicit configuration: Configuration,
     api: FastDiggingEffectApi[F, Player]
   ): fs2.Stream[F, Unit] = {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/bukkit/actions/GrantBukkitFastDiggingEffect.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/bukkit/actions/GrantBukkitFastDiggingEffect.scala
index 174c6976b0..6ce2baee5d 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/bukkit/actions/GrantBukkitFastDiggingEffect.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/bukkit/actions/GrantBukkitFastDiggingEffect.scala
@@ -1,12 +1,12 @@
 package com.github.unchama.seichiassist.subsystems.fastdiggingeffect.bukkit.actions
 
-import cats.effect.{Sync, SyncIO}
+import cats.effect.SyncIO
 import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.subsystems.fastdiggingeffect.domain.actions.GrantFastDiggingEffect
 import org.bukkit.entity.Player
 import org.bukkit.potion.{PotionEffect, PotionEffectType}
 
-class GrantBukkitFastDiggingEffect[F[_]: Sync: OnMinecraftServerThread]
+class GrantBukkitFastDiggingEffect[F[_]: OnMinecraftServerThread]
     extends GrantFastDiggingEffect[F, Player] {
 
   override def forTwoSeconds(player: Player)(amount: Int): F[Unit] = {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/infrastructure/JdbcFastDiggingEffectStatsSettingsPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/infrastructure/JdbcFastDiggingEffectStatsSettingsPersistence.scala
index 56d8fd3e63..6617c751d2 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/infrastructure/JdbcFastDiggingEffectStatsSettingsPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/infrastructure/JdbcFastDiggingEffectStatsSettingsPersistence.scala
@@ -33,7 +33,6 @@ class JdbcFastDiggingEffectStatsSettingsPersistence[F[_]: Sync]
       sql"select messageflag from playerdata where uuid = ${key.toString}"
         .map { rs => booleanToSettings(rs.boolean("messageflag")) }
         .headOption()
-        .apply()
     }
   }
 
@@ -42,9 +41,7 @@ class JdbcFastDiggingEffectStatsSettingsPersistence[F[_]: Sync]
       DB.localTx { implicit session =>
         val encoded = settingsToBoolean(value)
 
-        sql"update playerdata set messageflag = $encoded where uuid = ${key.toString}"
-          .update()
-          .apply()
+        sql"update playerdata set messageflag = $encoded where uuid = ${key.toString}".update()
       }
     }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/infrastructure/JdbcFastDiggingEffectSuppressionStatePersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/infrastructure/JdbcFastDiggingEffectSuppressionStatePersistence.scala
index 79be1e9472..05f7c83981 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/infrastructure/JdbcFastDiggingEffectSuppressionStatePersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/fastdiggingeffect/infrastructure/JdbcFastDiggingEffectSuppressionStatePersistence.scala
@@ -45,7 +45,6 @@ class JdbcFastDiggingEffectSuppressionStatePersistence[F[_]: Sync]
       sql"select effectflag from playerdata where uuid = ${key.toString}"
         .map { rs => intToSuppressionState(rs.int("effectflag")) }
         .headOption()
-        .apply()
     }
   }
 
@@ -54,9 +53,7 @@ class JdbcFastDiggingEffectSuppressionStatePersistence[F[_]: Sync]
       DB.localTx { implicit session =>
         val encoded = suppressionStateToInt(value)
 
-        sql"update playerdata set effectflag = $encoded where uuid = ${key.toString}"
-          .update()
-          .apply()
+        sql"update playerdata set effectflag = $encoded where uuid = ${key.toString}".update()
       }
     }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/fourdimensionalpocket/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/fourdimensionalpocket/System.scala
index 7de4971007..47216e0e1f 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/fourdimensionalpocket/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/fourdimensionalpocket/System.scala
@@ -76,7 +76,7 @@ object System {
         override val openPocketInventory: Kleisli[F, Player, Unit] = Kleisli { player =>
           Sync[F].delay {
             // 開く音を再生
-            player.playSound(player.getLocation, Sound.BLOCK_ENDERCHEST_OPEN, 1f, 0.1f)
+            player.playSound(player.getLocation, Sound.BLOCK_ENDER_CHEST_OPEN, 1f, 0.1f)
           } >> ContextCoercion {
             pocketInventoryRepositoryHandles.repository(player)._1.readLatest
           }.flatMap(inventory => interactInventory.open(inventory)(player))
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/fourdimensionalpocket/bukkit/listeners/OpenPocketInventoryOnPlacingEnderPortalFrame.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/fourdimensionalpocket/bukkit/listeners/OpenPocketInventoryOnPlacingEnderPortalFrame.scala
index 94dd36e456..137752e861 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/fourdimensionalpocket/bukkit/listeners/OpenPocketInventoryOnPlacingEnderPortalFrame.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/fourdimensionalpocket/bukkit/listeners/OpenPocketInventoryOnPlacingEnderPortalFrame.scala
@@ -22,7 +22,7 @@ class OpenPocketInventoryOnPlacingEnderPortalFrame[F[_]: Effect](
     val action = event.getAction
     val hand = event.getHand
 
-    if (event.getMaterial != Material.ENDER_PORTAL_FRAME) {
+    if (event.getMaterial != Material.END_PORTAL_FRAME) {
       return
     }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/fourdimensionalpocket/infrastructure/JdbcBukkitPocketInventoryPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/fourdimensionalpocket/infrastructure/JdbcBukkitPocketInventoryPersistence.scala
index 30946eca13..b71ac49658 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/fourdimensionalpocket/infrastructure/JdbcBukkitPocketInventoryPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/fourdimensionalpocket/infrastructure/JdbcBukkitPocketInventoryPersistence.scala
@@ -18,7 +18,6 @@ class JdbcBukkitPocketInventoryPersistence[F[_]: Sync]
       sql"select inventory from playerdata where uuid = ${key.toString}"
         .map { rs => BukkitSerialization.fromBase64forPocket(rs.string("inventory")) }
         .headOption()
-        .apply()
     }
   }
 
@@ -26,9 +25,7 @@ class JdbcBukkitPocketInventoryPersistence[F[_]: Sync]
     DB.localTx { implicit session =>
       val encoded = BukkitSerialization.toBase64(value)
 
-      sql"update playerdata set inventory = $encoded where uuid = ${key.toString}"
-        .update()
-        .apply()
+      sql"update playerdata set inventory = $encoded where uuid = ${key.toString}".update()
     }
   }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/System.scala
index 5371812d15..c010c31141 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/System.scala
@@ -2,7 +2,7 @@ package com.github.unchama.seichiassist.subsystems.gacha
 
 import cats.data.Kleisli
 import cats.effect.ConcurrentEffect
-import com.github.unchama.minecraft.actions.OnMinecraftServerThread
+import com.github.unchama.minecraft.actions.{GetConnectedPlayers, OnMinecraftServerThread}
 import com.github.unchama.minecraft.bukkit.algebra.CloneableBukkitItemStack.instance
 import com.github.unchama.seichiassist.meta.subsystem.Subsystem
 import com.github.unchama.seichiassist.subsystems.gacha.application.actions.{
@@ -38,9 +38,11 @@ trait System[F[_], Player] extends Subsystem[F] {
 
 object System {
 
-  def wired[F[_]: ConcurrentEffect: OnMinecraftServerThread](
+  def wired[F[_]: ConcurrentEffect: OnMinecraftServerThread: GetConnectedPlayers[
+    *[_],
+    Player
+  ]: GachaTicketAPI](
     implicit gachaPrizeAPI: GachaPrizeAPI[F, ItemStack, Player],
-    gachaTicketAPI: GachaTicketAPI[F],
     mineStackAPI: MineStackAPI[F, Player, ItemStack]
   ): System[F, Player] = {
     implicit val canBeSignedAsGachaPrize: CanBeSignedAsGachaPrize[ItemStack] =
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/bukkit/GachaCommand.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/bukkit/GachaCommand.scala
index 5846f2ebe5..11f4857e1b 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/bukkit/GachaCommand.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/bukkit/GachaCommand.scala
@@ -1,7 +1,7 @@
 package com.github.unchama.seichiassist.subsystems.gacha.bukkit
 
 import cats.data.Kleisli
-import cats.effect.{ConcurrentEffect, Effect, Sync}
+import cats.effect.{ConcurrentEffect, Sync}
 import com.github.unchama.contextualexecutor.ContextualExecutor
 import com.github.unchama.contextualexecutor.builder.ParserResponse.{failWith, succeedWith}
 import com.github.unchama.contextualexecutor.builder.{
@@ -31,7 +31,7 @@ import eu.timepit.refined.api.Refined
 import eu.timepit.refined.auto._
 import eu.timepit.refined.numeric.{Interval, NonNegative, Positive}
 import org.bukkit.ChatColor._
-import org.bukkit.command.TabExecutor
+import org.bukkit.command.{CommandSender, TabExecutor}
 import org.bukkit.entity.Player
 import org.bukkit.inventory.ItemStack
 import shapeless.HNil
@@ -77,7 +77,9 @@ class GachaCommand[F[_]: OnMinecraftServerThread: ConcurrentEffect](
         s"$RED/gacha delete-event <イベント名>",
         "イベントを削除します。(間違ってイベントを作成した時以外は使わないでください。)",
         s"$RED/gacha list-event",
-        "イベントの一覧を表示します。"
+        "イベントの一覧を表示します。",
+        s"$RED/gacha replace-prize <ID>",
+        "指定したIDのガチャ景品を手元のアイテムに置き換えます"
       )
     )
   )
@@ -95,7 +97,8 @@ class GachaCommand[F[_]: OnMinecraftServerThread: ConcurrentEffect](
         "setprob" -> setProbability,
         "create-event" -> createEvent,
         "delete-event" -> deleteEvent,
-        "list-event" -> eventList
+        "list-event" -> eventList,
+        "replace-prize" -> replaceGachaPrize
       ),
       whenBranchNotFound = Some(printDescriptionExecutor),
       whenArgInsufficient = Some(printDescriptionExecutor)
@@ -154,7 +157,7 @@ class GachaCommand[F[_]: OnMinecraftServerThread: ConcurrentEffect](
           case "all" =>
             Kleisli
               .liftF(gachaTicketAPI.addToAllKnownPlayers(amount))
-              .flatMap(_ => MessageEffectF(s"${GREEN}全プレイヤーへガチャ券${amount}枚加算成功"))
+              .flatMap(_ => MessageEffectF(s"${GREEN}全プレイヤーへガチャ券${amount.value}枚加算成功"))
           case value =>
             val uuidRegex =
               "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}".r
@@ -187,35 +190,34 @@ class GachaCommand[F[_]: OnMinecraftServerThread: ConcurrentEffect](
             MessageEffect("IDは0以上の整数を指定してください。")
           )
         )
-        .buildWithExecutionF { context =>
+        .buildWithExecutionCSEffect { context =>
           import shapeless.::
           val gachaPrizeId :: shapeless.HNil = context.args.parsed
           // optional
           val ownerName = context.args.yetToBeParsed.headOption
 
-          for {
-            gachaPrize <- gachaPrizeAPI.fetch(GachaPrizeId(gachaPrizeId))
-            existsGachaPrize = gachaPrize.nonEmpty
-            _ <- Sync[F].delay {
-              gachaPrize.foreach { gachaPrize =>
-                val itemStack = ownerName match {
-                  case Some(name) => gachaPrize.materializeWithOwnerSignature(name)
-                  case None       => gachaPrize.itemStack
+          Kleisli
+            .liftF {
+              for {
+                gachaPrize <- gachaPrizeAPI.fetch(GachaPrizeId(gachaPrizeId))
+                _ <- gachaPrize.traverse { gachaPrize =>
+                  val itemStack = ownerName match {
+                    case Some(name) => gachaPrize.materializeWithOwnerSignature(name)
+                    case None       => gachaPrize.itemStack
+                  }
+
+                  InventoryOperations.grantItemStacksEffect(itemStack).apply(context.sender)
                 }
-
-                InventoryOperations.grantItemStacksEffect(itemStack).apply(context.sender)
-              }
+              } yield gachaPrize
+            }
+            .flatMap {
+              case Some(_) => MessageEffectF("ガチャアイテムを付与しました。")
+              case None    => MessageEffectF("指定されたIDのガチャ景品は存在しません。")
             }
-          } yield {
-            if (existsGachaPrize)
-              MessageEffect("ガチャアイテムを付与しました。")
-            else
-              MessageEffect("指定されたIDのガチャ景品は存在しません。")
-          }
         }
 
     val add: ContextualExecutor =
-      playerCommandBuilder.thenParse(probabilityParser).buildWithExecutionF { context =>
+      playerCommandBuilder.thenParse(probabilityParser).buildWithExecutionCSEffect { context =>
         import shapeless.::
 
         val player = context.sender
@@ -223,45 +225,46 @@ class GachaCommand[F[_]: OnMinecraftServerThread: ConcurrentEffect](
         val eventName = context.args.yetToBeParsed.headOption.map(GachaEventName)
         val mainHandItem = player.getInventory.getItemInMainHand
 
-        for {
-          events <- gachaPrizeAPI.createdGachaEvents
-          _ <- gachaPrizeAPI.addGachaPrize(
-            domain.GachaPrizeTableEntry(
-              mainHandItem,
-              GachaProbability(probability),
-              probability < 0.1,
-              _,
-              events.find(gachaEvent => eventName.contains(gachaEvent.eventName))
-            )
-          )
-        } yield MessageEffect(List("ガチャアイテムを追加しました!"))
+        Kleisli
+          .liftF[F, CommandSender, Unit] {
+            for {
+              events <- gachaPrizeAPI.createdGachaEvents
+              _ <- gachaPrizeAPI.addGachaPrize(
+                domain.GachaPrizeTableEntry(
+                  mainHandItem,
+                  GachaProbability(probability),
+                  probability < 0.1,
+                  _,
+                  events.find(gachaEvent => eventName.contains(gachaEvent.eventName))
+                )
+              )
+            } yield ()
+          }
+          .productR(MessageEffectF("ガチャアイテムを追加しました!"))
       }
 
     val list: ContextualExecutor =
-      ContextualExecutorBuilder.beginConfiguration.buildWithExecutionF { context =>
+      ContextualExecutorBuilder.beginConfiguration.buildWithExecutionCSEffect { context =>
         val eventName = context.args.yetToBeParsed.headOption.map(GachaEventName)
-        for {
-          gachaPrizes <- gachaPrizeAPI.allGachaPrizeList
-        } yield {
-          val gachaPrizeInformation = gachaPrizes
-            .filter { gachaPrize =>
-              if (eventName.isEmpty) gachaPrize.nonGachaEventItem
-              else
-                gachaPrize.gachaEvent.map(_.eventName) == eventName
-            }
+        Kleisli.liftF(gachaPrizeAPI.allGachaPrizeList).flatMap { gachaPrizes =>
+          val eventGachaPrizes = gachaPrizes.filter { gachaPrize =>
+            if (eventName.isEmpty) gachaPrize.nonGachaEventItem
+            else
+              gachaPrize.gachaEvent.map(_.eventName) == eventName
+          }
+
+          val gachaPrizeInformation = eventGachaPrizes
             .sortBy(_.id.id)
             .map { gachaPrize =>
               val itemStack = gachaPrize.itemStack
               val probability = gachaPrize.probability.value
 
-              s"${gachaPrize.id.id}|${itemStack.getType.toString}/${itemStack
-                  .getItemMeta
-                  .getDisplayName}$RESET|${itemStack.getAmount}|$probability(${probability * 100}%)"
+              s"${gachaPrize.id.id}|${itemStack.getType.toString}/${itemStack.getItemMeta.getDisplayName}$RESET|${itemStack.getAmount}|$probability(${probability * 100}%)"
             }
             .toList
 
-          val totalProbability = gachaPrizes.map(_.probability.value).sum
-          MessageEffect(
+          val totalProbability = eventGachaPrizes.map(_.probability.value).sum
+          MessageEffectF(
             List(s"${RED}アイテム番号|アイテム名|アイテム数|出現確率") ++ gachaPrizeInformation ++ List(
               s"${RED}合計確率: $totalProbability(${totalProbability * 100}%)",
               s"${RED}合計確率は100%以内に収まるようにしてください。"
@@ -279,15 +282,15 @@ class GachaCommand[F[_]: OnMinecraftServerThread: ConcurrentEffect](
           MessageEffect("IDは正の値を指定してください。")
         )
       )
-      .buildWithExecutionF { context =>
+      .buildWithExecutionCSEffect { context =>
         val gachaId = GachaPrizeId(context.args.parsed.head)
-        for {
-          didRemoveGachaPrize <- gachaPrizeAPI.removeByGachaPrizeId(gachaId)
-        } yield {
-          if (didRemoveGachaPrize)
-            MessageEffect(List("ガチャアイテムを削除しました"))
-          else
-            MessageEffect("指定されたIDのガチャ景品が存在しないため、ガチャアイテムを削除できませんでした。")
+        Kleisli.liftF(gachaPrizeAPI.removeByGachaPrizeId(gachaId)).flatMap {
+          didRemoveGachaPrize =>
+            if (didRemoveGachaPrize) {
+              MessageEffectF("ガチャアイテムを削除しました")
+            } else {
+              MessageEffectF("指定されたIDのガチャ景品が存在しないため、ガチャアイテムを削除できませんでした。")
+            }
         }
       }
 
@@ -302,53 +305,56 @@ class GachaCommand[F[_]: OnMinecraftServerThread: ConcurrentEffect](
             MessageEffect("数は1~64で指定してください。")
           )
         )
-        .buildWithExecutionF { context =>
+        .buildWithExecutionCSEffect { context =>
           import shapeless.::
           val targetId :: amount :: HNil = context.args.parsed
-          for {
-            currentGachaPrize <- gachaPrizeAPI.fetch(targetId)
-            oldItemStack <- currentGachaPrize.traverse { prize =>
-              gachaPrizeAPI
-                .upsertGachaPrize(
-                  prize.copy(itemStack = prize.itemStack.tap(_.setAmount(amount)))
-                )
-                .as(Some(prize.itemStack))
-            }
-          } yield {
-            oldItemStack match {
+
+          Kleisli
+            .liftF(for {
+              currentGachaPrize <- gachaPrizeAPI.fetch(targetId)
+              oldItemStack <- currentGachaPrize.traverse { prize =>
+                gachaPrizeAPI
+                  .upsertGachaPrize(
+                    prize.copy(itemStack = prize.itemStack.tap(_.setAmount(amount)))
+                  )
+                  .as(Some(prize.itemStack))
+              }
+            } yield oldItemStack)
+            .flatMap {
               case Some(itemStack) =>
-                MessageEffect(
+                MessageEffectF(
                   s"${targetId.id}|${itemStack.get.getType.toString}/${itemStack.get.getItemMeta.getDisplayName}${RESET}のアイテム数を${amount}個に変更しました。"
                 )
               case None =>
-                MessageEffect("指定されたIDのガチャ景品が存在しないため、アイテム数が変更できませんでした。")
+                MessageEffectF("指定されたIDのガチャ景品が存在しないため、アイテム数が変更できませんでした。")
             }
-          }
         }
 
     val setProbability: ContextualExecutor = ContextualExecutorBuilder
       .beginConfiguration
       .thenParse(gachaPrizeIdExistsParser)
       .thenParse(probabilityParser)
-      .buildWithExecutionF { context =>
+      .buildWithExecutionCSEffect { context =>
         import shapeless.::
         val targetId :: newProb :: HNil = context.args.parsed
-        for {
-          currentGachaPrize <- gachaPrizeAPI.fetch(targetId)
-          probabilityChange <- currentGachaPrize.traverse { gachaPrize =>
-            gachaPrizeAPI.upsertGachaPrize(
-              gachaPrize.copy(probability = GachaProbability(newProb))
-            )
-          }
+
+        (for {
+          currentGachaPrize <- Kleisli.liftF(gachaPrizeAPI.fetch(targetId))
+          probabilityChange <- Kleisli.liftF(currentGachaPrize.traverse { gachaPrize =>
+            gachaPrizeAPI
+              .upsertGachaPrize(gachaPrize.copy(probability = GachaProbability(newProb)))
+          })
           itemStack = currentGachaPrize.map(_.itemStack)
         } yield {
-          if (probabilityChange.nonEmpty)
-            MessageEffect(
+          if (probabilityChange.nonEmpty) {
+            MessageEffectF(
               s"${targetId.id}|${itemStack.get.getType.toString}/${itemStack.get.getItemMeta.getDisplayName}${RESET}の確率を$newProb(${newProb * 100}%)に変更しました。"
             )
-          else
-            MessageEffect("指定されたIDのガチャ景品は存在しません。")
-        }
+          } else {
+            MessageEffectF("指定されたIDのガチャ景品は存在しません。")
+          }
+        }).flatten
+
       }
 
     val createEvent: ContextualExecutor =
@@ -357,7 +363,7 @@ class GachaCommand[F[_]: OnMinecraftServerThread: ConcurrentEffect](
         .thenParse(Parsers.identity)
         .thenParse(Parsers.identity)
         .thenParse(Parsers.identity)
-        .buildWithExecutionF { context =>
+        .buildWithExecutionCSEffect { context =>
           import shapeless.::
           val e :: startDate :: endDate :: HNil = context.args.parsed
           val eventName = GachaEventName(e)
@@ -366,38 +372,43 @@ class GachaCommand[F[_]: OnMinecraftServerThread: ConcurrentEffect](
           val dateRegex = "[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])".r
 
           if (!dateRegex.matches(startDate) || !dateRegex.matches(endDate)) {
-            Effect[F].pure(MessageEffect(s"${RED}開始日/終了日はyyyy-MM-ddの形式で指定してください。"))
+            MessageEffectF(s"${RED}開始日/終了日はyyyy-MM-ddの形式で指定してください。")
           } else if (eventName.name.length > 30) {
-            Effect[F].pure(MessageEffect(s"${RED}イベント名は30字以内で指定してください。"))
-          } else {
-            for {
-              existsEvent <- gachaPrizeAPI.existsGachaEvent(eventName)
-              _ <- gachaPrizeAPI
-                .createGachaEvent(
-                  GachaEvent(
-                    eventName,
-                    LocalDate.parse(startDate, dateTimeFormatter),
-                    LocalDate.parse(endDate, dateTimeFormatter)
-                  )
+            MessageEffectF(s"${RED}イベント名は30字以内で指定してください。")
+          } else
+            {
+              for {
+                existsEvent <- Kleisli.liftF(gachaPrizeAPI.existsGachaEvent(eventName))
+                _ <- Kleisli.liftF(
+                  gachaPrizeAPI
+                    .createGachaEvent(
+                      GachaEvent(
+                        eventName,
+                        LocalDate.parse(startDate, dateTimeFormatter),
+                        LocalDate.parse(endDate, dateTimeFormatter)
+                      )
+                    )
+                    .unlessA(existsEvent)
                 )
-                .unlessA(existsEvent)
 
-            } yield {
-              if (existsEvent) MessageEffect(s"${RED}指定された名前のイベントが既に存在します。")
-              else MessageEffect(s"${AQUA}イベントを作成しました。")
-            }
-          }
+              } yield {
+                if (existsEvent) MessageEffectF(s"${RED}指定された名前のイベントが既に存在します。")
+                else MessageEffectF(s"${AQUA}イベントを作成しました。")
+              }
+            }.flatten
+
         }
 
     val deleteEvent: ContextualExecutor =
       ContextualExecutorBuilder
         .beginConfiguration
         .thenParse(Parsers.identity)
-        .buildWithExecutionF { context =>
+        .buildWithExecutionCSEffect { context =>
           val eventName = GachaEventName(context.args.parsed.head)
-          for {
-            _ <- gachaPrizeAPI.deleteGachaEvent(eventName)
-          } yield MessageEffect(s"ガチャイベント: ${eventName.name}を削除しました。")
+
+          Kleisli.liftF(gachaPrizeAPI.deleteGachaEvent(eventName)).flatMap { _ =>
+            MessageEffectF(s"ガチャイベント: ${eventName.name}を削除しました。")
+          }
         }
 
     private def toTimeString(localDate: LocalDate): String = {
@@ -406,16 +417,34 @@ class GachaCommand[F[_]: OnMinecraftServerThread: ConcurrentEffect](
     }
 
     val eventList: ContextualExecutor =
-      ContextualExecutorBuilder.beginConfiguration.buildWithExecutionF { _ =>
-        for {
-          events <- gachaPrizeAPI.createdGachaEvents
-        } yield {
+      ContextualExecutorBuilder.beginConfiguration.buildWithExecutionCSEffect { _ =>
+        Kleisli.liftF(gachaPrizeAPI.createdGachaEvents).flatMap { events =>
           val messages = "イベント名 | 開始日 | 終了日" +: events.map { event =>
             s"${event.eventName.name} | ${toTimeString(event.startDate)} | ${toTimeString(event.endDate)}"
           }
-          MessageEffect(messages.toList)
+
+          MessageEffectF(messages.toList)
         }
       }
+
+    val replaceGachaPrize: ContextualExecutor =
+      playerCommandBuilder.thenParse(gachaPrizeIdExistsParser).buildWithExecutionCSEffect {
+        context =>
+          import shapeless.::
+          val targetId :: HNil = context.args.parsed
+
+          Kleisli
+            .liftF[F, CommandSender, Unit] {
+              for {
+                gachaPrize <- gachaPrizeAPI.fetch(targetId)
+                mainHandItem <- Sync[F].delay(context.sender.getInventory.getItemInMainHand)
+                _ <- gachaPrize.traverse { prize =>
+                  gachaPrizeAPI.upsertGachaPrize(prize.copy(itemStack = mainHandItem))
+                }
+              } yield ()
+            }
+            .productR(MessageEffectF("ガチャ景品を置き換えました。"))
+      }
   }
 
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/bukkit/actions/BukkitDrawGacha.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/bukkit/actions/BukkitDrawGacha.scala
index 4277428df4..2306118995 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/bukkit/actions/BukkitDrawGacha.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/bukkit/actions/BukkitDrawGacha.scala
@@ -1,7 +1,7 @@
 package com.github.unchama.seichiassist.subsystems.gacha.bukkit.actions
 
-import cats.effect.{IO, Sync}
-import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts.onMainThread
+import cats.effect.{LiftIO, Sync}
+import com.github.unchama.minecraft.actions.{GetConnectedPlayers, OnMinecraftServerThread}
 import com.github.unchama.seichiassist.subsystems.gacha.application.actions.{
   DrawGacha,
   GrantGachaPrize
@@ -11,24 +11,28 @@ import com.github.unchama.seichiassist.subsystems.gachaprize.GachaPrizeAPI
 import com.github.unchama.seichiassist.subsystems.gachaprize.domain.GachaRarity._
 import com.github.unchama.seichiassist.util.SendMessageEffect.sendMessageToEveryone
 import com.github.unchama.seichiassist.util._
+import net.md_5.bungee.api.chat.hover.content.Text
 import net.md_5.bungee.api.chat.{HoverEvent, TextComponent}
 import org.bukkit.ChatColor._
 import org.bukkit.Sound
 import org.bukkit.entity.Player
 import org.bukkit.inventory.ItemStack
 
-class BukkitDrawGacha[F[_]: Sync](
+class BukkitDrawGacha[
+  F[_]: LiftIO: Sync: OnMinecraftServerThread: GetConnectedPlayers[*[_], Player]
+](
   implicit gachaPrizeAPI: GachaPrizeAPI[F, ItemStack, Player],
   lotteryOfGachaItems: LotteryOfGachaItems[F, ItemStack],
   grantGachaPrize: GrantGachaPrize[F, ItemStack, Player]
 ) extends DrawGacha[F, Player] {
 
-  import PlayerSendable._
   import cats.implicits._
 
   import scala.jdk.CollectionConverters._
 
   override def draw(player: Player, count: Int): F[Unit] = {
+    implicitly[PlayerSendable[TextComponent, F]]
+
     for {
       currentGachaPrizes <- gachaPrizeAPI.listOfNow
       gachaPrizes <- lotteryOfGachaItems.runLottery(count, currentGachaPrizes)
@@ -49,7 +53,7 @@ class BukkitDrawGacha[F[_]: Sync](
               val localizedEnchantmentList =
                 prizeItem.getItemMeta.getEnchants.asScala.toSeq.map {
                   case (enchantment, level) =>
-                    s"$GRAY${EnchantNameToJapanese.getEnchantName(enchantment.getName, level)}"
+                    s"$GRAY${EnchantNameToJapanese.getEnchantName(enchantment.getKey.toString, level)}"
                 }
 
               import scala.util.chaining._
@@ -62,13 +66,11 @@ class BukkitDrawGacha[F[_]: Sync](
                   setHoverEvent {
                     new HoverEvent(
                       HoverEvent.Action.SHOW_TEXT,
-                      Array(
-                        new TextComponent(
-                          s" ${prizeItem.getItemMeta.getDisplayName}\n" +
-                            ListFormatters.getDescFormat(localizedEnchantmentList.toList) +
-                            ListFormatters
-                              .getDescFormat(prizeItem.getItemMeta.getLore.asScala.toList)
-                        )
+                      new Text(
+                        s" ${prizeItem.getItemMeta.getDisplayName}\n" +
+                          ListFormatters.getDescFormat(localizedEnchantmentList.toList) +
+                          ListFormatters
+                            .getDescFormat(prizeItem.getItemMeta.getLore.asScala.toList)
                       )
                     )
                   }
@@ -76,16 +78,15 @@ class BukkitDrawGacha[F[_]: Sync](
               Sync[F].delay {
                 player.sendMessage(s"${RED}おめでとう!!!!!Gigantic☆大当たり!$additionalMessage")
                 player.spigot().sendMessage(message)
-                sendMessageToEveryone(s"$GOLD${player.getName}がガチャでGigantic☆大当たり!")(
-                  forString[IO]
-                )
-                sendMessageToEveryone(message)(forTextComponent[IO])
+              } >> Sync[F].delay {
                 SendSoundEffect.sendEverySoundWithoutIgnore(
-                  Sound.ENTITY_ENDERDRAGON_DEATH,
+                  Sound.ENTITY_ENDER_DRAGON_DEATH,
                   0.5f,
                   2f
                 )
-              }
+              } >> sendMessageToEveryone[String, F](
+                s"$GOLD${player.getName}がガチャでGigantic☆大当たり!"
+              )
             case GachaRarity.Big =>
               Sync[F].delay {
                 player.playSound(player.getLocation, Sound.ENTITY_WITHER_SPAWN, 0.8f, 1f)
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/bukkit/actions/BukkitGrantGachaPrize.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/bukkit/actions/BukkitGrantGachaPrize.scala
index a020a2faa3..2d7afa8cf0 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/bukkit/actions/BukkitGrantGachaPrize.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/bukkit/actions/BukkitGrantGachaPrize.scala
@@ -28,18 +28,15 @@ class BukkitGrantGachaPrize[F[_]: Sync: OnMinecraftServerThread](
     Kleisli { player =>
       for {
         currentAutoMineStackState <- mineStackAPI.autoMineStack(player)
-        results <- prizes.traverse { gachaPrize =>
-          val itemStack = gachaPrize.itemStack
-          whenAOrElse(currentAutoMineStackState)(
-            mineStackAPI
-              .mineStackRepository
-              .tryIntoMineStack(player, itemStack, itemStack.getAmount)
-              .map(hasBeenStoredInMineStack => gachaPrize -> hasBeenStoredInMineStack),
-            gachaPrize -> false
-          )
-        }
-      } yield results.collect {
-        case (gachaPrize, result) if !result => gachaPrize
+        itemStacks <- Sync[F].delay(prizes.map(_.materializeWithOwnerSignature(player.getName)))
+        intoFailedItemStacksAndSuccessItemStacks <- whenAOrElse(currentAutoMineStackState)(
+          mineStackAPI.mineStackRepository.tryIntoMineStack(player, itemStacks),
+          (itemStacks, Vector.empty)
+        )
+      } yield prizes.filter { prize =>
+        intoFailedItemStacksAndSuccessItemStacks
+          ._1
+          .exists(_.isSimilar(prize.materializeWithOwnerSignature(player.getName)))
       }
     }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/domain/LotteryOfGachaItems.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/domain/LotteryOfGachaItems.scala
index da1d282802..9c3b74d30d 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/domain/LotteryOfGachaItems.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/domain/LotteryOfGachaItems.scala
@@ -2,8 +2,8 @@ package com.github.unchama.seichiassist.subsystems.gacha.domain
 
 import cats.effect.Sync
 import com.github.unchama.seichiassist.subsystems.gachaprize.domain.{
-  GachaPrizeTableEntry,
   GachaPrizeId,
+  GachaPrizeTableEntry,
   GachaProbability,
   StaticGachaPrizeFactory
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/subsystems/gachaticket/infrastructure/JdbcGachaTicketFromAdminTeamRepository.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/subsystems/gachaticket/infrastructure/JdbcGachaTicketFromAdminTeamRepository.scala
index c5a181a819..3b4c44426a 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/subsystems/gachaticket/infrastructure/JdbcGachaTicketFromAdminTeamRepository.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gacha/subsystems/gachaticket/infrastructure/JdbcGachaTicketFromAdminTeamRepository.scala
@@ -26,7 +26,6 @@ class JdbcGachaTicketFromAdminTeamRepository[F[_]: Sync: NonServerThreadContextS
       DB.localTx { implicit session =>
         sql"update playerdata set numofsorryforbug = numofsorryforbug + ${amount.value}"
           .execute()
-          .apply()
       }
     }
   }
@@ -42,8 +41,7 @@ class JdbcGachaTicketFromAdminTeamRepository[F[_]: Sync: NonServerThreadContextS
       DB.localTx { implicit session =>
         val affectedRows =
           sql"UPDATE playerdata SET numofsorryforbug = numofsorryforbug + ${amount.value} WHERE name = ${playerName.name}"
-            .update
-            .apply()
+            .update()
 
         getReceiptResult(affectedRows)
       }
@@ -62,7 +60,6 @@ class JdbcGachaTicketFromAdminTeamRepository[F[_]: Sync: NonServerThreadContextS
         val affectedRows =
           sql"UPDATE playerdata SET numofsorryforbug = numofsorryforbug + ${amount.value} WHERE uuid = ${uuid.toString}"
             .update()
-            .apply()
 
         getReceiptResult(affectedRows)
       }
@@ -76,7 +73,6 @@ class JdbcGachaTicketFromAdminTeamRepository[F[_]: Sync: NonServerThreadContextS
           sql"SELECT numofsorryforbug FROM playerdata WHERE uuid = ${uuid.toString} FOR UPDATE"
             .map(_.int("numofsorryforbug"))
             .toList()
-            .apply()
             .headOption
             .getOrElse(0)
 
@@ -87,7 +83,6 @@ class JdbcGachaTicketFromAdminTeamRepository[F[_]: Sync: NonServerThreadContextS
         if (updatedAmount >= 0) {
           sql"UPDATE playerdata SET numofsorryforbug = numofsorryforbug - $receiveAmount WHERE uuid = ${uuid.toString}"
             .execute()
-            .apply()
         }
 
         GachaTicketAmount(receiveAmount)
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/GachaPointApi.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/GachaPointApi.scala
index 3549b054c7..e7153e2692 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/GachaPointApi.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/GachaPointApi.scala
@@ -15,7 +15,12 @@ trait GachaPointApi[F[_], G[_], Player] {
   /**
    * プレーヤーのガチャポイントをガチャ券に変換して一括で受け取る作用。
    */
-  val receiveBatch: Kleisli[F, Player, Unit]
+  val receiveLargeBatch: Kleisli[F, Player, Unit]
+
+  /**
+   * プレーヤーのガチャポイントをガチャ券に変換して一括で受け取る作用。
+   */
+  val receiveSmallBatch: Kleisli[F, Player, Unit]
 
   /**
    * プレーヤーのガチャポイントを増やす作用。
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/System.scala
index ca33d5777e..7138ed0d5a 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/System.scala
@@ -11,7 +11,7 @@ import com.github.unchama.generic.ContextCoercion
 import com.github.unchama.generic.effect.EffectExtra
 import com.github.unchama.generic.effect.concurrent.ReadOnlyRef
 import com.github.unchama.generic.effect.stream.StreamExtra
-import com.github.unchama.minecraft.actions.{GetConnectedPlayers, OnMinecraftServerThread}
+import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.meta.subsystem.Subsystem
 import com.github.unchama.seichiassist.subsystems.breakcount.BreakCountReadAPI
 import com.github.unchama.seichiassist.subsystems.gachapoint.application.process.AddSeichiExpAsGachaPoint
@@ -20,6 +20,7 @@ import com.github.unchama.seichiassist.subsystems.gachapoint.bukkit.GrantBukkitG
 import com.github.unchama.seichiassist.subsystems.gachapoint.domain.GrantGachaTicketToAPlayer
 import com.github.unchama.seichiassist.subsystems.gachapoint.domain.gachapoint.GachaPoint
 import com.github.unchama.seichiassist.subsystems.gachapoint.infrastructure.JdbcGachaPointPersistence
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import io.chrisdavenport.log4cats.ErrorLogger
 import org.bukkit.entity.Player
 
@@ -34,11 +35,12 @@ object System {
   import cats.effect.implicits._
   import cats.implicits._
 
-  def wired[F[_]: ConcurrentEffect: Timer: GetConnectedPlayers[*[_], Player]: ErrorLogger, G[
+  def wired[F[_]: ConcurrentEffect: Timer: ErrorLogger, G[_]: SyncEffect: ContextCoercion[*[
     _
-  ]: SyncEffect: ContextCoercion[*[_], F]](
-    breakCountReadAPI: BreakCountReadAPI[F, G, Player]
-  )(implicit ioOnMainThread: OnMinecraftServerThread[IO]): G[System[F, G, Player]] = {
+  ], F]](breakCountReadAPI: BreakCountReadAPI[F, G, Player])(
+    implicit ioOnMainThread: OnMinecraftServerThread[IO],
+    playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
+  ): G[System[F, G, Player]] = {
     import com.github.unchama.minecraft.bukkit.algebra.BukkitPlayerHasUuid.instance
 
     val gachaPointPersistence = new JdbcGachaPointPersistence[G]
@@ -81,11 +83,18 @@ object System {
               ReadOnlyRef.fromRef(value.pointRef)
             )
 
-          override val receiveBatch: Kleisli[F, Player, Unit] = Kleisli { player =>
+          override val receiveLargeBatch: Kleisli[F, Player, Unit] = Kleisli { player =>
             gachaPointRepositoryControlsRepository
               .lift(player)
-              .traverse { value => value.semaphore.tryBatchTransaction }
-              .as(())
+              .traverse { _.semaphore.tryLargeBatchTransaction }
+              .void
+          }
+
+          override val receiveSmallBatch: Kleisli[F, Player, Unit] = Kleisli { player =>
+            gachaPointRepositoryControlsRepository
+              .lift(player)
+              .traverse { _.semaphore.trySmallBatchTransaction }
+              .void
           }
 
           override def addGachaPoint(point: GachaPoint): Kleisli[F, Player, Unit] =
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/application/process/AddSeichiExpAsGachaPoint.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/application/process/AddSeichiExpAsGachaPoint.scala
index d70733c303..f12b5e671f 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/application/process/AddSeichiExpAsGachaPoint.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/application/process/AddSeichiExpAsGachaPoint.scala
@@ -3,7 +3,6 @@ package com.github.unchama.seichiassist.subsystems.gachapoint.application.proces
 import cats.Applicative
 import cats.effect.concurrent.Ref
 import com.github.unchama.datarepository.KeyedDataRepository
-import com.github.unchama.minecraft.algebra.HasUuid
 import com.github.unchama.seichiassist.subsystems.breakcount.domain.level.SeichiExpAmount
 import com.github.unchama.seichiassist.subsystems.gachapoint.domain.gachapoint.GachaPoint
 
@@ -11,7 +10,7 @@ object AddSeichiExpAsGachaPoint {
 
   import cats.implicits._
 
-  def stream[F[_]: Applicative, Player: HasUuid](
+  def stream[F[_]: Applicative, Player](
     refRepository: KeyedDataRepository[Player, Ref[F, GachaPoint]]
   )(seichiExpStream: fs2.Stream[F, (Player, SeichiExpAmount)]): fs2.Stream[F, Unit] =
     seichiExpStream.evalMap {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/bukkit/GrantBukkitGachaTicketToAPlayer.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/bukkit/GrantBukkitGachaTicketToAPlayer.scala
index 2e42af0aa2..bd0791ed2b 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/bukkit/GrantBukkitGachaTicketToAPlayer.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/bukkit/GrantBukkitGachaTicketToAPlayer.scala
@@ -4,6 +4,7 @@ import cats.effect.{IO, LiftIO}
 import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.subsystems.gachaprize.bukkit.factories.BukkitGachaSkullData
 import com.github.unchama.seichiassist.subsystems.gachapoint.domain.GrantGachaTicketToAPlayer
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.util.InventoryOperations
 import com.github.unchama.targetedeffect.SequentialEffect
 import com.github.unchama.targetedeffect.TargetedEffect.emptyEffect
@@ -14,7 +15,8 @@ import org.bukkit.Sound
 import org.bukkit.entity.Player
 
 case class GrantBukkitGachaTicketToAPlayer[F[_]: LiftIO](player: Player)(
-  implicit ioOnMainThread: OnMinecraftServerThread[IO]
+  implicit ioOnMainThread: OnMinecraftServerThread[IO],
+  playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
 ) extends GrantGachaTicketToAPlayer[F] {
 
   override def give(count: Int): F[Unit] = {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/domain/BatchUsageSemaphore.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/domain/BatchUsageSemaphore.scala
index b34aba3816..fc2281ceae 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/domain/BatchUsageSemaphore.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/domain/BatchUsageSemaphore.scala
@@ -18,15 +18,24 @@ class BatchUsageSemaphore[F[_]: FlatMap, G[_]: ContextCoercion[*[_], F]](
   import cats.implicits._
 
   /**
-   * バッチでのガチャポイント変換を行い、 [[BatchUsageSemaphore.usageInterval]]の間使用不可にする作用。
+   * 576個(= 64 * 9スタック)のバッチでガチャポイント変換を行い、 [[BatchUsageSemaphore.usageInterval]]の間使用不可にする作用。
    */
-  def tryBatchTransaction: F[Unit] =
+  def tryLargeBatchTransaction: F[Unit] =
     recoveringSemaphore.tryUse {
       ContextCoercion {
-        gachaPointRef.modify { point => point.useInBatch.asTuple }
+        gachaPointRef.modify { _.useInLargeBatch.asTuple }
       }.flatTap(grantAction.give)
     }(BatchUsageSemaphore.usageInterval)
 
+  /**
+   * 64個(= 64 * 1スタック)のバッチでガチャポイント変換を行い、 [[BatchUsageSemaphore.usageInterval]]の間使用不可にする作用。
+   */
+  def trySmallBatchTransaction: F[Unit] =
+    recoveringSemaphore.tryUse {
+      ContextCoercion {
+        gachaPointRef.modify { _.useInSmallBatch.asTuple }
+      }.flatTap(grantAction.give)
+    }(BatchUsageSemaphore.usageInterval)
 }
 
 object BatchUsageSemaphore {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/domain/gachapoint/GachaPoint.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/domain/gachapoint/GachaPoint.scala
index 06f7c62021..acbb80be42 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/domain/gachapoint/GachaPoint.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/domain/gachapoint/GachaPoint.scala
@@ -5,7 +5,7 @@ import com.github.unchama.seichiassist.subsystems.breakcount.domain.level.Seichi
 /**
  * ガチャポイントとはプレーヤーが持つ「消費可能な整地経験量」である。
  *
- * プレーヤーは576個(= 64 * 9スタック)のバッチにてガチャポイントをガチャ券に交換できる。
+ * プレーヤーは576個(= 64 * 9スタック)のバッチもしくは、64個(1スタック)のバッチにてガチャポイントをガチャ券に交換できる。
  */
 case class GachaPoint(exp: SeichiExpAmount) {
 
@@ -18,8 +18,8 @@ case class GachaPoint(exp: SeichiExpAmount) {
   /**
    * ガチャポイントをバッチでガチャ券に変換した際のポイントの変化を計算する。
    */
-  lazy val useInBatch: GachaPoint.Usage = {
-    val ticketCount = availableTickets.min(GachaPoint.batchSize).toInt
+  private def useInBatch(batchSize: BatchSize): GachaPoint.Usage = {
+    val ticketCount = availableTickets.min(batchSize.value).toInt
 
     val expToUse = GachaPoint.perGachaTicket.exp.amount * ticketCount
     val remaining = GachaPoint.ofNonNegative(exp.amount - expToUse)
@@ -27,6 +27,16 @@ case class GachaPoint(exp: SeichiExpAmount) {
     GachaPoint.Usage(remaining, ticketCount)
   }
 
+  /**
+   * ガチャポイントを576個(= 64 * 9スタック)のバッチでガチャ券に変換した際のポイントの変化を計算する。
+   */
+  lazy val useInLargeBatch: GachaPoint.Usage = useInBatch(GachaPoint.largeBatchSize)
+
+  /**
+   * ガチャポイントを64個(= 64 * 1スタック)のバッチでガチャ券に変換した際のポイントの変化を計算する。
+   */
+  lazy val useInSmallBatch: GachaPoint.Usage = useInBatch(GachaPoint.smallBatchSize)
+
   /**
    * 次にガチャ券を利用できるようになるまでに必要な整地経験値量
    */
@@ -42,6 +52,10 @@ case class GachaPoint(exp: SeichiExpAmount) {
   def subtract(point: GachaPoint): GachaPoint = GachaPoint(exp.subtract(point.exp))
 }
 
+case class BatchSize(value: Int) {
+  require(value > 0, "batch size must be positive")
+}
+
 object GachaPoint {
 
   def ofNonNegative(x: BigDecimal): GachaPoint = GachaPoint(SeichiExpAmount.ofNonNegative(x))
@@ -54,15 +68,28 @@ object GachaPoint {
    *   変換にて得られるガチャ券の総数
    */
   case class Usage(remainingGachaPoint: GachaPoint, gachaTicketCount: Int) {
-    require(gachaTicketCount <= GachaPoint.batchSize, "usage must not exceed batch size")
+    require(
+      gachaTicketCount <= GachaPoint.maxBatchSize.value,
+      "usage must not exceed max batch size"
+    )
 
     def asTuple: (GachaPoint, Int) = (remainingGachaPoint, gachaTicketCount)
   }
 
+  /**
+   * ガチャ券を576個(= 64 * 9スタック)のバッチでガチャポイントに変換する際のバッチサイズ
+   */
+  final val largeBatchSize = BatchSize(9 * 64)
+
+  /**
+   * ガチャ券を64個(= 64 * 1スタック)のバッチでガチャポイントに変換する際のバッチサイズ
+   */
+  final val smallBatchSize = BatchSize(64)
+
   /**
    * ガチャ券へのポイント交換にて一度に得られるガチャ券の上限
    */
-  final val batchSize = 9 * 64
+  final val maxBatchSize = largeBatchSize
 
   /**
    * ガチャポイントの初期値
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/infrastructure/JdbcGachaPointPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/infrastructure/JdbcGachaPointPersistence.scala
index 405d324c9d..b4d3c217d2 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/infrastructure/JdbcGachaPointPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachapoint/infrastructure/JdbcGachaPointPersistence.scala
@@ -21,7 +21,6 @@ class JdbcGachaPointPersistence[F[_]: Sync] extends GachaPointPersistence[F] {
       sql"select gachapoint from playerdata where uuid = ${key.toString}"
         .map { rs => decode(rs.bigInt("gachapoint")) }
         .headOption()
-        .apply()
     }
   }
 
@@ -29,7 +28,6 @@ class JdbcGachaPointPersistence[F[_]: Sync] extends GachaPointPersistence[F] {
     DB.localTx { implicit session =>
       sql"update playerdata set gachapoint = ${encode(value)} where uuid = ${key.toString}"
         .update()
-        .apply()
     }
   }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/bukkit/factories/BukkitGachaSkullData.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/bukkit/factories/BukkitGachaSkullData.scala
index 816a4acda3..e5a46b08c5 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/bukkit/factories/BukkitGachaSkullData.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/bukkit/factories/BukkitGachaSkullData.scala
@@ -1,76 +1,39 @@
 package com.github.unchama.seichiassist.subsystems.gachaprize.bukkit.factories
 
-import com.github.unchama.seichiassist.util.ItemMetaFactory
+import com.github.unchama.itemstackbuilder.SkullItemStackBuilder
+import com.github.unchama.seichiassist.SkullOwners
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import org.bukkit.ChatColor._
-import org.bukkit.Material
 import org.bukkit.inventory.ItemStack
+import cats.effect.IO
+import org.bukkit.entity.Player
 
 object BukkitGachaSkullData {
 
-  import scala.jdk.CollectionConverters._
-  import scala.util.chaining._
-
   /**
    * ノーマルガチャ券
    */
-  val gachaSkull: ItemStack =
-    new ItemStack(Material.SKULL_ITEM, 1).tap { skull =>
-      import skull._
-      setDurability(3)
-      setItemMeta {
-        ItemMetaFactory.SKULL.getValue.tap { meta =>
-          import meta._
-          setDisplayName(s"$YELLOW${BOLD}ガチャ券")
-          setLore {
-            List(s"$RESET${GREEN}右クリックで使えます").asJava
-          }
-
-          // 参加したことのないプレーヤーはgetOfflinePlayerでデータが取れないのでこうするしか無い
-          setOwner("unchama")
-        }
-      }
-    }
+  def gachaSkull(implicit playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]): ItemStack =
+    new SkullItemStackBuilder(SkullOwners.unchama)
+      .title(s"$YELLOW${BOLD}ガチャ券")
+      .lore(List(s"$RESET${GREEN}右クリックで使えます"))
+      .build()
 
   /**
    * 投票報酬のガチャ券
    */
-  val gachaForVoting: ItemStack =
-    new ItemStack(Material.SKULL_ITEM, 1).tap { itemStack =>
-      import itemStack._
-      setDurability(3)
-      setItemMeta {
-        ItemMetaFactory.SKULL.getValue.tap { meta =>
-          import meta._
-          setDisplayName(s"$YELLOW${BOLD}ガチャ券")
-          setLore {
-            List(s"$RESET${GREEN}右クリックで使えます", s"$RESET${LIGHT_PURPLE}投票ありがとナス♡").asJava
-          }
-
-          // 参加したことのないプレーヤーはgetOfflinePlayerでデータが取れないのでこうするしか無い
-          setOwner("unchama")
-        }
-      }
-    }
+  def gachaForVoting(implicit playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]): ItemStack =
+    new SkullItemStackBuilder(SkullOwners.unchama)
+      .title(s"$YELLOW${BOLD}ガチャ券")
+      .lore(List(s"$RESET${GREEN}右クリックで使えます", s"$RESET${LIGHT_PURPLE}投票ありがとナス♡"))
+      .build()
 
   /**
    * ガチャ景品(当たり・大当たり)とガチャ券の交換システムで手に入るガチャ券
    */
-  val gachaForExchanging: ItemStack = {
-    new ItemStack(Material.SKULL_ITEM, 1).tap { itemStack =>
-      import itemStack._
-      setDurability(3)
-      setItemMeta {
-        ItemMetaFactory.SKULL.getValue.tap { meta =>
-          import meta._
-          setDisplayName(s"$YELLOW${BOLD}ガチャ券")
-          setLore {
-            List(s"$RESET${GREEN}右クリックで使えます", s"$RESET${GRAY}ガチャ景品と交換しました。").asJava
-          }
-
-          // 参加したことのないプレーヤーはgetOfflinePlayerでデータが取れないのでこうするしか無い
-          setOwner("unchama")
-        }
-      }
-    }
-  }
+  def gachaForExchanging(implicit playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]): ItemStack =
+    new SkullItemStackBuilder(SkullOwners.unchama)
+      .title(s"$YELLOW${BOLD}ガチャ券")
+      .lore(List(s"$RESET${GREEN}右クリックで使えます", s"$RESET${GRAY}ガチャ景品と交換しました。"))
+      .build()
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/bukkit/factories/BukkitStaticGachaPrizeFactory.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/bukkit/factories/BukkitStaticGachaPrizeFactory.scala
index e15fd197ad..e4c082226f 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/bukkit/factories/BukkitStaticGachaPrizeFactory.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/bukkit/factories/BukkitStaticGachaPrizeFactory.scala
@@ -28,10 +28,10 @@ object BukkitStaticGachaPrizeFactory extends StaticGachaPrizeFactory[ItemStack]
       setItemMeta(meta)
   }
 
-  override val expBottle: ItemStack = new ItemStack(Material.EXP_BOTTLE, 20)
+  override val expBottle: ItemStack = new ItemStack(Material.EXPERIENCE_BOTTLE, 20)
 
   override val mineHeadItem: ItemStack =
-    new ItemStack(Material.CARROT_STICK, 1, 1.toShort).tap { itemStack =>
+    new ItemStack(Material.CARROT_ON_A_STICK, 1).tap { itemStack =>
       import itemStack._
       val meta = getItemMeta
       meta.setDisplayName(s"${DARK_RED}死神の鎌")
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/domain/GachaRarity.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/domain/GachaRarity.scala
index c5983cb395..02871e6ec8 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/domain/GachaRarity.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/domain/GachaRarity.scala
@@ -38,11 +38,15 @@ object GachaRarity {
     override def values: IndexedSeq[GachaRarity] = findValues
 
     def of[ItemStack](gachaPrize: GachaPrizeTableEntry[ItemStack]): GachaRarity =
+      fromGachaProbability(gachaPrize.probability)
+
+    def fromGachaProbability(gachaProbability: GachaProbability): GachaRarity = {
       GachaRarity
         .values
-        .filter { rarity => rarity.probabilityUpperLimit.value > gachaPrize.probability.value }
+        .filter(rarity => rarity.probabilityUpperLimit.value > gachaProbability.value)
         .minByOption(_.probabilityUpperLimit.value)
         .getOrElse(GachaRingoOrExpBottle)
+    }
 
   }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/infrastructure/JdbcGachaEventPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/infrastructure/JdbcGachaEventPersistence.scala
index e38215dc90..345ccc945f 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/infrastructure/JdbcGachaEventPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/infrastructure/JdbcGachaEventPersistence.scala
@@ -17,13 +17,13 @@ class JdbcGachaEventPersistence[F[_]: Sync] extends GachaEventPersistence[F] {
         sql"""INSERT INTO gacha_events 
              | (event_name, event_start_time, event_end_time) VALUES 
              | (${gachaEvent.eventName.name}, ${gachaEvent.startDate}, ${gachaEvent.endDate})
-           """.stripMargin.execute().apply()
+           """.stripMargin.execute()
       }
     }
 
   override def deleteGachaEvent(eventName: GachaEventName): F[Unit] = Sync[F].delay {
     DB.localTx { implicit session =>
-      sql"DELETE FROM gacha_events WHERE event_name = ${eventName.name}".execute().apply()
+      sql"DELETE FROM gacha_events WHERE event_name = ${eventName.name}".execute()
     }
   }
 
@@ -38,7 +38,6 @@ class JdbcGachaEventPersistence[F[_]: Sync] extends GachaEventPersistence[F] {
           )
         }
         .toList()
-        .apply()
         .toVector
     }
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/infrastructure/JdbcGachaPrizeListPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/infrastructure/JdbcGachaPrizeListPersistence.scala
index bf9356bcb1..34f0e7ea4d 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/infrastructure/JdbcGachaPrizeListPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gachaprize/infrastructure/JdbcGachaPrizeListPersistence.scala
@@ -48,7 +48,6 @@ class JdbcGachaPrizeListPersistence[F[_]: Sync, ItemStack: Cloneable](
               .merge
           }
           .toList()
-          .apply()
           .toVector
       }
     }
@@ -61,7 +60,6 @@ class JdbcGachaPrizeListPersistence[F[_]: Sync, ItemStack: Cloneable](
           sql"SELECT id FROM gacha_events WHERE event_name = ${gachaEvent.eventName.name}"
             .map(_.int("id"))
             .single()
-            .apply()
         }
 
         val serializedItemStack = serializeAndDeserialize.serialize(gachaPrize.itemStack)
@@ -76,13 +74,13 @@ class JdbcGachaPrizeListPersistence[F[_]: Sync, ItemStack: Cloneable](
              | ON DUPLICATE KEY UPDATE
              |   probability = ${gachaPrize.probability.value},
              |   itemstack = $serializedItemStack
-         """.stripMargin.execute().apply()
+         """.stripMargin.execute()
       }
     }
 
   override def removeGachaPrize(gachaPrizeId: GachaPrizeId): F[Unit] = Sync[F].delay {
     DB.localTx { implicit session =>
-      sql"DELETE FROM gachadata WHERE id = ${gachaPrizeId.id}".execute().apply()
+      sql"DELETE FROM gachadata WHERE id = ${gachaPrizeId.id}".execute()
     }
   }
 
@@ -93,7 +91,7 @@ class JdbcGachaPrizeListPersistence[F[_]: Sync, ItemStack: Cloneable](
       sql"""INSERT INTO gachadata (probability, itemstack, event_id)
            | (SELECT probability, itemstack, (SELECT id FROM gacha_events WHERE event_name = $eventName) FROM gachadata
            | WHERE event_id IS NULL)
-         """.stripMargin.execute().apply()
+         """.stripMargin.execute()
     }
   }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/bukkit/BukkitRegionOperations.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/bukkit/BukkitRegionOperations.scala
index 9ab2c05318..ec789febc2 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/bukkit/BukkitRegionOperations.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/bukkit/BukkitRegionOperations.scala
@@ -8,6 +8,8 @@ import com.github.unchama.seichiassist.subsystems.gridregion.domain.CardinalDire
 import com.github.unchama.seichiassist.subsystems.gridregion.domain.HorizontalAxisAlignedSubjectiveDirection.Ahead
 import com.github.unchama.seichiassist.subsystems.gridregion.domain._
 import com.github.unchama.util.external.{WorldEditWrapper, WorldGuardWrapper}
+import com.sk89q.worldedit.math.BlockVector3
+import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion
 import org.bukkit.Location
 import org.bukkit.entity.Player
 
@@ -72,21 +74,16 @@ class BukkitRegionOperations[F[_]: Sync](
 
   override def tryCreatingSelectedWorldGuardRegion(player: Player): F[Unit] = for {
     regionCount <- regionCountRepository(player).get
+    wgManager = WorldGuardWrapper.getRegionManager(player.getWorld)
+    selection = WorldEditWrapper.getSelection(player)
+    regionName = s"${player.getName}_${regionCount.value}"
+    region = new ProtectedCuboidRegion(
+      regionName,
+      BlockVector3.at(selection.getBlockX, -64, selection.getBlockZ),
+      BlockVector3.at(selection.getBlockX, 320, selection.getBlockZ)
+    )
     regionCreateResult <- Sync[F].delay {
-      WorldEditWrapper
-        .getSelection(player)
-        .map { selection =>
-          val regionName = s"${player.getName}_${regionCount.value}"
-
-          WorldGuardWrapper.tryCreateRegion(
-            regionName,
-            player,
-            player.getWorld,
-            selection.getNativeMinimumPoint.toBlockVector,
-            selection.getNativeMaximumPoint.toBlockVector
-          )
-        }
-        .getOrElse(())
+      wgManager.addRegion(region)
     }
     _ <- regionCountRepository(player).update(_.increment)
   } yield regionCreateResult
@@ -103,27 +100,18 @@ class BukkitRegionOperations[F[_]: Sync](
       result <-
         if (!SeichiAssist.seichiAssistConfig.isGridProtectionEnabled(world)) {
           Sync[F].pure(RegionCreationResult.WorldProhibitsRegionCreation)
-        } else if (selection.isEmpty || wgManager.isEmpty) {
+        } else if (regionCount.value >= WorldGuardWrapper.getWorldMaxRegion(player.getWorld)) {
           Sync[F].pure(RegionCreationResult.Error)
         } else {
           Sync[F].delay {
-            val regions = WorldGuardWrapper.getApplicableRegionCount(
-              world,
-              s"${player.getName}_${regionCount.value}",
-              selection.get.getNativeMinimumPoint.toBlockVector,
-              selection.get.getNativeMaximumPoint.toBlockVector
-            )
-            if (regions != 0) {
+            wgManager.getApplicableRegions(selection)
+            val maxRegionCount = WorldGuardWrapper.getWorldMaxRegion(world)
+            val regionCountPerPlayer = WorldGuardWrapper.getNumberOfRegions(player, world)
+
+            if (maxRegionCount >= 0 && regionCountPerPlayer >= maxRegionCount) {
               RegionCreationResult.Error
             } else {
-              val maxRegionCount = WorldGuardWrapper.getMaxRegionCount(player, world)
-              val regionCountPerPlayer = WorldGuardWrapper.getRegionCountOfPlayer(player, world)
-
-              if (maxRegionCount >= 0 && regionCountPerPlayer >= maxRegionCount) {
-                RegionCreationResult.Error
-              } else {
-                RegionCreationResult.Success
-              }
+              RegionCreationResult.Success
             }
           }
         }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/domain/RegionShapeSelectionState.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/domain/RegionShapeSelectionState.scala
index da0a661d4f..ef30ba2922 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/domain/RegionShapeSelectionState.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/domain/RegionShapeSelectionState.scala
@@ -3,7 +3,7 @@ package com.github.unchama.seichiassist.subsystems.gridregion.domain
 import cats.effect.Sync
 import cats.effect.concurrent.Ref
 
-class RegionShapeSelectionState[F[_]: Sync] private (
+class RegionShapeSelectionState[F[_]] private (
   private val regionUnitsReference: Ref[F, SubjectiveRegionShape]
 ) {
   def currentShape: F[SubjectiveRegionShape] = regionUnitsReference.get
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/infrastructure/JdbcRegionCountPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/infrastructure/JdbcRegionCountPersistence.scala
index 5516824da7..d90f4149c9 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/infrastructure/JdbcRegionCountPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/infrastructure/JdbcRegionCountPersistence.scala
@@ -13,7 +13,6 @@ class JdbcRegionCountPersistence[F[_]: Sync] extends RegionCountPersistence[F] {
     DB.localTx { implicit session =>
       sql"UPDATE playerdata SET rgnum = ${regionCount.value} WHERE uuid = ${uuid.toString}"
         .execute()
-        .apply()
     }
   }
 
@@ -22,7 +21,6 @@ class JdbcRegionCountPersistence[F[_]: Sync] extends RegionCountPersistence[F] {
       sql"SELECT rgnum FROM playerdata WHERE uuid = ${uuid.toString}"
         .map(_.int("rgnum"))
         .single()
-        .apply()
         .map(num => RegionCount(num))
     }
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/infrastructure/JdbcRegionTemplatePersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/infrastructure/JdbcRegionTemplatePersistence.scala
index d5eb163761..c28eea4480 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/infrastructure/JdbcRegionTemplatePersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/gridregion/infrastructure/JdbcRegionTemplatePersistence.scala
@@ -33,7 +33,6 @@ class JdbcRegionTemplatePersistence[F[_]: Sync] extends RegionTemplatePersistenc
           RegionTemplate(id, regionUnits)
         }
         .toList()
-        .apply()
         .toVector
     }
   }
@@ -56,7 +55,7 @@ class JdbcRegionTemplatePersistence[F[_]: Sync] extends RegionTemplatePersistenc
              |  right_length = ${value.shape.right.rul}
              |  behind_length = ${value.shape.behind.rul}
              |  left_length = ${value.shape.left.rul}
-           """.stripMargin.execute().apply()
+           """.stripMargin.execute()
       }
     }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/home/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/home/System.scala
index 206e487bbd..3512ce47c7 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/home/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/home/System.scala
@@ -1,6 +1,6 @@
 package com.github.unchama.seichiassist.subsystems.home
 
-import cats.effect.{ConcurrentEffect, SyncEffect}
+import cats.effect.ConcurrentEffect
 import com.github.unchama.concurrent.NonServerThreadContextShift
 import com.github.unchama.generic.ContextCoercion
 import com.github.unchama.minecraft.actions.OnMinecraftServerThread
@@ -26,7 +26,7 @@ trait System[F[_]] extends Subsystem[F] {
 object System {
   def wired[F[_]: OnMinecraftServerThread: ConcurrentEffect: NonServerThreadContextShift, G[
     _
-  ]: SyncEffect: ContextCoercion[*[_], F]](
+  ]: ContextCoercion[*[_], F]](
     implicit breakCountReadAPI: BreakCountReadAPI[F, G, Player],
     buildCountReadAPI: BuildCountAPI[F, G, Player]
   ): System[F] = {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/home/bukkit/command/HomeCommand.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/home/bukkit/command/HomeCommand.scala
index 5f963be5f9..fda7d28c29 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/home/bukkit/command/HomeCommand.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/home/bukkit/command/HomeCommand.scala
@@ -1,8 +1,9 @@
 package com.github.unchama.seichiassist.subsystems.home.bukkit.command
 
 import cats.Monad
+import cats.data.Kleisli
 import cats.effect.implicits._
-import cats.effect.{ConcurrentEffect, Effect, IO, SyncEffect}
+import cats.effect.{ConcurrentEffect, IO}
 import com.github.unchama.chatinterceptor.CancellationReason.Overridden
 import com.github.unchama.chatinterceptor.ChatInterceptionScope
 import com.github.unchama.concurrent.NonServerThreadContextShift
@@ -32,7 +33,7 @@ class HomeCommand[F[
   _
 ]: OnMinecraftServerThread: ConcurrentEffect: NonServerThreadContextShift: HomeAPI, G[
   _
-]: SyncEffect: ContextCoercion[*[_], F]](
+]: ContextCoercion[*[_], F]](
   implicit scope: ChatInterceptionScope,
   breakCountReadAPI: BreakCountReadAPI[F, G, Player],
   buildCountReadAPI: BuildCountAPI[F, G, Player]
@@ -86,11 +87,9 @@ class HomeCommand[F[
   private def listExecutor() = {
     // locationの座標は負の無限大方向へ切り捨て(Debug画面のBlock:で表示される座標と同じ丸め方)
     def toBlockPos(pos: Double) = pos.floor.toInt
-    playerCommandBuilder.buildWithExecutionF { context =>
+    playerCommandBuilder.buildWithExecutionCSEffect { context =>
       val player = context.sender
-      val eff = for {
-        homeMap <- HomeReadAPI[F].list(player.getUniqueId)
-      } yield {
+      Kleisli.liftF(HomeReadAPI[F].list(player.getUniqueId)).flatMap { homeMap =>
         val title = s"${RED}登録ホームポイント一覧:"
         val messages = title +: homeMap.toList.sortBy(_._1.value).map {
           case (homeId, home) =>
@@ -100,9 +99,8 @@ class HomeCommand[F[
               ManagedWorld.fromName(worldName).map(_.japaneseName).getOrElse(worldName)
             f"${YELLOW}ID ${homeId.value}%2d $displayWorldName(${toBlockPos(x)}, ${toBlockPos(y)}, ${toBlockPos(z)}): $displayHomeName"
         }
-        MessageEffect(messages)
+        MessageEffectF(messages)
       }
-      eff.toIO
     }
   }
 
@@ -129,35 +127,36 @@ class HomeCommand[F[
     }
 
   private def warpExecutor =
-    argsAndSenderConfiguredBuilder.buildWithExecutionF { context =>
+    argsAndSenderConfiguredBuilder.buildWithExecutionCSEffect { context =>
       val homeId = HomeId(context.args.parsed.head)
       val player = context.sender
 
       val eff = for {
-        maxAvailableHomeCount <- Home.maxAvailableHomeCountF(player)
-        isHomeAvailable = maxAvailableHomeCount >= homeId.value
-        _ <- NonServerThreadContextShift[F].shift
-        homeLocation <- HomeReadAPI[F].get(player.getUniqueId, homeId)
+        maxAvailableHomeCount <- Kleisli.liftF(Home.maxAvailableHomeCountF(player))
+        _ <- Kleisli.liftF(NonServerThreadContextShift[F].shift)
+        homeLocation <- Kleisli.liftF(HomeReadAPI[F].get(player.getUniqueId, homeId))
       } yield {
+        val isHomeAvailable = maxAvailableHomeCount >= homeId.value
+
         if (isHomeAvailable)
-          homeLocation.fold(MessageEffect(s"ホームポイント${homeId}が設定されてません"))(home => {
+          homeLocation.fold(MessageEffectF[F](s"ホームポイント${homeId}が設定されてません")) { home =>
             val location = home.location
             LocationCodec
               .toBukkitLocation(location)
               .fold(
-                MessageEffect(
+                MessageEffectF[F](
                   List(s"${RED}ホームポイントへのワープに失敗しました", s"${RED}登録先のワールドが削除された可能性があります")
                 )
               )(bukkitLocation =>
-                TeleportEffect.to[F](bukkitLocation).mapK(Effect.toIOK[F]) >>
-                  MessageEffect(s"ホームポイント${homeId}にワープしました")
+                TeleportEffect.to[F](bukkitLocation) >>
+                  MessageEffectF[F](s"ホームポイント${homeId}にワープしました")
               )
-          })
+          }
         else
-          MessageEffect(s"ホームポイント${homeId}は現在のレベルでは使用できません")
+          MessageEffectF[F](s"ホームポイント${homeId}は現在のレベルでは使用できません")
       }
 
-      eff.toIO
+      eff.flatten
     }
 
   def setHomeExecutor(): ContextualExecutor =
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/home/domain/Home.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/home/domain/Home.scala
index 2e4146ce0c..fb47de08d3 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/home/domain/Home.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/home/domain/Home.scala
@@ -1,6 +1,6 @@
 package com.github.unchama.seichiassist.subsystems.home.domain
 
-import cats.effect.{ConcurrentEffect, SyncEffect}
+import cats.effect.ConcurrentEffect
 import cats.implicits._
 import com.github.unchama.generic.ContextCoercion
 import com.github.unchama.seichiassist.subsystems.breakcount.BreakCountReadAPI
@@ -30,10 +30,9 @@ object Home {
   /**
    * プレイヤーの現在レベル(整地レベル、建築レベル)で利用可能なホームポイント数を取得する作用
    */
-  def maxAvailableHomeCountF[F[_]: ConcurrentEffect, G[_]: SyncEffect: ContextCoercion[
-    *[_],
-    F
-  ], Player](player: Player)(
+  def maxAvailableHomeCountF[F[_]: ConcurrentEffect, G[_]: ContextCoercion[*[_], F], Player](
+    player: Player
+  )(
     implicit breakCountReadAPI: BreakCountReadAPI[F, G, Player],
     buildCountReadAPI: BuildCountAPI[F, G, Player]
   ): F[Int] = {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/home/infrastructure/JdbcHomePersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/home/infrastructure/JdbcHomePersistence.scala
index f52c8e430a..d6906e49d9 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/home/infrastructure/JdbcHomePersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/home/infrastructure/JdbcHomePersistence.scala
@@ -36,7 +36,7 @@ class JdbcHomePersistence[F[_]: Sync: NonServerThreadContextShift] extends HomeP
              |      location_z = $z,
              |      pitch = $pitch,
              |      yaw = $yaw,
-             |      world_name = $worldName""".stripMargin.update().apply()
+             |      world_name = $worldName""".stripMargin.update()
       }
     }
 
@@ -67,7 +67,6 @@ class JdbcHomePersistence[F[_]: Sync: NonServerThreadContextShift] extends HomeP
           )
           .stripMargin
           .list()
-          .apply()
       }.toMap
     }
 
@@ -78,7 +77,7 @@ class JdbcHomePersistence[F[_]: Sync: NonServerThreadContextShift] extends HomeP
         sql"""delete from seichiassist.home 
              |  where server_id = $serverId 
              |  and player_uuid = ${ownerUuid.toString} 
-             |  and id = ${id.value - 1}""".stripMargin.execute().apply()
+             |  and id = ${id.value - 1}""".stripMargin.execute()
       }
     }
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/System.scala
index 257ef27139..01274ae312 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/System.scala
@@ -1,10 +1,9 @@
 package com.github.unchama.seichiassist.subsystems.itemmigration
 
-import cats.effect.{ConcurrentEffect, ContextShift, IO, Sync, SyncEffect, SyncIO}
+import cats.effect.{ConcurrentEffect, IO, Sync, SyncEffect, SyncIO}
 import com.github.unchama.datarepository.bukkit.player.BukkitRepositoryControls
 import com.github.unchama.datarepository.template.RepositoryDefinition
 import com.github.unchama.generic.ContextCoercion
-import com.github.unchama.generic.effect.unsafe.EffectEnvironment
 import com.github.unchama.itemmigration.application.ItemMigrationStateRepositoryDefinitions
 import com.github.unchama.itemmigration.bukkit.controllers.player.PlayerItemMigrationController
 import com.github.unchama.itemmigration.service.ItemMigrationService
@@ -32,9 +31,8 @@ object System {
 
   import cats.implicits._
 
-  def wired[F[_]: ConcurrentEffect: ContextShift, G[_]: SyncEffect: ContextCoercion[*[_], F]](
-    implicit effectEnvironment: EffectEnvironment,
-    logger: Logger
+  def wired[F[_]: ConcurrentEffect, G[_]: SyncEffect: ContextCoercion[*[_], F]](
+    implicit logger: Logger
   ): G[System[F]] = for {
     migrations <- Sync[G].delay {
       implicit val syncIOUuidRepository: UuidRepository[SyncIO] =
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/controllers/DatabaseMigrationController.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/controllers/DatabaseMigrationController.scala
index db43855190..cc797a51fa 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/controllers/DatabaseMigrationController.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/controllers/DatabaseMigrationController.scala
@@ -1,7 +1,6 @@
 package com.github.unchama.seichiassist.subsystems.itemmigration.controllers
 
 import cats.effect.{Sync, SyncEffect, SyncIO}
-import com.github.unchama.generic.effect.unsafe.EffectEnvironment
 import com.github.unchama.itemmigration.domain.ItemMigrations
 import com.github.unchama.itemmigration.service.ItemMigrationService
 import com.github.unchama.seichiassist.subsystems.itemmigration.infrastructure.loggers.PersistedItemsMigrationSlf4jLogger
@@ -11,8 +10,7 @@ import org.slf4j.Logger
 import scalikejdbc.DB
 
 case class DatabaseMigrationController[F[_]: SyncEffect](migrations: ItemMigrations)(
-  implicit effectEnvironment: EffectEnvironment,
-  logger: Logger
+  implicit logger: Logger
 ) {
 
   lazy val runDatabaseMigration: F[Unit] = Sync[F].delay {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/minecraft/JdbcBackedUuidRepository.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/minecraft/JdbcBackedUuidRepository.scala
index fc00e4b536..a79a461429 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/minecraft/JdbcBackedUuidRepository.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/minecraft/JdbcBackedUuidRepository.scala
@@ -3,7 +3,6 @@ package com.github.unchama.seichiassist.subsystems.itemmigration.infrastructure.
 import cats.Applicative
 import cats.effect.Sync
 import com.github.unchama.seichiassist.subsystems.itemmigration.domain.minecraft.UuidRepository
-import org.slf4j.Logger
 
 import java.util.UUID
 
@@ -33,7 +32,6 @@ object JdbcBackedUuidRepository {
           (rs.string("name").toLowerCase, UUID.fromString(rs.string("uuid")))
         }
         .list()
-        .apply()
         .toMap
     }
 
@@ -44,9 +42,7 @@ object JdbcBackedUuidRepository {
     }
   }
 
-  def initializeInstanceIn[F[_]: Sync, G[_]: Applicative](
-    implicit logger: Logger
-  ): F[UuidRepository[G]] = {
+  def initializeInstanceIn[F[_]: Sync, G[_]: Applicative]: F[UuidRepository[G]] = {
     import cats.implicits._
 
     for {
@@ -56,6 +52,6 @@ object JdbcBackedUuidRepository {
     }
   }
 
-  def initializeInstance[F[_]: Sync](implicit logger: Logger): F[UuidRepository[F]] =
+  def initializeInstance[F[_]: Sync](): F[UuidRepository[F]] =
     initializeInstanceIn[F, F]
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/repositories/PersistedItemsMigrationVersionRepository.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/repositories/PersistedItemsMigrationVersionRepository.scala
index 70907fb507..4beb513c0f 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/repositories/PersistedItemsMigrationVersionRepository.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/repositories/PersistedItemsMigrationVersionRepository.scala
@@ -21,25 +21,24 @@ class PersistedItemsMigrationVersionRepository[F[_]](implicit dbSession: DBSessi
     Resource.makeCase(F.delay {
       // トランザクション開始がここになる
       // https://dev.mysql.com/doc/refman/5.6/ja/lock-tables-and-transactions.html
-      sql"set autocommit=0".update().apply()
+      sql"set autocommit=0".update()
 
       // ロックを取得するときは利用するテーブルすべてをロックしなければならない
       sql"lock tables seichiassist.item_migration_on_database write, seichiassist.playerdata write"
         .update()
-        .apply()
 
       // このリソースを使用する際にはロックが取れているというのを保証すればよいため、リソースの実体は無くて良い
       ()
     }) {
       case (_, ExitCase.Completed) =>
         F.delay {
-          sql"commit".update().apply()
-          sql"unlock tables".update().apply()
+          sql"commit".update()
+          sql"unlock tables".update()
         }
       case _ =>
         F.delay {
-          sql"rollback".update().apply()
-          sql"unlock tables".update().apply()
+          sql"rollback".update()
+          sql"unlock tables".update()
         }
     }
   }
@@ -52,8 +51,7 @@ class PersistedItemsMigrationVersionRepository[F[_]](implicit dbSession: DBSessi
         sql"""
         select version_string from seichiassist.item_migration_on_database
       """.map { rs => rs.string("version_string") }
-          .list
-          .apply()
+          .list()
           .flatMap(ItemMigrationVersionNumber.fromString)
           .toSet
       }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/repositories/PlayerItemsMigrationVersionRepository.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/repositories/PlayerItemsMigrationVersionRepository.scala
index 4c1e273b18..a4f8454a58 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/repositories/PlayerItemsMigrationVersionRepository.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/repositories/PlayerItemsMigrationVersionRepository.scala
@@ -33,8 +33,7 @@ class PlayerItemsMigrationVersionRepository[F[_]](serverId: String)(implicit F:
           select version_string from seichiassist.player_in_server_item_migration
             where server_id = $serverId and player_uuid = ${target.player.getUniqueId.toString}
         """.map { rs => rs.string("version_string") }
-            .list
-            .apply()
+            .list()
             .flatMap(ItemMigrationVersionNumber.fromString)
             .toSet
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/repositories/WorldLevelItemsMigrationVersionRepository.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/repositories/WorldLevelItemsMigrationVersionRepository.scala
index d925e4c87a..e2c55554be 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/repositories/WorldLevelItemsMigrationVersionRepository.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/repositories/WorldLevelItemsMigrationVersionRepository.scala
@@ -32,8 +32,7 @@ class WorldLevelItemsMigrationVersionRepository[F[_]](serverId: String)(implicit
           sql"""
           select version_string from seichiassist.item_migration_in_server_world_levels where server_id = $serverId
         """.map { rs => rs.string("version_string") }
-            .list
-            .apply()
+            .list()
             .flatMap(ItemMigrationVersionNumber.fromString)
             .toSet
         }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/targets/SeichiAssistPersistedItems.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/targets/SeichiAssistPersistedItems.scala
index f02354f219..7b4c5e9ade 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/targets/SeichiAssistPersistedItems.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/infrastructure/targets/SeichiAssistPersistedItems.scala
@@ -46,7 +46,6 @@ class SeichiAssistPersistedItems[F[_]](implicit dBSession: DBSession, F: Sync[F]
     val triples = sql"select uuid, shareinv, inventory from seichiassist.playerdata"
       .map { rs => (rs.string("uuid"), rs.stringOpt("shareinv"), rs.stringOpt("inventory")) }
       .list()
-      .apply()
 
     val batchParam: Seq[Seq[String]] = triples.map {
       case (uuid, shareinv, inventory) =>
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/migrations/V1_0_0_MigrateMebiusToNewCodec.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/migrations/V1_0_0_MigrateMebiusToNewCodec.scala
index c58bcd791a..38b3b37b9c 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/migrations/V1_0_0_MigrateMebiusToNewCodec.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/migrations/V1_0_0_MigrateMebiusToNewCodec.scala
@@ -6,7 +6,7 @@ import com.github.unchama.itemmigration.domain.{ItemMigration, ItemMigrationVers
 import com.github.unchama.seichiassist.subsystems.itemmigration.domain.minecraft.UuidRepository
 import com.github.unchama.seichiassist.subsystems.itemmigration.migrations.V1_0_0_MigrateMebiusToNewCodec.OldBukkitMebiusItemStackCodec.OldMebiusRawProperty
 import com.github.unchama.seichiassist.subsystems.mebius.bukkit.codec.BukkitMebiusItemStackCodec.NBTTagConstants
-import de.tr7zw.itemnbtapi.NBTItem
+import de.tr7zw.nbtapi.NBTItem
 import org.bukkit.ChatColor._
 import org.bukkit.Material
 import org.bukkit.inventory.ItemStack
@@ -24,7 +24,6 @@ object V1_0_0_MigrateMebiusToNewCodec {
   // noinspection DuplicatedCode
   object OldBukkitMebiusItemStackCodec {
 
-    import de.tr7zw.itemnbtapi.NBTItem
     import org.bukkit.inventory.ItemStack
 
     private val mebiusLoreHead =
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/migrations/V1_1_0_AddUnbreakableToNarutoRemake.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/migrations/V1_1_0_AddUnbreakableToNarutoRemake.scala
index f4d1bced70..fec6d6914d 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/migrations/V1_1_0_AddUnbreakableToNarutoRemake.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/itemmigration/migrations/V1_1_0_AddUnbreakableToNarutoRemake.scala
@@ -36,7 +36,6 @@ object V1_1_0_AddUnbreakableToNarutoRemake {
 
     itemStack.clone().tap { clone =>
       import clone._
-      setDurability(0.toShort)
       setItemMeta {
         getItemMeta.tap { itemMeta =>
           import itemMeta._
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/joinandquitmessenger/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/joinandquitmessenger/System.scala
new file mode 100644
index 0000000000..3ce22378fd
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/joinandquitmessenger/System.scala
@@ -0,0 +1,15 @@
+package com.github.unchama.seichiassist.subsystems.joinandquitmessenger
+
+import com.github.unchama.seichiassist.meta.subsystem.Subsystem
+import com.github.unchama.seichiassist.subsystems.joinandquitmessenger.bukkit.JoinAndQuitListeners
+import org.bukkit.event.Listener
+
+object System {
+
+  def wired[F[_]]: Subsystem[F] = {
+    new Subsystem[F] {
+      override val listeners: Seq[Listener] = Seq(new JoinAndQuitListeners)
+    }
+  }
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/joinandquitmessenger/bukkit/JoinAndQuitListeners.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/joinandquitmessenger/bukkit/JoinAndQuitListeners.scala
new file mode 100644
index 0000000000..5b19ae5551
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/joinandquitmessenger/bukkit/JoinAndQuitListeners.scala
@@ -0,0 +1,20 @@
+package com.github.unchama.seichiassist.subsystems.joinandquitmessenger.bukkit
+
+import com.github.unchama.seichiassist.subsystems.joinandquitmessenger.domain.Messages
+import org.bukkit.ChatColor
+import org.bukkit.event.{EventHandler, Listener}
+import org.bukkit.event.player.{PlayerJoinEvent, PlayerQuitEvent}
+
+class JoinAndQuitListeners extends Listener {
+
+  @EventHandler
+  def onJoin(event: PlayerJoinEvent): Unit = {
+    event.setJoinMessage(s"${ChatColor.GRAY}${Messages.joinMessage(event.getPlayer.getName)}")
+  }
+
+  @EventHandler
+  def onQuit(event: PlayerQuitEvent): Unit = {
+    event.setQuitMessage(Messages.quitMessage(event.getPlayer.getName))
+  }
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/joinandquitmessenger/domain/Messages.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/joinandquitmessenger/domain/Messages.scala
new file mode 100644
index 0000000000..0759f2ab00
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/joinandquitmessenger/domain/Messages.scala
@@ -0,0 +1,10 @@
+package com.github.unchama.seichiassist.subsystems.joinandquitmessenger.domain
+
+object Messages {
+
+  def joinMessage(playerName: String): String = s"$playerName がログインしました"
+
+  // Note: 整地鯖では退出メッセージを表示しない
+  def quitMessage(playerName: String): String = ""
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/lastquit/bukkit/commands/LastQuitCommand.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/lastquit/bukkit/commands/LastQuitCommand.scala
index 6abbe4235b..1cb66dc606 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/lastquit/bukkit/commands/LastQuitCommand.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/lastquit/bukkit/commands/LastQuitCommand.scala
@@ -1,14 +1,14 @@
 package com.github.unchama.seichiassist.subsystems.lastquit.bukkit.commands
 
-import cats.effect.ConcurrentEffect.ops.toAllConcurrentEffectOps
-import cats.effect.{ConcurrentEffect, IO}
+import cats.data.Kleisli
+import cats.effect.ConcurrentEffect
 import com.github.unchama.contextualexecutor.builder.{ContextualExecutorBuilder, Parsers}
 import com.github.unchama.seichiassist.infrastructure.minecraft.{
   JdbcLastSeenNameToUuid,
   LastSeenNameToUuidError
 }
 import com.github.unchama.seichiassist.subsystems.lastquit.LastQuitAPI
-import com.github.unchama.targetedeffect.commandsender.MessageEffect
+import com.github.unchama.targetedeffect.commandsender.MessageEffectF
 import org.bukkit.ChatColor.RED
 import org.bukkit.command.TabExecutor
 
@@ -21,30 +21,30 @@ class LastQuitCommand[F[_]: ConcurrentEffect](implicit lastQuitAPI: LastQuitAPI[
   val executor: TabExecutor = ContextualExecutorBuilder
     .beginConfiguration
     .thenParse(Parsers.identity)
-    .buildWithExecutionF { context =>
+    .buildWithExecutionCSEffect { context =>
       val playerName = context.args.parsed.head
 
-      for {
-        uuidEither <- new JdbcLastSeenNameToUuid[IO].of(playerName)
-        lastQuit <- uuidEither.traverse(uuid => lastQuitAPI.get(uuid).toIO)
+      (for {
+        uuidEither <- Kleisli.liftF(new JdbcLastSeenNameToUuid[F].of(playerName))
+        lastQuit <- Kleisli.liftF(uuidEither.traverse(uuid => lastQuitAPI.get(uuid)))
       } yield {
         lastQuit match {
           case Left(error) =>
             error match {
               case LastSeenNameToUuidError.MultipleFound =>
-                MessageEffect(s"${RED}指定された名前のプレイヤーが複数見つかりました。")
+                MessageEffectF(s"${RED}指定された名前のプレイヤーが複数見つかりました。")
               case LastSeenNameToUuidError.NotFound =>
-                MessageEffect(s"${RED}指定された名前のプレイヤーが見つかりませんでした。")
+                MessageEffectF(s"${RED}指定された名前のプレイヤーが見つかりませんでした。")
             }
           case Right(lastQuitTimeOpt) =>
             lastQuitTimeOpt match {
               case Some(lastQuitTime) =>
                 val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm")
-                MessageEffect(
+                MessageEffectF(
                   s"${playerName}の最終ログアウト日時:${lastQuitTime.dateTime.format(dateTimeFormatter)}"
                 )
               case None =>
-                MessageEffect(
+                MessageEffectF(
                   List(
                     s"${RED}最終ログアウト日時の照会に失敗しました。",
                     s"${RED}プレイヤー名が変更されていないか確認してください。",
@@ -53,7 +53,7 @@ class LastQuitCommand[F[_]: ConcurrentEffect](implicit lastQuitAPI: LastQuitAPI[
                 )
             }
         }
-      }
+      }).flatten
     }
     .asNonBlockingTabExecutor()
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/lastquit/infrastructure/JdbcLastQuitPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/lastquit/infrastructure/JdbcLastQuitPersistence.scala
index 7fd796338e..406f4a599a 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/lastquit/infrastructure/JdbcLastQuitPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/lastquit/infrastructure/JdbcLastQuitPersistence.scala
@@ -13,9 +13,7 @@ class JdbcLastQuitPersistence[F[_]: Sync] extends LastQuitPersistence[F] {
 
   override def updateLastQuitNow(uuid: UUID): F[Unit] = Sync[F].delay {
     DB.localTx { implicit session =>
-      sql"UPDATE playerdata SET lastquit = NOW() WHERE uuid = ${uuid.toString}"
-        .execute()
-        .apply()
+      sql"UPDATE playerdata SET lastquit = NOW() WHERE uuid = ${uuid.toString}".execute()
     }
   }
 
@@ -26,7 +24,6 @@ class JdbcLastQuitPersistence[F[_]: Sync] extends LastQuitPersistence[F] {
           sql"SELECT lastquit FROM playerdata WHERE uuid = ${uuid.toString}"
             .map(_.localDateTime("lastquit"))
             .toList()
-            .apply()
             .headOption
         lastQuitDateTime.map(LastQuitDateTime)
       }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/mana/application/process/RefillToCap.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/mana/application/process/RefillToCap.scala
index d56585e8a0..5cc675b0be 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/mana/application/process/RefillToCap.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/mana/application/process/RefillToCap.scala
@@ -2,7 +2,7 @@ package com.github.unchama.seichiassist.subsystems.mana.application.process
 
 import cats.effect.concurrent.Ref
 import cats.implicits._
-import cats.{Functor, Monad}
+import cats.Monad
 import com.github.unchama.datarepository.KeyedDataRepository
 import com.github.unchama.generic.{ContextCoercion, Diff}
 import com.github.unchama.seichiassist.subsystems.breakcount.BreakCountReadAPI
@@ -13,7 +13,7 @@ import com.github.unchama.seichiassist.subsystems.mana.domain.LevelCappedManaAmo
  */
 object RefillToCap {
 
-  def using[F[_]: Functor, G[_]: Monad: ContextCoercion[*[_], F], Player](
+  def using[F[_], G[_]: Monad: ContextCoercion[*[_], F], Player](
     repository: KeyedDataRepository[Player, Ref[G, LevelCappedManaAmount]]
   )(implicit breakCountReadAPI: BreakCountReadAPI[F, G, Player]): fs2.Stream[F, Unit] = {
     breakCountReadAPI.seichiStarLevelUpdates.evalMap {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/mana/application/process/UpdateManaCaps.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/mana/application/process/UpdateManaCaps.scala
index 4329e87385..1c9dd48735 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/mana/application/process/UpdateManaCaps.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/mana/application/process/UpdateManaCaps.scala
@@ -1,7 +1,7 @@
 package com.github.unchama.seichiassist.subsystems.mana.application.process
 
 import cats.effect.concurrent.Ref
-import cats.{Functor, Monad}
+import cats.Monad
 import com.github.unchama.datarepository.KeyedDataRepository
 import com.github.unchama.generic.{ContextCoercion, Diff}
 import com.github.unchama.seichiassist.subsystems.breakcount.BreakCountReadAPI
@@ -11,7 +11,7 @@ object UpdateManaCaps {
 
   import cats.implicits._
 
-  def using[F[_]: Functor, G[_]: Monad: ContextCoercion[*[_], F], Player](
+  def using[F[_], G[_]: Monad: ContextCoercion[*[_], F], Player](
     repository: KeyedDataRepository[Player, Ref[G, LevelCappedManaAmount]]
   )(implicit breakCountReadAPI: BreakCountReadAPI[F, G, Player]): fs2.Stream[F, Unit] =
     breakCountReadAPI.seichiLevelUpdates.evalMap {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/mana/infrastructure/JdbcManaAmountPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/mana/infrastructure/JdbcManaAmountPersistence.scala
index 2c27080658..b016a77dfa 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/mana/infrastructure/JdbcManaAmountPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/mana/infrastructure/JdbcManaAmountPersistence.scala
@@ -16,16 +16,13 @@ class JdbcManaAmountPersistence[F[_]](implicit F: Sync[F]) extends ManaAmountPer
         sql"select mana from playerdata where uuid = ${key.toString}"
           .map { rs => ManaAmount(rs.double("mana")) }
           .first()
-          .apply()
       }
     }
 
   override def write(key: UUID, value: ManaAmount): F[Unit] =
     F.delay {
       DB.localTx { implicit session =>
-        sql"update playerdata set mana = ${value.value} where uuid = ${key.toString}"
-          .update()
-          .apply()
+        sql"update playerdata set mana = ${value.value} where uuid = ${key.toString}".update()
       }
     }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/System.scala
index 16b3b21273..90ac7b627c 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/System.scala
@@ -16,10 +16,12 @@ import com.github.unchama.seichiassist.subsystems.managedfly.application._
 import com.github.unchama.seichiassist.subsystems.managedfly.application.repository.ActiveSessionReferenceRepositoryDefinition
 import com.github.unchama.seichiassist.subsystems.managedfly.bukkit.BukkitPlayerFlyStatusManipulation
 import com.github.unchama.seichiassist.subsystems.managedfly.bukkit.controllers.BukkitFlyCommand
+import com.github.unchama.seichiassist.subsystems.managedfly.bukkit.listeners.BukkitPlayerStatusChangeListener
 import com.github.unchama.seichiassist.subsystems.managedfly.domain.PlayerFlyStatus
 import com.github.unchama.seichiassist.subsystems.managedfly.infrastructure.JdbcFlyDurationPersistenceRepository
 import org.bukkit.command.TabExecutor
 import org.bukkit.entity.Player
+import org.bukkit.event.Listener
 
 /**
  * NOTE: このサブシステム(managedfly)は本来BuildAssist側に属するが、
@@ -75,6 +77,9 @@ object System {
             : Seq[BukkitRepositoryControls[AsyncContext, _]] =
             Seq(controls.coerceFinalizationContextTo[AsyncContext])
 
+          override val listeners: Seq[Listener] =
+            Seq(new BukkitPlayerStatusChangeListener[AsyncContext, SyncContext])
+
           override val commands: Map[String, TabExecutor] =
             Map("fly" -> BukkitFlyCommand.executor[AsyncContext, SyncContext])
         }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/application/ActiveSessionReference.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/application/ActiveSessionReference.scala
index 720fc0ea2d..2037fab461 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/application/ActiveSessionReference.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/application/ActiveSessionReference.scala
@@ -8,9 +8,7 @@ import com.github.unchama.seichiassist.subsystems.managedfly.domain.{NotFlying,
 /**
  * プレーヤーの飛行セッションの参照
  */
-class ActiveSessionReference[AsyncContext[_]: ConcurrentEffect, SyncContext[
-  _
-]: Sync: ContextCoercion[*[_], AsyncContext]](
+class ActiveSessionReference[AsyncContext[_]: ConcurrentEffect, SyncContext[_]: Sync](
   private val sessionMutexRef: Mutex[AsyncContext, SyncContext, Option[
     ActiveSession[AsyncContext, SyncContext]
   ]]
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/bukkit/BukkitPlayerFlyStatusManipulation.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/bukkit/BukkitPlayerFlyStatusManipulation.scala
index 83a5187dd1..d9911a265c 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/bukkit/BukkitPlayerFlyStatusManipulation.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/bukkit/BukkitPlayerFlyStatusManipulation.scala
@@ -1,7 +1,7 @@
 package com.github.unchama.seichiassist.subsystems.managedfly.bukkit
 
 import cats.data.Kleisli
-import cats.effect.{Concurrent, Sync, SyncIO, Timer}
+import cats.effect.{Concurrent, Sync, SyncIO}
 import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.subsystems.idletime.IdleTimeAPI
 import com.github.unchama.seichiassist.subsystems.managedfly.application._
@@ -10,9 +10,7 @@ import com.github.unchama.seichiassist.util.exp.ExperienceManager
 import org.bukkit.ChatColor.{GRAY, GREEN, RED}
 import org.bukkit.entity.Player
 
-class BukkitPlayerFlyStatusManipulation[AsyncContext[
-  _
-]: Timer: Concurrent: OnMinecraftServerThread](
+class BukkitPlayerFlyStatusManipulation[AsyncContext[_]: Concurrent: OnMinecraftServerThread](
   implicit configuration: SystemConfiguration,
   idleTimeAPI: IdleTimeAPI[AsyncContext, Player]
 ) extends PlayerFlyStatusManipulation[Kleisli[AsyncContext, Player, *]] {
@@ -92,7 +90,7 @@ class BukkitPlayerFlyStatusManipulation[AsyncContext[
   private val sendMessages: List[String] => Kleisli[AsyncContext, Player, Unit] = { messages =>
     Kleisli { player =>
       Sync[AsyncContext].delay {
-        player.sendMessage(messages.toArray)
+        player.sendMessage(messages.mkString("\n"))
       }
     }
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/bukkit/controllers/BukkitFlyCommand.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/bukkit/controllers/BukkitFlyCommand.scala
index 6e222d6196..71aa2a38b1 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/bukkit/controllers/BukkitFlyCommand.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/bukkit/controllers/BukkitFlyCommand.scala
@@ -1,6 +1,7 @@
 package com.github.unchama.seichiassist.subsystems.managedfly.bukkit.controllers
 
-import cats.effect.{ConcurrentEffect, IO, SyncEffect, SyncIO, Timer}
+import cats.data.Kleisli
+import cats.effect.{ConcurrentEffect, IO, SyncEffect, SyncIO}
 import com.github.unchama.contextualexecutor.ContextualExecutor
 import com.github.unchama.contextualexecutor.builder.Parsers
 import com.github.unchama.contextualexecutor.executors.BranchedExecutor
@@ -16,7 +17,7 @@ import com.github.unchama.seichiassist.subsystems.managedfly.domain.{
   RemainingFlyDuration
 }
 import com.github.unchama.targetedeffect.TargetedEffect
-import com.github.unchama.targetedeffect.commandsender.MessageEffect
+import com.github.unchama.targetedeffect.commandsender.{MessageEffect, MessageEffectF}
 import eu.timepit.refined.api.Refined
 import eu.timepit.refined.numeric.Positive
 import org.bukkit.ChatColor._
@@ -53,7 +54,7 @@ object BukkitFlyCommand {
   import cats.effect.implicits._
   import cats.implicits._
 
-  def startEndlessCommand[F[_]: ConcurrentEffect: Timer, G[_]: SyncEffect](
+  private def startEndlessCommand[F[_]: ConcurrentEffect, G[_]: SyncEffect](
     implicit
     sessionReferenceRepository: KeyedDataRepository[Player, ActiveSessionReference[F, G]],
     factory: ActiveSessionFactory[F, Player]
@@ -66,7 +67,7 @@ object BukkitFlyCommand {
       } yield TargetedEffect.emptyEffect
     }
 
-  def addCommand[F[_]: ConcurrentEffect: Timer, G[_]: SyncEffect](
+  private def addCommand[F[_]: ConcurrentEffect, G[_]: SyncEffect](
     implicit
     sessionReferenceRepository: KeyedDataRepository[Player, ActiveSessionReference[F, G]],
     factory: ActiveSessionFactory[F, Player]
@@ -91,24 +92,22 @@ object BukkitFlyCommand {
         } yield TargetedEffect.emptyEffect
     }
 
-  def finishCommand[F[_]: ConcurrentEffect, G[_]](
+  private def finishCommand[F[_]: ConcurrentEffect, G[_]](
     implicit
     sessionReferenceRepository: KeyedDataRepository[Player, ActiveSessionReference[F, G]]
   ): ContextualExecutor =
-    BuilderTemplates.playerCommandBuilder.buildWithExecutionF { context =>
-      for {
-        sessionStopped <-
-          sessionReferenceRepository(context.sender).stopAnyRunningSession
-      } yield {
-        if (sessionStopped) {
-          MessageEffect(s"${GREEN}fly効果を停止しました。")
-        } else {
-          MessageEffect(s"${GREEN}fly効果は現在OFFです。")
-        }
+    BuilderTemplates.playerCommandBuilder.buildWithExecutionCSEffect { context =>
+      Kleisli.liftF(sessionReferenceRepository(context.sender).stopAnyRunningSession).flatMap {
+        sessionStopped =>
+          if (sessionStopped) {
+            MessageEffectF(s"${GREEN}fly効果を停止しました。")
+          } else {
+            MessageEffectF(s"${GREEN}fly効果は現在OFFです。")
+          }
       }
     }
 
-  def executor[F[_]: ConcurrentEffect: Timer, G[_]: SyncEffect](
+  def executor[F[_]: ConcurrentEffect, G[_]: SyncEffect](
     implicit
     sessionReferenceRepository: KeyedDataRepository[Player, ActiveSessionReference[F, G]],
     factory: ActiveSessionFactory[F, Player]
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/bukkit/listeners/BukkitPlayerStatusChangeListener.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/bukkit/listeners/BukkitPlayerStatusChangeListener.scala
new file mode 100644
index 0000000000..0aae33467f
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/bukkit/listeners/BukkitPlayerStatusChangeListener.scala
@@ -0,0 +1,52 @@
+package com.github.unchama.seichiassist.subsystems.managedfly.bukkit.listeners
+
+import cats.data.Kleisli
+import cats.effect.{ConcurrentEffect, SyncEffect, SyncIO}
+import com.github.unchama.datarepository.KeyedDataRepository
+import com.github.unchama.seichiassist.subsystems.managedfly.application.{
+  ActiveSessionReference,
+  PlayerFlyStatusManipulation
+}
+import org.bukkit.entity.Player
+import org.bukkit.event.player.{PlayerChangedWorldEvent, PlayerRespawnEvent}
+import org.bukkit.event.{EventHandler, Listener}
+
+class BukkitPlayerStatusChangeListener[F[_]: ConcurrentEffect, G[_]: SyncEffect](
+  implicit
+  sessionReferenceRepository: KeyedDataRepository[Player, ActiveSessionReference[F, G]],
+  playerFlyStatusManipulation: PlayerFlyStatusManipulation[Kleisli[F, Player, *]]
+) extends Listener {
+
+  import cats.effect.implicits._
+
+  @EventHandler
+  def onWorldChange(event: PlayerChangedWorldEvent): Unit = {
+    val player = event.getPlayer
+
+    val program = for {
+      currentStatus <- sessionReferenceRepository(player)
+        .getLatestFlyStatus
+        .runSync[SyncIO]
+        .toIO
+      _ <- playerFlyStatusManipulation.synchronizeFlyStatus(currentStatus)(player).toIO
+    } yield ()
+
+    program.unsafeRunAsyncAndForget()
+  }
+
+  @EventHandler
+  def onPlayerRespawn(event: PlayerRespawnEvent): Unit = {
+    val player = event.getPlayer
+
+    val program = for {
+      currentStatus <- sessionReferenceRepository(player)
+        .getLatestFlyStatus
+        .runSync[SyncIO]
+        .toIO
+      _ <- playerFlyStatusManipulation.synchronizeFlyStatus(currentStatus)(player).toIO
+    } yield ()
+
+    program.unsafeRunAsyncAndForget()
+  }
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/infrastructure/JdbcFlyDurationPersistenceRepository.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/infrastructure/JdbcFlyDurationPersistenceRepository.scala
index bdb1d8bedc..4c49f1824f 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/infrastructure/JdbcFlyDurationPersistenceRepository.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/managedfly/infrastructure/JdbcFlyDurationPersistenceRepository.scala
@@ -23,7 +23,7 @@ class JdbcFlyDurationPersistenceRepository[SyncContext[_]](
         sql"""
         insert into fly_status_cache values (${key.toString}, $serializedDuration)
           on duplicate key update remaining_fly_minutes = $serializedDuration
-      """.stripMargin.update().apply()
+      """.stripMargin.update()
       }
     }
 
@@ -33,7 +33,7 @@ class JdbcFlyDurationPersistenceRepository[SyncContext[_]](
         sql"""
         select remaining_fly_minutes from fly_status_cache
           where player_uuid = ${key.toString}
-      """.map { rs => rs.int("remaining_fly_minutes") }.headOption().apply().map {
+      """.map { rs => rs.int("remaining_fly_minutes") }.headOption().map {
           case 0          => None
           case -1         => Some(RemainingFlyDuration.Infinity)
           case n if n > 0 => Some(RemainingFlyDuration.PositiveMinutes.fromPositive(n))
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/codec/BukkitMebiusAppearanceMaterialCodec.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/codec/BukkitMebiusAppearanceMaterialCodec.scala
index 937eb6606a..69e71cfff5 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/codec/BukkitMebiusAppearanceMaterialCodec.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/codec/BukkitMebiusAppearanceMaterialCodec.scala
@@ -7,7 +7,7 @@ object BukkitMebiusAppearanceMaterialCodec {
 
   private val appearanceThresholds = List(
     1 -> Material.LEATHER_HELMET,
-    5 -> Material.GOLD_HELMET,
+    5 -> Material.GOLDEN_HELMET,
     10 -> Material.CHAINMAIL_HELMET,
     20 -> Material.IRON_HELMET,
     25 -> Material.DIAMOND_HELMET
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/codec/BukkitMebiusItemStackCodec.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/codec/BukkitMebiusItemStackCodec.scala
index 226a5afa8e..e0295419e8 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/codec/BukkitMebiusItemStackCodec.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/codec/BukkitMebiusItemStackCodec.scala
@@ -3,7 +3,7 @@ package com.github.unchama.seichiassist.subsystems.mebius.bukkit.codec
 import com.github.unchama.seichiassist.subsystems.mebius.domain.property._
 import com.github.unchama.seichiassist.subsystems.mebius.domain.resources.MebiusTalks
 import com.github.unchama.seichiassist.subsystems.seasonalevents.christmas.ChristmasItemData
-import de.tr7zw.itemnbtapi.NBTItem
+import de.tr7zw.nbtapi.NBTItem
 import org.bukkit.ChatColor._
 import org.bukkit.Material
 import org.bukkit.entity.Player
@@ -119,19 +119,19 @@ object BukkitMebiusItemStackCodec {
    *
    * を満足する。
    */
-  def materialize(property: MebiusProperty, damageValue: Short): ItemStack = {
+  def materialize(property: MebiusProperty): ItemStack = {
     val material = property.forcedMaterial match {
       case MebiusForcedMaterial.None =>
         BukkitMebiusAppearanceMaterialCodec.appearanceMaterialAt(property.level)
       case MebiusForcedMaterial.Leather => Material.LEATHER_HELMET // 革のヘルメット
       case MebiusForcedMaterial.Iron    => Material.IRON_HELMET // 鉄のヘルメット
       case MebiusForcedMaterial.Chain   => Material.CHAINMAIL_HELMET // チェーンのヘルメット
-      case MebiusForcedMaterial.Gold    => Material.GOLD_HELMET // 金のヘルメット
+      case MebiusForcedMaterial.Gold    => Material.GOLDEN_HELMET // 金のヘルメット
     }
 
     import scala.util.chaining._
 
-    val item = new ItemStack(material, 1, damageValue)
+    val item = new ItemStack(material, 1)
 
     item.setItemMeta {
       item.getItemMeta.tap { meta =>
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/command/MebiusCommandExecutorProvider.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/command/MebiusCommandExecutorProvider.scala
index e15664d7fc..49195bf506 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/command/MebiusCommandExecutorProvider.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/command/MebiusCommandExecutorProvider.scala
@@ -64,8 +64,7 @@ class MebiusCommandExecutorProvider(
                 SequentialEffect(
                   UnfocusedEffect {
                     player.getInventory.setHelmet {
-                      BukkitMebiusItemStackCodec
-                        .materialize(newProperty, damageValue = helmet.getDurability)
+                      BukkitMebiusItemStackCodec.materialize(newProperty)
                     }
                   },
                   additionalEffectsOnModification(newProperty)
@@ -117,7 +116,7 @@ class MebiusCommandExecutorProvider(
           if (property.level.isMaximum) {
             val newProperty = property.toggleForcedMaterial
             val newItem =
-              BukkitMebiusItemStackCodec.materialize(newProperty, mainHand.getDurability)
+              BukkitMebiusItemStackCodec.materialize(newProperty)
 
             val newMaterialName = newProperty.forcedMaterial match {
               case MebiusForcedMaterial.None    => "ダイヤモンド"
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/gateway/BukkitMebiusSpeechGateway.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/gateway/BukkitMebiusSpeechGateway.scala
index 8298ce99c5..778a3562d8 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/gateway/BukkitMebiusSpeechGateway.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/gateway/BukkitMebiusSpeechGateway.scala
@@ -44,13 +44,13 @@ class BukkitMebiusSpeechGateway(player: Player)(implicit timer: Timer[IO])
     val effect = strength match {
       case MebiusSpeechStrength.Medium =>
         playSoundsInSequence(
-          RepeatedEffect(3)(FocusedSoundEffect(Sound.BLOCK_NOTE_HARP, 2.0f, 1.0f)),
-          RepeatedEffect(3)(FocusedSoundEffect(Sound.BLOCK_NOTE_HARP, 2.0f, 1.5f))
+          RepeatedEffect(3)(FocusedSoundEffect(Sound.BLOCK_NOTE_BLOCK_HARP, 2.0f, 1.0f)),
+          RepeatedEffect(3)(FocusedSoundEffect(Sound.BLOCK_NOTE_BLOCK_HARP, 2.0f, 1.5f))
         )
       case MebiusSpeechStrength.Loud =>
         playSoundsInSequence(
-          RepeatedEffect(5)(FocusedSoundEffect(Sound.BLOCK_NOTE_HARP, 2.0f, 1.5f)),
-          RepeatedEffect(5)(FocusedSoundEffect(Sound.BLOCK_NOTE_HARP, 2.0f, 2.0f))
+          RepeatedEffect(5)(FocusedSoundEffect(Sound.BLOCK_NOTE_BLOCK_HARP, 2.0f, 1.5f)),
+          RepeatedEffect(5)(FocusedSoundEffect(Sound.BLOCK_NOTE_BLOCK_HARP, 2.0f, 2.0f))
         )
     }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusDropTrialListener.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusDropTrialListener.scala
index 37b7facbca..6faf7eccae 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusDropTrialListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusDropTrialListener.scala
@@ -51,7 +51,7 @@ class MebiusDropTrialListener[G[_]: ChristmasEventsAPI: RandomEffect: SyncEffect
       )
 
     val mebius =
-      BukkitMebiusItemStackCodec.materialize(droppedMebiusProperty, damageValue = 0.toShort)
+      BukkitMebiusItemStackCodec.materialize(droppedMebiusProperty)
 
     player.sendMessage(s"$RESET$YELLOW${BOLD}おめでとうございます。採掘中にMEBIUSを発見しました。")
     player.sendMessage(s"$RESET$YELLOW${BOLD}MEBIUSはプレイヤーと共に成長するヘルメットです。")
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusInteractionResponder.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusInteractionResponder.scala
index 1fdff31a1e..5bb0ad78db 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusInteractionResponder.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusInteractionResponder.scala
@@ -21,6 +21,7 @@ import org.bukkit.event.block.BlockBreakEvent
 import org.bukkit.event.entity.{EntityDamageByEntityEvent, EntityDeathEvent}
 import org.bukkit.event.player.PlayerItemBreakEvent
 import org.bukkit.event.{EventHandler, EventPriority, Listener}
+import org.bukkit.inventory.meta.Damageable
 
 class MebiusInteractionResponder(
   implicit serviceRepository: PlayerDataRepository[MebiusSpeechService[SyncIO]],
@@ -40,32 +41,37 @@ class MebiusInteractionResponder(
 
         val speechService = serviceRepository(player)
 
-        val messageProgram = if (helmet.getDurability >= helmet.getType.getMaxDurability - 10) {
-          MebiusMessages.onDamageBreaking.pickOne[SyncIO].flatMap { message =>
-            // 耐久閾値を超えていたら破損警告
-            speechService.tryMakingSpeech(
-              mebiusProperty,
-              MebiusSpeech(
-                message.interpolate(mebiusProperty.ownerNickname),
-                MebiusSpeechStrength.Medium
+        val messageProgram =
+          if (
+            helmet.getItemMeta.asInstanceOf[Damageable].getDamage >= helmet
+              .getType
+              .getMaxDurability - 10
+          ) {
+            MebiusMessages.onDamageBreaking.pickOne[SyncIO].flatMap { message =>
+              // 耐久閾値を超えていたら破損警告
+              speechService.tryMakingSpeech(
+                mebiusProperty,
+                MebiusSpeech(
+                  message.interpolate(mebiusProperty.ownerNickname),
+                  MebiusSpeechStrength.Medium
+                )
               )
-            )
-          }
-        } else
-          event.getDamager match {
-            case monster: Monster =>
-              // モンスターからダメージを受けた場合の対モンスターメッセージ
-              MebiusMessages.onDamageWarnEnemy.pickOne[SyncIO].flatMap { message =>
-                speechService.tryMakingSpeech(
-                  mebiusProperty,
-                  MebiusSpeech(
-                    message.interpolate(mebiusProperty.ownerNickname, monster.getName),
-                    MebiusSpeechStrength.Medium
+            }
+          } else
+            event.getDamager match {
+              case monster: Monster =>
+                // モンスターからダメージを受けた場合の対モンスターメッセージ
+                MebiusMessages.onDamageWarnEnemy.pickOne[SyncIO].flatMap { message =>
+                  speechService.tryMakingSpeech(
+                    mebiusProperty,
+                    MebiusSpeech(
+                      message.interpolate(mebiusProperty.ownerNickname, monster.getName),
+                      MebiusSpeechStrength.Medium
+                    )
                   )
-                )
-              }
-            case _ => SyncIO.unit
-          }
+                }
+              case _ => SyncIO.unit
+            }
 
         messageProgram.unsafeRunSync()
       case _ =>
@@ -98,7 +104,7 @@ class MebiusInteractionResponder(
               MessageEffect(
                 s"${BukkitMebiusItemStackCodec.displayNameOfMaterializedItem(property)}${RESET}が旅立ちました。"
               ),
-              FocusedSoundEffect(Sound.ENTITY_ENDERDRAGON_DEATH, 1.0f, 0.1f)
+              FocusedSoundEffect(Sound.ENTITY_ENDER_DRAGON_DEATH, 1.0f, 0.1f)
             ).run(player)
           }
         )
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusLevelUpTrialListener.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusLevelUpTrialListener.scala
index 1505585cb9..3dd1de4d2f 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusLevelUpTrialListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusLevelUpTrialListener.scala
@@ -39,7 +39,7 @@ class MebiusLevelUpTrialListener(
 
     if (newMebiusProperty != oldMebiusProperty) {
       player.getInventory.setHelmet {
-        BukkitMebiusItemStackCodec.materialize(newMebiusProperty, damageValue = 0)
+        BukkitMebiusItemStackCodec.materialize(newMebiusProperty)
       }
 
       import cats.implicits._
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusPlayerJoinGreeter.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusPlayerJoinGreeter.scala
index 83f684de10..b22544bae9 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusPlayerJoinGreeter.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/mebius/bukkit/listeners/MebiusPlayerJoinGreeter.scala
@@ -1,6 +1,6 @@
 package com.github.unchama.seichiassist.subsystems.mebius.bukkit.listeners
 
-import cats.effect.{Effect, IO, SyncIO, Timer}
+import cats.effect.{IO, SyncIO, Timer}
 import com.github.unchama.datarepository.bukkit.player.PlayerDataRepository
 import com.github.unchama.generic.effect.unsafe.EffectEnvironment
 import com.github.unchama.seichiassist.subsystems.mebius.bukkit.codec.BukkitMebiusItemStackCodec
@@ -16,7 +16,7 @@ import org.bukkit.event.{EventHandler, EventPriority, Listener}
 import java.util.concurrent.TimeUnit
 import scala.concurrent.duration.FiniteDuration
 
-class MebiusPlayerJoinGreeter[F[_]: Effect](
+class MebiusPlayerJoinGreeter[F[_]](
   implicit effectEnvironment: EffectEnvironment,
   speechServiceRepository: PlayerDataRepository[MebiusSpeechService[SyncIO]],
   timer: Timer[IO]
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/bukkit/BukkitMineStackObjectList.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/bukkit/BukkitMineStackObjectList.scala
index 5700a0c451..7ad705b0c6 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/bukkit/BukkitMineStackObjectList.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/bukkit/BukkitMineStackObjectList.scala
@@ -6,6 +6,7 @@ import cats.effect.concurrent.Ref
 import com.github.unchama.minecraft.bukkit.algebra.CloneableBukkitItemStack._
 import com.github.unchama.minecraft.objects.MinecraftMaterial
 import com.github.unchama.seichiassist.subsystems.gachaprize.GachaPrizeAPI
+import com.github.unchama.seichiassist.subsystems.gachaprize.domain.CanBeSignedAsGachaPrize
 import com.github.unchama.seichiassist.subsystems.minestack.domain.minestackobject.MineStackObject.{
   MineStackObjectByItemStack,
   MineStackObjectByMaterial
@@ -15,6 +16,8 @@ import com.github.unchama.seichiassist.subsystems.minestack.domain.minestackobje
 import org.bukkit.Material
 import org.bukkit.entity.Player
 import org.bukkit.inventory.ItemStack
+import org.bukkit.inventory.meta.PotionMeta
+import org.bukkit.potion.{PotionData, PotionType}
 
 class BukkitMineStackObjectList[F[_]: Sync](
   implicit gachaPrizeAPI: GachaPrizeAPI[F, ItemStack, Player],
@@ -29,567 +32,1063 @@ class BukkitMineStackObjectList[F[_]: Sync](
 
   // 採掘可能ブロック
   private val minestacklistmine: List[MineStackObjectGroup[ItemStack]] = leftElems(
-    MineStackObjectByMaterial(ORES, "coal_ore", "石炭鉱石", Material.COAL_ORE, 0),
-    MineStackObjectByMaterial(ORES, "coal", "石炭", Material.COAL, 0),
-    MineStackObjectByMaterial(ORES, "coal_block", "石炭ブロック", Material.COAL_BLOCK, 0),
-    MineStackObjectByMaterial(ORES, "coal_1", "木炭", Material.COAL, 1),
-    MineStackObjectByMaterial(ORES, "iron_ore", "鉄鉱石", Material.IRON_ORE, 0),
-    MineStackObjectByMaterial(ORES, "iron_ingot", "鉄インゴット", Material.IRON_INGOT, 0),
-    MineStackObjectByMaterial(ORES, "iron_block", "鉄ブロック", Material.IRON_BLOCK, 0),
-    MineStackObjectByMaterial(ORES, "quartz_ore", "ネザー水晶鉱石", Material.QUARTZ_ORE, 0),
-    MineStackObjectByMaterial(ORES, "quartz", "ネザー水晶", Material.QUARTZ, 0),
-    MineStackObjectByMaterial(ORES, "gold_ore", "金鉱石", Material.GOLD_ORE, 0),
-    MineStackObjectByMaterial(ORES, "gold_ingot", "金インゴット", Material.GOLD_INGOT, 0),
-    MineStackObjectByMaterial(ORES, "gold_block", "金ブロック", Material.GOLD_BLOCK, 0),
-    MineStackObjectByMaterial(ORES, "redstone_ore", "レッドストーン鉱石", Material.REDSTONE_ORE, 0),
-    MineStackObjectByMaterial(ORES, "lapis_ore", "ラピスラズリ鉱石", Material.LAPIS_ORE, 0),
-    MineStackObjectByMaterial(ORES, "lapis_lazuli", "ラピスラズリ", Material.INK_SACK, 4),
-    MineStackObjectByMaterial(ORES, "lapis_block", "ラピスラズリブロック", Material.LAPIS_BLOCK, 0),
-    MineStackObjectByMaterial(ORES, "diamond_ore", "ダイヤモンド鉱石", Material.DIAMOND_ORE, 0),
-    MineStackObjectByMaterial(ORES, "diamond", "ダイヤモンド", Material.DIAMOND, 0),
-    MineStackObjectByMaterial(ORES, "diamond_block", "ダイヤモンドブロック", Material.DIAMOND_BLOCK, 0),
-    MineStackObjectByMaterial(ORES, "emerald_ore", "エメラルド鉱石", Material.EMERALD_ORE, 0),
-    MineStackObjectByMaterial(ORES, "emerald", "エメラルド", Material.EMERALD, 0),
-    MineStackObjectByMaterial(ORES, "emerald_block", "エメラルドブロック", Material.EMERALD_BLOCK, 0)
+    MineStackObjectByMaterial(ORES, "coal_ore", "石炭鉱石", Material.COAL_ORE),
+    MineStackObjectByMaterial(ORES, "coal", "石炭", Material.COAL),
+    MineStackObjectByMaterial(ORES, "coal_block", "石炭ブロック", Material.COAL_BLOCK),
+    MineStackObjectByMaterial(ORES, "coal_1", "木炭", Material.CHARCOAL),
+    MineStackObjectByMaterial(ORES, "iron_ore", "鉄鉱石", Material.IRON_ORE),
+    MineStackObjectByMaterial(ORES, "iron_ingot", "鉄インゴット", Material.IRON_INGOT),
+    MineStackObjectByMaterial(ORES, "iron_block", "鉄ブロック", Material.IRON_BLOCK),
+    MineStackObjectByMaterial(ORES, "quartz_ore", "ネザークォーツ鉱石", Material.NETHER_QUARTZ_ORE),
+    MineStackObjectByMaterial(ORES, "quartz", "ネザークォーツ", Material.QUARTZ),
+    MineStackObjectByMaterial(ORES, "gold_ore", "金鉱石", Material.GOLD_ORE),
+    MineStackObjectByMaterial(ORES, "gold_ingot", "金インゴット", Material.GOLD_INGOT),
+    MineStackObjectByMaterial(ORES, "gold_block", "金ブロック", Material.GOLD_BLOCK),
+    MineStackObjectByMaterial(ORES, "redstone_ore", "レッドストーン鉱石", Material.REDSTONE_ORE),
+    MineStackObjectByMaterial(ORES, "lapis_ore", "ラピスラズリ鉱石", Material.LAPIS_ORE),
+    MineStackObjectByMaterial(ORES, "lapis_lazuli", "ラピスラズリ", Material.LAPIS_LAZULI),
+    MineStackObjectByMaterial(ORES, "lapis_block", "ラピスラズリブロック", Material.LAPIS_BLOCK),
+    MineStackObjectByMaterial(ORES, "diamond_ore", "ダイヤモンド鉱石", Material.DIAMOND_ORE),
+    MineStackObjectByMaterial(ORES, "diamond", "ダイヤモンド", Material.DIAMOND),
+    MineStackObjectByMaterial(ORES, "diamond_block", "ダイヤモンドブロック", Material.DIAMOND_BLOCK),
+    MineStackObjectByMaterial(ORES, "emerald_ore", "エメラルド鉱石", Material.EMERALD_ORE),
+    MineStackObjectByMaterial(ORES, "emerald", "エメラルド", Material.EMERALD),
+    MineStackObjectByMaterial(ORES, "emerald_block", "エメラルドブロック", Material.EMERALD_BLOCK),
+    MineStackObjectByMaterial(ORES, "copper_ore", "銅鉱石", Material.COPPER_ORE),
+    MineStackObjectByMaterial(ORES, "copper_ingot", "銅インゴット", Material.COPPER_INGOT),
+    MineStackObjectByMaterial(ORES, "copper_block", "銅ブロック", Material.COPPER_BLOCK),
+    MineStackObjectByMaterial(ORES, "deepslate_coal_ore", "深層石炭鉱石", Material.DEEPSLATE_COAL_ORE),
+    MineStackObjectByMaterial(ORES, "deepslate_iron_ore", "深層鉄鉱石", Material.DEEPSLATE_IRON_ORE),
+    MineStackObjectByMaterial(ORES, "deepslate_gold_ore", "深層金鉱石", Material.DEEPSLATE_GOLD_ORE),
+    MineStackObjectByMaterial(ORES, "deepslate_redstone_ore", "深層レッドストーン鉱石", Material.DEEPSLATE_REDSTONE_ORE),
+    MineStackObjectByMaterial(ORES, "deepslate_emerald_ore", "深層エメラルド鉱石", Material.DEEPSLATE_EMERALD_ORE),
+    MineStackObjectByMaterial(ORES, "deepslate_lapis_ore", "深層ラピスラズリ鉱石", Material.DEEPSLATE_LAPIS_ORE),
+    MineStackObjectByMaterial(ORES, "deepslate_diamond_ore", "深層ダイヤモンド鉱石", Material.DEEPSLATE_DIAMOND_ORE),
+    MineStackObjectByMaterial(ORES, "deepslate_copper_ore", "深層銅鉱石", Material.DEEPSLATE_COPPER_ORE),
+    MineStackObjectByMaterial(ORES, "nether_gold_ore", "ネザー金鉱石", Material.NETHER_GOLD_ORE),
+    MineStackObjectByMaterial(ORES, "ancient_debris", "古代の残骸", Material.ANCIENT_DEBRIS),
+    MineStackObjectByMaterial(ORES, "raw_copper_block", "銅の原石ブロック", Material.RAW_COPPER_BLOCK),
+    MineStackObjectByMaterial(ORES, "raw_iron_block", "鉄の原石ブロック", Material.RAW_IRON_BLOCK),
+    MineStackObjectByMaterial(ORES, "raw_gold_block", "金の原石ブロック", Material.RAW_GOLD_BLOCK),
+    MineStackObjectByMaterial(ORES, "amethyst_block", "アメジストブロック", Material.AMETHYST_BLOCK),
+    MineStackObjectByMaterial(ORES, "netherite_block", "ネザライトブロック", Material.NETHERITE_BLOCK),
+    MineStackObjectByMaterial(ORES, "amethyst_shard", "アメジストの欠片", Material.AMETHYST_SHARD),
+    MineStackObjectByMaterial(ORES, "raw_copper", "銅の原石", Material.RAW_COPPER),
+    MineStackObjectByMaterial(ORES, "raw_iron", "鉄の原石", Material.RAW_IRON),
+    MineStackObjectByMaterial(ORES, "raw_gold", "金の原石", Material.RAW_GOLD),
+    MineStackObjectByMaterial(ORES, "netherite_ingot", "ネザライトインゴット", Material.NETHERITE_INGOT),
+    MineStackObjectByMaterial(ORES, "netherite_scrap", "ネザライトの欠片", Material.NETHERITE_SCRAP),
+    MineStackObjectByMaterial(ORES, "small_amethyst_bud", "小さなアメジストの芽", Material.SMALL_AMETHYST_BUD),
+    MineStackObjectByMaterial(ORES, "medium_amethyst_bud", "中くらいのアメジストの芽", Material.MEDIUM_AMETHYST_BUD),
+    MineStackObjectByMaterial(ORES, "large_amethyst_bud", "大きなアメジストの芽", Material.LARGE_AMETHYST_BUD),
+    MineStackObjectByMaterial(ORES, "amethyst_cluster", "アメジストの塊", Material.AMETHYST_CLUSTER),
+    MineStackObjectByMaterial(ORES, "iron_nugget", "鉄塊", Material.IRON_NUGGET),
+    MineStackObjectByMaterial(ORES, "waxed_copper_block", "錆止めされた銅ブロック", Material.WAXED_COPPER_BLOCK),
+    MineStackObjectByMaterial(ORES, "waxed_exposed_copper", "錆止めされた風化した銅", Material.WAXED_EXPOSED_COPPER),
+    MineStackObjectByMaterial(ORES, "waxed_weathered_copper", "錆止めされた錆びた銅", Material.WAXED_WEATHERED_COPPER),
+    MineStackObjectByMaterial(ORES, "waxed_oxidized_copper", "錆止めされた酸化した銅", Material.WAXED_OXIDIZED_COPPER),
+    MineStackObjectByMaterial(ORES, "waxed_cut_copper", "錆止めされた切り込み入りの銅", Material.WAXED_CUT_COPPER),
+    MineStackObjectByMaterial(ORES, "waxed_exposed_cut_copper", "錆止めされた風化した切り込み入りの銅", Material.WAXED_EXPOSED_CUT_COPPER),
+    MineStackObjectByMaterial(ORES, "waxed_weathered_cut_copper", "錆止めされた錆びた切り込み入りの銅", Material.WAXED_WEATHERED_CUT_COPPER),
+    MineStackObjectByMaterial(ORES, "waxed_oxidized_cut_copper", "錆止めされた酸化した切り込み入りの銅", Material.WAXED_OXIDIZED_CUT_COPPER),
+    MineStackObjectByMaterial(ORES, "exposed_copper", "風化した銅", Material.EXPOSED_COPPER),
+    MineStackObjectByMaterial(ORES, "weathered_copper", "錆びた銅", Material.WEATHERED_COPPER),
+    MineStackObjectByMaterial(ORES, "oxidized_copper", "酸化した銅", Material.OXIDIZED_COPPER),
+    MineStackObjectByMaterial(ORES, "cut_copper", "切り込み入りの銅", Material.CUT_COPPER),
+    MineStackObjectByMaterial(ORES, "exposed_cut_copper", "風化した切り込み入りの銅", Material.EXPOSED_CUT_COPPER),
+    MineStackObjectByMaterial(ORES, "weathered_cut_copper", "錆びた切り込み入りの銅", Material.WEATHERED_CUT_COPPER),
+    MineStackObjectByMaterial(ORES, "oxidized_cut_copper", "酸化した切り込み入りの銅", Material.OXIDIZED_CUT_COPPER),
   )
 
+  import scala.util.chaining._
+
   // モンスター+動物ドロップ
-  private val minestacklistdrop: List[Either[MineStackObject[ItemStack], MineStackObjectWithColorVariants[ItemStack]]] = leftElems(
-    MineStackObjectByMaterial(MOB_DROP, "ender_pearl", "エンダーパール", Material.ENDER_PEARL, 0),
-    MineStackObjectByMaterial(MOB_DROP, "ender_eye", "エンダーアイ", Material.EYE_OF_ENDER, 0),
-    MineStackObjectByMaterial(MOB_DROP, "slime_ball", "スライムボール", Material.SLIME_BALL, 0),
-    MineStackObjectByMaterial(MOB_DROP, "slime", "スライムブロック", Material.SLIME_BLOCK, 0),
-    MineStackObjectByMaterial(MOB_DROP, "rotten_flesh", "腐った肉", Material.ROTTEN_FLESH, 0),
-    MineStackObjectByMaterial(MOB_DROP, "bone", "骨", Material.BONE, 0),
-    MineStackObjectByMaterial(MOB_DROP, "sulphur", "火薬", Material.SULPHUR, 0),
-    MineStackObjectByMaterial(MOB_DROP, "arrow", "矢", Material.ARROW, 0),
-    MineStackObjectByMaterial(MOB_DROP, "tipped_arrow", "鈍化の矢", Material.TIPPED_ARROW, 0),
-    MineStackObjectByMaterial(MOB_DROP, "spider_eye", "蜘蛛の目", Material.SPIDER_EYE, 0),
-    MineStackObjectByMaterial(MOB_DROP, "string", "糸", Material.STRING, 0),
-    MineStackObjectByMaterial(MOB_DROP, "name_tag", "名札", Material.NAME_TAG, 0),
-    MineStackObjectByMaterial(MOB_DROP, "lead", "リード", Material.LEASH, 0),
-    MineStackObjectByMaterial(MOB_DROP, "glass_bottle", "ガラス瓶", Material.GLASS_BOTTLE, 0),
-    MineStackObjectByMaterial(MOB_DROP, "gold_nugget", "金塊", Material.GOLD_NUGGET, 0),
-    MineStackObjectByMaterial(MOB_DROP, "blaze_rod", "ブレイズロッド", Material.BLAZE_ROD, 0),
-    MineStackObjectByMaterial(MOB_DROP, "blaze_powder", "ブレイズパウダー", Material.BLAZE_POWDER, 0),
-    MineStackObjectByMaterial(MOB_DROP, "ghast_tear", "ガストの涙", Material.GHAST_TEAR, 0),
-    MineStackObjectByMaterial(MOB_DROP, "magma_cream", "マグマクリーム", Material.MAGMA_CREAM, 0),
-    MineStackObjectByMaterial(MOB_DROP, "prismarine_shard", "プリズマリンの欠片", Material.PRISMARINE_SHARD, 0),
-    MineStackObjectByMaterial(MOB_DROP, "prismarine_crystals", "プリズマリンクリスタル", Material.PRISMARINE_CRYSTALS, 0),
-    MineStackObjectByMaterial(MOB_DROP, "feather", "羽", Material.FEATHER, 0),
-    MineStackObjectByMaterial(MOB_DROP, "leather", "革", Material.LEATHER, 0),
-    MineStackObjectByMaterial(MOB_DROP, "rabbit_hide", "ウサギの皮", Material.RABBIT_HIDE, 0),
-    MineStackObjectByMaterial(MOB_DROP, "rabbit_foot", "ウサギの足", Material.RABBIT_FOOT, 0),
-    MineStackObjectByMaterial(MOB_DROP, "dragon_egg", "エンドラの卵", Material.DRAGON_EGG, 0),
-    MineStackObjectByMaterial(MOB_DROP, "shulker_shell", "シュルカーの殻", Material.SHULKER_SHELL, 0),
-    MineStackObjectByMaterial(MOB_DROP, "totem_of_undying", "不死のトーテム", Material.TOTEM, 0),
-    MineStackObjectByMaterial(MOB_DROP, "dragon_head", "エンダードラゴンの頭", Material.SKULL_ITEM, 5),
-    MineStackObjectByMaterial(MOB_DROP, "wither_skeleton_skull", "ウィザースケルトンの頭", Material.SKULL_ITEM, 1),
-    MineStackObjectByMaterial(MOB_DROP, "stick", "棒", Material.STICK, 0)
+  private val minestacklistdrop: List[MineStackObjectGroup[ItemStack]] = leftElems(
+    MineStackObjectByMaterial(MOB_DROP, "ender_pearl", "エンダーパール", Material.ENDER_PEARL),
+    MineStackObjectByMaterial(MOB_DROP, "ender_eye", "エンダーアイ", Material.ENDER_EYE),
+    MineStackObjectByMaterial(MOB_DROP, "slime_ball", "スライムボール", Material.SLIME_BALL),
+    MineStackObjectByMaterial(MOB_DROP, "slime", "スライムブロック", Material.SLIME_BLOCK),
+    MineStackObjectByMaterial(MOB_DROP, "rotten_flesh", "腐った肉", Material.ROTTEN_FLESH),
+    MineStackObjectByMaterial(MOB_DROP, "bone", "骨", Material.BONE),
+    MineStackObjectByMaterial(MOB_DROP, "sulphur", "火薬", Material.GUNPOWDER),
+    MineStackObjectByMaterial(MOB_DROP, "arrow", "矢", Material.ARROW),
+    MineStackObjectByMaterial(MOB_DROP, "spider_eye", "クモの目", Material.SPIDER_EYE),
+    MineStackObjectByItemStack(MOB_DROP, "tipped_arrow", Some("鈍化の矢"), hasNameLore = false, new ItemStack(Material.TIPPED_ARROW).tap { itemStack =>
+      val meta = itemStack.getItemMeta.asInstanceOf[PotionMeta]
+      meta.setBasePotionData(new PotionData(PotionType.SLOWNESS))
+      itemStack.setItemMeta(meta)
+    }),
+    MineStackObjectByMaterial(MOB_DROP, "string", "糸", Material.STRING),
+    MineStackObjectByMaterial(MOB_DROP, "name_tag", "名札", Material.NAME_TAG),
+    MineStackObjectByMaterial(MOB_DROP, "lead", "リード", Material.LEAD),
+    MineStackObjectByMaterial(MOB_DROP, "glass_bottle", "ガラス瓶", Material.GLASS_BOTTLE),
+    MineStackObjectByMaterial(MOB_DROP, "gold_nugget", "金塊", Material.GOLD_NUGGET),
+    MineStackObjectByMaterial(MOB_DROP, "blaze_rod", "ブレイズロッド", Material.BLAZE_ROD),
+    MineStackObjectByMaterial(MOB_DROP, "blaze_powder", "ブレイズパウダー", Material.BLAZE_POWDER),
+    MineStackObjectByMaterial(MOB_DROP, "ghast_tear", "ガストの涙", Material.GHAST_TEAR),
+    MineStackObjectByMaterial(MOB_DROP, "magma_cream", "マグマクリーム", Material.MAGMA_CREAM),
+    MineStackObjectByMaterial(MOB_DROP, "prismarine_shard", "プリズマリンの欠片", Material.PRISMARINE_SHARD),
+    MineStackObjectByMaterial(MOB_DROP, "prismarine_crystals", "プリズマリンクリスタル", Material.PRISMARINE_CRYSTALS),
+    MineStackObjectByMaterial(MOB_DROP, "feather", "羽根", Material.FEATHER),
+    MineStackObjectByMaterial(MOB_DROP, "leather", "革", Material.LEATHER),
+    MineStackObjectByMaterial(MOB_DROP, "rabbit_hide", "ウサギの皮", Material.RABBIT_HIDE),
+    MineStackObjectByMaterial(MOB_DROP, "rabbit_foot", "ウサギの足", Material.RABBIT_FOOT),
+    MineStackObjectByMaterial(MOB_DROP, "dragon_egg", "ドラゴンの卵", Material.DRAGON_EGG),
+    MineStackObjectByMaterial(MOB_DROP, "shulker_shell", "シュルカーの殻", Material.SHULKER_SHELL),
+    MineStackObjectByMaterial(MOB_DROP, "totem_of_undying", "不死のトーテム", Material.TOTEM_OF_UNDYING),
+    MineStackObjectByMaterial(MOB_DROP, "dragon_head", "ドラゴンの頭", Material.DRAGON_HEAD),
+    MineStackObjectByMaterial(MOB_DROP, "wither_skeleton_skull", "ウィザースケルトンの頭蓋骨", Material.WITHER_SKELETON_SKULL),
+    MineStackObjectByMaterial(MOB_DROP, "stick", "棒", Material.STICK),
+    MineStackObjectByMaterial(MOB_DROP, "scute", "カメのウロコ", Material.SCUTE),
+    MineStackObjectByMaterial(MOB_DROP, "fermented_spider_eye", "発酵したクモの目", Material.FERMENTED_SPIDER_EYE),
+    MineStackObjectByMaterial(MOB_DROP, "golden_carrot", "金のニンジン", Material.GOLDEN_CARROT),
+    MineStackObjectByMaterial(MOB_DROP, "skeleton_skull", "スケルトンの頭蓋骨", Material.SKELETON_SKULL),
+    MineStackObjectByMaterial(MOB_DROP, "zombie_head", "ゾンビの頭", Material.ZOMBIE_HEAD),
+    MineStackObjectByMaterial(MOB_DROP, "creeper_head", "クリーパーの頭", Material.CREEPER_HEAD),
+    MineStackObjectByMaterial(MOB_DROP, "nether_star", "ネザースター", Material.NETHER_STAR),
+    MineStackObjectByMaterial(MOB_DROP, "dragon_breath", "ドラゴンブレス", Material.DRAGON_BREATH),
+    MineStackObjectByMaterial(MOB_DROP, "phantom_membrane", "ファントムの皮膜", Material.PHANTOM_MEMBRANE),
+    MineStackObjectByMaterial(MOB_DROP, "nautilus_shell", "オウムガイの殻", Material.NAUTILUS_SHELL),
+    MineStackObjectByMaterial(MOB_DROP, "heart_of_the_sea", "海洋の心", Material.HEART_OF_THE_SEA),
+    MineStackObjectByMaterial(MOB_DROP, "ink_sack0", "イカスミ", Material.INK_SAC),
+    MineStackObjectByMaterial(MOB_DROP, "glow_ink_sac", "輝くイカスミ", Material.GLOW_INK_SAC),
+  ) ++ rightElems(
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(MOB_DROP, "music_disc_otherside", "レコード", Material.MUSIC_DISC_OTHERSIDE),
+      List(
+        MineStackObjectByMaterial(MOB_DROP, "music_disc_pigstep", "レコード", Material.MUSIC_DISC_PIGSTEP),
+        MineStackObjectByMaterial(MOB_DROP,"record_13","レコード",Material.MUSIC_DISC_13),
+        MineStackObjectByMaterial(MOB_DROP,"record_cat","レコード",Material.MUSIC_DISC_CAT),
+        MineStackObjectByMaterial(MOB_DROP,"record_blocks","レコード",Material.MUSIC_DISC_BLOCKS),
+        MineStackObjectByMaterial(MOB_DROP,"record_chirp","レコード",Material.MUSIC_DISC_CHIRP),
+        MineStackObjectByMaterial(MOB_DROP,"record_far","レコード",Material.MUSIC_DISC_FAR),
+        MineStackObjectByMaterial(MOB_DROP,"record_mall","レコード",Material.MUSIC_DISC_MALL),
+        MineStackObjectByMaterial(MOB_DROP,"record_mellohi","レコード",Material.MUSIC_DISC_MELLOHI),
+        MineStackObjectByMaterial(MOB_DROP,"record_stal","レコード",Material.MUSIC_DISC_STAL),
+        MineStackObjectByMaterial(MOB_DROP,"record_strad","レコード",Material.MUSIC_DISC_STRAD),
+        MineStackObjectByMaterial(MOB_DROP,"record_ward","レコード",Material.MUSIC_DISC_WARD),
+        MineStackObjectByMaterial(MOB_DROP,"record_11","レコード",Material.MUSIC_DISC_11),
+        MineStackObjectByMaterial(MOB_DROP,"record_wait","レコード",Material.MUSIC_DISC_WAIT),
+      )
+    )
   )
 
   // 採掘で入手可能な農業系ブロック
   private val minestacklistfarm: List[MineStackObjectGroup[ItemStack]] = leftElems(
-    MineStackObjectByMaterial(AGRICULTURAL, "seeds", "種", Material.SEEDS, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "apple", "リンゴ", Material.APPLE, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "long_grass1", "草", Material.LONG_GRASS, 1),
-    MineStackObjectByMaterial(AGRICULTURAL, "long_grass2", "シダ", Material.LONG_GRASS, 2),
-    MineStackObjectByMaterial(AGRICULTURAL, "dead_bush", "枯れ木", Material.DEAD_BUSH, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "cactus", "サボテン", Material.CACTUS, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "vine", "ツタ", Material.VINE, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "water_lily", "スイレンの葉", Material.WATER_LILY, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "yellow_flower", "タンポポ", Material.YELLOW_FLOWER, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "red_rose0", "ポピー", Material.RED_ROSE, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "red_rose1", "ヒスイラン", Material.RED_ROSE, 1),
-    MineStackObjectByMaterial(AGRICULTURAL, "red_rose2", "アリウム", Material.RED_ROSE, 2),
-    MineStackObjectByMaterial(AGRICULTURAL, "red_rose3", "ヒナソウ", Material.RED_ROSE, 3),
-    MineStackObjectByMaterial(AGRICULTURAL, "red_rose4", "赤色のチューリップ", Material.RED_ROSE, 4),
-    MineStackObjectByMaterial(AGRICULTURAL, "red_rose5", "橙色のチューリップ", Material.RED_ROSE, 5),
-    MineStackObjectByMaterial(AGRICULTURAL, "red_rose6", "白色のチューリップ", Material.RED_ROSE, 6),
-    MineStackObjectByMaterial(AGRICULTURAL, "red_rose7", "桃色のチューリップ", Material.RED_ROSE, 7),
-    MineStackObjectByMaterial(AGRICULTURAL, "red_rose8", "フランスギク", Material.RED_ROSE, 8),
-    MineStackObjectByMaterial(AGRICULTURAL, "leaves", "オークの葉", Material.LEAVES, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "leaves1", "マツの葉", Material.LEAVES, 1),
-    MineStackObjectByMaterial(AGRICULTURAL, "leaves2", "シラカバの葉", Material.LEAVES, 2),
-    MineStackObjectByMaterial(AGRICULTURAL, "leaves3", "ジャングルの葉", Material.LEAVES, 3),
-    MineStackObjectByMaterial(AGRICULTURAL, "leaves_2", "アカシアの葉", Material.LEAVES_2, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "leaves_21", "ダークオークの葉", Material.LEAVES_2, 1),
-    MineStackObjectByMaterial(AGRICULTURAL, "double_plant0", "ヒマワリ", Material.DOUBLE_PLANT, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "double_plant1", "ライラック", Material.DOUBLE_PLANT, 1),
-    MineStackObjectByMaterial(AGRICULTURAL, "double_plant2", "高い草", Material.DOUBLE_PLANT, 2),
-    MineStackObjectByMaterial(AGRICULTURAL, "double_plant3", "大きなシダ", Material.DOUBLE_PLANT, 3),
-    MineStackObjectByMaterial(AGRICULTURAL, "double_plant4", "バラの低木", Material.DOUBLE_PLANT, 4),
-    MineStackObjectByMaterial(AGRICULTURAL, "double_plant5", "ボタン", Material.DOUBLE_PLANT, 5),
-    MineStackObjectByMaterial(AGRICULTURAL, "sugar_cane", "サトウキビ", Material.SUGAR_CANE, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "pumpkin", "カボチャ", Material.PUMPKIN, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "ink_sack3", "カカオ豆", Material.INK_SACK, 3),
-    MineStackObjectByMaterial(AGRICULTURAL, "huge_mushroom_1", "キノコ", Material.HUGE_MUSHROOM_1, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "huge_mushroom_2", "キノコ", Material.HUGE_MUSHROOM_2, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "melon", "スイカ", Material.MELON, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "melon_block", "スイカ", Material.MELON_BLOCK, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "brown_mushroom", "キノコ", Material.BROWN_MUSHROOM, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "red_mushroom", "キノコ", Material.RED_MUSHROOM, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "sapling", "オークの苗木", Material.SAPLING, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "sapling1", "マツの苗木", Material.SAPLING, 1),
-    MineStackObjectByMaterial(AGRICULTURAL, "sapling2", "シラカバの苗木", Material.SAPLING, 2),
-    MineStackObjectByMaterial(AGRICULTURAL, "sapling3", "ジャングルの苗木", Material.SAPLING, 3),
-    MineStackObjectByMaterial(AGRICULTURAL, "sapling4", "アカシアの苗木", Material.SAPLING, 4),
-    MineStackObjectByMaterial(AGRICULTURAL, "sapling5", "ダークオークの苗木", Material.SAPLING, 5),
-    MineStackObjectByMaterial(AGRICULTURAL, "beetroot", "ビートルート", Material.BEETROOT, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "beetroot_seeds", "ビートルートの種", Material.BEETROOT_SEEDS, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "carrot_item", "ニンジン", Material.CARROT_ITEM, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "potato_item", "ジャガイモ", Material.POTATO_ITEM, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "poisonous_potato", "青くなったジャガイモ", Material.POISONOUS_POTATO, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "wheat", "小麦", Material.WHEAT, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "pumpkin_seeds", "カボチャの種", Material.PUMPKIN_SEEDS, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "melon_seeds", "スイカの種", Material.MELON_SEEDS, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "nether_stalk", "ネザーウォート", Material.NETHER_STALK, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "chorus_fruit", "コーラスフルーツ", Material.CHORUS_FRUIT, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "chorus_flower", "コーラスフラワー", Material.CHORUS_FLOWER, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "popped_chorus_fruit", "焼いたコーラスフルーツ", Material.CHORUS_FRUIT_POPPED, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "egg", "卵", Material.EGG, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "pork", "生の豚肉", Material.PORK, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "cooked_porkchop", "焼き豚", Material.GRILLED_PORK, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "raw_chicken", "生の鶏肉", Material.RAW_CHICKEN, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "cooked_chicken", "焼き鳥", Material.COOKED_CHICKEN, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "mutton", "生の羊肉", Material.MUTTON, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "cooked_mutton", "焼いた羊肉", Material.COOKED_MUTTON, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "raw_beef", "生の牛肉", Material.RAW_BEEF, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "cooked_beaf", "ステーキ", Material.COOKED_BEEF, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "rabbit", "生の兎肉", Material.RABBIT, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "cooked_rabbit", "焼き兎肉", Material.COOKED_RABBIT, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "raw_fish0", "生魚", Material.RAW_FISH, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "cooked_fish0", "焼き魚", Material.COOKED_FISH, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "raw_fish1", "生鮭", Material.RAW_FISH, 1),
-    MineStackObjectByMaterial(AGRICULTURAL, "cooked_fish1", "焼き鮭", Material.COOKED_FISH, 1),
-    MineStackObjectByMaterial(AGRICULTURAL, "raw_fish2", "クマノミ", Material.RAW_FISH, 2),
-    MineStackObjectByMaterial(AGRICULTURAL, "raw_fish3", "フグ", Material.RAW_FISH, 3),
-    MineStackObjectByMaterial(AGRICULTURAL, "bread", "パン", Material.BREAD, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "sugar", "砂糖", Material.SUGAR, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "baked_potato", "ベイクドポテト", Material.BAKED_POTATO, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "cake", "ケーキ", Material.CAKE, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "mushroom_stew", "キノコシチュー", Material.MUSHROOM_SOUP, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "rabbit_stew", "ウサギシチュー", Material.RABBIT_STEW, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "beetroot_soup", "ビートルートスープ", Material.BEETROOT_SOUP, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "bowl", "ボウル", Material.BOWL, 0),
-    MineStackObjectByMaterial(AGRICULTURAL, "milk_bucket", "牛乳", Material.MILK_BUCKET, 0)
+    MineStackObjectByMaterial(AGRICULTURAL, "seeds", "小麦の種", Material.WHEAT_SEEDS),
+    MineStackObjectByMaterial(AGRICULTURAL, "apple", "リンゴ", Material.APPLE),
+    MineStackObjectByMaterial(AGRICULTURAL, "long_grass2", "シダ", Material.FERN),
+    MineStackObjectByMaterial(AGRICULTURAL, "dead_bush", "枯れ木", Material.DEAD_BUSH),
+    MineStackObjectByMaterial(AGRICULTURAL, "cactus", "サボテン", Material.CACTUS),
+    MineStackObjectByMaterial(AGRICULTURAL, "vine", "ツタ", Material.VINE),
+    MineStackObjectByMaterial(AGRICULTURAL, "water_lily", "スイレンの葉", Material.LILY_PAD),
+    MineStackObjectByMaterial(AGRICULTURAL, "yellow_flower", "タンポポ", Material.DANDELION),
+    MineStackObjectByMaterial(AGRICULTURAL, "red_rose0", "ポピー", Material.POPPY),
+    MineStackObjectByMaterial(AGRICULTURAL, "red_rose1", "ヒスイラン", Material.BLUE_ORCHID),
+    MineStackObjectByMaterial(AGRICULTURAL, "red_rose2", "アリウム", Material.ALLIUM),
+    MineStackObjectByMaterial(AGRICULTURAL, "red_rose3", "ヒナソウ", Material.AZURE_BLUET),
+    MineStackObjectByMaterial(AGRICULTURAL, "red_rose4", "赤色のチューリップ", Material.RED_TULIP),
+    MineStackObjectByMaterial(AGRICULTURAL, "red_rose5", "橙色のチューリップ", Material.ORANGE_TULIP),
+    MineStackObjectByMaterial(AGRICULTURAL, "red_rose6", "白色のチューリップ", Material.WHITE_TULIP),
+    MineStackObjectByMaterial(AGRICULTURAL, "red_rose7", "桃色のチューリップ", Material.PINK_TULIP),
+    MineStackObjectByMaterial(AGRICULTURAL, "red_rose8", "フランスギク", Material.OXEYE_DAISY),
+    MineStackObjectByMaterial(AGRICULTURAL, "leaves", "オークの葉", Material.OAK_LEAVES),
+    MineStackObjectByMaterial(AGRICULTURAL, "leaves1", "トウヒの葉", Material.SPRUCE_LEAVES),
+    MineStackObjectByMaterial(AGRICULTURAL, "leaves2", "シラカバの葉", Material.BIRCH_LEAVES),
+    MineStackObjectByMaterial(AGRICULTURAL, "leaves3", "ジャングルの葉", Material.JUNGLE_LEAVES),
+    MineStackObjectByMaterial(AGRICULTURAL, "leaves_2", "アカシアの葉", Material.ACACIA_LEAVES),
+    MineStackObjectByMaterial(AGRICULTURAL, "leaves_21", "ダークオークの葉", Material.DARK_OAK_LEAVES),
+    MineStackObjectByMaterial(AGRICULTURAL, "double_plant0", "ヒマワリ", Material.SUNFLOWER),
+    MineStackObjectByMaterial(AGRICULTURAL, "double_plant1", "ライラック", Material.LILAC),
+    MineStackObjectByMaterial(AGRICULTURAL, "double_plant2", "背の高い草", Material.TALL_GRASS),
+    MineStackObjectByMaterial(AGRICULTURAL, "double_plant3", "大きなシダ", Material.LARGE_FERN),
+    MineStackObjectByMaterial(AGRICULTURAL, "double_plant4", "バラの低木", Material.ROSE_BUSH),
+    MineStackObjectByMaterial(AGRICULTURAL, "double_plant5", "ボタン", Material.PEONY),
+    MineStackObjectByMaterial(AGRICULTURAL, "sugar_cane", "サトウキビ", Material.SUGAR_CANE),
+    MineStackObjectByMaterial(AGRICULTURAL, "pumpkin", "カボチャ", Material.PUMPKIN),
+    MineStackObjectByMaterial(AGRICULTURAL, "ink_sack3", "カカオ豆", Material.COCOA_BEANS),
+    MineStackObjectByMaterial(AGRICULTURAL, "huge_mushroom_1", "茶色のキノコ", Material.BROWN_MUSHROOM),
+    MineStackObjectByMaterial(AGRICULTURAL, "huge_mushroom_2", "赤色のキノコ", Material.RED_MUSHROOM),
+    MineStackObjectByMaterial(AGRICULTURAL, "melon", "スイカの薄切り", Material.MELON_SLICE),
+    MineStackObjectByMaterial(AGRICULTURAL, "melon_block", "スイカ", Material.MELON),
+    MineStackObjectByMaterial(AGRICULTURAL, "sapling", "オークの苗木", Material.OAK_SAPLING),
+    MineStackObjectByMaterial(AGRICULTURAL, "sapling1", "トウヒの苗木", Material.SPRUCE_SAPLING),
+    MineStackObjectByMaterial(AGRICULTURAL, "sapling2", "シラカバの苗木", Material.BIRCH_SAPLING),
+    MineStackObjectByMaterial(AGRICULTURAL, "sapling3", "ジャングルの苗木", Material.JUNGLE_SAPLING),
+    MineStackObjectByMaterial(AGRICULTURAL, "sapling4", "アカシアの苗木", Material.ACACIA_SAPLING),
+    MineStackObjectByMaterial(AGRICULTURAL, "sapling5", "ダークオークの苗木", Material.DARK_OAK_SAPLING),
+    MineStackObjectByMaterial(AGRICULTURAL, "beetroot", "ビートルート", Material.BEETROOT),
+    MineStackObjectByMaterial(AGRICULTURAL, "beetroot_seeds", "ビートルートの種", Material.BEETROOT_SEEDS),
+    MineStackObjectByMaterial(AGRICULTURAL, "carrot_item", "ニンジン", Material.CARROT),
+    MineStackObjectByMaterial(AGRICULTURAL, "potato_item", "ジャガイモ", Material.POTATO),
+    MineStackObjectByMaterial(AGRICULTURAL, "poisonous_potato", "青くなったジャガイモ", Material.POISONOUS_POTATO),
+    MineStackObjectByMaterial(AGRICULTURAL, "wheat", "小麦", Material.WHEAT),
+    MineStackObjectByMaterial(AGRICULTURAL, "pumpkin_seeds", "カボチャの種", Material.PUMPKIN_SEEDS),
+    MineStackObjectByMaterial(AGRICULTURAL, "melon_seeds", "スイカの種", Material.MELON_SEEDS),
+    MineStackObjectByMaterial(AGRICULTURAL, "nether_stalk", "ネザーウォート", Material.NETHER_WART),
+    MineStackObjectByMaterial(AGRICULTURAL, "chorus_fruit", "コーラスフルーツ", Material.CHORUS_FRUIT),
+    MineStackObjectByMaterial(AGRICULTURAL, "chorus_flower", "コーラスフラワー", Material.CHORUS_FLOWER),
+    MineStackObjectByMaterial(AGRICULTURAL, "popped_chorus_fruit", "焼いたコーラスフルーツ", Material.POPPED_CHORUS_FRUIT),
+    MineStackObjectByMaterial(AGRICULTURAL, "egg", "卵", Material.EGG),
+    MineStackObjectByMaterial(AGRICULTURAL, "pork", "生の豚肉", Material.PORKCHOP),
+    MineStackObjectByMaterial(AGRICULTURAL, "cooked_porkchop", "焼き豚", Material.COOKED_PORKCHOP),
+    MineStackObjectByMaterial(AGRICULTURAL, "raw_chicken", "生の鶏肉", Material.CHICKEN),
+    MineStackObjectByMaterial(AGRICULTURAL, "cooked_chicken", "焼き鳥", Material.COOKED_CHICKEN),
+    MineStackObjectByMaterial(AGRICULTURAL, "mutton", "生の羊肉", Material.MUTTON),
+    MineStackObjectByMaterial(AGRICULTURAL, "cooked_mutton", "焼き羊肉", Material.COOKED_MUTTON),
+    MineStackObjectByMaterial(AGRICULTURAL, "raw_beef", "生の牛肉", Material.BEEF),
+    MineStackObjectByMaterial(AGRICULTURAL, "cooked_beaf", "ステーキ", Material.COOKED_BEEF),
+    MineStackObjectByMaterial(AGRICULTURAL, "rabbit", "生の兎肉", Material.RABBIT),
+    MineStackObjectByMaterial(AGRICULTURAL, "cooked_rabbit", "焼き兎肉", Material.COOKED_RABBIT),
+    MineStackObjectByMaterial(AGRICULTURAL, "raw_fish0", "生鱈", Material.COD),
+    MineStackObjectByMaterial(AGRICULTURAL, "cooked_fish0", "焼き鱈", Material.COOKED_COD),
+    MineStackObjectByMaterial(AGRICULTURAL, "raw_fish1", "生鮭", Material.SALMON),
+    MineStackObjectByMaterial(AGRICULTURAL, "cooked_fish1", "焼き鮭", Material.COOKED_SALMON),
+    MineStackObjectByMaterial(AGRICULTURAL, "raw_fish2", "熱帯魚", Material.TROPICAL_FISH),
+    MineStackObjectByMaterial(AGRICULTURAL, "raw_fish3", "フグ", Material.PUFFERFISH),
+    MineStackObjectByMaterial(AGRICULTURAL, "bread", "パン", Material.BREAD),
+    MineStackObjectByMaterial(AGRICULTURAL, "sugar", "砂糖", Material.SUGAR),
+    MineStackObjectByMaterial(AGRICULTURAL, "baked_potato", "ベイクドポテト", Material.BAKED_POTATO),
+    MineStackObjectByMaterial(AGRICULTURAL, "cake", "ケーキ", Material.CAKE),
+    MineStackObjectByMaterial(AGRICULTURAL, "mushroom_stew", "キノコシチュー", Material.MUSHROOM_STEW),
+    MineStackObjectByMaterial(AGRICULTURAL, "rabbit_stew", "ウサギシチュー", Material.RABBIT_STEW),
+    MineStackObjectByMaterial(AGRICULTURAL, "beetroot_soup", "ビートルートスープ", Material.BEETROOT_SOUP),
+    MineStackObjectByMaterial(AGRICULTURAL, "bowl", "ボウル", Material.BOWL),
+    MineStackObjectByMaterial(AGRICULTURAL, "milk_bucket", "ミルク入りバケツ", Material.MILK_BUCKET),
+    MineStackObjectByMaterial(AGRICULTURAL, "kelp", "コンブ", Material.KELP),
+    MineStackObjectByMaterial(AGRICULTURAL, "azalea_leaves", "ツツジの葉", Material.AZALEA_LEAVES),
+    MineStackObjectByMaterial(AGRICULTURAL, "flowering_azalea_leaves", "開花したツツジの葉", Material.FLOWERING_AZALEA_LEAVES),
+    MineStackObjectByMaterial(AGRICULTURAL, "carved_pumpkin", "くり抜かれたカボチャ", Material.CARVED_PUMPKIN),
+    MineStackObjectByMaterial(AGRICULTURAL, "dried_kelp_block", "乾燥した昆布ブロック", Material.DRIED_KELP_BLOCK),
+    MineStackObjectByMaterial(AGRICULTURAL, "cookie", "クッキー", Material.COOKIE),
+    MineStackObjectByMaterial(AGRICULTURAL, "dried_kelp", "乾燥した昆布", Material.DRIED_KELP),
+    MineStackObjectByMaterial(AGRICULTURAL, "glistering_melon_slice", "きらめくスイカの薄切り", Material.GLISTERING_MELON_SLICE),
+    MineStackObjectByMaterial(AGRICULTURAL, "pumpkin_pie", "パンプキンパイ", Material.PUMPKIN_PIE),
+    MineStackObjectByMaterial(AGRICULTURAL, "dye_15", "骨粉", Material.BONE_MEAL),
+    MineStackObjectByMaterial(AGRICULTURAL, "grass_block", "草", Material.GRASS),
+    MineStackObjectByMaterial(AGRICULTURAL, "azalea", "ツツジ", Material.AZALEA),
+    MineStackObjectByMaterial(AGRICULTURAL, "flowering_azalea", "開花したツツジ", Material.FLOWERING_AZALEA),
+    MineStackObjectByMaterial(AGRICULTURAL, "seagrass", "海草", Material.SEAGRASS),
+    MineStackObjectByMaterial(AGRICULTURAL, "sea_pickle", "シーピクルス", Material.SEA_PICKLE),
+    MineStackObjectByMaterial(AGRICULTURAL, "cornflower", "ヤグルマギク", Material.CORNFLOWER),
+    MineStackObjectByMaterial(AGRICULTURAL, "lily_of_the_valley", "スズラン", Material.LILY_OF_THE_VALLEY),
+    MineStackObjectByMaterial(AGRICULTURAL, "wither_rose", "ウィザーローズ", Material.WITHER_ROSE),
+    MineStackObjectByMaterial(AGRICULTURAL, "spore_blossom", "胞子の花", Material.SPORE_BLOSSOM),
+    MineStackObjectByMaterial(AGRICULTURAL, "crimson_fungus", "真紅のキノコ", Material.CRIMSON_FUNGUS),
+    MineStackObjectByMaterial(AGRICULTURAL, "warped_fungus", "歪んだキノコ", Material.WARPED_FUNGUS),
+    MineStackObjectByMaterial(AGRICULTURAL, "crimson_roots", "真紅の根", Material.CRIMSON_ROOTS),
+    MineStackObjectByMaterial(AGRICULTURAL, "warped_roots", "歪んだ根", Material.WARPED_ROOTS),
+    MineStackObjectByMaterial(AGRICULTURAL, "nether_sprouts", "ネザースプラウト", Material.NETHER_SPROUTS),
+    MineStackObjectByMaterial(AGRICULTURAL, "weeping_vines", "しだれツタ", Material.WEEPING_VINES),
+    MineStackObjectByMaterial(AGRICULTURAL, "twisting_vines", "ねじれツタ", Material.TWISTING_VINES),
+    MineStackObjectByMaterial(AGRICULTURAL, "big_dripleaf", "大きなドリップリーフ", Material.BIG_DRIPLEAF),
+    MineStackObjectByMaterial(AGRICULTURAL, "small_dripleaf", "小さなドリップリーフ", Material.SMALL_DRIPLEAF),
+    MineStackObjectByMaterial(AGRICULTURAL, "bamboo", "竹", Material.BAMBOO),
+    MineStackObjectByMaterial(AGRICULTURAL, "glow_lichen", "ヒカリゴケ", Material.GLOW_LICHEN),
+    MineStackObjectByMaterial(AGRICULTURAL, "sweet_berries", "スイートベリー", Material.SWEET_BERRIES),
+    MineStackObjectByMaterial(AGRICULTURAL, "glow_berries", "グロウベリー", Material.GLOW_BERRIES),
+    MineStackObjectByMaterial(AGRICULTURAL, "hanging_roots", "垂れ根", Material.HANGING_ROOTS),
   )
 
   // 建築系ブロック
   private val minestacklistbuild: List[MineStackObjectGroup[ItemStack]] = leftElems(
-    MineStackObjectByMaterial(BUILDING, "log", "オークの原木", Material.LOG, 0),
-    MineStackObjectByMaterial(BUILDING, "wood", "オークの木材", Material.WOOD, 0),
-    MineStackObjectByMaterial(BUILDING, "wood_step0", "オークの木材ハーフブロック", Material.WOOD_STEP, 0),
-    MineStackObjectByMaterial(BUILDING, "oak_stairs", "オークの木の階段", Material.WOOD_STAIRS, 0),
-    MineStackObjectByMaterial(BUILDING, "fence", "オークのフェンス", Material.FENCE, 0),
-    MineStackObjectByMaterial(BUILDING, "log1", "マツの原木", Material.LOG, 1),
-    MineStackObjectByMaterial(BUILDING, "wood_1", "マツの木材", Material.WOOD, 1),
-    MineStackObjectByMaterial(BUILDING, "wood_step1", "マツの木材ハーフブロック", Material.WOOD_STEP, 1),
-    MineStackObjectByMaterial(BUILDING, "spruce_stairs", "マツの木の階段", Material.SPRUCE_WOOD_STAIRS, 0),
-    MineStackObjectByMaterial(BUILDING, "spruce_fence", "マツのフェンス", Material.SPRUCE_FENCE, 0),
-    MineStackObjectByMaterial(BUILDING, "log2", "シラカバの原木", Material.LOG, 2),
-    MineStackObjectByMaterial(BUILDING, "wood_2", "シラカバの木材", Material.WOOD, 2),
-    MineStackObjectByMaterial(BUILDING, "wood_step2", "シラカバの木材ハーフブロック", Material.WOOD_STEP, 2),
-    MineStackObjectByMaterial(BUILDING, "birch_stairs", "シラカバの木の階段", Material.BIRCH_WOOD_STAIRS, 0),
-    MineStackObjectByMaterial(BUILDING, "birch_fence", "シラカバのフェンス", Material.BIRCH_FENCE, 0),
-    MineStackObjectByMaterial(BUILDING, "log3", "ジャングルの原木", Material.LOG, 3),
-    MineStackObjectByMaterial(BUILDING, "wood_3", "ジャングルの木材", Material.WOOD, 3),
-    MineStackObjectByMaterial(BUILDING, "wood_step3", "ジャングルの木材ハーフブロック", Material.WOOD_STEP, 3),
-    MineStackObjectByMaterial(BUILDING, "jungle_stairs", "ジャングルの木の階段", Material.JUNGLE_WOOD_STAIRS, 0),
-    MineStackObjectByMaterial(BUILDING, "jungle_fence", "ジャングルのフェンス", Material.JUNGLE_FENCE, 0),
-    MineStackObjectByMaterial(BUILDING, "log_2", "アカシアの原木", Material.LOG_2, 0),
-    MineStackObjectByMaterial(BUILDING, "wood_4", "アカシアの木材", Material.WOOD, 4),
-    MineStackObjectByMaterial(BUILDING, "wood_step4", "アカシアの木材ハーフブロック", Material.WOOD_STEP, 4),
-    MineStackObjectByMaterial(BUILDING, "acacia_stairs", "アカシアの木の階段", Material.ACACIA_STAIRS, 0),
-    MineStackObjectByMaterial(BUILDING, "acacia_fence", "アカシアのフェンス", Material.ACACIA_FENCE, 0),
-    MineStackObjectByMaterial(BUILDING, "log_21", "ダークオークの原木", Material.LOG_2, 1),
-    MineStackObjectByMaterial(BUILDING, "wood_5", "ダークオークの木材", Material.WOOD, 5),
-    MineStackObjectByMaterial(BUILDING, "wood_step5", "ダークオークの木材ハーフブロック", Material.WOOD_STEP, 5),
-    MineStackObjectByMaterial(BUILDING, "dark_oak_stairs", "ダークオークの木の階段", Material.DARK_OAK_STAIRS, 0),
-    MineStackObjectByMaterial(BUILDING, "dark_oak_fence", "ダークオークのフェンス", Material.DARK_OAK_FENCE, 0),
-    MineStackObjectByMaterial(BUILDING, "cobblestone", "丸石", Material.COBBLESTONE, 0),
-    MineStackObjectByMaterial(BUILDING, "step3", "丸石ハーフブロック", Material.STEP, 3),
-    MineStackObjectByMaterial(BUILDING, "stone_stairs", "丸石の階段", Material.COBBLESTONE_STAIRS, 0),
-    MineStackObjectByMaterial(BUILDING, "cobblestone_wall_0", "丸石の壁", Material.COBBLE_WALL, 0),
-    MineStackObjectByMaterial(BUILDING, "mossy_cobblestone", "苔石", Material.MOSSY_COBBLESTONE, 0),
-    MineStackObjectByMaterial(BUILDING, "cobblestone_wall_1", "苔石の壁", Material.COBBLE_WALL, 1),
-    MineStackObjectByMaterial(BUILDING, "stone", "石", Material.STONE, 0),
-    MineStackObjectByMaterial(BUILDING, "step0", "石ハーフブロック", Material.STEP, 0),
-    MineStackObjectByMaterial(BUILDING, "smooth_brick0", "石レンガ", Material.SMOOTH_BRICK, 0),
-    MineStackObjectByMaterial(BUILDING, "step5", "石レンガハーフブロック", Material.STEP, 5),
-    MineStackObjectByMaterial(BUILDING, "smooth_stairs", "石レンガの階段", Material.SMOOTH_STAIRS, 0),
-    MineStackObjectByMaterial(BUILDING, "smooth_brick3", "模様入り石レンガ", Material.SMOOTH_BRICK, 3),
-    MineStackObjectByMaterial(BUILDING, "smooth_brick1", "苔石レンガ", Material.SMOOTH_BRICK, 1),
-    MineStackObjectByMaterial(BUILDING, "smooth_brick2", "ひびの入った石レンガ", Material.SMOOTH_BRICK, 2),
-    MineStackObjectByMaterial(BUILDING, "sand", "砂", Material.SAND, 0),
-    MineStackObjectByMaterial(BUILDING, "sandstone", "砂岩", Material.SANDSTONE, 0),
-    MineStackObjectByMaterial(BUILDING, "step1", "砂岩ハーフブロック", Material.STEP, 1),
-    MineStackObjectByMaterial(BUILDING, "standstone_stairs", "砂岩の階段", Material.SANDSTONE_STAIRS, 0),
-    MineStackObjectByMaterial(BUILDING, "sandstone1", "模様入りの砂岩", Material.SANDSTONE, 1),
-    MineStackObjectByMaterial(BUILDING, "sandstone2", "なめらかな砂岩", Material.SANDSTONE, 2),
-    MineStackObjectByMaterial(BUILDING, "red_sand", "赤い砂", Material.SAND, 1),
-    MineStackObjectByMaterial(BUILDING, "red_sandstone", "赤い砂岩", Material.RED_SANDSTONE, 0),
-    MineStackObjectByMaterial(BUILDING, "stone_slab20", "赤い砂岩ハーフブロック", Material.STONE_SLAB2, 0),
-    MineStackObjectByMaterial(BUILDING, "red_sandstone_stairs", "赤い砂岩の階段", Material.RED_SANDSTONE_STAIRS, 0),
-    MineStackObjectByMaterial(BUILDING, "red_sandstone1", "模様入りの赤い砂岩", Material.RED_SANDSTONE, 1),
-    MineStackObjectByMaterial(BUILDING, "red_sandstone2", "なめらかな赤い砂岩", Material.RED_SANDSTONE, 2),
-    MineStackObjectByMaterial(BUILDING, "clay_ball", "粘土", Material.CLAY_BALL, 0),
-    MineStackObjectByMaterial(BUILDING, "clay", "粘土(ブロック)", Material.CLAY, 0),
-    MineStackObjectByMaterial(BUILDING, "brick_item", "レンガ", Material.CLAY_BRICK, 0),
-    MineStackObjectByMaterial(BUILDING, "brick", "レンガ(ブロック)", Material.BRICK, 0),
-    MineStackObjectByMaterial(BUILDING, "step4", "レンガハーフブロック", Material.STEP, 4),
-    MineStackObjectByMaterial(BUILDING, "brick_stairs", "レンガの階段", Material.BRICK_STAIRS, 0),
-    MineStackObjectByMaterial(BUILDING, "quartz_block", "ネザー水晶ブロック", Material.QUARTZ_BLOCK, 0),
-    MineStackObjectByMaterial(BUILDING, "step7", "ネザー水晶ハーフブロック", Material.STEP, 7),
-    MineStackObjectByMaterial(BUILDING, "quartz_stairs", "ネザー水晶の階段", Material.QUARTZ_STAIRS, 0),
-    MineStackObjectByMaterial(BUILDING, "quartz_block1", "模様入りネザー水晶ブロック", Material.QUARTZ_BLOCK, 1),
-    MineStackObjectByMaterial(BUILDING, "quartz_block2", "柱状ネザー水晶ブロック", Material.QUARTZ_BLOCK, 2),
-    MineStackObjectByMaterial(BUILDING, "netherrack", "ネザーラック", Material.NETHERRACK, 0),
-    MineStackObjectByMaterial(BUILDING, "nether_brick_item", "ネザーレンガ", Material.NETHER_BRICK_ITEM, 0),
-    MineStackObjectByMaterial(BUILDING, "nether_brick", "ネザーレンガ(ブロック)", Material.NETHER_BRICK, 0),
-    MineStackObjectByMaterial(BUILDING, "step6", "ネザーレンガハーフブロック", Material.STEP, 6),
-    MineStackObjectByMaterial(BUILDING, "nether_brick_stairs", "ネザーレンガの階段", Material.NETHER_BRICK_STAIRS, 0),
-    MineStackObjectByMaterial(BUILDING, "nether_brick_fence", "ネザーレンガのフェンス", Material.NETHER_FENCE, 0),
-    MineStackObjectByMaterial(BUILDING, "red_nether_brick", "赤いネザーレンガ", Material.RED_NETHER_BRICK, 0),
-    MineStackObjectByMaterial(BUILDING, "nether_wart_block", "ネザ-ウォートブロック", Material.NETHER_WART_BLOCK, 0),
-    MineStackObjectByMaterial(BUILDING, "ender_stone", "エンドストーン", Material.ENDER_STONE, 0),
-    MineStackObjectByMaterial(BUILDING, "end_bricks", "エンドストーンレンガ", Material.END_BRICKS, 0),
-    MineStackObjectByMaterial(BUILDING, "purpur_block", "プルプァブロック", Material.PURPUR_BLOCK, 0),
-    MineStackObjectByMaterial(BUILDING, "purpur_pillar", "柱状プルプァブロック", Material.PURPUR_PILLAR, 0),
-    MineStackObjectByMaterial(BUILDING, "purpur_slab", "プルプァハーフブロック", Material.PURPUR_SLAB, 0),
-    MineStackObjectByMaterial(BUILDING, "purpur_stairs", "プルプァの階段", Material.PURPUR_STAIRS, 0),
-    MineStackObjectByMaterial(BUILDING, "prismarine0", "プリズマリン", Material.PRISMARINE, 0),
-    MineStackObjectByMaterial(BUILDING, "prismarine1", "プリズマリンレンガ", Material.PRISMARINE, 1),
-    MineStackObjectByMaterial(BUILDING, "prismarine2", "ダークプリズマリン", Material.PRISMARINE, 2),
-    MineStackObjectByMaterial(BUILDING, "sea_lantern", "シーランタン", Material.SEA_LANTERN, 0),
-    MineStackObjectByMaterial(BUILDING, "granite", "花崗岩", Material.STONE, 1),
-    MineStackObjectByMaterial(BUILDING, "polished_granite", "磨かれた花崗岩", Material.STONE, 2),
-    MineStackObjectByMaterial(BUILDING, "diorite", "閃緑岩", Material.STONE, 3),
-    MineStackObjectByMaterial(BUILDING, "polished_diorite", "磨かれた閃緑岩", Material.STONE, 4),
-    MineStackObjectByMaterial(BUILDING, "andesite", "安山岩", Material.STONE, 5),
-    MineStackObjectByMaterial(BUILDING, "polished_andesite", "磨かれた安山岩", Material.STONE, 6),
-    MineStackObjectByMaterial(BUILDING, "dirt", "土", Material.DIRT, 0),
-    MineStackObjectByMaterial(BUILDING, "grass", "草ブロック", Material.GRASS, 0),
-    MineStackObjectByMaterial(BUILDING, "gravel", "砂利", Material.GRAVEL, 0),
-    MineStackObjectByMaterial(BUILDING, "flint", "火打石", Material.FLINT, 0),
-    MineStackObjectByMaterial(BUILDING, "flint_and_steel", "火打石と打ち金", Material.FLINT_AND_STEEL, 0),
-    MineStackObjectByMaterial(BUILDING, "dirt1", "粗い土", Material.DIRT, 1),
-    MineStackObjectByMaterial(BUILDING, "dirt2", "ポドゾル", Material.DIRT, 2),
-    MineStackObjectByMaterial(BUILDING, "snow_block", "雪", Material.SNOW_BLOCK, 0),
-    MineStackObjectByMaterial(BUILDING, "snow_layer", "雪タイル", Material.SNOW, 0),
-    MineStackObjectByMaterial(BUILDING, "snow_ball", "雪玉", Material.SNOW_BALL, 0),
-    MineStackObjectByMaterial(BUILDING, "ice", "氷", Material.ICE, 0),
-    MineStackObjectByMaterial(BUILDING, "packed_ice", "氷塊", Material.PACKED_ICE, 0),
-    MineStackObjectByMaterial(BUILDING, "mycel", "菌糸", Material.MYCEL, 0),
-    MineStackObjectByMaterial(BUILDING, "bone_block", "骨ブロック", Material.BONE_BLOCK, 0),
-    MineStackObjectByMaterial(BUILDING, "sponge", "スポンジ", Material.SPONGE, 0),
-    MineStackObjectByMaterial(BUILDING, "wet_sponge", "濡れたスポンジ", Material.SPONGE, 1),
-    MineStackObjectByMaterial(BUILDING, "soul_sand", "ソウルサンド", Material.SOUL_SAND, 0),
-    MineStackObjectByMaterial(BUILDING, "magma", "マグマブロック", Material.MAGMA, 0),
-    MineStackObjectByMaterial(BUILDING, "obsidian", "黒曜石", Material.OBSIDIAN, 0),
-    MineStackObjectByMaterial(BUILDING, "glowstone_dust", "グロウストーンダスト", Material.GLOWSTONE_DUST, 0),
-    MineStackObjectByMaterial(BUILDING, "glowstone", "グロウストーン", Material.GLOWSTONE, 0),
-    MineStackObjectByMaterial(BUILDING, "torch", "松明", Material.TORCH, 0),
-    MineStackObjectByMaterial(BUILDING, "jack_o_lantern", "ジャック・オ・ランタン", Material.JACK_O_LANTERN, 0),
-    MineStackObjectByMaterial(BUILDING, "end_rod", "エンドロッド", Material.END_ROD, 0),
-    MineStackObjectByMaterial(BUILDING, "bucket", "バケツ", Material.BUCKET, 0),
-    MineStackObjectByMaterial(BUILDING, "water_bucket", "水入りバケツ", Material.WATER_BUCKET, 0),
-    MineStackObjectByMaterial(BUILDING, "lava_bucket", "溶岩入りバケツ", Material.LAVA_BUCKET, 0),
-    MineStackObjectByMaterial(BUILDING, "web", "クモの巣", Material.WEB, 0),
-    MineStackObjectByMaterial(BUILDING, "rails", "レール", Material.RAILS, 0),
-    MineStackObjectByMaterial(BUILDING, "furnace", "かまど", Material.FURNACE, 0),
-    MineStackObjectByMaterial(BUILDING, "chest", "チェスト", Material.CHEST, 0),
-    MineStackObjectByMaterial(BUILDING, "book", "本", Material.BOOK, 0),
-    MineStackObjectByMaterial(BUILDING, "bookshelf", "本棚", Material.BOOKSHELF, 0),
-    MineStackObjectByMaterial(BUILDING, "iron_bars", "鉄格子", Material.IRON_FENCE, 0),
-    MineStackObjectByMaterial(BUILDING, "anvil", "金床", Material.ANVIL, 0),
-    MineStackObjectByMaterial(BUILDING, "cauldron", "大釜", Material.CAULDRON_ITEM, 0),
-    MineStackObjectByMaterial(BUILDING, "brewing_stand", "醸造台", Material.BREWING_STAND_ITEM, 0),
-    MineStackObjectByMaterial(BUILDING, "flower_pot", "植木鉢", Material.FLOWER_POT_ITEM, 0),
-    MineStackObjectByMaterial(BUILDING, "hay_block", "干し草の俵", Material.HAY_BLOCK, 0),
-    MineStackObjectByMaterial(BUILDING, "ladder", "はしご", Material.LADDER, 0),
-    MineStackObjectByMaterial(BUILDING, "sign", "看板", Material.SIGN, 0),
-    MineStackObjectByMaterial(BUILDING, "item_frame", "額縁", Material.ITEM_FRAME, 0),
-    MineStackObjectByMaterial(BUILDING, "painting", "絵画", Material.PAINTING, 0),
-    MineStackObjectByMaterial(BUILDING, "beacon", "ビーコン", Material.BEACON, 0),
-    MineStackObjectByMaterial(BUILDING, "armor_stand", "アーマースタンド", Material.ARMOR_STAND, 0),
-    MineStackObjectByMaterial(BUILDING, "end_crystal", "エンドクリスタル", Material.END_CRYSTAL, 0),
-    MineStackObjectByMaterial(BUILDING, "enchanting_table", "エンチャントテーブル", Material.ENCHANTMENT_TABLE, 0),
-    MineStackObjectByMaterial(BUILDING, "jukebox", "ジュークボックス", Material.JUKEBOX, 0),
-    MineStackObjectByMaterial(BUILDING, "hard_clay", "テラコッタ", Material.HARD_CLAY, 0),
-    MineStackObjectByMaterial(BUILDING, "workbench", "作業台", Material.WORKBENCH, 0)
+    MineStackObjectByMaterial(BUILDING, "cobblestone", "丸石", Material.COBBLESTONE),
+    MineStackObjectByMaterial(BUILDING, "mossy_cobblestone", "苔むした丸石", Material.MOSSY_COBBLESTONE),
+    MineStackObjectByMaterial(BUILDING, "stone", "石", Material.STONE),
+    MineStackObjectByMaterial(BUILDING, "smooth_brick0", "石レンガ", Material.STONE_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "smooth_brick3", "模様入りの石レンガ", Material.CHISELED_STONE_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "smooth_brick1", "苔むした石レンガ", Material.MOSSY_STONE_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "smooth_brick2", "ひび割れた石レンガ", Material.CRACKED_STONE_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "sand", "砂", Material.SAND),
+    MineStackObjectByMaterial(BUILDING, "sandstone", "砂岩", Material.SANDSTONE),
+    MineStackObjectByMaterial(BUILDING, "sandstone1", "模様入りの砂岩", Material.CHISELED_SANDSTONE),
+    MineStackObjectByMaterial(BUILDING, "sandstone2", "滑らかな砂岩", Material.SMOOTH_SANDSTONE),
+    MineStackObjectByMaterial(BUILDING, "red_sand", "赤い砂", Material.RED_SAND),
+    MineStackObjectByMaterial(BUILDING, "red_sandstone", "赤い砂岩", Material.RED_SANDSTONE),
+    MineStackObjectByMaterial(BUILDING, "red_sandstone1", "模様入りの赤い砂岩", Material.CHISELED_RED_SANDSTONE),
+    MineStackObjectByMaterial(BUILDING, "red_sandstone2", "滑らかな赤い砂岩", Material.SMOOTH_RED_SANDSTONE),
+    MineStackObjectByMaterial(BUILDING, "clay_ball", "粘土玉", Material.CLAY_BALL),
+    MineStackObjectByMaterial(BUILDING, "clay", "粘土", Material.CLAY),
+    MineStackObjectByMaterial(BUILDING, "brick_item", "レンガ", Material.BRICK),
+    MineStackObjectByMaterial(BUILDING, "brick", "レンガ(ブロック)", Material.BRICKS),
+    MineStackObjectByMaterial(BUILDING, "quartz_block", "クォーツブロック", Material.QUARTZ_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "quartz_block1", "模様入りのクォーツブロック", Material.CHISELED_QUARTZ_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "quartz_block2", "クォーツの柱", Material.QUARTZ_PILLAR),
+    MineStackObjectByMaterial(BUILDING, "netherrack", "ネザーラック", Material.NETHERRACK),
+    MineStackObjectByMaterial(BUILDING, "nether_brick_item", "ネザーレンガ", Material.NETHER_BRICK),
+    MineStackObjectByMaterial(BUILDING, "nether_brick", "ネザーレンガ(ブロック)", Material.NETHER_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "red_nether_brick", "赤いネザーレンガ", Material.RED_NETHER_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "nether_wart_block", "ネザ-ウォートブロック", Material.NETHER_WART_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "ender_stone", "エンドストーン", Material.END_STONE),
+    MineStackObjectByMaterial(BUILDING, "end_bricks", "エンドストーンレンガ", Material.END_STONE_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "purpur_block", "プルプァブロック", Material.PURPUR_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "purpur_pillar", "プルプァの柱", Material.PURPUR_PILLAR),
+    MineStackObjectByMaterial(BUILDING, "prismarine0", "プリズマリン", Material.PRISMARINE),
+    MineStackObjectByMaterial(BUILDING, "prismarine1", "プリズマリンレンガ", Material.PRISMARINE_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "prismarine2", "ダークプリズマリン", Material.DARK_PRISMARINE),
+    MineStackObjectByMaterial(BUILDING, "sea_lantern", "シーランタン", Material.SEA_LANTERN),
+    MineStackObjectByMaterial(BUILDING, "granite", "花崗岩", Material.GRANITE),
+    MineStackObjectByMaterial(BUILDING, "polished_granite", "磨かれた花崗岩", Material.POLISHED_GRANITE),
+    MineStackObjectByMaterial(BUILDING, "diorite", "閃緑岩", Material.DIORITE),
+    MineStackObjectByMaterial(BUILDING, "polished_diorite", "磨かれた閃緑岩", Material.POLISHED_DIORITE),
+    MineStackObjectByMaterial(BUILDING, "andesite", "安山岩", Material.ANDESITE),
+    MineStackObjectByMaterial(BUILDING, "polished_andesite", "磨かれた安山岩", Material.POLISHED_ANDESITE),
+    MineStackObjectByMaterial(BUILDING, "dirt", "土", Material.DIRT),
+    MineStackObjectByMaterial(BUILDING, "grass", "草ブロック", Material.GRASS_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "gravel", "砂利", Material.GRAVEL),
+    MineStackObjectByMaterial(BUILDING, "flint", "火打石", Material.FLINT),
+    MineStackObjectByMaterial(BUILDING, "flint_and_steel", "火打石と打ち金", Material.FLINT_AND_STEEL),
+    MineStackObjectByMaterial(BUILDING, "dirt1", "粗い土", Material.COARSE_DIRT),
+    MineStackObjectByMaterial(BUILDING, "dirt2", "ポドゾル", Material.PODZOL),
+    MineStackObjectByMaterial(BUILDING, "snow_block", "雪ブロック", Material.SNOW_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "snow_layer", "雪", Material.SNOW),
+    MineStackObjectByMaterial(BUILDING, "snow_ball", "雪玉", Material.SNOWBALL),
+    MineStackObjectByMaterial(BUILDING, "ice", "氷", Material.ICE),
+    MineStackObjectByMaterial(BUILDING, "packed_ice", "氷塊", Material.PACKED_ICE),
+    MineStackObjectByMaterial(BUILDING, "mycel", "菌糸", Material.MYCELIUM),
+    MineStackObjectByMaterial(BUILDING, "bone_block", "骨ブロック", Material.BONE_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "sponge", "スポンジ", Material.SPONGE),
+    MineStackObjectByMaterial(BUILDING, "wet_sponge", "濡れたスポンジ", Material.WET_SPONGE),
+    MineStackObjectByMaterial(BUILDING, "soul_sand", "ソウルサンド", Material.SOUL_SAND),
+    MineStackObjectByMaterial(BUILDING, "magma", "マグマブロック", Material.MAGMA_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "obsidian", "黒曜石", Material.OBSIDIAN),
+    MineStackObjectByMaterial(BUILDING, "glowstone_dust", "グロウストーンダスト", Material.GLOWSTONE_DUST),
+    MineStackObjectByMaterial(BUILDING, "glowstone", "グロウストーン", Material.GLOWSTONE),
+    MineStackObjectByMaterial(BUILDING, "torch", "松明", Material.TORCH),
+    MineStackObjectByMaterial(BUILDING, "jack_o_lantern", "ジャック・オ・ランタン", Material.JACK_O_LANTERN),
+    MineStackObjectByMaterial(BUILDING, "end_rod", "エンドロッド", Material.END_ROD),
+    MineStackObjectByMaterial(BUILDING, "bucket", "バケツ", Material.BUCKET),
+    MineStackObjectByMaterial(BUILDING, "water_bucket", "水入りバケツ", Material.WATER_BUCKET),
+    MineStackObjectByMaterial(BUILDING, "lava_bucket", "溶岩入りバケツ", Material.LAVA_BUCKET),
+    MineStackObjectByMaterial(BUILDING, "web", "クモの巣", Material.COBWEB),
+    MineStackObjectByMaterial(BUILDING, "rails", "レール", Material.RAIL),
+    MineStackObjectByMaterial(BUILDING, "furnace", "かまど", Material.FURNACE),
+    MineStackObjectByMaterial(BUILDING, "chest", "チェスト", Material.CHEST),
+    MineStackObjectByMaterial(BUILDING, "book", "本", Material.BOOK),
+    MineStackObjectByMaterial(BUILDING, "bookshelf", "本棚", Material.BOOKSHELF),
+    MineStackObjectByMaterial(BUILDING, "iron_bars", "鉄格子", Material.IRON_BARS),
+    MineStackObjectByMaterial(BUILDING, "anvil", "金床", Material.ANVIL),
+    MineStackObjectByMaterial(BUILDING, "cauldron", "大釜", Material.CAULDRON),
+    MineStackObjectByMaterial(BUILDING, "brewing_stand", "醸造台", Material.BREWING_STAND),
+    MineStackObjectByMaterial(BUILDING, "flower_pot", "植木鉢", Material.FLOWER_POT),
+    MineStackObjectByMaterial(BUILDING, "hay_block", "干草の俵", Material.HAY_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "ladder", "はしご", Material.LADDER),
+    MineStackObjectByMaterial(BUILDING, "item_frame", "額縁", Material.ITEM_FRAME),
+    MineStackObjectByMaterial(BUILDING, "painting", "絵画", Material.PAINTING),
+    MineStackObjectByMaterial(BUILDING, "beacon", "ビーコン", Material.BEACON),
+    MineStackObjectByMaterial(BUILDING, "armor_stand", "防具立て", Material.ARMOR_STAND),
+    MineStackObjectByMaterial(BUILDING, "end_crystal", "エンドクリスタル", Material.END_CRYSTAL),
+    MineStackObjectByMaterial(BUILDING, "enchanting_table", "エンチャントテーブル", Material.ENCHANTING_TABLE),
+    MineStackObjectByMaterial(BUILDING, "jukebox", "ジュークボックス", Material.JUKEBOX),
+    MineStackObjectByMaterial(BUILDING, "workbench", "作業台", Material.CRAFTING_TABLE),
+    MineStackObjectByMaterial(BUILDING, "deepslate", "深層岩", Material.DEEPSLATE),
+    MineStackObjectByMaterial(BUILDING, "cobbled_deepslate", "深層岩の丸石", Material.COBBLED_DEEPSLATE),
+    MineStackObjectByMaterial(BUILDING, "polished_deepslate", "磨かれた深層岩", Material.POLISHED_DEEPSLATE),
+    MineStackObjectByMaterial(BUILDING, "calcite", "方解石", Material.CALCITE),
+    MineStackObjectByMaterial(BUILDING, "tuff", "凝灰岩", Material.TUFF),
+    MineStackObjectByMaterial(BUILDING, "dripstone_block", "鍾乳石ブロック", Material.DRIPSTONE_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "rooted_dirt", "根付いた土", Material.ROOTED_DIRT),
+    MineStackObjectByMaterial(BUILDING, "crimson_nylium", "真紅のナイリウム", Material.CRIMSON_NYLIUM),
+    MineStackObjectByMaterial(BUILDING, "warped_nylium", "歪んだナイリウム", Material.WARPED_NYLIUM),
+    MineStackObjectByMaterial(BUILDING, "warped_wart_block", "歪んだウォートブロック", Material.WARPED_WART_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "tinted_glass", "遮光ガラス", Material.TINTED_GLASS),
+    MineStackObjectByMaterial(BUILDING, "cut_sandstone", "研がれた砂岩", Material.CUT_SANDSTONE),
+    MineStackObjectByMaterial(BUILDING, "moss_carpet", "苔のカーペット", Material.MOSS_CARPET),
+    MineStackObjectByMaterial(BUILDING, "moss_block", "苔ブロック", Material.MOSS_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "smooth_quartz", "滑らかなクォーツブロック", Material.SMOOTH_QUARTZ),
+    MineStackObjectByMaterial(BUILDING, "smooth_stone", "滑らかな石", Material.SMOOTH_STONE),
+    MineStackObjectByMaterial(BUILDING, "soul_soil", "ソウルソイル", Material.SOUL_SOIL),
+    MineStackObjectByMaterial(BUILDING, "basalt", "玄武岩", Material.BASALT),
+    MineStackObjectByMaterial(BUILDING, "polished_basalt", "磨かれた玄武岩", Material.POLISHED_BASALT),
+    MineStackObjectByMaterial(BUILDING, "smooth_basalt", "滑らかな玄武岩", Material.SMOOTH_BASALT),
+    MineStackObjectByMaterial(BUILDING, "soul_torch", "魂の松明", Material.SOUL_TORCH),
+    MineStackObjectByMaterial(BUILDING, "deepslate_bricks", "深層岩レンガ", Material.DEEPSLATE_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "cracked_deepslate_bricks", "ひび割れた深層岩レンガ", Material.CRACKED_DEEPSLATE_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "deepslate_tiles", "深層岩タイル", Material.DEEPSLATE_TILES),
+    MineStackObjectByMaterial(BUILDING, "cracked_deepslate_tiles", "ひび割れた深層岩タイル", Material.CRACKED_DEEPSLATE_TILES),
+    MineStackObjectByMaterial(BUILDING, "chiseled_deepslate", "模様入りの深層岩", Material.CHISELED_DEEPSLATE),
+    MineStackObjectByMaterial(BUILDING, "brown_mushroom_block", "茶色のキノコブロック", Material.BROWN_MUSHROOM_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "red_mushroom_block", "赤色のキノコブロック", Material.RED_MUSHROOM_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "mushroom_stem", "キノコの柄", Material.MUSHROOM_STEM),
+    MineStackObjectByMaterial(BUILDING, "chain", "鎖", Material.CHAIN),
+    MineStackObjectByMaterial(BUILDING, "cracked_nether_bricks", "ひび割れたネザーレンガ", Material.CRACKED_NETHER_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "chiseled_nether_bricks", "模様入りのネザーレンガ", Material.CHISELED_NETHER_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "quartz_bricks", "クォーツレンガ", Material.QUARTZ_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "cut_red_sandstone", "研がれた赤い砂岩", Material.CUT_RED_SANDSTONE),
+    MineStackObjectByMaterial(BUILDING, "turtle_egg", "カメの卵", Material.TURTLE_EGG),
+    MineStackObjectByMaterial(BUILDING, "blue_ice", "青氷", Material.BLUE_ICE),
+    MineStackObjectByMaterial(BUILDING, "conduit", "コンジット", Material.CONDUIT),
+    MineStackObjectByMaterial(BUILDING, "scaffolding", "足場", Material.SCAFFOLDING),
+    MineStackObjectByMaterial(BUILDING, "honey_block", "ハチミツブロック", Material.HONEY_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "loom", "機織り機", Material.LOOM),
+    MineStackObjectByMaterial(BUILDING, "composter", "コンポスター", Material.COMPOSTER),
+    MineStackObjectByMaterial(BUILDING, "barrel", "樽", Material.BARREL),
+    MineStackObjectByMaterial(BUILDING, "smoker", "燻製器", Material.SMOKER),
+    MineStackObjectByMaterial(BUILDING, "blast_furnace", "溶鉱炉", Material.BLAST_FURNACE),
+    MineStackObjectByMaterial(BUILDING, "cartography_table", "製図台", Material.CARTOGRAPHY_TABLE),
+    MineStackObjectByMaterial(BUILDING, "fletching_table", "矢細工台", Material.FLETCHING_TABLE),
+    MineStackObjectByMaterial(BUILDING, "grindstone", "砥石", Material.GRINDSTONE),
+    MineStackObjectByMaterial(BUILDING, "smithing_table", "鍛冶台", Material.SMITHING_TABLE),
+    MineStackObjectByMaterial(BUILDING, "stonecutter", "石切台", Material.STONECUTTER),
+    MineStackObjectByMaterial(BUILDING, "bell", "鐘", Material.BELL),
+    MineStackObjectByMaterial(BUILDING, "lantern", "ランタン", Material.LANTERN),
+    MineStackObjectByMaterial(BUILDING, "soul_lantern", "魂のランタン", Material.SOUL_LANTERN),
+    MineStackObjectByMaterial(BUILDING, "campfire", "焚き火", Material.CAMPFIRE),
+    MineStackObjectByMaterial(BUILDING, "soul_campfire", "魂の焚き火", Material.SOUL_CAMPFIRE),
+    MineStackObjectByMaterial(BUILDING, "shroomlight", "シュルームライト", Material.SHROOMLIGHT),
+    MineStackObjectByMaterial(BUILDING, "honeycomb", "ハニカム", Material.HONEYCOMB),
+    MineStackObjectByMaterial(BUILDING, "beehive", "養蜂箱", Material.BEEHIVE),
+    MineStackObjectByMaterial(BUILDING, "honey_bottle", "ハチミツ入りの瓶", Material.HONEY_BOTTLE),
+    MineStackObjectByMaterial(BUILDING, "honeycomb_block", "ハニカムブロック", Material.HONEYCOMB_BLOCK),
+    MineStackObjectByMaterial(BUILDING, "lodestone", "ロードストーン", Material.LODESTONE),
+    MineStackObjectByMaterial(BUILDING, "crying_obsidian", "泣く黒曜石", Material.CRYING_OBSIDIAN),
+    MineStackObjectByMaterial(BUILDING, "blackstone", "ブラックストーン", Material.BLACKSTONE),
+    MineStackObjectByMaterial(BUILDING, "gilded_blackstone", "きらめくブラックストーン", Material.GILDED_BLACKSTONE),
+    MineStackObjectByMaterial(BUILDING, "polished_blackstone", "磨かれたブラックストーン", Material.POLISHED_BLACKSTONE),
+    MineStackObjectByMaterial(BUILDING, "chiseled_polished_blackstone", "模様入りの磨かれたブラックストーン", Material.CHISELED_POLISHED_BLACKSTONE),
+    MineStackObjectByMaterial(BUILDING, "polished_blackstone_bricks", "磨かれたブラックストーンレンガ", Material.POLISHED_BLACKSTONE_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "cracked_polished_blackstone_bricks", "ひび割れたブラックストーンレンガ", Material.CRACKED_POLISHED_BLACKSTONE_BRICKS),
+    MineStackObjectByMaterial(BUILDING, "respawn_anchor", "リスポーンアンカー", Material.RESPAWN_ANCHOR),
+    MineStackObjectByMaterial(BUILDING, "pointed_dripstone", "鍾乳石", Material.POINTED_DRIPSTONE),
+    MineStackObjectByMaterial(BUILDING, "powder_snow_bucket", "粉雪入りバケツ", Material.POWDER_SNOW_BUCKET),
+    MineStackObjectByMaterial(BUILDING, "fire_charge", "ファイヤーチャージ", Material.FIRE_CHARGE),
+    MineStackObjectByMaterial(BUILDING, "writable_book", "本と羽根ペン", Material.WRITABLE_BOOK),
+    MineStackObjectByMaterial(BUILDING, "glow_item_frame", "輝く額縁", Material.GLOW_ITEM_FRAME),
   ) ++ rightElems(
-    MineStackObjectWithColorVariants(
-      MineStackObjectByMaterial(BUILDING, "bed", "白色のベッド", Material.BED, 0),
-      List(
-        MineStackObjectByMaterial(BUILDING, "bed_1", "橙色のベッド", Material.BED, 1),
-        MineStackObjectByMaterial(BUILDING, "bed_2", "赤紫色のベッド", Material.BED, 2),
-        MineStackObjectByMaterial(BUILDING, "bed_3", "空色のベッド", Material.BED, 3),
-        MineStackObjectByMaterial(BUILDING, "bed_4", "黄色のベッド", Material.BED, 4),
-        MineStackObjectByMaterial(BUILDING, "bed_5", "黄緑色のベッド", Material.BED, 5),
-        MineStackObjectByMaterial(BUILDING, "bed_6", "桃色のベッド", Material.BED, 6),
-        MineStackObjectByMaterial(BUILDING, "bed_7", "灰色のベッド", Material.BED, 7),
-        MineStackObjectByMaterial(BUILDING, "bed_8", "薄灰色のベッド", Material.BED, 8),
-        MineStackObjectByMaterial(BUILDING, "bed_9", "青緑色のベッド", Material.BED, 9),
-        MineStackObjectByMaterial(BUILDING, "bed_10", "紫色のベッド", Material.BED, 10),
-        MineStackObjectByMaterial(BUILDING, "bed_11", "青色のベッド", Material.BED, 11),
-        MineStackObjectByMaterial(BUILDING, "bed_12", "茶色のベッド", Material.BED, 12),
-        MineStackObjectByMaterial(BUILDING, "bed_13", "緑色のベッド", Material.BED, 13),
-        MineStackObjectByMaterial(BUILDING, "bed_14", "赤色のベッド", Material.BED, 14),
-        MineStackObjectByMaterial(BUILDING, "bed_15", "黒色のベッド", Material.BED, 15)
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "log", "オークの原木", Material.OAK_LOG),
+      List(
+        MineStackObjectByMaterial(BUILDING, "log1", "トウヒの原木", Material.SPRUCE_LOG),
+        MineStackObjectByMaterial(BUILDING, "log2", "シラカバの原木", Material.BIRCH_LOG),
+        MineStackObjectByMaterial(BUILDING, "log3", "ジャングルの原木", Material.JUNGLE_LOG),
+        MineStackObjectByMaterial(BUILDING, "log_2", "アカシアの原木", Material.ACACIA_LOG),
+        MineStackObjectByMaterial(BUILDING, "log_21", "ダークオークの原木", Material.DARK_OAK_LOG),
+        MineStackObjectByMaterial(BUILDING, "crimson_stem", "真紅の幹", Material.CRIMSON_STEM),
+        MineStackObjectByMaterial(BUILDING, "warped_stem", "歪んだ幹", Material.WARPED_STEM),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "stripped_oak_log", "樹皮を剥いだオークの原木", Material.STRIPPED_OAK_LOG),
+      List(
+        MineStackObjectByMaterial(BUILDING, "stripped_spruce_log", "樹皮を剥いだトウヒの原木", Material.STRIPPED_SPRUCE_LOG),
+        MineStackObjectByMaterial(BUILDING, "stripped_birch_log", "樹皮を剥いだシラカバの原木", Material.STRIPPED_BIRCH_LOG),
+        MineStackObjectByMaterial(BUILDING, "stripped_jungle_log", "樹皮を剥いだジャングルの原木", Material.STRIPPED_JUNGLE_LOG),
+        MineStackObjectByMaterial(BUILDING, "stripped_acacia_log", "樹皮を剥いだアカシアの原木", Material.STRIPPED_ACACIA_LOG),
+        MineStackObjectByMaterial(BUILDING, "stripped_dark_oak_log", "樹皮を剥いだダークオークの原木", Material.STRIPPED_DARK_OAK_LOG),
+        MineStackObjectByMaterial(BUILDING, "stripped_crimson_stem", "表皮を剥いだ真紅の幹", Material.STRIPPED_CRIMSON_STEM),
+        MineStackObjectByMaterial(BUILDING, "stripped_warped_stem", "表皮を剥いだ歪んだ幹", Material.STRIPPED_WARPED_STEM),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "stripped_oak_wood", "樹皮を剥いだオークの木", Material.STRIPPED_OAK_WOOD),
+      List(
+        MineStackObjectByMaterial(BUILDING, "stripped_spruce_wood", "樹皮を剥いだトウヒの木", Material.STRIPPED_SPRUCE_WOOD),
+        MineStackObjectByMaterial(BUILDING, "stripped_birch_wood", "樹皮を剥いだシラカバの木", Material.STRIPPED_BIRCH_WOOD),
+        MineStackObjectByMaterial(BUILDING, "stripped_jungle_wood", "樹皮を剥いだジャングルの木", Material.STRIPPED_JUNGLE_WOOD),
+        MineStackObjectByMaterial(BUILDING, "stripped_acacia_wood", "樹皮を剥いだアカシアの木", Material.STRIPPED_ACACIA_WOOD),
+        MineStackObjectByMaterial(BUILDING, "stripped_dark_oak_wood", "樹皮を剥いだダークオークの木", Material.STRIPPED_DARK_OAK_WOOD),
+        MineStackObjectByMaterial(BUILDING, "stripped_crimson_hyphae", "表皮を剥いだ真紅の菌糸", Material.STRIPPED_CRIMSON_HYPHAE),
+        MineStackObjectByMaterial(BUILDING, "stripped_warped_hyphae", "表皮を剥いだ歪んだ菌糸", Material.STRIPPED_WARPED_HYPHAE),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "wood", "オークの木", Material.OAK_WOOD),
+      List(
+        MineStackObjectByMaterial(BUILDING, "wood_1", "トウヒの木", Material.SPRUCE_WOOD),
+        MineStackObjectByMaterial(BUILDING, "wood_2", "シラカバの木", Material.BIRCH_WOOD),
+        MineStackObjectByMaterial(BUILDING, "wood_3", "ジャングルの木", Material.JUNGLE_WOOD),
+        MineStackObjectByMaterial(BUILDING, "wood_4", "アカシアの木", Material.ACACIA_WOOD),
+        MineStackObjectByMaterial(BUILDING, "wood_5", "ダークオークの木", Material.DARK_OAK_WOOD),
+        MineStackObjectByMaterial(BUILDING, "crimson_hyphae", "真紅の菌糸", Material.CRIMSON_HYPHAE),
+        MineStackObjectByMaterial(BUILDING, "warped_hyphae", "歪んだ菌糸", Material.WARPED_HYPHAE),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "oak_planks", "オークの板材", Material.OAK_PLANKS),
+      List(
+        MineStackObjectByMaterial(BUILDING, "spruce_planks", "トウヒの板材", Material.SPRUCE_PLANKS),
+        MineStackObjectByMaterial(BUILDING, "birch_planks", "シラカバの板材", Material.BIRCH_PLANKS),
+        MineStackObjectByMaterial(BUILDING, "jungle_planks", "ジャングルの板材", Material.JUNGLE_PLANKS),
+        MineStackObjectByMaterial(BUILDING, "acacia_planks", "アカシアの板材", Material.ACACIA_PLANKS),
+        MineStackObjectByMaterial(BUILDING, "dark_oak_planks", "ダークオークの板材", Material.DARK_OAK_PLANKS),
+        MineStackObjectByMaterial(BUILDING, "crimson_planks", "真紅の板材", Material.CRIMSON_PLANKS),
+        MineStackObjectByMaterial(BUILDING, "warped_planks", "歪んだ板材", Material.WARPED_PLANKS),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "wood_step0", "オークのハーフブロック", Material.OAK_SLAB),
+      List(
+        MineStackObjectByMaterial(BUILDING, "wood_step1", "トウヒのハーフブロック", Material.SPRUCE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "wood_step2", "シラカバのハーフブロック", Material.BIRCH_SLAB),
+        MineStackObjectByMaterial(BUILDING, "wood_step3", "ジャングルのハーフブロック", Material.JUNGLE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "wood_step4", "アカシアのハーフブロック", Material.ACACIA_SLAB),
+        MineStackObjectByMaterial(BUILDING, "wood_step5", "ダークオークのハーフブロック", Material.DARK_OAK_SLAB),
+        MineStackObjectByMaterial(BUILDING, "step3", "丸石のハーフブロック", Material.COBBLESTONE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "step0", "石のハーフブロック", Material.STONE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "step5", "石レンガのハーフブロック", Material.STONE_BRICK_SLAB),
+        MineStackObjectByMaterial(BUILDING, "step1", "砂岩のハーフブロック", Material.SANDSTONE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "stone_slab20", "赤い砂岩のハーフブロック", Material.RED_SANDSTONE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "step4", "レンガのハーフブロック", Material.BRICK_SLAB),
+        MineStackObjectByMaterial(BUILDING, "step7", "クォーツのハーフブロック", Material.QUARTZ_SLAB),
+        MineStackObjectByMaterial(BUILDING, "step6", "ネザーレンガのハーフブロック", Material.NETHER_BRICK_SLAB),
+        MineStackObjectByMaterial(BUILDING, "purpur_slab", "プルプァのハーフブロック", Material.PURPUR_SLAB),
+        MineStackObjectByMaterial(BUILDING, "cut_copper_slab", "切り込み入りの銅のハーフブロック", Material.CUT_COPPER_SLAB),
+        MineStackObjectByMaterial(BUILDING, "exposed_cut_copper_slab", "風化した切り込み入りの銅のハーフブロック", Material.EXPOSED_CUT_COPPER_SLAB),
+        MineStackObjectByMaterial(BUILDING, "weathered_cut_copper_slab", "錆びた切り込み入りの銅のハーフブロック", Material.WEATHERED_CUT_COPPER_SLAB),
+        MineStackObjectByMaterial(BUILDING, "oxidized_cut_copper_slab", "酸化した切り込み入りの銅のハーフブロック", Material.OXIDIZED_CUT_COPPER_SLAB),
+        MineStackObjectByMaterial(BUILDING, "waxed_cut_copper_slab", "錆止めされた切り込み入りの銅のハーフブロック", Material.WAXED_CUT_COPPER_SLAB),
+        MineStackObjectByMaterial(BUILDING, "waxed_exposed_cut_copper_slab", "錆止めされた風化した切り込み入りの銅のハーフブロック", Material.WAXED_EXPOSED_CUT_COPPER_SLAB),
+        MineStackObjectByMaterial(BUILDING, "waxed_weathered_cut_copper_slab", "錆止めされた錆びた切り込み入りの銅のハーフブロック", Material.WAXED_WEATHERED_CUT_COPPER_SLAB),
+        MineStackObjectByMaterial(BUILDING, "waxed_oxidized_cut_copper_slab", "錆止めされた酸化した切り込み入りの銅のハーフブロック", Material.WAXED_OXIDIZED_CUT_COPPER_SLAB),
+        MineStackObjectByMaterial(BUILDING, "crimson_slab", "真紅のハーフブロック", Material.CRIMSON_SLAB),
+        MineStackObjectByMaterial(BUILDING, "warped_slab", "歪んだハーフブロック", Material.WARPED_SLAB),
+        MineStackObjectByMaterial(BUILDING, "smooth_stone_slab", "滑らかな石のハーフブロック", Material.SMOOTH_STONE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "cut_sandstone_slab", "研がれた砂岩のハーフブロック", Material.CUT_SANDSTONE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "cut_red_sandstone_slab", "研がれた赤い砂岩のハーフブロック", Material.CUT_RED_SANDSTONE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "prismarine_slab", "プリズマリンのハーフブロック", Material.PRISMARINE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "prismarine_brick_slab", "プリズマリンレンガのハーフブロック", Material.PRISMARINE_BRICK_SLAB),
+        MineStackObjectByMaterial(BUILDING, "dark_prismarine_slab", "ダークプリズマリンのハーフブロック", Material.DARK_PRISMARINE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "polished_granite_slab", "磨かれた花崗岩のハーフブロック", Material.POLISHED_GRANITE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "smooth_red_sandstone_slab", "滑らかな赤い砂岩のハーフブロック", Material.SMOOTH_RED_SANDSTONE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "mossy_stone_brick_slab", "苔むした石レンガのハーフブロック", Material.MOSSY_STONE_BRICK_SLAB),
+        MineStackObjectByMaterial(BUILDING, "polished_diorite_slab", "磨かれた閃緑岩のハーフブロック", Material.POLISHED_DIORITE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "mossy_cobblestone_slab", "苔むした丸石のハーフブロック", Material.MOSSY_COBBLESTONE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "end_stone_brick_slab", "エンドストーンレンガのハーフブロック", Material.END_STONE_BRICK_SLAB),
+        MineStackObjectByMaterial(BUILDING, "smooth_sandstone_slab", "滑らかな砂岩のハーフブロック", Material.SMOOTH_SANDSTONE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "smooth_quartz_slab", "滑らかなクォーツのハーフブロック", Material.SMOOTH_QUARTZ_SLAB),
+        MineStackObjectByMaterial(BUILDING, "granite_slab", "花崗岩のハーフブロック", Material.GRANITE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "andesite_slab", "安山岩のハーフブロック", Material.ANDESITE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "red_nether_brick_slab", "赤いネザーレンガのハーフブロック", Material.RED_NETHER_BRICK_SLAB),
+        MineStackObjectByMaterial(BUILDING, "polished_andesite_slab", "磨かれた安山岩のハーフブロック", Material.POLISHED_ANDESITE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "diorite_slab", "閃緑岩のハーフブロック", Material.DIORITE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "cobbled_deepslate_slab", "深層岩の丸石のハーフブロック", Material.COBBLED_DEEPSLATE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "polished_deepslate_slab", "磨かれた深層岩のハーフブロック", Material.POLISHED_DEEPSLATE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "deepslate_brick_slab", "深層岩レンガのハーフブロック", Material.DEEPSLATE_BRICK_SLAB),
+        MineStackObjectByMaterial(BUILDING, "deepslate_tile_slab", "深層岩タイルのハーフブロック", Material.DEEPSLATE_TILE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "blackstone_slab", "ブラックストーンのハーフブロック", Material.BLACKSTONE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "polished_blackstone_slab", "磨かれたブラックストーンのハーフブロック", Material.POLISHED_BLACKSTONE_SLAB),
+        MineStackObjectByMaterial(BUILDING, "polished_blackstone_brick_slab", "磨かれたブラックストーンレンガのハーフブロック", Material.POLISHED_BLACKSTONE_BRICK_SLAB),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "oak_stairs", "オークの階段", Material.OAK_STAIRS),
+      List(
+        MineStackObjectByMaterial(BUILDING, "spruce_stairs", "トウヒの階段", Material.SPRUCE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "birch_stairs", "シラカバの階段", Material.BIRCH_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "jungle_stairs", "ジャングルの階段", Material.JUNGLE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "acacia_stairs", "アカシアの階段", Material.ACACIA_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "dark_oak_stairs", "ダークオークの階段", Material.DARK_OAK_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "stone_stairs", "丸石の階段", Material.COBBLESTONE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "smooth_stairs", "石レンガの階段", Material.STONE_BRICK_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "standstone_stairs", "砂岩の階段", Material.SANDSTONE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "red_sandstone_stairs", "赤い砂岩の階段", Material.RED_SANDSTONE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "brick_stairs", "レンガの階段", Material.BRICK_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "quartz_stairs", "クォーツの階段", Material.QUARTZ_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "nether_brick_stairs", "ネザーレンガの階段", Material.NETHER_BRICK_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "purpur_stairs", "プルプァの階段", Material.PURPUR_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "cut_copper_stairs", "切り込み入りの銅の階段", Material.CUT_COPPER_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "exposed_cut_copper_stairs", "風化した切り込み入りの銅の階段", Material.EXPOSED_CUT_COPPER_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "weathered_cut_copper_stairs", "錆びた切り込み入りの銅の階段", Material.WEATHERED_CUT_COPPER_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "oxidized_cut_copper_stairs", "酸化した切り込み入りの銅の階段", Material.OXIDIZED_CUT_COPPER_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "waxed_cut_copper_stairs", "錆止めされた切り込み入りの銅の階段", Material.WAXED_CUT_COPPER_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "waxed_exposed_cut_copper_stairs", "錆止めされた風化した切り込み入りの銅の階段", Material.WAXED_EXPOSED_CUT_COPPER_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "waxed_weathered_cut_copper_stairs", "錆止めされた錆びた切り込み入りの銅の階段", Material.WAXED_WEATHERED_CUT_COPPER_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "waxed_oxidized_cut_copper_stairs", "錆止めされた酸化した切り込み入りの銅の階段", Material.WAXED_OXIDIZED_CUT_COPPER_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "crimson_stairs", "真紅の階段", Material.CRIMSON_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "prismarine_stairs", "プリズマリンの階段", Material.PRISMARINE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "prismarine_brick_stairs", "プリズマリンレンガの階段", Material.PRISMARINE_BRICK_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "dark_prismarine_stairs", "ダークプリズマリンの階段", Material.DARK_PRISMARINE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "polished_granite_stairs", "磨かれた花崗岩の階段", Material.POLISHED_GRANITE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "smooth_red_sandstone_stairs", "滑らかな赤い砂岩の階段", Material.SMOOTH_RED_SANDSTONE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "mossy_stone_brick_stairs", "苔むした石レンガの階段", Material.MOSSY_STONE_BRICK_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "polished_diorite_stairs", "磨かれた閃緑岩の階段", Material.POLISHED_DIORITE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "mossy_cobblestone_stairs", "苔むした丸石の階段", Material.MOSSY_COBBLESTONE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "end_stone_brick_stairs", "エンドストーンレンガの階段", Material.END_STONE_BRICK_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "stone_stairs", "石の階段", Material.STONE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "smooth_sandstone_stairs", "滑らかな砂岩の階段", Material.SMOOTH_SANDSTONE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "smooth_quartz_stairs", "滑らかなクォーツの階段", Material.SMOOTH_QUARTZ_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "granite_stairs", "花崗岩の階段", Material.GRANITE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "andesite_stairs", "安山岩の階段", Material.ANDESITE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "red_nether_brick_stairs", "赤いネザーレンガの階段", Material.RED_NETHER_BRICK_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "polished_andesite_stairs", "磨かれた安山岩の階段", Material.POLISHED_ANDESITE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "diorite_stairs", "閃緑岩の階段", Material.DIORITE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "cobbled_deepslate_stairs", "深層岩の丸石の階段", Material.COBBLED_DEEPSLATE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "polished_deepslate_stairs", "磨かれた深層岩の階段", Material.POLISHED_DEEPSLATE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "deepslate_brick_stairs", "深層岩レンガの階段", Material.DEEPSLATE_BRICK_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "deepslate_tile_stairs", "深層岩タイルの階段", Material.DEEPSLATE_TILE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "blackstone_stairs", "ブラックストーンの階段", Material.BLACKSTONE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "polished_blackstone_stairs", "磨かれたブラックストーンの階段", Material.POLISHED_BLACKSTONE_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "polished_blackstone_brick_stairs", "磨かれたブラックストーンレンガの階段", Material.POLISHED_BLACKSTONE_BRICK_STAIRS),
+        MineStackObjectByMaterial(BUILDING, "warped_stairs", "歪んだ階段", Material.WARPED_STAIRS),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "brick_wall", "レンガの塀", Material.BRICK_WALL),
+      List(
+        MineStackObjectByMaterial(BUILDING, "cobblestone_wall_0", "丸石の塀", Material.COBBLESTONE_WALL),
+        MineStackObjectByMaterial(BUILDING, "cobblestone_wall_1", "苔むした丸石の塀", Material.MOSSY_COBBLESTONE_WALL),
+        MineStackObjectByMaterial(BUILDING, "prismarine_wall", "プリズマリンの塀", Material.PRISMARINE_WALL),
+        MineStackObjectByMaterial(BUILDING, "red_sandstone_wall", "赤い砂岩の塀", Material.RED_SANDSTONE_WALL),
+        MineStackObjectByMaterial(BUILDING, "mossy_stone_brick_wall", "苔むした石レンガの塀", Material.MOSSY_STONE_BRICK_WALL),
+        MineStackObjectByMaterial(BUILDING, "granite_wall", "花崗岩の塀", Material.GRANITE_WALL),
+        MineStackObjectByMaterial(BUILDING, "stone_brick_wall", "石レンガの塀", Material.STONE_BRICK_WALL),
+        MineStackObjectByMaterial(BUILDING, "nether_brick_wall", "ネザーレンガの塀", Material.NETHER_BRICK_WALL),
+        MineStackObjectByMaterial(BUILDING, "andesite_wall", "安山岩の塀", Material.ANDESITE_WALL),
+        MineStackObjectByMaterial(BUILDING, "red_nether_brick_wall", "赤いネザーレンガの塀", Material.RED_NETHER_BRICK_WALL),
+        MineStackObjectByMaterial(BUILDING, "sandstone_wall", "砂岩の塀", Material.SANDSTONE_WALL),
+        MineStackObjectByMaterial(BUILDING, "end_stone_brick_wall", "エンドストーンレンガの塀", Material.END_STONE_BRICK_WALL),
+        MineStackObjectByMaterial(BUILDING, "diorite_wall", "閃緑岩の塀", Material.DIORITE_WALL),
+        MineStackObjectByMaterial(BUILDING, "blackstone_wall", "ブラックストーンの塀", Material.BLACKSTONE_WALL),
+        MineStackObjectByMaterial(BUILDING, "polished_blackstone_wall", "磨かれたブラックストーンの塀", Material.POLISHED_BLACKSTONE_WALL),
+        MineStackObjectByMaterial(BUILDING, "polished_blackstone_brick_wall", "磨かれたブラックストーンレンガの塀", Material.POLISHED_BLACKSTONE_BRICK_WALL),
+        MineStackObjectByMaterial(BUILDING, "cobbled_deepslate_wall", "深層岩の丸石の塀", Material.COBBLED_DEEPSLATE_WALL),
+        MineStackObjectByMaterial(BUILDING, "polished_deepslate_wall", "磨かれた深層岩の塀", Material.POLISHED_DEEPSLATE_WALL),
+        MineStackObjectByMaterial(BUILDING, "deepslate_brick_wall", "深層岩レンガの塀", Material.DEEPSLATE_BRICK_WALL),
+        MineStackObjectByMaterial(BUILDING, "deepslate_tile_wall", "深層岩タイルの塀", Material.DEEPSLATE_TILE_WALL),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "fence", "オークのフェンス", Material.OAK_FENCE),
+      List(
+        MineStackObjectByMaterial(BUILDING, "spruce_fence", "トウヒのフェンス", Material.SPRUCE_FENCE),
+        MineStackObjectByMaterial(BUILDING, "birch_fence", "シラカバのフェンス", Material.BIRCH_FENCE),
+        MineStackObjectByMaterial(BUILDING, "jungle_fence", "ジャングルのフェンス", Material.JUNGLE_FENCE),
+        MineStackObjectByMaterial(BUILDING, "acacia_fence", "アカシアのフェンス", Material.ACACIA_FENCE),
+        MineStackObjectByMaterial(BUILDING, "dark_oak_fence", "ダークオークのフェンス", Material.DARK_OAK_FENCE),
+        MineStackObjectByMaterial(BUILDING, "nether_brick_fence", "ネザーレンガのフェンス", Material.NETHER_BRICK_FENCE),
+        MineStackObjectByMaterial(BUILDING, "crimson_fence", "真紅のフェンス", Material.CRIMSON_FENCE),
+        MineStackObjectByMaterial(BUILDING, "warped_fence", "歪んだフェンス", Material.WARPED_FENCE),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "dead_tube_coral_fan", "死んだクダウチワサンゴ", Material.DEAD_TUBE_CORAL_FAN),
+      List(
+        MineStackObjectByMaterial(BUILDING, "dead_brain_coral_fan", "死んだノウウチワサンゴ", Material.DEAD_BRAIN_CORAL_FAN),
+        MineStackObjectByMaterial(BUILDING, "dead_bubble_coral_fan", "死んだミズタマウチワサンゴ", Material.DEAD_BUBBLE_CORAL_FAN),
+        MineStackObjectByMaterial(BUILDING, "dead_fire_coral_fan", "死んだミレポラウチワサンゴ", Material.DEAD_FIRE_CORAL_FAN),
+        MineStackObjectByMaterial(BUILDING, "dead_horn_coral_fan", "死んだシカツノウチワサンゴ", Material.DEAD_HORN_CORAL_FAN),
+        MineStackObjectByMaterial(BUILDING, "dead_brain_coral", "死んだノウサンゴ", Material.DEAD_BRAIN_CORAL),
+        MineStackObjectByMaterial(BUILDING, "dead_bubble_coral", "死んだミズタマサンゴ", Material.DEAD_BUBBLE_CORAL),
+        MineStackObjectByMaterial(BUILDING, "dead_fire_coral", "死んだミレポラサンゴ", Material.DEAD_FIRE_CORAL),
+        MineStackObjectByMaterial(BUILDING, "dead_horn_coral", "死んだシカツノサンゴ", Material.DEAD_HORN_CORAL),
+        MineStackObjectByMaterial(BUILDING, "dead_tube_coral", "死んだクダサンゴ", Material.DEAD_TUBE_CORAL),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "tube_coral_block", "クダサンゴブロック", Material.TUBE_CORAL_BLOCK),
+      List(
+        MineStackObjectByMaterial(BUILDING, "brain_coral_block", "ノウサンゴブロック", Material.BRAIN_CORAL_BLOCK),
+        MineStackObjectByMaterial(BUILDING, "bubble_coral_block", "ミズタマサンゴブロック", Material.BUBBLE_CORAL_BLOCK),
+        MineStackObjectByMaterial(BUILDING, "fire_coral_block", "ミレポラサンゴブロック", Material.FIRE_CORAL_BLOCK),
+        MineStackObjectByMaterial(BUILDING, "horn_coral_block", "シカツノサンゴブロック", Material.HORN_CORAL_BLOCK),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "dead_tube_coral_block", "死んだクダサンゴブロック", Material.DEAD_TUBE_CORAL_BLOCK),
+      List(
+        MineStackObjectByMaterial(BUILDING, "dead_brain_coral_block", "死んだノウサンゴブロック", Material.DEAD_BRAIN_CORAL_BLOCK),
+        MineStackObjectByMaterial(BUILDING, "dead_bubble_coral_block", "死んだミズタマサンゴブロック", Material.DEAD_BUBBLE_CORAL_BLOCK),
+        MineStackObjectByMaterial(BUILDING, "dead_fire_coral_block", "死んだミレポラサンゴブロック", Material.DEAD_FIRE_CORAL_BLOCK),
+        MineStackObjectByMaterial(BUILDING, "dead_horn_coral_block", "死んだシカツノサンゴブロック", Material.DEAD_HORN_CORAL_BLOCK),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "tube_coral", "クダサンゴ", Material.TUBE_CORAL),
+      List(
+        MineStackObjectByMaterial(BUILDING, "brain_coral", "ノウサンゴ", Material.BRAIN_CORAL),
+        MineStackObjectByMaterial(BUILDING, "bubble_coral", "ミズタマサンゴ", Material.BUBBLE_CORAL),
+        MineStackObjectByMaterial(BUILDING, "fire_coral", "ミレポラサンゴ", Material.FIRE_CORAL),
+        MineStackObjectByMaterial(BUILDING, "horn_coral", "シカツノサンゴ", Material.HORN_CORAL),
+        MineStackObjectByMaterial(BUILDING, "tube_coral_fan", "クダウチワサンゴ", Material.TUBE_CORAL_FAN),
+        MineStackObjectByMaterial(BUILDING, "brain_coral_fan", "ノウウチワサンゴ", Material.BRAIN_CORAL_FAN),
+        MineStackObjectByMaterial(BUILDING, "bubble_coral_fan", "ミズタマウチワサンゴ", Material.BUBBLE_CORAL_FAN),
+        MineStackObjectByMaterial(BUILDING, "fire_coral_fan", "ミレポラウチワサンゴ", Material.FIRE_CORAL_FAN),
+        MineStackObjectByMaterial(BUILDING, "horn_coral_fan", "シカツノウチワサンゴ", Material.HORN_CORAL_FAN),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "flower_banner_pattern", "旗の模様", Material.FLOWER_BANNER_PATTERN),
+      List(
+        MineStackObjectByMaterial(BUILDING, "creeper_banner_pattern", "旗の模様", Material.CREEPER_BANNER_PATTERN),
+        MineStackObjectByMaterial(BUILDING, "skull_banner_pattern", "旗の模様", Material.SKULL_BANNER_PATTERN),
+        MineStackObjectByMaterial(BUILDING, "mojang_banner_pattern", "旗の模様", Material.MOJANG_BANNER_PATTERN),
+        MineStackObjectByMaterial(BUILDING, "globe_banner_pattern", "旗の模様", Material.GLOBE_BANNER_PATTERN),
+        MineStackObjectByMaterial(BUILDING, "piglin_banner_pattern", "旗の模様", Material.PIGLIN_BANNER_PATTERN),
       )
     ),
-    MineStackObjectWithColorVariants(
-      MineStackObjectByMaterial(BUILDING, "stained_clay", "白色のテラコッタ", Material.STAINED_CLAY, 0),
-      List(
-        MineStackObjectByMaterial(BUILDING, "stained_clay1", "橙色のテラコッタ", Material.STAINED_CLAY, 1),
-        MineStackObjectByMaterial(BUILDING, "stained_clay2", "赤紫色のテラコッタ", Material.STAINED_CLAY, 2),
-        MineStackObjectByMaterial(BUILDING, "stained_clay3", "空色のテラコッタ", Material.STAINED_CLAY, 3),
-        MineStackObjectByMaterial(BUILDING, "stained_clay4", "黄色のテラコッタ", Material.STAINED_CLAY, 4),
-        MineStackObjectByMaterial(BUILDING, "stained_clay5", "黄緑色のテラコッタ", Material.STAINED_CLAY, 5),
-        MineStackObjectByMaterial(BUILDING, "stained_clay6", "桃色のテラコッタ", Material.STAINED_CLAY, 6),
-        MineStackObjectByMaterial(BUILDING, "stained_clay7", "灰色のテラコッタ", Material.STAINED_CLAY, 7),
-        MineStackObjectByMaterial(BUILDING, "stained_clay8", "薄灰色のテラコッタ", Material.STAINED_CLAY, 8),
-        MineStackObjectByMaterial(BUILDING, "stained_clay9", "青緑色のテラコッタ", Material.STAINED_CLAY, 9),
-        MineStackObjectByMaterial(BUILDING, "stained_clay10", "紫色のテラコッタ", Material.STAINED_CLAY, 10),
-        MineStackObjectByMaterial(BUILDING, "stained_clay11", "青色のテラコッタ", Material.STAINED_CLAY, 11),
-        MineStackObjectByMaterial(BUILDING, "stained_clay12", "茶色のテラコッタ", Material.STAINED_CLAY, 12),
-        MineStackObjectByMaterial(BUILDING, "stained_clay13", "緑色のテラコッタ", Material.STAINED_CLAY, 13),
-        MineStackObjectByMaterial(BUILDING, "stained_clay14", "赤色のテラコッタ", Material.STAINED_CLAY, 14),
-        MineStackObjectByMaterial(BUILDING, "stained_clay15", "黒色のテラコッタ", Material.STAINED_CLAY, 15)
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "white_banner", "白色の旗", Material.WHITE_BANNER),
+      List(
+        MineStackObjectByMaterial(BUILDING, "orange_banner", "橙色の旗", Material.ORANGE_BANNER),
+        MineStackObjectByMaterial(BUILDING, "magenta_banner", "赤紫色の旗", Material.MAGENTA_BANNER),
+        MineStackObjectByMaterial(BUILDING, "light_blue_banner", "空色の旗", Material.LIGHT_BLUE_BANNER),
+        MineStackObjectByMaterial(BUILDING, "yellow_banner", "黄色の旗", Material.YELLOW_BANNER),
+        MineStackObjectByMaterial(BUILDING, "lime_banner", "黄緑色の旗", Material.LIME_BANNER),
+        MineStackObjectByMaterial(BUILDING, "pink_banner", "桃色の旗", Material.PINK_BANNER),
+        MineStackObjectByMaterial(BUILDING, "gray_banner", "灰色の旗", Material.GRAY_BANNER),
+        MineStackObjectByMaterial(BUILDING, "light_gray_banner", "薄灰色の旗", Material.LIGHT_GRAY_BANNER),
+        MineStackObjectByMaterial(BUILDING, "cyan_banner", "青緑色の旗", Material.CYAN_BANNER),
+        MineStackObjectByMaterial(BUILDING, "purple_banner", "紫色の旗", Material.PURPLE_BANNER),
+        MineStackObjectByMaterial(BUILDING, "blue_banner", "青色の旗", Material.BLUE_BANNER),
+        MineStackObjectByMaterial(BUILDING, "brown_banner", "茶色の旗", Material.BROWN_BANNER),
+        MineStackObjectByMaterial(BUILDING, "green_banner", "緑色の旗", Material.GREEN_BANNER),
+        MineStackObjectByMaterial(BUILDING, "red_banner", "赤色の旗", Material.RED_BANNER),
+        MineStackObjectByMaterial(BUILDING, "black_banner", "黒色の旗", Material.BLACK_BANNER),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "sign", "オークの看板", Material.OAK_SIGN),
+      List(
+        MineStackObjectByMaterial(BUILDING, "spruce_sign", "トウヒの看板", Material.SPRUCE_SIGN),
+        MineStackObjectByMaterial(BUILDING, "birch_sign", "シラカバの看板", Material.BIRCH_SIGN),
+        MineStackObjectByMaterial(BUILDING, "jungle_sign", "ジャングルの看板", Material.JUNGLE_SIGN),
+        MineStackObjectByMaterial(BUILDING, "acacia_sign", "アカシアの看板", Material.ACACIA_SIGN),
+        MineStackObjectByMaterial(BUILDING, "dark_oak_sign", "ダークオークの看板", Material.DARK_OAK_SIGN),
+        MineStackObjectByMaterial(BUILDING, "crimson_sign", "真紅の看板", Material.CRIMSON_SIGN),
+        MineStackObjectByMaterial(BUILDING, "warped_sign", "歪んだ看板", Material.WARPED_SIGN),
       )
     ),
-    MineStackObjectWithColorVariants(
-      MineStackObjectByMaterial(BUILDING, "concrete", "白色のコンクリート", Material.CONCRETE, 0),
-      List(
-        MineStackObjectByMaterial(BUILDING, "concrete1", "橙色のコンクリート", Material.CONCRETE, 1),
-        MineStackObjectByMaterial(BUILDING, "concrete2", "赤紫色のコンクリート", Material.CONCRETE, 2),
-        MineStackObjectByMaterial(BUILDING, "concrete3", "空色のコンクリート", Material.CONCRETE, 3),
-        MineStackObjectByMaterial(BUILDING, "concrete4", "黄色のコンクリート", Material.CONCRETE, 4),
-        MineStackObjectByMaterial(BUILDING, "concrete5", "黄緑色のコンクリート", Material.CONCRETE, 5),
-        MineStackObjectByMaterial(BUILDING, "concrete6", "桃色のコンクリート", Material.CONCRETE, 6),
-        MineStackObjectByMaterial(BUILDING, "concrete7", "灰色のコンクリート", Material.CONCRETE, 7),
-        MineStackObjectByMaterial(BUILDING, "concrete8", "薄灰色のコンクリート", Material.CONCRETE, 8),
-        MineStackObjectByMaterial(BUILDING, "concrete9", "青緑色のコンクリート", Material.CONCRETE, 9),
-        MineStackObjectByMaterial(BUILDING, "concrete10", "紫色のコンクリート", Material.CONCRETE, 10),
-        MineStackObjectByMaterial(BUILDING, "concrete11", "青色のコンクリート", Material.CONCRETE, 11),
-        MineStackObjectByMaterial(BUILDING, "concrete12", "茶色のコンクリート", Material.CONCRETE, 12),
-        MineStackObjectByMaterial(BUILDING, "concrete13", "緑色のコンクリート", Material.CONCRETE, 13),
-        MineStackObjectByMaterial(BUILDING, "concrete14", "赤色のコンクリート", Material.CONCRETE, 14),
-        MineStackObjectByMaterial(BUILDING, "concrete15", "黒色のコンクリート", Material.CONCRETE, 15)
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "candle", "ろうそく", Material.CANDLE),
+      List(
+        MineStackObjectByMaterial(BUILDING, "white_candle", "白色のろうそく", Material.WHITE_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "orange_candle", "橙色のろうそく", Material.ORANGE_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "magenta_candle", "赤紫色のろうそく", Material.MAGENTA_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "light_blue_candle", "空色のろうそく", Material.LIGHT_BLUE_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "yellow_candle", "黄色のろうそく", Material.YELLOW_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "lime_candle", "黄緑色のろうそく", Material.LIME_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "pink_candle", "桃色のろうそく", Material.PINK_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "gray_candle", "灰色のろうそく", Material.GRAY_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "light_gray_candle", "薄灰色のろうそく", Material.LIGHT_GRAY_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "cyan_candle", "青緑色のろうそく", Material.CYAN_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "purple_candle", "紫色のろうそく", Material.PURPLE_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "blue_candle", "青色のろうそく", Material.BLUE_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "brown_candle", "茶色のろうそく", Material.BROWN_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "green_candle", "緑色のろうそく", Material.GREEN_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "red_candle", "赤色のろうそく", Material.RED_CANDLE),
+        MineStackObjectByMaterial(BUILDING, "black_candle", "黒色のろうそく", Material.BLACK_CANDLE),
       )
     ),
-    MineStackObjectWithColorVariants(
-      MineStackObjectByMaterial(BUILDING, "concrete_powder", "白色のコンクリートパウダー", Material.CONCRETE_POWDER, 0),
-      List(
-        MineStackObjectByMaterial(BUILDING, "concrete_powder1", "橙色のコンクリートパウダー", Material.CONCRETE_POWDER, 1),
-        MineStackObjectByMaterial(BUILDING, "concrete_powder2", "赤紫色のコンクリートパウダー", Material.CONCRETE_POWDER, 2),
-        MineStackObjectByMaterial(BUILDING, "concrete_powder3", "空色のコンクリートパウダー", Material.CONCRETE_POWDER, 3),
-        MineStackObjectByMaterial(BUILDING, "concrete_powder4", "黄色のコンクリートパウダー", Material.CONCRETE_POWDER, 4),
-        MineStackObjectByMaterial(BUILDING, "concrete_powder5", "黄緑色のコンクリートパウダー", Material.CONCRETE_POWDER, 5),
-        MineStackObjectByMaterial(BUILDING, "concrete_powder6", "桃色のコンクリートパウダー", Material.CONCRETE_POWDER, 6),
-        MineStackObjectByMaterial(BUILDING, "concrete_powder7", "灰色のコンクリートパウダー", Material.CONCRETE_POWDER, 7),
-        MineStackObjectByMaterial(BUILDING, "concrete_powder8", "薄灰色のコンクリートパウダー", Material.CONCRETE_POWDER, 8),
-        MineStackObjectByMaterial(BUILDING, "concrete_powder9", "青緑色のコンクリートパウダー", Material.CONCRETE_POWDER, 9),
-        MineStackObjectByMaterial(BUILDING, "concrete_powder10", "紫色のコンクリートパウダー", Material.CONCRETE_POWDER, 10),
-        MineStackObjectByMaterial(BUILDING, "concrete_powder11", "青色のコンクリートパウダー", Material.CONCRETE_POWDER, 11),
-        MineStackObjectByMaterial(BUILDING, "concrete_powder12", "茶色のコンクリートパウダー", Material.CONCRETE_POWDER, 12),
-        MineStackObjectByMaterial(BUILDING, "concrete_powder13", "緑色のコンクリートパウダー", Material.CONCRETE_POWDER, 13),
-        MineStackObjectByMaterial(BUILDING, "concrete_powder14", "赤色のコンクリートパウダー", Material.CONCRETE_POWDER, 14),
-        MineStackObjectByMaterial(BUILDING, "concrete_powder15", "黒色のコンクリートパウダー", Material.CONCRETE_POWDER, 15)
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "bed", "白色のベッド", Material.WHITE_BED),
+      List(
+        MineStackObjectByMaterial(BUILDING, "bed_1", "橙色のベッド", Material.ORANGE_BED),
+        MineStackObjectByMaterial(BUILDING, "bed_2", "赤紫色のベッド", Material.MAGENTA_BED),
+        MineStackObjectByMaterial(BUILDING, "bed_3", "空色のベッド", Material.LIGHT_BLUE_BED),
+        MineStackObjectByMaterial(BUILDING, "bed_4", "黄色のベッド", Material.YELLOW_BED),
+        MineStackObjectByMaterial(BUILDING, "bed_5", "黄緑色のベッド", Material.LIME_BED),
+        MineStackObjectByMaterial(BUILDING, "bed_6", "桃色のベッド", Material.PINK_BED),
+        MineStackObjectByMaterial(BUILDING, "bed_7", "灰色のベッド", Material.GRAY_BED),
+        MineStackObjectByMaterial(BUILDING, "bed_8", "薄灰色のベッド", Material.LIGHT_GRAY_BED),
+        MineStackObjectByMaterial(BUILDING, "bed_9", "青緑色のベッド", Material.CYAN_BED),
+        MineStackObjectByMaterial(BUILDING, "bed_10", "紫色のベッド", Material.PURPLE_BED),
+        MineStackObjectByMaterial(BUILDING, "bed_11", "青色のベッド", Material.BLUE_BED),
+        MineStackObjectByMaterial(BUILDING, "bed_12", "茶色のベッド", Material.BROWN_BED),
+        MineStackObjectByMaterial(BUILDING, "bed_13", "緑色のベッド", Material.GREEN_BED),
+        MineStackObjectByMaterial(BUILDING, "bed_14", "赤色のベッド", Material.RED_BED),
+        MineStackObjectByMaterial(BUILDING, "bed_15", "黒色のベッド", Material.BLACK_BED)
       )
     ),
-    MineStackObjectWithColorVariants(
-      MineStackObjectByMaterial(BUILDING, "white_glazed_terracotta", "白色の彩釉テラコッタ", Material.WHITE_GLAZED_TERRACOTTA, 0),
-      List(
-        MineStackObjectByMaterial(BUILDING, "orange_glazed_terracotta", "橙色の彩釉テラコッタ", Material.ORANGE_GLAZED_TERRACOTTA, 0),
-        MineStackObjectByMaterial(BUILDING, "magenta_glazed_terracotta", "赤紫色の彩釉テラコッタ", Material.MAGENTA_GLAZED_TERRACOTTA, 0),
-        MineStackObjectByMaterial(BUILDING, "light_blue_glazed_terracotta", "空色の彩釉テラコッタ", Material.LIGHT_BLUE_GLAZED_TERRACOTTA, 0),
-        MineStackObjectByMaterial(BUILDING, "yellow_glazed_terracotta", "黄色の彩釉テラコッタ", Material.YELLOW_GLAZED_TERRACOTTA, 0),
-        MineStackObjectByMaterial(BUILDING, "lime_glazed_terracotta", "黄緑色の彩釉テラコッタ", Material.LIME_GLAZED_TERRACOTTA, 0),
-        MineStackObjectByMaterial(BUILDING, "pink_glazed_terracotta", "桃色の彩釉テラコッタ", Material.PINK_GLAZED_TERRACOTTA, 0),
-        MineStackObjectByMaterial(BUILDING, "gray_glazed_terracotta", "灰色の彩釉テラコッタ", Material.GRAY_GLAZED_TERRACOTTA, 0),
-        MineStackObjectByMaterial(BUILDING, "silver_glazed_terracotta", "薄灰色の彩釉テラコッタ", Material.SILVER_GLAZED_TERRACOTTA, 0),
-        MineStackObjectByMaterial(BUILDING, "cyan_glazed_terracotta", "青緑色の彩釉テラコッタ", Material.CYAN_GLAZED_TERRACOTTA, 0),
-        MineStackObjectByMaterial(BUILDING, "purple_glazed_terracotta", "紫色の彩釉テラコッタ", Material.PURPLE_GLAZED_TERRACOTTA, 0),
-        MineStackObjectByMaterial(BUILDING, "blue_glazed_terracotta", "青色の彩釉テラコッタ", Material.BLUE_GLAZED_TERRACOTTA, 0),
-        MineStackObjectByMaterial(BUILDING, "brown_glazed_terracotta", "茶色の彩釉テラコッタ", Material.BROWN_GLAZED_TERRACOTTA, 0),
-        MineStackObjectByMaterial(BUILDING, "green_glazed_terracotta", "緑色の彩釉テラコッタ", Material.GREEN_GLAZED_TERRACOTTA, 0),
-        MineStackObjectByMaterial(BUILDING, "red_glazed_terracotta", "赤色の彩釉テラコッタ", Material.RED_GLAZED_TERRACOTTA, 0),
-        MineStackObjectByMaterial(BUILDING, "black_glazed_terracotta", "黒色の彩釉テラコッタ", Material.BLACK_GLAZED_TERRACOTTA, 0)
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "hard_clay", "テラコッタ", Material.TERRACOTTA),
+      List(
+        MineStackObjectByMaterial(BUILDING, "stained_clay", "白色のテラコッタ", Material.WHITE_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay1", "橙色のテラコッタ", Material.ORANGE_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay2", "赤紫色のテラコッタ", Material.MAGENTA_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay3", "空色のテラコッタ", Material.LIGHT_BLUE_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay4", "黄色のテラコッタ", Material.YELLOW_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay5", "黄緑色のテラコッタ", Material.LIME_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay6", "桃色のテラコッタ", Material.PINK_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay7", "灰色のテラコッタ", Material.GRAY_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay8", "薄灰色のテラコッタ", Material.LIGHT_GRAY_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay9", "青緑色のテラコッタ", Material.CYAN_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay10", "紫色のテラコッタ", Material.PURPLE_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay11", "青色のテラコッタ", Material.BLUE_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay12", "茶色のテラコッタ", Material.BROWN_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay13", "緑色のテラコッタ", Material.GREEN_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay14", "赤色のテラコッタ", Material.RED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING, "stained_clay15", "黒色のテラコッタ", Material.BLACK_TERRACOTTA)
       )
     ),
-    MineStackObjectWithColorVariants(
-      MineStackObjectByMaterial(BUILDING, "wool_0", "白色の羊毛", Material.WOOL, 0),
-      List(
-        MineStackObjectByMaterial(BUILDING, "wool_1", "橙色の羊毛", Material.WOOL, 1),
-        MineStackObjectByMaterial(BUILDING, "wool_2", "赤紫色の羊毛", Material.WOOL, 2),
-        MineStackObjectByMaterial(BUILDING, "wool_3", "空色の羊毛", Material.WOOL, 3),
-        MineStackObjectByMaterial(BUILDING, "wool_4", "黄色の羊毛", Material.WOOL, 4),
-        MineStackObjectByMaterial(BUILDING, "wool_5", "黄緑色の羊毛", Material.WOOL, 5),
-        MineStackObjectByMaterial(BUILDING, "wool_6", "桃色の羊毛", Material.WOOL, 6),
-        MineStackObjectByMaterial(BUILDING, "wool_7", "灰色の羊毛", Material.WOOL, 7),
-        MineStackObjectByMaterial(BUILDING, "wool_8", "薄灰色の羊毛", Material.WOOL, 8),
-        MineStackObjectByMaterial(BUILDING, "wool_9", "青緑色の羊毛", Material.WOOL, 9),
-        MineStackObjectByMaterial(BUILDING, "wool_10", "紫色の羊毛", Material.WOOL, 10),
-        MineStackObjectByMaterial(BUILDING, "wool_11", "青色の羊毛", Material.WOOL, 11),
-        MineStackObjectByMaterial(BUILDING, "wool_12", "茶色の羊毛", Material.WOOL, 12),
-        MineStackObjectByMaterial(BUILDING, "wool_13", "緑色の羊毛", Material.WOOL, 13),
-        MineStackObjectByMaterial(BUILDING, "wool_14", "赤色の羊毛", Material.WOOL, 14),
-        MineStackObjectByMaterial(BUILDING, "wool_15", "黒色の羊毛", Material.WOOL, 15)
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "concrete", "白色のコンクリート", Material.WHITE_CONCRETE),
+      List(
+        MineStackObjectByMaterial(BUILDING, "concrete1", "橙色のコンクリート", Material.ORANGE_CONCRETE),
+        MineStackObjectByMaterial(BUILDING, "concrete2", "赤紫色のコンクリート", Material.MAGENTA_CONCRETE),
+        MineStackObjectByMaterial(BUILDING, "concrete3", "空色のコンクリート", Material.LIGHT_BLUE_CONCRETE),
+        MineStackObjectByMaterial(BUILDING, "concrete4", "黄色のコンクリート", Material.YELLOW_CONCRETE),
+        MineStackObjectByMaterial(BUILDING, "concrete5", "黄緑色のコンクリート", Material.LIME_CONCRETE),
+        MineStackObjectByMaterial(BUILDING, "concrete6", "桃色のコンクリート", Material.PINK_CONCRETE),
+        MineStackObjectByMaterial(BUILDING, "concrete7", "灰色のコンクリート", Material.GRAY_CONCRETE),
+        MineStackObjectByMaterial(BUILDING, "concrete8", "薄灰色のコンクリート", Material.LIGHT_GRAY_CONCRETE),
+        MineStackObjectByMaterial(BUILDING, "concrete9", "青緑色のコンクリート", Material.CYAN_CONCRETE),
+        MineStackObjectByMaterial(BUILDING, "concrete10", "紫色のコンクリート", Material.PURPLE_CONCRETE),
+        MineStackObjectByMaterial(BUILDING, "concrete11", "青色のコンクリート", Material.BLUE_CONCRETE),
+        MineStackObjectByMaterial(BUILDING, "concrete12", "茶色のコンクリート", Material.BROWN_CONCRETE),
+        MineStackObjectByMaterial(BUILDING, "concrete13", "緑色のコンクリート", Material.GREEN_CONCRETE),
+        MineStackObjectByMaterial(BUILDING, "concrete14", "赤色のコンクリート", Material.RED_CONCRETE),
+        MineStackObjectByMaterial(BUILDING, "concrete15", "黒色のコンクリート", Material.BLACK_CONCRETE)
       )
     ),
-    MineStackObjectWithColorVariants(
-      MineStackObjectByMaterial(BUILDING, "carpet_0", "白色のカーペット", Material.CARPET, 0),
-      List(
-        MineStackObjectByMaterial(BUILDING, "carpet_1", "橙色のカーペット", Material.CARPET, 1),
-        MineStackObjectByMaterial(BUILDING, "carpet_2", "赤紫色のカーペット", Material.CARPET, 2),
-        MineStackObjectByMaterial(BUILDING, "carpet_3", "空色のカーペット", Material.CARPET, 3),
-        MineStackObjectByMaterial(BUILDING, "carpet_4", "黄色のカーペット", Material.CARPET, 4),
-        MineStackObjectByMaterial(BUILDING, "carpet_5", "黄緑色のカーペット", Material.CARPET, 5),
-        MineStackObjectByMaterial(BUILDING, "carpet_6", "桃色のカーペット", Material.CARPET, 6),
-        MineStackObjectByMaterial(BUILDING, "carpet_7", "灰色のカーペット", Material.CARPET, 7),
-        MineStackObjectByMaterial(BUILDING, "carpet_8", "薄灰色のカーペット", Material.CARPET, 8),
-        MineStackObjectByMaterial(BUILDING, "carpet_9", "青緑色のカーペット", Material.CARPET, 9),
-        MineStackObjectByMaterial(BUILDING, "carpet_10", "紫色のカーペット", Material.CARPET, 10),
-        MineStackObjectByMaterial(BUILDING, "carpet_11", "青色のカーペット", Material.CARPET, 11),
-        MineStackObjectByMaterial(BUILDING, "carpet_12", "茶色のカーペット", Material.CARPET, 12),
-        MineStackObjectByMaterial(BUILDING, "carpet_13", "緑色のカーペット", Material.CARPET, 13),
-        MineStackObjectByMaterial(BUILDING, "carpet_14", "赤色のカーペット", Material.CARPET, 14),
-        MineStackObjectByMaterial(BUILDING, "carpet_15", "黒色のカーペット", Material.CARPET, 15)
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "concrete_powder", "白色のコンクリートパウダー", Material.WHITE_CONCRETE_POWDER),
+      List(
+        MineStackObjectByMaterial(BUILDING, "concrete_powder1", "橙色のコンクリートパウダー", Material.ORANGE_CONCRETE_POWDER),
+        MineStackObjectByMaterial(BUILDING, "concrete_powder2", "赤紫色のコンクリートパウダー", Material.MAGENTA_CONCRETE_POWDER),
+        MineStackObjectByMaterial(BUILDING, "concrete_powder3", "空色のコンクリートパウダー", Material.LIGHT_BLUE_CONCRETE_POWDER),
+        MineStackObjectByMaterial(BUILDING, "concrete_powder4", "黄色のコンクリートパウダー", Material.YELLOW_CONCRETE_POWDER),
+        MineStackObjectByMaterial(BUILDING, "concrete_powder5", "黄緑色のコンクリートパウダー", Material.LIME_CONCRETE_POWDER),
+        MineStackObjectByMaterial(BUILDING,"concrete_powder6","桃色のコンクリートパウダー",Material.PINK_CONCRETE_POWDER),
+        MineStackObjectByMaterial(BUILDING,"concrete_powder7","灰色のコンクリートパウダー",Material.GRAY_CONCRETE_POWDER),
+        MineStackObjectByMaterial(BUILDING,"concrete_powder8","薄灰色のコンクリートパウダー",Material.LIGHT_GRAY_CONCRETE_POWDER),
+        MineStackObjectByMaterial(BUILDING,"concrete_powder9","青緑色のコンクリートパウダー",Material.CYAN_CONCRETE_POWDER),
+        MineStackObjectByMaterial(BUILDING,"concrete_powder10","紫色のコンクリートパウダー",Material.PURPLE_CONCRETE_POWDER),
+        MineStackObjectByMaterial(BUILDING,"concrete_powder11","青色のコンクリートパウダー",Material.BLUE_CONCRETE_POWDER),
+        MineStackObjectByMaterial(BUILDING,"concrete_powder12","茶色のコンクリートパウダー",Material.BROWN_CONCRETE_POWDER),
+        MineStackObjectByMaterial(BUILDING,"concrete_powder13","緑色のコンクリートパウダー",Material.GREEN_CONCRETE_POWDER),
+        MineStackObjectByMaterial(BUILDING,"concrete_powder14","赤色のコンクリートパウダー",Material.RED_CONCRETE_POWDER),
+        MineStackObjectByMaterial(BUILDING,"concrete_powder15","黒色のコンクリートパウダー",Material.BLACK_CONCRETE_POWDER)
       )
     ),
-    MineStackObjectWithColorVariants(
-      MineStackObjectByMaterial(BUILDING, "glass", "ガラス", Material.GLASS, 0),
-      List(
-        MineStackObjectByMaterial(BUILDING, "stained_glass_0", "白色の色付きガラス", Material.STAINED_GLASS, 0),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_1", "橙色の色付きガラス", Material.STAINED_GLASS, 1),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_2", "赤紫色の色付きガラス", Material.STAINED_GLASS, 2),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_3", "空色の色付きガラス", Material.STAINED_GLASS, 3),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_4", "黄色の色付きガラス", Material.STAINED_GLASS, 4),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_5", "黄緑色の色付きガラス", Material.STAINED_GLASS, 5),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_6", "桃色の色付きガラス", Material.STAINED_GLASS, 6),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_7", "灰色の色付きガラス", Material.STAINED_GLASS, 7),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_8", "薄灰色の色付きガラス", Material.STAINED_GLASS, 8),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_9", "青緑色の色付きガラス", Material.STAINED_GLASS, 9),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_10", "紫色の色付きガラス", Material.STAINED_GLASS, 10),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_11", "青色の色付きガラス", Material.STAINED_GLASS, 11),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_12", "茶色の色付きガラス", Material.STAINED_GLASS, 12),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_13", "緑色の色付きガラス", Material.STAINED_GLASS, 13),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_14", "赤色の色付きガラス", Material.STAINED_GLASS, 14),
-        MineStackObjectByMaterial(BUILDING, "stained_glass_15", "黒色の色付きガラス", Material.STAINED_GLASS, 15)
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING,"white_glazed_terracotta","白色の彩釉テラコッタ",Material.WHITE_GLAZED_TERRACOTTA),
+      List(
+        MineStackObjectByMaterial(BUILDING,"orange_glazed_terracotta","橙色の彩釉テラコッタ",Material.ORANGE_GLAZED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING,"magenta_glazed_terracotta","赤紫色の彩釉テラコッタ",Material.MAGENTA_GLAZED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING,"light_blue_glazed_terracotta","空色の彩釉テラコッタ",Material.LIGHT_BLUE_GLAZED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING,"yellow_glazed_terracotta","黄色の彩釉テラコッタ",Material.YELLOW_GLAZED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING,"lime_glazed_terracotta","黄緑色の彩釉テラコッタ",Material.LIME_GLAZED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING,"pink_glazed_terracotta","桃色の彩釉テラコッタ",Material.PINK_GLAZED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING,"gray_glazed_terracotta","灰色の彩釉テラコッタ",Material.GRAY_GLAZED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING,"silver_glazed_terracotta","薄灰色の彩釉テラコッタ",Material.LIGHT_GRAY_GLAZED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING,"cyan_glazed_terracotta","青緑色の彩釉テラコッタ",Material.CYAN_GLAZED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING,"purple_glazed_terracotta","紫色の彩釉テラコッタ",Material.PURPLE_GLAZED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING,"blue_glazed_terracotta","青色の彩釉テラコッタ",Material.BLUE_GLAZED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING,"brown_glazed_terracotta","茶色の彩釉テラコッタ",Material.BROWN_GLAZED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING,"green_glazed_terracotta","緑色の彩釉テラコッタ",Material.GREEN_GLAZED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING,"red_glazed_terracotta","赤色の彩釉テラコッタ",Material.RED_GLAZED_TERRACOTTA),
+        MineStackObjectByMaterial(BUILDING,"black_glazed_terracotta","黒色の彩釉テラコッタ",Material.BLACK_GLAZED_TERRACOTTA)
       )
     ),
-    MineStackObjectWithColorVariants(
-      MineStackObjectByMaterial(BUILDING, "glass_panel", "板ガラス", Material.THIN_GLASS, 0),
-      List(
-        MineStackObjectByMaterial(BUILDING, "glass_panel_0", "白色の色付きガラス板", Material.STAINED_GLASS_PANE, 0),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_1", "橙色の色付きガラス板", Material.STAINED_GLASS_PANE, 1),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_2", "赤紫色の色付きガラス板", Material.STAINED_GLASS_PANE, 2),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_3", "空色の色付きガラス板", Material.STAINED_GLASS_PANE, 3),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_4", "黄色の色付きガラス板", Material.STAINED_GLASS_PANE, 4),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_5", "黄緑色の色付きガラス板", Material.STAINED_GLASS_PANE, 5),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_6", "桃色の色付きガラス板", Material.STAINED_GLASS_PANE, 6),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_7", "灰色の色付きガラス板", Material.STAINED_GLASS_PANE, 7),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_8", "薄灰色の色付きガラス板", Material.STAINED_GLASS_PANE, 8),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_9", "青緑色の色付きガラス板", Material.STAINED_GLASS_PANE, 9),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_10", "紫色の色付きガラス板", Material.STAINED_GLASS_PANE, 10),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_11", "青色の色付きガラス板", Material.STAINED_GLASS_PANE, 11),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_12", "茶色の色付きガラス板", Material.STAINED_GLASS_PANE, 12),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_13", "緑色の色付きガラス板", Material.STAINED_GLASS_PANE, 13),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_14", "赤色の色付きガラス板", Material.STAINED_GLASS_PANE, 14),
-        MineStackObjectByMaterial(BUILDING, "glass_panel_15", "黒色の色付きガラス板", Material.STAINED_GLASS_PANE, 15)
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "wool_0", "白色の羊毛", Material.WHITE_WOOL),
+      List(
+        MineStackObjectByMaterial(BUILDING, "wool_1", "橙色の羊毛", Material.ORANGE_WOOL),
+        MineStackObjectByMaterial(BUILDING, "wool_2", "赤紫色の羊毛", Material.MAGENTA_WOOL),
+        MineStackObjectByMaterial(BUILDING, "wool_3", "空色の羊毛", Material.LIGHT_BLUE_WOOL),
+        MineStackObjectByMaterial(BUILDING, "wool_4", "黄色の羊毛", Material.YELLOW_WOOL),
+        MineStackObjectByMaterial(BUILDING, "wool_5", "黄緑色の羊毛", Material.LIME_WOOL),
+        MineStackObjectByMaterial(BUILDING, "wool_6", "桃色の羊毛", Material.PINK_WOOL),
+        MineStackObjectByMaterial(BUILDING, "wool_7", "灰色の羊毛", Material.GRAY_WOOL),
+        MineStackObjectByMaterial(BUILDING, "wool_8", "薄灰色の羊毛", Material.LIGHT_GRAY_WOOL),
+        MineStackObjectByMaterial(BUILDING, "wool_9", "青緑色の羊毛", Material.CYAN_WOOL),
+        MineStackObjectByMaterial(BUILDING, "wool_10", "紫色の羊毛", Material.PURPLE_WOOL),
+        MineStackObjectByMaterial(BUILDING, "wool_11", "青色の羊毛", Material.BLUE_WOOL),
+        MineStackObjectByMaterial(BUILDING, "wool_12", "茶色の羊毛", Material.BROWN_WOOL),
+        MineStackObjectByMaterial(BUILDING, "wool_13", "緑色の羊毛", Material.GREEN_WOOL),
+        MineStackObjectByMaterial(BUILDING, "wool_14", "赤色の羊毛", Material.RED_WOOL),
+        MineStackObjectByMaterial(BUILDING, "wool_15", "黒色の羊毛", Material.BLACK_WOOL)
       )
     ),
-    MineStackObjectWithColorVariants(
-      MineStackObjectByMaterial(BUILDING, "dye_1", "赤色の染料", Material.INK_SACK, 1),
-      List(
-        MineStackObjectByMaterial(BUILDING, "dye_2", "緑色の染料", Material.INK_SACK, 2),
-        MineStackObjectByMaterial(BUILDING, "dye_5", "紫色の染料", Material.INK_SACK, 5),
-        MineStackObjectByMaterial(BUILDING, "dye_6", "青緑色の染料", Material.INK_SACK, 6),
-        MineStackObjectByMaterial(BUILDING, "dye_7", "薄灰色の染料", Material.INK_SACK, 7),
-        MineStackObjectByMaterial(BUILDING, "dye_8", "灰色の染料", Material.INK_SACK, 8),
-        MineStackObjectByMaterial(BUILDING, "dye_9", "桃色の染料", Material.INK_SACK, 9),
-        MineStackObjectByMaterial(BUILDING, "dye_10", "黄緑色の染料", Material.INK_SACK, 10),
-        MineStackObjectByMaterial(BUILDING, "dye_11", "黄色の染料", Material.INK_SACK, 11),
-        MineStackObjectByMaterial(BUILDING, "dye_12", "空色の染料", Material.INK_SACK, 12),
-        MineStackObjectByMaterial(BUILDING, "dye_13", "赤紫色の染料", Material.INK_SACK, 13),
-        MineStackObjectByMaterial(BUILDING, "dye_14", "橙色の染料", Material.INK_SACK, 14),
-        MineStackObjectByMaterial(BUILDING, "dye_15", "骨粉", Material.INK_SACK, 15),
-        MineStackObjectByMaterial(BUILDING, "ink_sack0", "イカスミ", Material.INK_SACK, 0)
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "carpet_0", "白色のカーペット", Material.WHITE_CARPET),
+      List(
+        MineStackObjectByMaterial(BUILDING, "carpet_1", "橙色のカーペット", Material.ORANGE_CARPET),
+        MineStackObjectByMaterial(BUILDING, "carpet_2", "赤紫色のカーペット", Material.MAGENTA_CARPET),
+        MineStackObjectByMaterial(BUILDING, "carpet_3", "空色のカーペット", Material.LIGHT_BLUE_CARPET),
+        MineStackObjectByMaterial(BUILDING, "carpet_4", "黄色のカーペット", Material.YELLOW_CARPET),
+        MineStackObjectByMaterial(BUILDING, "carpet_5", "黄緑色のカーペット", Material.LIME_CARPET),
+        MineStackObjectByMaterial(BUILDING, "carpet_6", "桃色のカーペット", Material.PINK_CARPET),
+        MineStackObjectByMaterial(BUILDING, "carpet_7", "灰色のカーペット", Material.GRAY_CARPET),
+        MineStackObjectByMaterial(BUILDING, "carpet_8", "薄灰色のカーペット", Material.LIGHT_GRAY_CARPET),
+        MineStackObjectByMaterial(BUILDING, "carpet_9", "青緑色のカーペット", Material.CYAN_CARPET),
+        MineStackObjectByMaterial(BUILDING, "carpet_10", "紫色のカーペット", Material.PURPLE_CARPET),
+        MineStackObjectByMaterial(BUILDING, "carpet_11", "青色のカーペット", Material.BLUE_CARPET),
+        MineStackObjectByMaterial(BUILDING, "carpet_12", "茶色のカーペット", Material.BROWN_CARPET),
+        MineStackObjectByMaterial(BUILDING, "carpet_13", "緑色のカーペット", Material.GREEN_CARPET),
+        MineStackObjectByMaterial(BUILDING, "carpet_14", "赤色のカーペット", Material.RED_CARPET),
+        MineStackObjectByMaterial(BUILDING, "carpet_15", "黒色のカーペット", Material.BLACK_CARPET)
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "glass", "ガラス",Material.GLASS),
+      List(
+        MineStackObjectByMaterial(BUILDING, "stained_glass_0", "白色の色付きガラス", Material.WHITE_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_1", "橙色の色付きガラス", Material.ORANGE_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_2", "赤紫色の色付きガラス", Material.MAGENTA_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_3", "空色の色付きガラス", Material.LIGHT_BLUE_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_4", "黄色の色付きガラス", Material.YELLOW_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_5", "黄緑色の色付きガラス", Material.LIME_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_6", "桃色の色付きガラス", Material.PINK_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_7", "灰色の色付きガラス", Material.GRAY_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_8", "薄灰色の色付きガラス", Material.LIGHT_GRAY_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_9", "青緑色の色付きガラス", Material.CYAN_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_10", "紫色の色付きガラス", Material.PURPLE_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_11", "青色の色付きガラス", Material.BLUE_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_12", "茶色の色付きガラス", Material.BROWN_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_13", "緑色の色付きガラス", Material.GREEN_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_14", "赤色の色付きガラス", Material.RED_STAINED_GLASS),
+        MineStackObjectByMaterial(BUILDING, "stained_glass_15", "黒色の色付きガラス", Material.BLACK_STAINED_GLASS)
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "glass_panel", "ガラス板", Material.GLASS_PANE),
+      List(
+          MineStackObjectByMaterial(BUILDING,"glass_panel_0","白色の色付きガラス板",Material.WHITE_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_1","橙色の色付きガラス板",Material.ORANGE_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_2","赤紫色の色付きガラス板",Material.MAGENTA_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_3","空色の色付きガラス板",Material.LIGHT_BLUE_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_4","黄色の色付きガラス板",Material.YELLOW_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_5","黄緑色の色付きガラス板",Material.LIME_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_6","桃色の色付きガラス板",Material.PINK_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_7","灰色の色付きガラス板",Material.GRAY_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_8","薄灰色の色付きガラス板",Material.LIGHT_GRAY_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_9","青緑色の色付きガラス板",Material.CYAN_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_10","紫色の色付きガラス板",Material.PURPLE_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_11","青色の色付きガラス板",Material.BLUE_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_12","茶色の色付きガラス板",Material.BROWN_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_13","緑色の色付きガラス板",Material.GREEN_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_14","赤色の色付きガラス板",Material.RED_STAINED_GLASS_PANE),
+          MineStackObjectByMaterial(BUILDING,"glass_panel_15","黒色の色付きガラス板",Material.BLACK_STAINED_GLASS_PANE)
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(BUILDING, "dye_1", "赤色の染料", Material.RED_DYE),
+      List(
+        MineStackObjectByMaterial(BUILDING, "dye_2", "緑色の染料", Material.GREEN_DYE),
+        MineStackObjectByMaterial(BUILDING, "dye_5", "紫色の染料", Material.PURPLE_DYE),
+        MineStackObjectByMaterial(BUILDING, "dye_6", "青緑色の染料", Material.CYAN_DYE),
+        MineStackObjectByMaterial(BUILDING, "dye_7", "薄灰色の染料", Material.LIGHT_GRAY_DYE),
+        MineStackObjectByMaterial(BUILDING, "dye_8", "灰色の染料", Material.GRAY_DYE),
+        MineStackObjectByMaterial(BUILDING, "dye_9", "桃色の染料", Material.PINK_DYE),
+        MineStackObjectByMaterial(BUILDING, "dye_10", "黄緑色の染料", Material.LIME_DYE),
+        MineStackObjectByMaterial(BUILDING, "dye_11", "黄色の染料", Material.YELLOW_DYE),
+        MineStackObjectByMaterial(BUILDING, "dye_12", "空色の染料", Material.LIGHT_BLUE_DYE),
+        MineStackObjectByMaterial(BUILDING, "dye_13", "赤紫色の染料", Material.MAGENTA_DYE),
+        MineStackObjectByMaterial(BUILDING, "dye_14", "橙色の染料", Material.ORANGE_DYE),
+        MineStackObjectByMaterial(BUILDING, "white_dye", "白色の染料", Material.WHITE_DYE),
+        MineStackObjectByMaterial(BUILDING, "blue_dye", "青色の染料", Material.BLUE_DYE),
+        MineStackObjectByMaterial(BUILDING, "brown_dye", "茶色の染料", Material.BROWN_DYE),
+        MineStackObjectByMaterial(BUILDING, "black_dye", "黒色の染料", Material.BLACK_DYE),
       )
     )
   )
 
   // レッドストーン系ブロック
   private val minestacklistrs: List[MineStackObjectGroup[ItemStack]] = leftElems(
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "redstone", "レッドストーン", Material.REDSTONE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "stone_button", "石のボタン", Material.STONE_BUTTON, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "wood_button", "木のボタン", Material.WOOD_BUTTON, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "stone_plate", "石の感圧版", Material.STONE_PLATE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "wood_plate", "木の感圧版", Material.WOOD_PLATE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "fence_gate", "オークのフェンスゲート", Material.FENCE_GATE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "spruce_fence_gate", "マツのフェンスゲート", Material.SPRUCE_FENCE_GATE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "birch_fence_gate", "シラカバのフェンスゲート", Material.BIRCH_FENCE_GATE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "jungle_fence_gate", "ジャングルのフェンスゲート", Material.JUNGLE_FENCE_GATE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "dark_oak_fence_gate", "ダークオークのフェンスゲート", Material.DARK_OAK_FENCE_GATE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "acacia_fence_gate", "アカシアのフェンスゲート", Material.ACACIA_FENCE_GATE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "redstone_block", "レッドストーンブロック", Material.REDSTONE_BLOCK, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "lever", "レバー", Material.LEVER, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "redstone_torch_on", "レッドストーントーチ", Material.REDSTONE_TORCH_ON, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "trap_door", "木のトラップドア", Material.TRAP_DOOR, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "iron_trapdoor", "鉄のトラップドア", Material.IRON_TRAPDOOR, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "gold_plate", "重量感圧版 (軽) ", Material.GOLD_PLATE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "iron_plate", "重量感圧版 (重) ", Material.IRON_PLATE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "wood_door", "オークのドア", Material.WOOD_DOOR, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "spruce_door_item", "マツのドア", Material.SPRUCE_DOOR_ITEM, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "birch_door_item", "シラカバのドア", Material.BIRCH_DOOR_ITEM, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "jungle_door_item", "ジャングルのドア", Material.JUNGLE_DOOR_ITEM, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "acacia_door_item", "アカシアのドア", Material.ACACIA_DOOR_ITEM, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "dark_oak_door_item", "ダークオークのドア", Material.DARK_OAK_DOOR_ITEM, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "note_block", "音符ブロック", Material.NOTE_BLOCK, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "redstone_lamp_off", "レッドストーンランプ", Material.REDSTONE_LAMP_OFF, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "tripwire_hook", "トリップワイヤーフック", Material.TRIPWIRE_HOOK, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "dropper", "ドロッパー", Material.DROPPER, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "piston_sticky_base", "粘着ピストン", Material.PISTON_STICKY_BASE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "piston_base", "ピストン", Material.PISTON_BASE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "tnt", "TNT", Material.TNT, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "trapped_chest", "トラップチェスト", Material.TRAPPED_CHEST, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "daylight_detector", "日照センサー", Material.DAYLIGHT_DETECTOR, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "iron_door", "鉄のドア", Material.IRON_DOOR, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "diode", "レッドストーンリピーター", Material.DIODE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "dispenser", "ディスペンサー", Material.DISPENSER, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "hopper", "ホッパー", Material.HOPPER, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "redstone_comparator", "レッドストーンコンパレーター", Material.REDSTONE_COMPARATOR, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "powered_rail", "パワードレール", Material.POWERED_RAIL, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "detector_rail", "ディテクターレール", Material.DETECTOR_RAIL, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "activator_rail", "アクティベーターレール", Material.ACTIVATOR_RAIL, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "boat", "オークのボート", Material.BOAT, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "spruce_boat", "マツのボート", Material.BOAT_SPRUCE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "birch_boat", "シラカバのボート", Material.BOAT_BIRCH, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "jungle_boat", "ジャングルのボート", Material.BOAT_JUNGLE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "acacia_boat", "アカシアのボート", Material.BOAT_ACACIA, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "dark_oak_boat", "ダークオークのボート", Material.BOAT_DARK_OAK, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "saddle", "サドル", Material.SADDLE, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "minecart", "トロッコ", Material.MINECART, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "chest_minecart", "チェスト付きトロッコ", Material.STORAGE_MINECART, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "furnace_minecart", "かまど付きトロッコ", Material.POWERED_MINECART, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "hopper_minecart", "ホッパー付きトロッコ", Material.HOPPER_MINECART, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "iron_horse_armor", "鉄の馬鎧", Material.IRON_BARDING, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "golden_horse_armor", "金の馬鎧", Material.GOLD_BARDING, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "diamond_horse_armor", "ダイヤの馬鎧", Material.DIAMOND_BARDING, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "record_13", "レコード", Material.GOLD_RECORD, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "record_cat", "レコード", Material.GREEN_RECORD, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "record_blocks", "レコード", Material.RECORD_3, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "record_chirp", "レコード", Material.RECORD_4, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "record_far", "レコード", Material.RECORD_5, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "record_mall", "レコード", Material.RECORD_6, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "record_mellohi", "レコード", Material.RECORD_7, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "record_stal", "レコード", Material.RECORD_8, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "record_strad", "レコード", Material.RECORD_9, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "record_ward", "レコード", Material.RECORD_10, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "record_11", "レコード", Material.RECORD_11, 0),
-    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "record_wait", "レコード", Material.RECORD_12, 0)
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"redstone","レッドストーンダスト",Material.REDSTONE),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"redstone_block","レッドストーンブロック",Material.REDSTONE_BLOCK),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "lever", "レバー", Material.LEVER),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"redstone_torch_on","レッドストーントーチ",Material.REDSTONE_TORCH),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"note_block","音符ブロック",Material.NOTE_BLOCK),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"redstone_lamp_off","レッドストーンランプ",Material.REDSTONE_LAMP),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"tripwire_hook","トリップワイヤーフック",Material.TRIPWIRE_HOOK),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "dropper", "ドロッパー", Material.DROPPER),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"piston_sticky_base","粘着ピストン",Material.STICKY_PISTON),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"piston_base","ピストン",Material.PISTON),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "tnt", "TNT", Material.TNT),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"trapped_chest","トラップチェスト",Material.TRAPPED_CHEST),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"daylight_detector","日照センサー",Material.DAYLIGHT_DETECTOR),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"diode","レッドストーンリピーター",Material.REPEATER),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"dispenser","ディスペンサー",Material.DISPENSER),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "hopper", "ホッパー", Material.HOPPER),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"redstone_comparator","レッドストーンコンパレーター",Material.COMPARATOR),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"powered_rail","パワードレール",Material.POWERED_RAIL),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"detector_rail","ディテクターレール",Material.DETECTOR_RAIL),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"activator_rail","アクティベーターレール",Material.ACTIVATOR_RAIL),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "saddle", "鞍", Material.SADDLE),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "minecart", "トロッコ", Material.MINECART),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"chest_minecart","チェスト付きトロッコ",Material.CHEST_MINECART),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"furnace_minecart","かまど付きトロッコ",Material.FURNACE_MINECART),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"hopper_minecart","ホッパー付きトロッコ",Material.HOPPER_MINECART),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"iron_horse_armor","鉄の馬鎧",Material.IRON_HORSE_ARMOR),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"golden_horse_armor","金の馬鎧",Material.GOLDEN_HORSE_ARMOR),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"diamond_horse_armor","ダイヤモンドの馬鎧",Material.DIAMOND_HORSE_ARMOR),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "lectern", "書見台", Material.LECTERN),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "target", "的", Material.TARGET),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "lightning_rod", "避雷針", Material.LIGHTNING_ROD),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "clock", "時計", Material.CLOCK),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "spyglass", "望遠鏡", Material.SPYGLASS),
+    MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "leather_horse_armor", "革の馬鎧", Material.LEATHER_HORSE_ARMOR),
+  ) ++ rightElems(
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"wood_button","オークのボタン",Material.OAK_BUTTON),
+      List(
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"stone_button","石のボタン",Material.STONE_BUTTON),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "spruce_button", "トウヒのボタン", Material.SPRUCE_BUTTON),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "birch_button", "シラカバのボタン", Material.BIRCH_BUTTON),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "jungle_button", "ジャングルのボタン", Material.JUNGLE_BUTTON),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "acacia_button", "アカシアのボタン", Material.ACACIA_BUTTON),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "dark_oak_button", "ダークオークのボタン", Material.DARK_OAK_BUTTON),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "polished_blackstone_button", "磨かれたブラックストーンのボタン", Material.POLISHED_BLACKSTONE_BUTTON),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "crimson_button", "真紅のボタン", Material.CRIMSON_BUTTON),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "warped_button", "歪んだボタン", Material.WARPED_BUTTON),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"wood_door","オークのドア",Material.OAK_DOOR),
+      List(
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"spruce_door_item","トウヒのドア",Material.SPRUCE_DOOR),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"birch_door_item","シラカバのドア",Material.BIRCH_DOOR),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"jungle_door_item","ジャングルのドア",Material.JUNGLE_DOOR),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"acacia_door_item","アカシアのドア",Material.ACACIA_DOOR),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"dark_oak_door_item","ダークオークのドア",Material.DARK_OAK_DOOR),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"iron_door","鉄のドア",Material.IRON_DOOR),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "crimson_door", "真紅のドア", Material.CRIMSON_DOOR),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "warped_door", "歪んだドア", Material.WARPED_DOOR),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"trap_door","オークのトラップドア",Material.OAK_TRAPDOOR),
+      List(
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"iron_trapdoor","鉄のトラップドア",Material.IRON_TRAPDOOR),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "spruce_trapdoor", "トウヒのトラップドア", Material.SPRUCE_TRAPDOOR),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "birch_trapdoor", "シラカバのトラップドア", Material.BIRCH_TRAPDOOR),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "jungle_trapdoor", "ジャングルのトラップドア", Material.JUNGLE_TRAPDOOR),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "acacia_trapdoor", "アカシアのトラップドア", Material.ACACIA_TRAPDOOR),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "dark_oak_trapdoor", "ダークオークのトラップドア", Material.DARK_OAK_TRAPDOOR),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "crimson_trapdoor", "真紅のトラップドア", Material.CRIMSON_TRAPDOOR),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "warped_trapdoor", "歪んだトラップドア", Material.WARPED_TRAPDOOR),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"fence_gate","オークのフェンスゲート",Material.OAK_FENCE_GATE),
+      List(
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"spruce_fence_gate","トウヒのフェンスゲート",Material.SPRUCE_FENCE_GATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"birch_fence_gate","シラカバのフェンスゲート",Material.BIRCH_FENCE_GATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"jungle_fence_gate","ジャングルのフェンスゲート",Material.JUNGLE_FENCE_GATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"dark_oak_fence_gate","ダークオークのフェンスゲート",Material.DARK_OAK_FENCE_GATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"acacia_fence_gate","アカシアのフェンスゲート",Material.ACACIA_FENCE_GATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "crimson_fence_gate", "真紅のフェンスゲート", Material.CRIMSON_FENCE_GATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "warped_fence_gate", "歪んだフェンスゲート", Material.WARPED_FENCE_GATE),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"wood_plate","オークの感圧板",Material.OAK_PRESSURE_PLATE),
+      List(
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"stone_plate","石の感圧板",Material.STONE_PRESSURE_PLATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "polished_blackstone_pressure_plate", "磨かれたブラックストーンの感圧板", Material.POLISHED_BLACKSTONE_PRESSURE_PLATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "spruce_pressure_plate", "トウヒの感圧板", Material.SPRUCE_PRESSURE_PLATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "birch_pressure_plate", "シラカバの感圧板", Material.BIRCH_PRESSURE_PLATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "jungle_pressure_plate", "ジャングルの感圧板", Material.JUNGLE_PRESSURE_PLATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "acacia_pressure_plate", "アカシアの感圧板", Material.ACACIA_PRESSURE_PLATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "dark_oak_pressure_plate", "ダークオークの感圧板", Material.DARK_OAK_PRESSURE_PLATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "crimson_pressure_plate", "真紅の感圧板", Material.CRIMSON_PRESSURE_PLATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "warped_pressure_plate", "歪んだ感圧板", Material.WARPED_PRESSURE_PLATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"gold_plate","軽量用感圧板",Material.LIGHT_WEIGHTED_PRESSURE_PLATE),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"iron_plate","重量用感圧板",Material.HEAVY_WEIGHTED_PRESSURE_PLATE),
+      )
+    ),
+    MineStackObjectWithKindVariants(
+      MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION, "boat", "オークのボート", Material.OAK_BOAT),
+      List(
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"spruce_boat","トウヒのボート",Material.SPRUCE_BOAT),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"birch_boat","シラカバのボート",Material.BIRCH_BOAT),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"jungle_boat","ジャングルのボート",Material.JUNGLE_BOAT),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"acacia_boat","アカシアのボート",Material.ACACIA_BOAT),
+        MineStackObjectByMaterial(REDSTONE_AND_TRANSPORTATION,"dark_oak_boat","ダークオークのボート",Material.DARK_OAK_BOAT),
+      )
+    )
   )
 
   /**
@@ -597,7 +1096,7 @@ class BukkitMineStackObjectList[F[_]: Sync](
    */
   private val minestackBuiltinGachaPrizes: List[MineStackObjectGroup[ItemStack]] = leftElems(
     MineStackObjectByItemStack(GACHA_PRIZES, "gachaimo", None, hasNameLore = true, gachaPrizeAPI.staticGachaPrizeFactory.gachaRingo),
-    MineStackObjectByItemStack(GACHA_PRIZES, "exp_bottle", Some("エンチャントの瓶"), hasNameLore = false, new ItemStack(Material.EXP_BOTTLE, 1))
+    MineStackObjectByItemStack(GACHA_PRIZES, "exp_bottle", Some("エンチャントの瓶"), hasNameLore = false, new ItemStack(Material.EXPERIENCE_BOTTLE))
   )
 
   // @formatter:on
@@ -640,7 +1139,7 @@ class BukkitMineStackObjectList[F[_]: Sync](
   override def allMineStackObjects: F[Vector[MineStackObject[ItemStack]]] =
     allMineStackGroups.map(_.flatMap {
       case Left(mineStackObject: MineStackObject[ItemStack]) => List(mineStackObject)
-      case Right(group) => List(group.representative) ++ group.coloredVariants
+      case Right(group) => List(group.representative) ++ group.kindVariants
     }.toVector)
 
   override def getAllObjectGroupsInCategory(
@@ -656,37 +1155,36 @@ class BukkitMineStackObjectList[F[_]: Sync](
     allMineStackGroups.map(_.filter { group => categoryOf(group) == category })
   }
 
-  override def findBySignedItemStack(
-    itemStack: ItemStack,
+  override def findBySignedItemStacks(
+    itemStacks: Vector[ItemStack],
     player: Player
-  ): F[Option[MineStackObject[ItemStack]]] = for {
-    gachaPrizes <- gachaPrizeAPI.gachaPrizesWhenGachaEventsIsNotHolding
-    canBeSignedAsGachaPrize = gachaPrizeAPI.canBeSignedAsGachaPrize
-    foundGachaPrizeOpt = gachaPrizes.find { gachaPrize =>
-      if (gachaPrize.signOwner) {
-        gachaPrize
-          .materializeWithOwnerSignature(player.getName)(canBeSignedAsGachaPrize)
-          .isSimilar(itemStack)
-      } else {
-        gachaPrize.itemStack.isSimilar(itemStack)
+  ): F[Vector[(ItemStack, Option[MineStackObject[ItemStack]])]] = {
+    for {
+      gachaPrizes <- gachaPrizeAPI.gachaPrizesWhenGachaEventsIsNotHolding
+      mineStackObjects <- allMineStackObjects
+    } yield {
+      implicit val canBeSignedAsGachaPrize: CanBeSignedAsGachaPrize[ItemStack] =
+        gachaPrizeAPI.canBeSignedAsGachaPrize
+
+      val signedItemStacks = gachaPrizes.map { gachaPrize =>
+        gachaPrize.materializeWithOwnerSignature(player.getName) -> gachaPrize.itemStack
       }
-    }
-    isGachaPrize = foundGachaPrizeOpt.nonEmpty
-    mineStackObjects <- allMineStackObjects
-  } yield {
-    // ItemStackのLoreはnullの可能性がある
-    val isSignedItemStack =
-      Option(itemStack.getItemMeta.getLore).exists(_.contains("所有者:"))
-    if (isGachaPrize && foundGachaPrizeOpt.get.signOwner) {
-      mineStackObjects.find { mineStackObject =>
-        foundGachaPrizeOpt.get.itemStack.isSimilar(mineStackObject.itemStack)
+
+      itemStacks.map { _itemStack =>
+        signedItemStacks.find(_._1.isSimilar(_itemStack)) match {
+          case Some((_, notSignedItemStack)) =>
+            _itemStack -> mineStackObjects.find(_.itemStack.isSimilar(notSignedItemStack))
+          case None =>
+            mineStackObjects.find(_.itemStack.isSimilar(_itemStack)) match {
+              case Some(value)
+                  if value.category != GACHA_PRIZES || minestackBuiltinGachaPrizes.exists(
+                    _.swap.contains(value)
+                  ) =>
+                _itemStack -> Some(value)
+              case _ => _itemStack -> None
+            }
+        }
       }
-    } else if (isSignedItemStack) {
-      // 所有者名が違うとガチャ景品として認識しないが、違ったらそもそも見つかっていない
-      // 記名が入っていないアイテムは収納できてしまうが仕様
-      None
-    } else {
-      mineStackObjects.find(_.itemStack.isSimilar(itemStack))
     }
   }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/bukkit/BukkitMineStackRepository.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/bukkit/BukkitMineStackRepository.scala
index 80e77fded1..5e6763f417 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/bukkit/BukkitMineStackRepository.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/bukkit/BukkitMineStackRepository.scala
@@ -66,9 +66,38 @@ class BukkitMineStackRepository[F[_]: Sync](
     )
   }
 
-  override def tryIntoMineStack(player: Player, itemStack: ItemStack, amount: Int): F[Boolean] =
+  override def tryIntoMineStack(
+    player: Player,
+    itemStack: ItemStack,
+    amount: Int
+  ): F[Boolean] = {
+    for {
+      foundMineStackObject <- mineStackObjectList.findBySignedItemStacks(
+        Vector(itemStack),
+        player
+      )
+      _ <- foundMineStackObject.head.traverse {
+        case Some(mineStackObject) =>
+          addStackedAmountOf(player, mineStackObject, amount)
+        case None => Sync[F].unit
+      }
+    } yield foundMineStackObject.head._2.isDefined
+  }
+
+  override def tryIntoMineStack(
+    player: Player,
+    itemStacks: Vector[ItemStack]
+  ): F[(Vector[ItemStack], Vector[ItemStack])] = {
     for {
-      foundMineStackObject <- mineStackObjectList.findBySignedItemStack(itemStack, player)
-      _ <- foundMineStackObject.traverse(addStackedAmountOf(player, _, amount))
-    } yield foundMineStackObject.isDefined
+      mineStackObjects <- mineStackObjectList.findBySignedItemStacks(itemStacks, player)
+      _ <- mineStackObjects.traverse {
+        case (itemStack, Some(mineStackObject)) =>
+          addStackedAmountOf(player, mineStackObject, itemStack.getAmount)
+        case _ => Sync[F].unit
+      }
+    } yield mineStackObjects.partitionMap {
+      case (itemStack, Some(_)) => Right(itemStack)
+      case (itemStack, None)    => Left(itemStack)
+    }
+  }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/bukkit/PlayerPickupItemListener.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/bukkit/PlayerPickupItemListener.scala
index b97140073a..e9d998d394 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/bukkit/PlayerPickupItemListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/bukkit/PlayerPickupItemListener.scala
@@ -37,9 +37,9 @@ class PlayerPickupItemListener[F[_]: ConcurrentEffect, G[_]: ContextCoercion[*[_
           currentAutoMineStackState <- ContextCoercion(
             mineStackSettingRepository(player).isAutoCollectionTurnedOn
           )
-          isSucceedTryIntoMineStack <- whenAOrElse(currentAutoMineStackState)(
-            mineStackRepository.tryIntoMineStack(player, itemStack, itemStack.getAmount),
-            false
+          intoSucceedItemStacksAndFailedItemStacks <- whenAOrElse(currentAutoMineStackState)(
+            mineStackRepository.tryIntoMineStack(player, Vector(itemStack)),
+            (Vector(itemStack), Vector.empty)
           )
           _ <- Sync[F]
             .delay {
@@ -48,13 +48,13 @@ class PlayerPickupItemListener[F[_]: ConcurrentEffect, G[_]: ContextCoercion[*[_
               item.remove()
               if (SeichiAssist.DEBUG) {
                 player.sendMessage(RED.toString + "pick:" + itemStack.toString)
-                player.sendMessage(RED.toString + "pickDurability:" + itemStack.getDurability)
               }
             }
-            .whenA(isSucceedTryIntoMineStack)
+            .whenA(intoSucceedItemStacksAndFailedItemStacks._2.nonEmpty)
         } yield ()
 
         program.toIO.unsafeRunAsyncAndForget()
+      case _ => ()
     }
   }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/MineStackRepository.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/MineStackRepository.scala
index 1dd9e97231..a6b48d13f9 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/MineStackRepository.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/MineStackRepository.scala
@@ -37,4 +37,14 @@ trait MineStackRepository[F[_], Player, ItemStack] {
    */
   def tryIntoMineStack(player: Player, itemStack: ItemStack, amount: Int): F[Boolean]
 
+  /**
+   * [[Player]]のMineStackリポジトリに[[ItemStack]]を格納することを試みます。
+   * @return `itemStacks`の要素である[[ItemStack]]をMineStackに格納し
+   *         格納できなかったアイテムをTupleの第1要素、格納できたアイテムを第2要素として返す作用
+   */
+  def tryIntoMineStack(
+    player: Player,
+    itemStacks: Vector[ItemStack]
+  ): F[(Vector[ItemStack], Vector[ItemStack])]
+
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/MineStackObject.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/MineStackObject.scala
index f742352f38..7a95afeb3a 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/MineStackObject.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/MineStackObject.scala
@@ -54,15 +54,14 @@ object MineStackObject {
     category: MineStackObjectCategory,
     mineStackObjectName: String,
     japaneseName: String,
-    material: Material,
-    durability: Short
+    material: Material
   )(
     implicit minecraftMaterial: MinecraftMaterial[Material, ItemStack]
   ): MineStackObject[ItemStack] = {
     MineStackObject(
       mineStackObjectName,
       Some(japaneseName),
-      minecraftMaterial.toItemStack(material, durability),
+      minecraftMaterial.toItemStack(material),
       hasNameLore = false,
       category
     )
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/MineStackObjectList.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/MineStackObjectList.scala
index bd30603044..5a1ce7590a 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/MineStackObjectList.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/MineStackObjectList.scala
@@ -11,12 +11,12 @@ trait MineStackObjectList[F[_], ItemStack, Player] {
 
   /**
    * @param itemStack 記名することのできるアイテムは、既に記名されていることを想定している
-   * @return [[ItemStack]]から[[MineStackObject]]を取得しようとする作用
+   * @return `itemStack`の各要素に紐づいた[[MineStackObject]]を返す作用
    */
-  def findBySignedItemStack(
-    itemStack: ItemStack,
+  def findBySignedItemStacks(
+    itemStack: Vector[ItemStack],
     player: Player
-  ): F[Option[MineStackObject[ItemStack]]]
+  ): F[Vector[(ItemStack, Option[MineStackObject[ItemStack]])]]
 
   protected implicit val F: Functor[F]
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/MineStackObjectWithColorVariants.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/MineStackObjectWithKindVariants.scala
similarity index 52%
rename from src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/MineStackObjectWithColorVariants.scala
rename to src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/MineStackObjectWithKindVariants.scala
index 35db22e653..3be993045a 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/MineStackObjectWithColorVariants.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/MineStackObjectWithKindVariants.scala
@@ -1,10 +1,10 @@
 package com.github.unchama.seichiassist.subsystems.minestack.domain.minestackobject
 
-case class MineStackObjectWithColorVariants[ItemStack](
+case class MineStackObjectWithKindVariants[ItemStack](
   representative: MineStackObject[ItemStack],
-  coloredVariants: List[MineStackObject[ItemStack]]
+  kindVariants: List[MineStackObject[ItemStack]]
 ) {
-  require(coloredVariants.forall(_.category == representative.category))
+  require(kindVariants.forall(_.category == representative.category))
 
   def category: MineStackObjectCategory = representative.category
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/package.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/package.scala
index 77b55a1aca..d1649c73ba 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/package.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/domain/minestackobject/package.scala
@@ -3,6 +3,6 @@ package com.github.unchama.seichiassist.subsystems.minestack.domain
 package object minestackobject {
 
   type MineStackObjectGroup[ItemStack] =
-    Either[MineStackObject[ItemStack], MineStackObjectWithColorVariants[ItemStack]]
+    Either[MineStackObject[ItemStack], MineStackObjectWithKindVariants[ItemStack]]
 
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/infrastructure/JdbcMineStackObjectPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/infrastructure/JdbcMineStackObjectPersistence.scala
index e57a68055a..be50653998 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/infrastructure/JdbcMineStackObjectPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/infrastructure/JdbcMineStackObjectPersistence.scala
@@ -29,7 +29,6 @@ class JdbcMineStackObjectPersistence[F[_]: Sync, ItemStack, Player](
             }
           }
           .toList()
-          .apply()
           .filterNot(_.isEmpty)
           .map(_.get)
       }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/infrastructure/JdbcPlayerSettingPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/infrastructure/JdbcPlayerSettingPersistence.scala
index 15ed250a38..2699cf3dd3 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/infrastructure/JdbcPlayerSettingPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/minestack/infrastructure/JdbcPlayerSettingPersistence.scala
@@ -13,24 +13,19 @@ class JdbcPlayerSettingPersistence[F[_]: Sync] extends PlayerSettingPersistence[
       sql"SELECT minestackflag FROM playerdata WHERE uuid = ${uuid.toString}"
         .map(_.boolean("minestackflag"))
         .single()
-        .apply()
         .getOrElse(false)
     }
   }
 
   override def turnOnAutoMineStack(uuid: UUID): F[Unit] = Sync[F].delay {
     DB.localTx { implicit session =>
-      sql"UPDATE playerdata SET minestackflag = true WHERE uuid = ${uuid.toString}"
-        .execute()
-        .apply()
+      sql"UPDATE playerdata SET minestackflag = true WHERE uuid = ${uuid.toString}".execute()
     }
   }
 
   override def turnOffAutoMineStack(uuid: UUID): F[Unit] = Sync[F].delay {
     DB.localTx { implicit session =>
-      sql"UPDATE playerdata SET minestackflag = false WHERE uuid = ${uuid.toString}"
-        .execute()
-        .apply()
+      sql"UPDATE playerdata SET minestackflag = false WHERE uuid = ${uuid.toString}".execute()
     }
   }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/openirontrapdoor/bukkit/listeners/PlayerClickIronTrapDoor.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/openirontrapdoor/bukkit/listeners/PlayerClickIronTrapDoor.scala
index 1935fce2be..e4208cb298 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/openirontrapdoor/bukkit/listeners/PlayerClickIronTrapDoor.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/openirontrapdoor/bukkit/listeners/PlayerClickIronTrapDoor.scala
@@ -2,11 +2,12 @@ package com.github.unchama.seichiassist.subsystems.openirontrapdoor.bukkit.liste
 
 import com.github.unchama.util.external.WorldGuardWrapper.isRegionMember
 import org.bukkit.Material
+import org.bukkit.block.data.BlockData
 import org.bukkit.event.block.Action
 import org.bukkit.event.player.PlayerInteractEvent
 import org.bukkit.event.{EventHandler, Listener}
 import org.bukkit.inventory.EquipmentSlot
-import org.bukkit.material.{MaterialData, Openable}
+import org.bukkit.material.Openable
 
 object PlayerClickIronTrapDoor extends Listener {
   @EventHandler
@@ -21,10 +22,15 @@ object PlayerClickIronTrapDoor extends Listener {
     ) return
 
     // TODO: 手に何も持っていない場合は機能するが、ブロックなどを持っている場合は機能しない(手に持っているものが設置できるもののときや弓矢は反応する)
-    val blockState = clickedBlock.getState
-    val materialData = blockState.getData.asInstanceOf[Openable]
-    materialData.setOpen(!materialData.isOpen)
-    blockState.setData(materialData.asInstanceOf[MaterialData])
-    blockState.update()
+    val blockData = clickedBlock.getBlockData
+    blockData match {
+      case openable: Openable =>
+        openable.setOpen(!openable.isOpen)
+
+        val blockState = clickedBlock.getState
+        blockState.setBlockData(openable.asInstanceOf[BlockData])
+        blockState.update()
+      case _ =>
+    }
   }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/PlayerHeadSkinAPI.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/PlayerHeadSkinAPI.scala
new file mode 100644
index 0000000000..2f853565d2
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/PlayerHeadSkinAPI.scala
@@ -0,0 +1,11 @@
+package com.github.unchama.seichiassist.subsystems.playerheadskin
+
+import com.github.unchama.seichiassist.subsystems.playerheadskin.domain.HeadSkinUrl
+
+import java.util.UUID
+
+trait PlayerHeadSkinAPI[F[_], Player] {
+
+  def playerHeadSkinUrlByUUID(player: UUID): F[Option[HeadSkinUrl]]
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/System.scala
new file mode 100644
index 0000000000..0ede8a41ab
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/System.scala
@@ -0,0 +1,40 @@
+package com.github.unchama.seichiassist.subsystems.playerheadskin
+
+import cats.effect.Sync
+import com.github.unchama.seichiassist.meta.subsystem.Subsystem
+import com.github.unchama.seichiassist.subsystems.playerheadskin.domain.{
+  PlayerHeadSkinUrlFetcher,
+  PlayerHeadUrlRepository
+}
+import com.github.unchama.seichiassist.subsystems.playerheadskin.infrastructure.{
+  JdbcPlayerHeadSkinPersistence,
+  PlayerHeadSkinUrlFetcherByMojangAPI
+}
+import org.bukkit.entity.Player
+
+import java.util.UUID
+
+trait System[F[_], Player] extends Subsystem[F] {
+  val api: PlayerHeadSkinAPI[F, Player]
+}
+
+object System {
+
+  def wired[F[_]: Sync]: System[F, Player] = {
+    implicit val playerHeadSkinUrlFetcher: PlayerHeadSkinUrlFetcher[F] =
+      new PlayerHeadSkinUrlFetcherByMojangAPI[F]
+    val repository = new PlayerHeadUrlRepository[F]
+    val persistence = new JdbcPlayerHeadSkinPersistence[F]
+
+    new System[F, Player] {
+      import cats.implicits._
+
+      override val api: PlayerHeadSkinAPI[F, Player] = (player: UUID) =>
+        for {
+          playerName <- persistence.fetchLastSeenPlayerName(player)
+          url <- playerName.flatTraverse(repository.readUrl)
+        } yield url
+    }
+  }
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/domain/HeadSkinUrl.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/domain/HeadSkinUrl.scala
new file mode 100644
index 0000000000..96257cce7f
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/domain/HeadSkinUrl.scala
@@ -0,0 +1,3 @@
+package com.github.unchama.seichiassist.subsystems.playerheadskin.domain
+
+case class HeadSkinUrl(playerName: String, url: String)
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/domain/PlayerHeadSkinPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/domain/PlayerHeadSkinPersistence.scala
new file mode 100644
index 0000000000..8b4f0aad8c
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/domain/PlayerHeadSkinPersistence.scala
@@ -0,0 +1,12 @@
+package com.github.unchama.seichiassist.subsystems.playerheadskin.domain
+
+import java.util.UUID
+
+trait PlayerHeadSkinPersistence[F[_]] {
+
+  /**
+   * @return `player`に一致するUUIDの、最後に確認されたプレイヤー名を取得する作用
+   */
+  def fetchLastSeenPlayerName(player: UUID): F[Option[String]]
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/domain/PlayerHeadSkinUrlFetcher.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/domain/PlayerHeadSkinUrlFetcher.scala
new file mode 100644
index 0000000000..94dbfe2311
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/domain/PlayerHeadSkinUrlFetcher.scala
@@ -0,0 +1,10 @@
+package com.github.unchama.seichiassist.subsystems.playerheadskin.domain
+
+trait PlayerHeadSkinUrlFetcher[F[_]] {
+
+  /**
+   * @return `playerName`の頭のスキンのURLを取ってくる作用
+   */
+  def fetchHeadSkinUrl(playerName: String): F[Option[HeadSkinUrl]]
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/domain/PlayerHeadUrlRepository.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/domain/PlayerHeadUrlRepository.scala
new file mode 100644
index 0000000000..ea48c0b622
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/domain/PlayerHeadUrlRepository.scala
@@ -0,0 +1,24 @@
+package com.github.unchama.seichiassist.subsystems.playerheadskin.domain
+
+import cats.effect.Sync
+import cats.effect.concurrent.Ref
+import com.github.unchama.generic.ApplicativeExtra
+
+class PlayerHeadUrlRepository[F[_]: Sync](implicit fetcher: PlayerHeadSkinUrlFetcher[F]) {
+
+  private val skinUrls: Ref[F, Vector[HeadSkinUrl]] = Ref.unsafe(Vector.empty)
+
+  import cats.implicits._
+
+  def readUrl(targetPlayer: String): F[Option[HeadSkinUrl]] = for {
+    urls <- skinUrls.get
+    targetPlayersHeadSkinUrl <- ApplicativeExtra.whenAOrElse(
+      !urls.exists(_.playerName == targetPlayer)
+    )(fetcher.fetchHeadSkinUrl(targetPlayer), None)
+    _ <- skinUrls
+      .update(_ :+ targetPlayersHeadSkinUrl.get)
+      .whenA(targetPlayersHeadSkinUrl.isDefined)
+    resultUrls <- skinUrls.get
+  } yield resultUrls.find(_.playerName == targetPlayer)
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/infrastructure/JdbcPlayerHeadSkinPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/infrastructure/JdbcPlayerHeadSkinPersistence.scala
new file mode 100644
index 0000000000..6f27c7d293
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/infrastructure/JdbcPlayerHeadSkinPersistence.scala
@@ -0,0 +1,20 @@
+package com.github.unchama.seichiassist.subsystems.playerheadskin.infrastructure
+
+import cats.effect.Sync
+import com.github.unchama.seichiassist.subsystems.playerheadskin.domain.PlayerHeadSkinPersistence
+import scalikejdbc._
+
+import java.util.UUID
+
+class JdbcPlayerHeadSkinPersistence[F[_]: Sync] extends PlayerHeadSkinPersistence[F] {
+
+  override def fetchLastSeenPlayerName(player: UUID): F[Option[String]] = Sync[F].delay {
+    DB.readOnly { implicit session =>
+      sql"SELECT name FROM playerdata WHERE uuid = ${player.toString}"
+        .map(_.string("name"))
+        .first
+        .apply()
+    }
+  }
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/infrastructure/PlayerHeadSkinUrlFetcherByMojangAPI.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/infrastructure/PlayerHeadSkinUrlFetcherByMojangAPI.scala
new file mode 100644
index 0000000000..a0db85fb7c
--- /dev/null
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/playerheadskin/infrastructure/PlayerHeadSkinUrlFetcherByMojangAPI.scala
@@ -0,0 +1,79 @@
+package com.github.unchama.seichiassist.subsystems.playerheadskin.infrastructure
+
+import cats.effect.Sync
+import com.github.unchama.seichiassist.subsystems.playerheadskin.domain.{
+  HeadSkinUrl,
+  PlayerHeadSkinUrlFetcher
+}
+import org.apache.commons.codec.binary.Base64
+import org.jline.utils.InputStreamReader
+
+import java.io.BufferedReader
+import java.net.{HttpURLConnection, URL}
+import java.nio.charset.StandardCharsets
+
+class PlayerHeadSkinUrlFetcherByMojangAPI[F[_]: Sync] extends PlayerHeadSkinUrlFetcher[F] {
+
+  import cats.implicits._
+
+  private def getHttpRequest(url: String): F[Option[String]] = for {
+    url <- Sync[F].pure(new URL(url))
+    connection <- Sync[F].delay(url.openConnection().asInstanceOf[HttpURLConnection])
+    _ <- Sync[F].delay(connection.connect())
+    responseCode <- Sync[F].delay(connection.getResponseCode)
+    response <- Sync[F].delay {
+      Option.when(responseCode == HttpURLConnection.HTTP_OK) {
+        val inputStream = connection.getInputStream
+        val inputStreamReader = new InputStreamReader(inputStream, "UTF-8")
+        val bufferedReader = new BufferedReader(inputStreamReader)
+
+        val result =
+          Iterator.continually(bufferedReader.readLine()).takeWhile(_ != null).mkString
+
+        bufferedReader.close()
+        inputStreamReader.close()
+        inputStream.close()
+
+        result
+      }
+    }
+  } yield response
+
+  import io.circe.parser._
+
+  private def textureUrl(name: String): F[Option[String]] = {
+    for {
+      profileOpt <- getHttpRequest(s"https://api.mojang.com/users/profiles/minecraft/$name")
+      id = for {
+        profile <- profileOpt
+        id <- parse(profile).toOption.flatMap(_.hcursor.get[String]("id").toOption)
+      } yield id
+      playerDataOpt <- getHttpRequest(
+        s"https://sessionserver.mojang.com/session/minecraft/profile/$id"
+      )
+      url = for {
+        playerData <- playerDataOpt
+        base64TextureProperties <- parse(playerData)
+          .toOption
+          .flatMap(
+            _.hcursor
+              .downField("properties")
+              .values
+              .flatMap(_.head.hcursor.get[String]("value").toOption)
+          )
+        url <- parse(
+          new String(Base64.decodeBase64(base64TextureProperties), StandardCharsets.UTF_8)
+        ).toOption
+          .flatMap(
+            _.hcursor.downField("textures").downField("SKIN").get[String]("url").toOption
+          )
+      } yield url
+
+    } yield url
+  }
+
+  override def fetchHeadSkinUrl(playerName: String): F[Option[HeadSkinUrl]] = for {
+    textureUrl <- textureUrl(playerName)
+  } yield textureUrl.map(url => HeadSkinUrl(playerName, url))
+
+}
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/present/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/present/System.scala
index f63133a04e..841ea82975 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/present/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/present/System.scala
@@ -1,8 +1,7 @@
 package com.github.unchama.seichiassist.subsystems.present
 
-import cats.effect.{ConcurrentEffect, IO}
+import cats.effect.ConcurrentEffect
 import com.github.unchama.concurrent.NonServerThreadContextShift
-import com.github.unchama.generic.effect.unsafe.EffectEnvironment
 import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.domain.actions.UuidToLastSeenName
 import com.github.unchama.seichiassist.meta.subsystem.Subsystem
@@ -11,10 +10,10 @@ import com.github.unchama.seichiassist.subsystems.present.infrastructure.JdbcBac
 import org.bukkit.command.TabExecutor
 
 object System {
-  def wired[ConcurrentContext[_]: ConcurrentEffect: NonServerThreadContextShift](
-    implicit environment: EffectEnvironment,
-    uuidToLastSeenName: UuidToLastSeenName[ConcurrentContext],
-    ioOnMainThread: OnMinecraftServerThread[IO]
+  def wired[ConcurrentContext[
+    _
+  ]: ConcurrentEffect: NonServerThreadContextShift: OnMinecraftServerThread](
+    implicit uuidToLastSeenName: UuidToLastSeenName[ConcurrentContext]
   ): Subsystem[ConcurrentContext] = {
     implicit val repo: JdbcBackedPresentPersistence[ConcurrentContext] =
       new JdbcBackedPresentPersistence[ConcurrentContext]
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/present/bukkit/command/PresentCommand.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/present/bukkit/command/PresentCommand.scala
index ace10b8278..04695cbee7 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/present/bukkit/command/PresentCommand.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/present/bukkit/command/PresentCommand.scala
@@ -1,8 +1,8 @@
 package com.github.unchama.seichiassist.subsystems.present.bukkit.command
 
-import cats.Monad
+import cats.data.Kleisli
 import cats.effect.implicits._
-import cats.effect.{ConcurrentEffect, IO}
+import cats.effect.{ConcurrentEffect, Sync}
 import cats.implicits._
 import com.github.unchama.concurrent.NonServerThreadContextShift
 import com.github.unchama.contextualexecutor.ContextualExecutor
@@ -18,8 +18,8 @@ import com.github.unchama.seichiassist.domain.actions.UuidToLastSeenName
 import com.github.unchama.seichiassist.subsystems.present.domain.OperationResult.DeleteResult
 import com.github.unchama.seichiassist.subsystems.present.domain._
 import com.github.unchama.seichiassist.util.InventoryOperations
-import com.github.unchama.targetedeffect.commandsender.MessageEffect
-import com.github.unchama.targetedeffect.{SequentialEffect, TargetedEffect}
+import com.github.unchama.targetedeffect.{SequentialEffect, TargetedEffectF}
+import com.github.unchama.targetedeffect.commandsender.{MessageEffect, MessageEffectF}
 import eu.timepit.refined.api.Refined
 import eu.timepit.refined.auto._
 import eu.timepit.refined.numeric.Positive
@@ -28,7 +28,6 @@ import org.bukkit.entity.Player
 import org.bukkit.inventory.ItemStack
 import org.bukkit.{ChatColor, Material}
 import shapeless.HNil
-import shapeless.syntax.std.tuple._
 
 /**
  * `/present` コマンドを定義する。
@@ -38,8 +37,10 @@ import shapeless.syntax.std.tuple._
  * 別に表記がない限り、この実装は以下の条件を満たす:
  *   - 存在しないプレゼントIDの指定は必ずエラーになる。
  *   - 操作が成功しなかったときは適切なメッセージを表示する。
+ *
+ * TODO: 型パラメータが関数のあちこちに散りばめられているが、classの型引数に集約できそう
  */
-class PresentCommand(implicit val ioOnMainThread: OnMinecraftServerThread[IO]) {
+class PresentCommand {
   private val presentIdParser =
     Parsers.integer(MessageEffect("presentコマンドに与えるプレゼントIDは整数である必要があります。"))
 
@@ -54,7 +55,8 @@ class PresentCommand(implicit val ioOnMainThread: OnMinecraftServerThread[IO]) {
     MessageEffect("presentコマンドで対象を指定する際のモードは、playerまたはallを指定してください。")
   )
 
-  private val noPermissionMessage = MessageEffect("You don't have the permission.")
+  private def noPermissionMessage[F[_]: Sync] =
+    MessageEffectF[F]("You don't have the permission.")
 
   private object SubCommands {
     object State {
@@ -166,47 +168,45 @@ class PresentCommand(implicit val ioOnMainThread: OnMinecraftServerThread[IO]) {
        *
        * 出力: 受け取った場合は、その旨表示する。失敗した場合は、適切なエラーメッセージを表示する。
        */
-      def executor[F[_]: ConcurrentEffect: NonServerThreadContextShift](
-        implicit persistence: PresentPersistence[F, ItemStack]
-      ): ContextualExecutor =
+      def executor[
+        F[_]: ConcurrentEffect: NonServerThreadContextShift: OnMinecraftServerThread
+      ](implicit persistence: PresentPersistence[F, ItemStack]): ContextualExecutor =
         playerCommandBuilder
           .thenParse(presentIdParser)
           .ifArgumentsMissing(help)
-          .buildWithExecutionF { context =>
+          .buildWithExecutionCSEffect { context =>
             val player = context.sender.getUniqueId
             val presentId = context.args.parsed.head
 
-            val eff: F[TargetedEffect[Player]] = for {
-              _ <- NonServerThreadContextShift[F].shift
-              states <- persistence.fetchState(player)
-              claimState = states.getOrElse(presentId, PresentClaimingState.Unavailable)
-              effect <- claimState match {
+            (for {
+              _ <- Kleisli.liftF(NonServerThreadContextShift[F].shift)
+              states <- Kleisli.liftF(persistence.fetchState(player))
+            } yield {
+              val claimState = states.getOrElse(presentId, PresentClaimingState.Unavailable)
+
+              claimState match {
                 case PresentClaimingState.Claimed =>
-                  Monad[F].pure(MessageEffect(s"ID: ${presentId}のプレゼントはすでに受け取っています。"))
+                  MessageEffectF[F](s"ID: ${presentId}のプレゼントはすでに受け取っています。")
                 case PresentClaimingState.NotClaimed =>
-                  for {
-                    _ <- persistence.markAsClaimed(presentId, player)
-                    item <- persistence.lookup(presentId)
-                  } yield {
-                    // 注釈: この明示的な型変数の指定は必要
-                    // see: https://discord.com/channels/237758724121427969/565935041574731807/823495317499805776
-                    item.fold[TargetedEffect[Player]](
-                      MessageEffect(s"ID: ${presentId}のプレゼントは存在しません。IDをお確かめください。")
-                    ) { item =>
-                      SequentialEffect(
-                        InventoryOperations.grantItemStacksEffect[IO](item),
-                        MessageEffect(s"ID: ${presentId}のプレゼントを付与しました。")
-                      )
+                  Kleisli
+                    .liftF(for {
+                      _ <- persistence.markAsClaimed(presentId, player)
+                      item <- persistence.lookup(presentId)
+                    } yield item)
+                    .flatMap { item =>
+                      item.fold[TargetedEffectF[F, Player]](
+                        MessageEffectF[F](s"ID: ${presentId}のプレゼントは存在しません。IDをお確かめください。")
+                      ) { item =>
+                        SequentialEffect(
+                          InventoryOperations.grantItemStacksEffect[F](item),
+                          MessageEffectF[F](s"ID: ${presentId}のプレゼントを付与しました。")
+                        )
+                      }
                     }
-                  }
                 case PresentClaimingState.Unavailable =>
-                  Monad[F].pure(
-                    MessageEffect(s"ID: ${presentId}のプレゼントは存在しないか、あるいは配布対象ではありません。")
-                  )
+                  MessageEffectF[F](s"ID: ${presentId}のプレゼントは存在しないか、あるいは配布対象ではありません。")
               }
-            } yield effect
-
-            eff
+            }).flatten
           }
     }
 
@@ -228,25 +228,23 @@ class PresentCommand(implicit val ioOnMainThread: OnMinecraftServerThread[IO]) {
       def executor[F[_]: ConcurrentEffect: NonServerThreadContextShift](
         implicit persistence: PresentPersistence[F, ItemStack]
       ): ContextualExecutor =
-        playerCommandBuilder.buildWithExecutionF { context =>
+        playerCommandBuilder.buildWithExecutionCSEffect { context =>
           val player = context.sender
           if (player.hasPermission("seichiassist.present.define")) {
             val mainHandItem = player.getInventory.getItemInMainHand
-            if (mainHandItem.getType eq Material.AIR) {
+            if (mainHandItem.getType == Material.AIR) {
               // おそらくこれは意図した動作ではないのでエラーメッセージを表示する
-              ConcurrentEffect[F].pure(
-                MessageEffect("メインハンドに何も持っていません。プレゼントを定義するためには、メインハンドに対象アイテムを持ってください。")
-              )
+              MessageEffectF[F]("メインハンドに何も持っていません。プレゼントを定義するためには、メインハンドに対象アイテムを持ってください。")
             } else {
-              for {
-                _ <- NonServerThreadContextShift[F].shift
-                presentID <- persistence.define(mainHandItem)
+              (for {
+                _ <- Kleisli.liftF(NonServerThreadContextShift[F].shift)
+                presentID <- Kleisli.liftF(persistence.define(mainHandItem))
               } yield {
-                MessageEffect(s"メインハンドに持ったアイテムをプレゼントとして定義しました。IDは${presentID}です。")
-              }
+                MessageEffectF(s"メインハンドに持ったアイテムをプレゼントとして定義しました。IDは${presentID}です。")
+              }).flatten
             }
           } else {
-            ConcurrentEffect[F].pure(noPermissionMessage)
+            noPermissionMessage
           }
         }
     }
@@ -270,21 +268,21 @@ class PresentCommand(implicit val ioOnMainThread: OnMinecraftServerThread[IO]) {
           .beginConfiguration
           .thenParse(presentIdParser)
           .ifArgumentsMissing(help)
-          .buildWithExecutionF { context =>
+          .buildWithExecutionCSEffect { context =>
             {
               val presentId = context.args.parsed.head
               if (!context.sender.hasPermission("seichiassist.present.delete")) {
-                ConcurrentEffect[F].pure(noPermissionMessage)
+                noPermissionMessage
               } else {
-                for {
-                  _ <- NonServerThreadContextShift[F].shift
-                  result <- persistence.delete(presentId)
+                (for {
+                  _ <- Kleisli.liftF(NonServerThreadContextShift[F].shift)
+                  result <- Kleisli.liftF(persistence.delete(presentId))
                 } yield result match {
                   case DeleteResult.Done =>
-                    MessageEffect(s"IDが${presentId}のプレゼントの消去は正常に行われました。")
+                    MessageEffectF(s"IDが${presentId}のプレゼントの消去は正常に行われました。")
                   case DeleteResult.NotFound =>
-                    MessageEffect(s"IDが${presentId}のプレゼントは存在しませんでした。")
-                }
+                    MessageEffectF(s"IDが${presentId}のプレゼントは存在しませんでした。")
+                }).flatten
               }
             }
           }
@@ -325,16 +323,16 @@ class PresentCommand(implicit val ioOnMainThread: OnMinecraftServerThread[IO]) {
           .thenParse(presentIdParser)
           .thenParse(presentScopeModeParser)
           .ifArgumentsMissing(help)
-          .buildWithExecutionF { context =>
+          .buildWithExecutionCSEffect { context =>
             if (context.sender.hasPermission("seichiassist.present.grant")) {
               import shapeless.::
               val presentId :: mode :: HNil = context.args.parsed
               // Parserを通した段階でargs[0]は "player" | "all" になっているのでこれでOK
               val isGlobal = mode == "all"
-              for {
-                _ <- NonServerThreadContextShift[F].shift
+              (for {
+                _ <- Kleisli.liftF(NonServerThreadContextShift[F].shift)
                 // TODO: 以下の処理は多分共通化できるがうまい方法が思いつかない
-                globalUUID2Name <- globalPlayerAccessor.entries
+                globalUUID2Name <- Kleisli.liftF(globalPlayerAccessor.entries)
                 // 可変長引数には対応していないので`yetToBeParsed`を使う
                 restArg = context
                   .args
@@ -348,19 +346,19 @@ class PresentCommand(implicit val ioOnMainThread: OnMinecraftServerThread[IO]) {
                   else
                     globalUUID2Name.filter { case (_, name) => restArg.contains(name) }.keys
                 errorIfNobody = Option.when(target.isEmpty) {
-                  MessageEffect("対象のプレイヤーが存在しません!")
+                  MessageEffectF("対象のプレイヤーが存在しません!")
                 }
-                grantError <- persistence.grant(presentId, target.toSet)
+                grantError <- Kleisli.liftF(persistence.grant(presentId, target.toSet))
               } yield errorIfNobody.getOrElse(
                 grantError
                   .map {
                     case GrantRejectReason.NoSuchPresentID =>
-                      MessageEffect("指定されたプレゼントIDは存在しません!")
+                      MessageEffectF("指定されたプレゼントIDは存在しません!")
                   }
-                  .getOrElse(MessageEffect(s"プレゼント(id: $presentId)を受け取れるプレイヤーを追加しました。"))
-              )
+                  .getOrElse(MessageEffectF(s"プレゼント(id: $presentId)を受け取れるプレイヤーを追加しました。"))
+              )).flatten
             } else {
-              ConcurrentEffect[F].pure(noPermissionMessage)
+              noPermissionMessage
             }
           }
     }
@@ -399,15 +397,15 @@ class PresentCommand(implicit val ioOnMainThread: OnMinecraftServerThread[IO]) {
           .thenParse(presentIdParser)
           .thenParse(presentScopeModeParser)
           .ifArgumentsMissing(help)
-          .buildWithExecutionF { context =>
+          .buildWithExecutionCSEffect { context =>
             if (context.sender.hasPermission("seichiassist.present.revoke")) {
               import shapeless.::
               val args = context.args
               val presentId :: presentScope :: HNil = args.parsed
               val isGlobal = presentScope == "all"
-              for {
-                _ <- NonServerThreadContextShift[F].shift
-                globalUUID2Name <- globalPlayerAccessor.entries
+              (for {
+                _ <- Kleisli.liftF(NonServerThreadContextShift[F].shift)
+                globalUUID2Name <- Kleisli.liftF(globalPlayerAccessor.entries)
                 // 可変長引数には対応していないので`yetToBeParsed`を使う
                 restArg = args
                   // プレイヤー名は /[A-Za-z0-9_]{,16}/であるため空白が誤って解釈されることはない
@@ -420,22 +418,23 @@ class PresentCommand(implicit val ioOnMainThread: OnMinecraftServerThread[IO]) {
                   else
                     globalUUID2Name.filter { case (_, name) => restArg.contains(name) }.keys
                 errorIfNobody =
-                  if (target.isEmpty) Some(MessageEffect("対象のプレイヤーが存在しません!")) else None
-                warning <- persistence.revoke(presentId, target.toSet)
+                  if (target.isEmpty) Some(MessageEffectF("対象のプレイヤーが存在しません!")) else None
+                warning <- Kleisli.liftF(persistence.revoke(presentId, target.toSet))
               } yield {
                 errorIfNobody.getOrElse {
                   warning
                     .map {
-                      case RevokeWarning.NoSuchPresentID => MessageEffect("そのようなプレゼントIDはありません!")
-                      case RevokeWarning.NoPlayers       => MessageEffect("対象となるプレイヤーが存在しません!")
+                      case RevokeWarning.NoSuchPresentID =>
+                        MessageEffectF("そのようなプレゼントIDはありません!")
+                      case RevokeWarning.NoPlayers => MessageEffectF("対象となるプレイヤーが存在しません!")
                     }
                     .getOrElse {
-                      MessageEffect(s"プレゼント(id: $presentId)を受け取れるプレイヤーを削除しました。")
+                      MessageEffectF(s"プレゼント(id: $presentId)を受け取れるプレイヤーを削除しました。")
                     }
                 }
-              }
+              }).flatten
             } else {
-              ConcurrentEffect[F].pure(noPermissionMessage)
+              noPermissionMessage
             }
           }
     }
@@ -473,7 +472,7 @@ class PresentCommand(implicit val ioOnMainThread: OnMinecraftServerThread[IO]) {
     }
   }
 
-  def executor[F[_]: ConcurrentEffect: NonServerThreadContextShift](
+  def executor[F[_]: ConcurrentEffect: NonServerThreadContextShift: OnMinecraftServerThread](
     implicit persistence: PresentPersistence[F, ItemStack],
     globalPlayerAccessor: UuidToLastSeenName[F]
   ): TabExecutor = BranchedExecutor(
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/present/infrastructure/GlobalPlayerAccessor.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/present/infrastructure/GlobalPlayerAccessor.scala
index 228b6814be..aaa2f9d5f0 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/present/infrastructure/GlobalPlayerAccessor.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/present/infrastructure/GlobalPlayerAccessor.scala
@@ -20,7 +20,6 @@ class GlobalPlayerAccessor[F[_]: Sync] extends UuidToLastSeenName[F] {
       sql"""SELECT name, uuid from seichiassist.playerdata"""
         .map { rs => (UUID.fromString(rs.string("uuid")), rs.string("name")) }
         .list()
-        .apply()
         .toMap
     }
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/present/infrastructure/JdbcBackedPresentPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/present/infrastructure/JdbcBackedPresentPersistence.scala
index 197c85ee08..79e3feffb5 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/present/infrastructure/JdbcBackedPresentPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/present/infrastructure/JdbcBackedPresentPersistence.scala
@@ -22,8 +22,7 @@ class JdbcBackedPresentPersistence[F[_]: Sync] extends PresentPersistence[F, Ite
     DB.localTx { implicit session =>
       // プレゼントのIDはauto_incrementなので明示的に指定しなくて良い
       sql"""INSERT INTO present (itemstack) VALUES ($stackAsBlob)"""
-        .updateAndReturnGeneratedKey
-        .apply()
+        .updateAndReturnGeneratedKey()
     }
   }
 
@@ -36,10 +35,10 @@ class JdbcBackedPresentPersistence[F[_]: Sync] extends PresentPersistence[F, Ite
   override def delete(presentId: PresentID): F[DeleteResult] = Sync[F].delay {
     DB.localTx { implicit session =>
       // 制約をかけているのでpresent_stateの方から先に消さないと整合性エラーを吐く
-      sql"""DELETE FROM present_state WHERE present_id = $presentId""".execute().apply()
+      sql"""DELETE FROM present_state WHERE present_id = $presentId""".execute()
 
       val deletedRows =
-        sql"""DELETE FROM present WHERE present_id = $presentId""".update().apply()
+        sql"""DELETE FROM present WHERE present_id = $presentId""".update()
 
       if (deletedRows == 1) DeleteResult.Done else DeleteResult.NotFound
     }
@@ -50,22 +49,21 @@ class JdbcBackedPresentPersistence[F[_]: Sync] extends PresentPersistence[F, Ite
     val program = for {
       exists <- Sync[F].delay {
         DB.readOnly { implicit session =>
-          sql"""SELECT present_id FROM present""".map(x => x.long("present_id")).list().apply()
+          sql"""SELECT present_id FROM present""".map(x => x.long("present_id")).list()
         }.contains(presentID)
       }
     } yield {
       if (exists) {
         Sync[F].delay {
-          import scala.collection.Seq.iterableFactory
 
           val initialValues = players.map { uuid => Seq(presentID, uuid.toString, false) }.toSeq
 
-          DB.localTx { implicit session =>
+          DB.localTx { _ =>
             // upsert - これによってfilterなしで整合性違反を起こすことはなくなる
             sql"""
                   INSERT INTO present_state VALUES (?, ?, ?)
                   ON DUPLICATE KEY UPDATE present_id=present_id, uuid=uuid
-                 """.batch(initialValues: _*).apply()
+                 """.batch(initialValues: _*)
           }
 
           // 型推論
@@ -93,7 +91,6 @@ class JdbcBackedPresentPersistence[F[_]: Sync] extends PresentPersistence[F, Ite
           // https://discord.com/channels/237758724121427969/565935041574731807/824107651985834004
           sql"""DELETE FROM present_state WHERE present_id = $presentID AND uuid IN ($scopeAsSQL)"""
             .update()
-            .apply()
         }
 
         Option.when(deleteCount == 0) { RevokeWarning.NoSuchPresentID }
@@ -105,7 +102,6 @@ class JdbcBackedPresentPersistence[F[_]: Sync] extends PresentPersistence[F, Ite
     DB.localTx { implicit session =>
       sql"""UPDATE present_state SET claimed = TRUE WHERE uuid = ${player.toString} AND present_id = $presentId"""
         .update()
-        .apply()
     }
   }
 
@@ -114,7 +110,6 @@ class JdbcBackedPresentPersistence[F[_]: Sync] extends PresentPersistence[F, Ite
       sql"""SELECT present_id, itemstack FROM present"""
         .map { rs => (rs.long("present_id"), unwrapItemStack(rs)) }
         .list()
-        .apply()
         .toMap
     }
   }
@@ -141,7 +136,7 @@ class JdbcBackedPresentPersistence[F[_]: Sync] extends PresentPersistence[F, Ite
                |FROM present_state
                |WHERE uuid = ${player.toString} AND present_id IN ($idSliceWithPagination)
                |ORDER BY present_id
-        """.stripMargin.map(wrapResultForState).toList().apply()
+        """.stripMargin.map(wrapResultForState).toList()
         }
 
         Right(
@@ -167,7 +162,6 @@ class JdbcBackedPresentPersistence[F[_]: Sync] extends PresentPersistence[F, Ite
         sql"""SELECT present_id, claimed FROM present_state WHERE uuid = ${player.toString}"""
           .map(wrapResultForState)
           .list()
-          .apply()
       }
 
       MapExtra.fillOnBaseSet(
@@ -183,7 +177,6 @@ class JdbcBackedPresentPersistence[F[_]: Sync] extends PresentPersistence[F, Ite
       sql"""SELECT itemstack FROM present WHERE present_id = $presentID"""
         .map(unwrapItemStack)
         .first()
-        .apply()
     }
   }
 
@@ -197,7 +190,6 @@ class JdbcBackedPresentPersistence[F[_]: Sync] extends PresentPersistence[F, Ite
         sql"""SELECT present_id FROM present ORDER BY present_id LIMIT ${perPage.value} OFFSET $offset"""
           .map { _.long("present_id") }
           .toList()
-          .apply()
           .toSet
       }
     }
@@ -218,7 +210,7 @@ class JdbcBackedPresentPersistence[F[_]: Sync] extends PresentPersistence[F, Ite
 
   private def computeValidPresentCount: F[Long] = Sync[F].delay {
     DB.readOnly { implicit session =>
-      sql"""SELECT COUNT(*) AS c FROM present""".map(_.long("c")).first().apply().get // safe
+      sql"""SELECT COUNT(*) AS c FROM present""".map(_.long("c")).first().get // safe
     }
   }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/System.scala
index 425c46cfdf..30651b6c60 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/System.scala
@@ -12,6 +12,8 @@ import com.github.unchama.seichiassist.subsystems.ranking.domain.values.{LoginTi
 import com.github.unchama.seichiassist.subsystems.ranking.infrastructure._
 import io.chrisdavenport.log4cats.ErrorLogger
 
+import scala.concurrent.duration.DurationInt
+
 object System {
 
   import cats.implicits._
@@ -19,16 +21,20 @@ object System {
   def wired[F[_]: Timer: Concurrent: ErrorLogger, H[_]]: F[AssortedRankingApi[F]] =
     for {
       seichiRanking <- GenericRefreshingRankingCache.withPersistence(
-        new JdbcSeichiRankingRecordPersistence[F]
+        new JdbcSeichiRankingRecordPersistence[F],
+        30.seconds
       )
       buildRanking <- GenericRefreshingRankingCache.withPersistence(
-        new JdbcBuildRankingRecordPersistence[F]
+        new JdbcBuildRankingRecordPersistence[F],
+        30.seconds
       )
       loginRanking <- GenericRefreshingRankingCache.withPersistence(
-        new JdbcLoginRankingRecordPersistence[F]
+        new JdbcLoginRankingRecordPersistence[F],
+        1.hours
       )
       voteRanking <- GenericRefreshingRankingCache.withPersistence(
-        new JdbcVoteRankingRecordPersistence[F]
+        new JdbcVoteRankingRecordPersistence[F],
+        1.hours
       )
     } yield {
       new AssortedRankingApi[F] {
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/application/GenericRefreshingRankingCache.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/application/GenericRefreshingRankingCache.scala
index c1649c7ec3..4ddac9ae9a 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/application/GenericRefreshingRankingCache.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/application/GenericRefreshingRankingCache.scala
@@ -11,12 +11,13 @@ import com.github.unchama.generic.effect.stream.StreamExtra
 import com.github.unchama.seichiassist.subsystems.ranking.domain._
 import io.chrisdavenport.log4cats.ErrorLogger
 
-import scala.concurrent.duration.DurationInt
+import scala.concurrent.duration.FiniteDuration
 
 object GenericRefreshingRankingCache {
 
   def withPersistence[F[_]: Concurrent: Timer: ErrorLogger, R: Order: Monoid](
-    persistence: RankingRecordPersistence[F, R]
+    persistence: RankingRecordPersistence[F, R],
+    duration: FiniteDuration
   ): F[ReadOnlyRef[F, Ranking[R]]] =
     for {
       initialRankingRecords <- persistence.getAllRankingRecords
@@ -26,7 +27,7 @@ object GenericRefreshingRankingCache {
           .compileToRestartingStream[F, Unit]("[GenericRefreshingRankingCache]") {
             fs2
               .Stream
-              .awakeEvery[F](30.seconds)
+              .awakeEvery[F](duration)
               .evalMap(_ => persistence.getAllRankingRecords)
               .evalTap(newRecords => rankingRef.set(new Ranking(newRecords)))
           }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/domain/RankingRecord.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/domain/RankingRecord.scala
index 4efa97c7da..08ea3b1b2c 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/domain/RankingRecord.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/domain/RankingRecord.scala
@@ -1,5 +1,7 @@
 package com.github.unchama.seichiassist.subsystems.ranking.domain
 
-case class RankingRecord[V](playerName: String, value: V)
+import java.util.UUID
+
+case class RankingRecord[V](playerName: String, uuid: UUID, value: V)
 
 case class RankingRecordWithPosition[V](record: RankingRecord[V], positionInRanking: Int)
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcBuildRankingRecordPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcBuildRankingRecordPersistence.scala
index 710c99798a..fcb6de1c99 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcBuildRankingRecordPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcBuildRankingRecordPersistence.scala
@@ -9,20 +9,22 @@ import com.github.unchama.seichiassist.subsystems.ranking.domain.{
 }
 import scalikejdbc.{DB, scalikejdbcSQLInterpolationImplicitDef}
 
+import java.util.UUID
+
 class JdbcBuildRankingRecordPersistence[F[_]: Sync]
     extends RankingRecordPersistence[F, BuildAmountData] {
 
   override def getAllRankingRecords: F[Vector[RankingRecord[BuildAmountData]]] = Sync[F].delay {
     DB.readOnly { implicit session =>
-      sql"SELECT name,build_count from playerdata"
+      sql"SELECT name, uuid, build_count from playerdata"
         .map { rs =>
           RankingRecord(
             rs.string("name"),
+            UUID.fromString(rs.string("uuid")),
             BuildAmountData(BuildExpAmount(BigDecimal(rs.string("build_count"))))
           )
         }
         .list()
-        .apply()
         .toVector
     }
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcLoginRankingRecordPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcLoginRankingRecordPersistence.scala
index 73182ccd80..4322202d79 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcLoginRankingRecordPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcLoginRankingRecordPersistence.scala
@@ -8,14 +8,21 @@ import com.github.unchama.seichiassist.subsystems.ranking.domain.{
 }
 import scalikejdbc.{DB, scalikejdbcSQLInterpolationImplicitDef}
 
+import java.util.UUID
+
 class JdbcLoginRankingRecordPersistence[F[_]: Sync]
     extends RankingRecordPersistence[F, LoginTime] {
   override def getAllRankingRecords: F[Vector[RankingRecord[LoginTime]]] = Sync[F].delay {
     DB.readOnly { implicit session =>
-      sql"SELECT name,playtick from playerdata"
-        .map { rs => RankingRecord(rs.string("name"), LoginTime(rs.long("playtick"))) }
+      sql"SELECT name, uuid, playtick from playerdata"
+        .map { rs =>
+          RankingRecord(
+            rs.string("name"),
+            UUID.fromString(rs.string("uuid")),
+            LoginTime(rs.long("playtick"))
+          )
+        }
         .list()
-        .apply()
         .toVector
     }
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcSeichiRankingRecordPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcSeichiRankingRecordPersistence.scala
index ea8c6ef7cc..108d40f74d 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcSeichiRankingRecordPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcSeichiRankingRecordPersistence.scala
@@ -9,23 +9,25 @@ import com.github.unchama.seichiassist.subsystems.ranking.domain.{
 }
 import scalikejdbc.{DB, scalikejdbcSQLInterpolationImplicitDef}
 
+import java.util.UUID
+
 class JdbcSeichiRankingRecordPersistence[F[_]: Sync]
     extends RankingRecordPersistence[F, SeichiAmountData] {
 
   override def getAllRankingRecords: F[Vector[RankingRecord[SeichiAmountData]]] =
     Sync[F].delay {
       DB.localTx { implicit session =>
-        sql"select name, totalbreaknum from playerdata"
+        sql"select name, uuid, totalbreaknum from playerdata"
           .map { rs =>
             RankingRecord(
               rs.string("name"),
+              UUID.fromString(rs.string("uuid")),
               SeichiAmountData(
                 SeichiExpAmount.ofNonNegative(rs.bigInt("totalbreaknum").longValueExact())
               )
             )
           }
           .list()
-          .apply()
           .toVector
       }
     }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcVoteRankingRecordPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcVoteRankingRecordPersistence.scala
index 2a06e54cc6..9a9a5726cc 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcVoteRankingRecordPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/ranking/infrastructure/JdbcVoteRankingRecordPersistence.scala
@@ -8,14 +8,21 @@ import com.github.unchama.seichiassist.subsystems.ranking.domain.{
 }
 import scalikejdbc.{DB, scalikejdbcSQLInterpolationImplicitDef}
 
+import java.util.UUID
+
 class JdbcVoteRankingRecordPersistence[F[_]: Sync]
     extends RankingRecordPersistence[F, VoteCount] {
   override def getAllRankingRecords: F[Vector[RankingRecord[VoteCount]]] = Sync[F].delay {
     DB.readOnly { implicit session =>
-      sql"SELECT playerdata.name,vote_number FROM vote INNER JOIN playerdata ON vote.uuid = playerdata.uuid"
-        .map { rs => RankingRecord(rs.string("name"), VoteCount(rs.int("vote_number"))) }
+      sql"SELECT playerdata.name, playerdata.uuid, vote_number FROM vote INNER JOIN playerdata ON vote.uuid = playerdata.uuid"
+        .map { rs =>
+          RankingRecord(
+            rs.string("name"),
+            UUID.fromString(rs.string("uuid")),
+            VoteCount(rs.int("vote_number"))
+          )
+        }
         .list()
-        .apply()
         .toVector
     }
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/rescueplayer/bukkit/listeners/RescuePlayerListener.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/rescueplayer/bukkit/listeners/RescuePlayerListener.scala
index 0dd495654e..0efebbcceb 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/rescueplayer/bukkit/listeners/RescuePlayerListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/rescueplayer/bukkit/listeners/RescuePlayerListener.scala
@@ -7,7 +7,7 @@ import org.bukkit.event.{EventHandler, Listener}
 class RescuePlayerListener extends Listener {
   @EventHandler
   def onPlayerFallenToVoid(event: PlayerMoveEvent): Unit = {
-    if (event.getTo.getBlockY < 0.0) {
+    if (event.getTo.getBlockY < -64.0) {
       val player = event.getPlayer
       val worldSpawnLocation = player.getWorld.getSpawnLocation
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/System.scala
index b4ee0b2c57..a5d793ec42 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/System.scala
@@ -7,6 +7,7 @@ import com.github.unchama.generic.effect.unsafe.EffectEnvironment
 import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.meta.subsystem.Subsystem
 import com.github.unchama.seichiassist.subsystems.mana.ManaWriteApi
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.seasonalevents.anniversary.AnniversaryListener
 import com.github.unchama.seichiassist.subsystems.seasonalevents.api.SeasonalEventsAPI
 import com.github.unchama.seichiassist.subsystems.seasonalevents.christmas.ChristmasItemListener
@@ -43,7 +44,8 @@ object System {
     implicit manaWriteApi: ManaWriteApi[G, Player],
     effectEnvironment: EffectEnvironment,
     ioOnMainThread: OnMinecraftServerThread[IO],
-    gtToSiinaAPI: GtToSiinaAPI[ItemStack]
+    gtToSiinaAPI: GtToSiinaAPI[ItemStack],
+    playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   ): System[H] = {
 
     implicit val repository: LastQuitPersistenceRepository[F, UUID] =
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/anniversary/AnniversaryItemData.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/anniversary/AnniversaryItemData.scala
index 259899bcf2..4170c1ed3e 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/anniversary/AnniversaryItemData.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/anniversary/AnniversaryItemData.scala
@@ -1,13 +1,16 @@
 package com.github.unchama.seichiassist.subsystems.seasonalevents.anniversary
 
+import cats.effect.IO
 import com.github.unchama.itemstackbuilder.{SkullItemStackBuilder, SkullOwnerTextureValue}
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.seasonalevents.anniversary.Anniversary.ANNIVERSARY_COUNT
 import com.github.unchama.seichiassist.util.EnchantNameToJapanese
-import de.tr7zw.itemnbtapi.NBTItem
+import de.tr7zw.nbtapi.NBTItem
 import org.bukkit.Bukkit
 import org.bukkit.ChatColor._
 import org.bukkit.Material._
 import org.bukkit.enchantments.Enchantment
+import org.bukkit.entity.Player
 import org.bukkit.inventory.meta.BookMeta.Generation
 import org.bukkit.inventory.meta.{BookMeta, ItemMeta, SkullMeta}
 import org.bukkit.inventory.{ItemFlag, ItemStack}
@@ -22,10 +25,11 @@ object AnniversaryItemData {
   private val mineChan = SkullOwnerTextureValue(
     "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNDhmNTQ0OGI0ZDg4ZTQwYjE0YzgyOGM2ZjFiNTliMzg1NDVkZGE5MzNlNzNkZmYzZjY5NWU2ZmI0Mjc4MSJ9fX0="
   )
-  val mineHead: ItemStack = new SkullItemStackBuilder(mineChan)
-    .title("まいんちゃん")
-    .lore("", s"${YELLOW}ギガンティック☆整地鯖${ANNIVERSARY_COUNT}周年記念だよ!")
-    .build()
+  def mineHead(implicit playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]): ItemStack =
+    new SkullItemStackBuilder(mineChan)
+      .title("まいんちゃん")
+      .lore("", s"${YELLOW}ギガンティック☆整地鯖${ANNIVERSARY_COUNT}周年記念だよ!")
+      .build()
 
   // endregion
 
@@ -36,13 +40,13 @@ object AnniversaryItemData {
       .map(lore => s"$RESET$GRAY$lore")
       .asJava
 
-    val itemMeta = Bukkit.getItemFactory.getItemMeta(SAPLING).tap { meta =>
+    val itemMeta = Bukkit.getItemFactory.getItemMeta(OAK_SAPLING).tap { meta =>
       import meta._
       setDisplayName(s"$GOLD${BOLD}「気になる木」の苗")
       setLore(loreList)
     }
 
-    val itemStack = new ItemStack(SAPLING, 1)
+    val itemStack = new ItemStack(OAK_SAPLING, 1)
     itemStack.setItemMeta(itemMeta)
 
     new NBTItem(itemStack)
@@ -64,25 +68,29 @@ object AnniversaryItemData {
     COAL_BLOCK,
     DIAMOND_BLOCK,
     DRAGON_EGG,
-    FENCE,
+    OAK_FENCE,
+    JUNGLE_FENCE,
+    ACACIA_FENCE,
+    BIRCH_FENCE,
+    DARK_OAK_FENCE,
     FLOWER_POT,
     GLOWSTONE,
     GOLD_BLOCK,
     GRASS,
     ICE,
     IRON_BLOCK,
-    MELON_BLOCK,
+    MELON,
     NETHER_BRICK,
     QUARTZ_BLOCK,
     SAND,
     SPONGE,
-    WORKBENCH
+    CRAFTING_TABLE
   )
 
   val strangeSaplingSiinaRate = 0.0008
 
   def isStrangeSapling(item: ItemStack): Boolean =
-    item != null && item.getType == SAPLING && {
+    item != null && item.getType == OAK_SAPLING && {
       new NBTItem(item).getByte(NBTTagConstants.typeIdTag) == 1
     }
 
@@ -135,14 +143,15 @@ object AnniversaryItemData {
 
     val loreList = {
       val enchDescription = enchantments.map {
-        case (ench, lvl) => s"$GRAY${EnchantNameToJapanese.getEnchantName(ench.getName, lvl)}"
+        case (ench, lvl) =>
+          s"$GRAY${EnchantNameToJapanese.getEnchantName(ench.getKey.getKey, lvl)}"
       }.toList
       val lore = List("", "特殊なエンチャントが付与されています").map(lore => s"$YELLOW$lore")
 
       enchDescription ::: lore
     }.map(lore => s"$RESET$lore").asJava
 
-    val itemMeta = Bukkit.getItemFactory.getItemMeta(DIAMOND_SPADE).tap { meta =>
+    val itemMeta = Bukkit.getItemFactory.getItemMeta(DIAMOND_SHOVEL).tap { meta =>
       import meta._
       setDisplayName(s"$GOLD${BOLD}SCARLET")
       setLore(loreList)
@@ -150,7 +159,7 @@ object AnniversaryItemData {
       enchantments.foreach { case (ench, lvl) => addEnchant(ench, lvl, true) }
     }
 
-    val itemStack = new ItemStack(DIAMOND_SPADE, 1)
+    val itemStack = new ItemStack(DIAMOND_SHOVEL, 1)
     itemStack.setItemMeta(itemMeta)
 
     new NBTItem(itemStack)
@@ -162,7 +171,7 @@ object AnniversaryItemData {
   }
 
   def isAnniversaryShovel(item: ItemStack): Boolean =
-    item != null && item.getType == DIAMOND_SPADE && {
+    item != null && item.getType == DIAMOND_SHOVEL && {
       new NBTItem(item).getByte(NBTTagConstants.typeIdTag) == 3
     }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/anniversary/AnniversaryListener.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/anniversary/AnniversaryListener.scala
index ff9311350f..2af8dde12c 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/anniversary/AnniversaryListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/anniversary/AnniversaryListener.scala
@@ -4,6 +4,7 @@ import cats.effect.IO
 import com.github.unchama.generic.effect.unsafe.EffectEnvironment
 import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.SeichiAssist
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.seasonalevents.anniversary.Anniversary.{
   ANNIVERSARY_COUNT,
   blogArticleUrl,
@@ -21,7 +22,7 @@ import com.github.unchama.targetedeffect.player.FocusedSoundEffect
 import com.github.unchama.targetedeffect.{SequentialEffect, UnfocusedEffect}
 import org.bukkit.ChatColor._
 import org.bukkit.block.{Block, Chest}
-import org.bukkit.entity.LivingEntity
+import org.bukkit.entity.{LivingEntity, Player}
 import org.bukkit.event.block.{Action, BlockBreakEvent, BlockPlaceEvent}
 import org.bukkit.event.entity.PlayerDeathEvent
 import org.bukkit.event.player.{PlayerInteractEvent, PlayerJoinEvent}
@@ -35,7 +36,8 @@ import scala.util.Random
 class AnniversaryListener(
   implicit effectEnvironment: EffectEnvironment,
   ioOnMainThread: OnMinecraftServerThread[IO],
-  gtToSiinaAPI: GtToSiinaAPI[ItemStack]
+  gtToSiinaAPI: GtToSiinaAPI[ItemStack],
+  playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
 ) extends Listener {
 
   @EventHandler
@@ -91,7 +93,7 @@ class AnniversaryListener(
     // Y座標を下に動かして(木の上方から)オークの木の頂点を探し、そのブロックを置き換える
     (10 to 0 by -1)
       .map(placedBlock.getRelative(0, _, 0))
-      .find(block => block.getType == Material.LOG || block.getType == Material.LEAVES)
+      .find(block => block.getType == Material.OAK_LOG || block.getType == Material.OAK_LEAVES)
       .foreach(replaceBlockOnTreeTop(_, event.getPlayer.getName))
   }
 
@@ -109,7 +111,6 @@ class AnniversaryListener(
     val offHandItem = player.getInventory.getItemInOffHand
     if (offHandItem == null) return
 
-    offHandItem.setDurability(0)
     removeItemfromPlayerInventory(player.getInventory, item, 1)
   }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/christmas/ChristmasItemData.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/christmas/ChristmasItemData.scala
index 44b8541612..75a1564a03 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/christmas/ChristmasItemData.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/christmas/ChristmasItemData.scala
@@ -1,7 +1,7 @@
 package com.github.unchama.seichiassist.subsystems.seasonalevents.christmas
 
 import com.github.unchama.seichiassist.subsystems.seasonalevents.christmas.Christmas.EVENT_YEAR
-import de.tr7zw.itemnbtapi.NBTItem
+import de.tr7zw.nbtapi.NBTItem
 import org.bukkit.ChatColor._
 import org.bukkit.Color.fromRGB
 import org.bukkit.enchantments.Enchantment
@@ -197,7 +197,7 @@ object ChristmasItemData {
       s"$RED${UNDERLINE}スポーン地点にいる村人に欲しい物を詰めてもらおう!"
     ).map(str => s"$RESET$str").asJava
 
-    val itemMeta = Bukkit.getItemFactory.getItemMeta(Material.INK_SACK).tap { meta =>
+    Bukkit.getItemFactory.getItemMeta(Material.INK_SAC).tap { meta =>
       import meta._
       setDisplayName(s"${AQUA}靴下(${EVENT_YEAR}年)")
       setLore(loreList)
@@ -206,11 +206,7 @@ object ChristmasItemData {
     }
 
     // 赤の染料
-    val itemStack = new ItemStack(Material.INK_SACK, 1).tap { itemStack =>
-      import itemStack._
-      setDurability(1.toShort)
-      setItemMeta(itemMeta)
-    }
+    val itemStack = new ItemStack(Material.RED_DYE, 1)
 
     itemStack
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/christmas/ChristmasItemListener.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/christmas/ChristmasItemListener.scala
index 3a9efe1632..a2b12ad3bb 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/christmas/ChristmasItemListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/christmas/ChristmasItemListener.scala
@@ -13,7 +13,7 @@ import com.github.unchama.seichiassist.util.InventoryOperations.{
   isPlayerInventoryFull,
   removeItemfromPlayerInventory
 }
-import de.tr7zw.itemnbtapi.NBTItem
+import de.tr7zw.nbtapi.NBTItem
 import org.bukkit.ChatColor._
 import org.bukkit.entity.EntityType._
 import org.bukkit.entity.{EntityType, LivingEntity, Player}
@@ -57,7 +57,7 @@ class ChristmasItemListener[F[_], G[_]: SyncEffect](instance: JavaPlugin)(
 
     val rand = new Random().nextDouble()
     val potionEffectType = if (rand > 0.5) PotionEffectType.LUCK else PotionEffectType.UNLUCK
-    player.addPotionEffect(new PotionEffect(potionEffectType, 20 * 30, 0), true)
+    player.addPotionEffect(new PotionEffect(potionEffectType, 20 * 30, 0))
 
     removeItemfromPlayerInventory(player.getInventory, item, 1)
 
@@ -74,7 +74,7 @@ class ChristmasItemListener[F[_], G[_]: SyncEffect](instance: JavaPlugin)(
 
     val rand = new Random().nextDouble()
     val potionEffectType = if (rand > 0.5) PotionEffectType.SPEED else PotionEffectType.SLOW
-    event.getPlayer.addPotionEffect(new PotionEffect(potionEffectType, 20 * 30, 0), true)
+    event.getPlayer.addPotionEffect(new PotionEffect(potionEffectType, 20 * 30, 0))
   }
 
   @EventHandler
@@ -117,7 +117,7 @@ class ChristmasItemListener[F[_], G[_]: SyncEffect](instance: JavaPlugin)(
       GUARDIAN,
       HUSK,
       MAGMA_CUBE,
-      PIG_ZOMBIE,
+      ZOMBIFIED_PIGLIN,
       SHULKER,
       SILVERFISH,
       SKELETON,
@@ -186,7 +186,7 @@ class ChristmasItemListener[F[_], G[_]: SyncEffect](instance: JavaPlugin)(
         addItem(player, christmasSock)
         player.sendMessage(s"$AQUA「靴下」を見つけたよ!")
       }
-      player.playSound(player.getLocation, Sound.BLOCK_NOTE_HARP, 3.0f, 1.0f)
+      player.playSound(player.getLocation, Sound.BLOCK_NOTE_BLOCK_HARP, 3.0f, 1.0f)
     }
   }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/commands/EventCommand.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/commands/EventCommand.scala
index 837f2538c0..9186ba4773 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/commands/EventCommand.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/commands/EventCommand.scala
@@ -4,6 +4,7 @@ import cats.effect.IO
 import com.github.unchama.contextualexecutor.builder.Parsers
 import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.commands.contextual.builder.BuilderTemplates.playerCommandBuilder
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.seasonalevents.anniversary.AnniversaryItemData._
 import com.github.unchama.seichiassist.subsystems.seasonalevents.christmas.ChristmasItemData._
 import com.github.unchama.seichiassist.subsystems.seasonalevents.halloween.HalloweenItemData._
@@ -14,7 +15,10 @@ import com.github.unchama.targetedeffect.TargetedEffect._
 import org.bukkit.command.TabExecutor
 import org.bukkit.entity.Player
 
-class EventCommand(implicit ioOnMainThread: OnMinecraftServerThread[IO]) {
+class EventCommand(
+  implicit ioOnMainThread: OnMinecraftServerThread[IO],
+  playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
+) {
 
   import com.github.unchama.targetedeffect._
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/halloween/HalloweenItemData.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/halloween/HalloweenItemData.scala
index 11ad0aeaf1..62e86be13d 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/halloween/HalloweenItemData.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/halloween/HalloweenItemData.scala
@@ -1,7 +1,7 @@
 package com.github.unchama.seichiassist.subsystems.seasonalevents.halloween
 
 import com.github.unchama.seichiassist.util.EnchantNameToJapanese
-import de.tr7zw.itemnbtapi.NBTItem
+import de.tr7zw.nbtapi.NBTItem
 import org.bukkit.ChatColor._
 import org.bukkit.Color.fromRGB
 import org.bukkit.enchantments.Enchantment
@@ -82,7 +82,7 @@ object HalloweenItemData {
       val year = Calendar.getInstance().get(Calendar.YEAR)
       val enchDescription = enchantments.map {
         case (ench, lvl) =>
-          s"$RESET$GRAY${EnchantNameToJapanese.getEnchantName(ench.getName, lvl)}"
+          s"$RESET$GRAY${EnchantNameToJapanese.getEnchantName(ench.getKey.toString, lvl)}"
       }.toList
       val lore = List(
         "",
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/halloween/HalloweenItemListener.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/halloween/HalloweenItemListener.scala
index 00c6368525..3ae83e2665 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/halloween/HalloweenItemListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/halloween/HalloweenItemListener.scala
@@ -9,7 +9,7 @@ import com.github.unchama.seichiassist.subsystems.seasonalevents.halloween.Hallo
   isHalloweenHoe,
   isHalloweenPotion
 }
-import com.github.unchama.util.external.WorldGuardWrapper.isRegionMember
+import com.github.unchama.util.external.WorldGuardWrapper
 import org.bukkit.ChatColor.{DARK_GREEN, LIGHT_PURPLE, UNDERLINE}
 import org.bukkit.Material
 import org.bukkit.block.Block
@@ -40,7 +40,7 @@ object HalloweenItemListener extends Listener {
       // 10分
       event
         .getPlayer
-        .addPotionEffect(new PotionEffect(PotionEffectType.SATURATION, 20 * 60 * 10, 0), true)
+        .addPotionEffect(new PotionEffect(PotionEffectType.SATURATION, 20 * 60 * 10, 0))
     }
   }
 
@@ -62,17 +62,19 @@ object HalloweenItemListener extends Listener {
     val player = event.getPlayer
     // まず、Playerが自分でクリックしたブロックについて判定する
     if (!canBeReplacedWithSoil(player, clickedBlock)) return
-    clickedBlock.setType(Material.SOIL)
+    clickedBlock.setType(Material.FARMLAND)
 
     // 次にクリックされたブロックから半径4ブロック以内のブロックについて判定する
     for (relX <- -4 to 4; relZ <- -4 to 4) {
       val block = clickedBlock.getRelative(relX, 0, relZ)
-      if (block != null && canBeReplacedWithSoil(player, block)) block.setType(Material.SOIL)
+      if (block != null && canBeReplacedWithSoil(player, block))
+        block.setType(Material.FARMLAND)
     }
   }
 
   private def canBeReplacedWithSoil(player: Player, block: Block) = {
-    (block.getType == Material.DIRT || block.getType == Material.GRASS) && isRegionMember(
+    (block.getType == Material.FARMLAND || block.getType == Material.GRASS_BLOCK || block
+      .getType() == Material.DIRT) && WorldGuardWrapper.isRegionMember(
       player,
       block.getLocation
     )
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/infrastructure/JdbcLastQuitPersistenceRepository.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/infrastructure/JdbcLastQuitPersistenceRepository.scala
index 6b69e28bed..44d0985db8 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/infrastructure/JdbcLastQuitPersistenceRepository.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/infrastructure/JdbcLastQuitPersistenceRepository.scala
@@ -13,10 +13,9 @@ class JdbcLastQuitPersistenceRepository[F[_]](implicit SyncContext: Sync[F])
     SyncContext.delay {
       DB.localTx { implicit session =>
         sql"select lastquit from playerdata where uuid = {uuid}"
-          .bindByName(Symbol("uuid") -> key.toString)
+          .bindByName("uuid" -> key.toString)
           .map(_.timestampOpt("lastquit").map(_.toLocalDateTime))
           .single()
-          .apply()
           .flatten
       }
     }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/limitedlogin/LimitedLoginBonusGifter.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/limitedlogin/LimitedLoginBonusGifter.scala
index 80785d3ea2..68e20ef15f 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/limitedlogin/LimitedLoginBonusGifter.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/limitedlogin/LimitedLoginBonusGifter.scala
@@ -3,6 +3,7 @@ package com.github.unchama.seichiassist.subsystems.seasonalevents.limitedlogin
 import cats.effect.IO
 import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.subsystems.gachaprize.bukkit.factories.BukkitGachaSkullData
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.seasonalevents.limitedlogin.LimitedLoginEvent.{
   START_DATE,
   isInEvent
@@ -22,8 +23,10 @@ import org.bukkit.inventory.ItemStack
 import java.time.LocalDate
 import java.time.format.DateTimeFormatter
 
-class LimitedLoginBonusGifter(implicit ioOnMainThread: OnMinecraftServerThread[IO])
-    extends Listener {
+class LimitedLoginBonusGifter(
+  implicit ioOnMainThread: OnMinecraftServerThread[IO],
+  playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
+) extends Listener {
   @EventHandler
   def onPlayerJoin(event: PlayerJoinEvent): Unit = {
     if (!isInEvent) return
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/newyear/NewYearItemData.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/newyear/NewYearItemData.scala
index 92ff0f8111..09802d3fd9 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/newyear/NewYearItemData.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/newyear/NewYearItemData.scala
@@ -1,14 +1,17 @@
 package com.github.unchama.seichiassist.subsystems.seasonalevents.newyear
 
+import cats.effect.IO
 import com.github.unchama.itemstackbuilder.{SkullItemStackBuilder, SkullOwnerTextureValue}
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.seasonalevents.newyear.NewYear.{
   END_DATE,
   EVENT_YEAR,
   NEW_YEAR_EVE
 }
-import de.tr7zw.itemnbtapi.NBTItem
+import de.tr7zw.nbtapi.NBTItem
 import org.bukkit.ChatColor._
 import org.bukkit.enchantments.Enchantment
+import org.bukkit.entity.Player
 import org.bukkit.inventory.{ItemFlag, ItemStack}
 import org.bukkit.{Bukkit, Material}
 
@@ -43,7 +46,7 @@ object NewYearItemData {
       .tap { item =>
         import item._
         setByte(NBTTagConstants.typeIdTag, 1.toByte)
-        setObject(NBTTagConstants.expiryDateTag, END_DATE)
+        setLong(NBTTagConstants.expiryDateTag, END_DATE.toEpochDay)
       }
       .pipe(_.getItem)
   }
@@ -76,15 +79,15 @@ object NewYearItemData {
     itemStack
   }
 
-  // https://minecraft-heads.com/custom-heads/food-drinks/413-bowl-of-noodles
   private val soba = SkullOwnerTextureValue(
     "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMjY4MzRiNWIyNTQyNmRlNjM1MzhlYzgyY2E4ZmJlY2ZjYmIzZTY4MmQ4MDYzNjQzZDJlNjdhNzYyMWJkIn19fQ=="
   )
 
-  val sobaHead: ItemStack = new SkullItemStackBuilder(soba)
-    .title(s"年越し蕎麦(${NEW_YEAR_EVE.from.getYear}年)")
-    .lore(List("", s"${YELLOW}大晦日記念アイテムだよ!"))
-    .build()
+  def sobaHead(implicit playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]): ItemStack =
+    new SkullItemStackBuilder(soba)
+      .title(s"年越し蕎麦(${NEW_YEAR_EVE.from.getYear}年)")
+      .lore(List("", s"${YELLOW}大晦日記念アイテムだよ!"))
+      .build()
 
   object NBTTagConstants {
     val typeIdTag = "newYearItemTypeId"
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/newyear/NewYearListener.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/newyear/NewYearListener.scala
index a09d4ac3a8..012a02cbcf 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/newyear/NewYearListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/newyear/NewYearListener.scala
@@ -7,6 +7,7 @@ import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.ManagedWorld._
 import com.github.unchama.seichiassist.MaterialSets
 import com.github.unchama.seichiassist.subsystems.mana.ManaWriteApi
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.seasonalevents.domain.LastQuitPersistenceRepository
 import com.github.unchama.seichiassist.subsystems.seasonalevents.newyear.NewYear._
 import com.github.unchama.seichiassist.subsystems.seasonalevents.newyear.NewYearItemData._
@@ -20,7 +21,7 @@ import com.github.unchama.targetedeffect.SequentialEffect
 import com.github.unchama.targetedeffect.TargetedEffect.emptyEffect
 import com.github.unchama.targetedeffect.commandsender.MessageEffect
 import com.github.unchama.targetedeffect.player.FocusedSoundEffect
-import de.tr7zw.itemnbtapi.NBTItem
+import de.tr7zw.nbtapi.NBTItem
 import org.bukkit.ChatColor._
 import org.bukkit.Sound
 import org.bukkit.entity.Player
@@ -35,7 +36,8 @@ class NewYearListener[F[_]: ConcurrentEffect: NonServerThreadContextShift, G[_]:
   implicit effectEnvironment: EffectEnvironment,
   repository: LastQuitPersistenceRepository[F, UUID],
   manaApi: ManaWriteApi[G, Player],
-  ioOnMainThread: OnMinecraftServerThread[IO]
+  ioOnMainThread: OnMinecraftServerThread[IO],
+  playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
 ) extends Listener {
 
   import cats.implicits._
@@ -91,7 +93,7 @@ class NewYearListener[F[_]: ConcurrentEffect: NonServerThreadContextShift, G[_]:
     val player = event.getPlayer
     val today = LocalDate.now()
     val expiryDate =
-      new NBTItem(item).getObject(NBTTagConstants.expiryDateTag, classOf[LocalDate])
+      LocalDate.ofEpochDay(new NBTItem(item).getLong(NBTTagConstants.expiryDateTag))
     if (today.isBefore(expiryDate) || today.isEqual(expiryDate)) {
       // マナを10%回復する
       manaApi.manaAmount(player).restoreFraction(0.1).runSync[SyncIO].unsafeRunSync()
@@ -117,7 +119,7 @@ class NewYearListener[F[_]: ConcurrentEffect: NonServerThreadContextShift, G[_]:
         addItem(player, newYearBag)
         player.sendMessage(s"$AQUA「お年玉袋」を見つけたよ!")
       }
-      player.playSound(player.getLocation, Sound.BLOCK_NOTE_HARP, 3.0f, 1.0f)
+      player.playSound(player.getLocation, Sound.BLOCK_NOTE_BLOCK_HARP, 3.0f, 1.0f)
     }
   }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/seizonsiki/SeizonsikiItemData.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/seizonsiki/SeizonsikiItemData.scala
index d5a72532db..b0e0e3db04 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/seizonsiki/SeizonsikiItemData.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/seizonsiki/SeizonsikiItemData.scala
@@ -1,7 +1,7 @@
 package com.github.unchama.seichiassist.subsystems.seasonalevents.seizonsiki
 
 import com.github.unchama.seichiassist.subsystems.seasonalevents.seizonsiki.Seizonsiki.END_DATE
-import de.tr7zw.itemnbtapi.NBTItem
+import de.tr7zw.nbtapi.NBTItem
 import org.bukkit.ChatColor._
 import org.bukkit.inventory.ItemStack
 import org.bukkit.{Bukkit, Material}
@@ -36,7 +36,7 @@ object SeizonsikiItemData {
       .tap { item =>
         import item._
         setByte(NBTTagConstants.typeIdTag, 1.toByte)
-        setObject(NBTTagConstants.expiryDateTag, END_DATE)
+        setLong(NBTTagConstants.expiryDateTag, END_DATE.toEpochDay)
       }
       .pipe(_.getItem)
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/seizonsiki/SeizonsikiListener.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/seizonsiki/SeizonsikiListener.scala
index e23d9fa1c2..40211b4de8 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/seizonsiki/SeizonsikiListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/seizonsiki/SeizonsikiListener.scala
@@ -6,9 +6,9 @@ import com.github.unchama.seichiassist.subsystems.mana.ManaWriteApi
 import com.github.unchama.seichiassist.subsystems.seasonalevents.Util.randomlyDropItemAt
 import com.github.unchama.seichiassist.subsystems.seasonalevents.seizonsiki.Seizonsiki._
 import com.github.unchama.seichiassist.subsystems.seasonalevents.seizonsiki.SeizonsikiItemData._
-import com.github.unchama.seichiassist.util.SendMessageEffect.sendMessageToEveryoneIgnoringPreference
+import com.github.unchama.seichiassist.util.SendMessageEffect.sendMessageToEveryoneIgnoringPreferenceIO
 import com.github.unchama.seichiassist.util.EntityDeathCause.isEntityKilledByThornsEnchant
-import de.tr7zw.itemnbtapi.NBTItem
+import de.tr7zw.nbtapi.NBTItem
 import org.bukkit.ChatColor.{DARK_GREEN, LIGHT_PURPLE, UNDERLINE}
 import org.bukkit.Sound
 import org.bukkit.entity.{EntityType, Player}
@@ -56,7 +56,7 @@ class SeizonsikiListener[F[_], G[_]: SyncEffect](implicit manaApi: ManaWriteApi[
 
     val player = event.getPlayer
     val today = LocalDate.now()
-    val exp = new NBTItem(item).getObject(NBTTagConstants.expiryDateTag, classOf[LocalDate])
+    val exp = LocalDate.ofEpochDay(new NBTItem(item).getLong(NBTTagConstants.expiryDateTag))
     if (today.isBefore(exp)) {
       // マナを10%回復する
       manaApi.manaAmount(player).restoreFraction(0.1).runSync[SyncIO].unsafeRunSync()
@@ -67,7 +67,8 @@ class SeizonsikiListener[F[_], G[_]: SyncEffect](implicit manaApi: ManaWriteApi[
       player.setHealth(0)
 
       val messages = deathMessages(player.getName)
-      sendMessageToEveryoneIgnoringPreference(messages(new Random().nextInt(messages.size)))
+      sendMessageToEveryoneIgnoringPreferenceIO(messages(new Random().nextInt(messages.size)))
+        .unsafeRunAsyncAndForget()
     }
   }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/valentine/ValentineItemData.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/valentine/ValentineItemData.scala
index 80a4411381..f1b2d369a2 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/valentine/ValentineItemData.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/valentine/ValentineItemData.scala
@@ -5,13 +5,13 @@ import com.github.unchama.seichiassist.subsystems.seasonalevents.valentine.Valen
   EVENT_DURATION,
   EVENT_YEAR
 }
-import de.tr7zw.itemnbtapi.NBTItem
+import de.tr7zw.nbtapi.NBTItem
 import org.bukkit.ChatColor._
 import org.bukkit.inventory.ItemStack
 import org.bukkit.inventory.meta.SkullMeta
 import org.bukkit.{Bukkit, Material}
 
-import java.time.LocalDateTime
+import java.time.{LocalDateTime, ZoneOffset}
 import java.util.UUID
 import scala.jdk.CollectionConverters._
 import scala.util.chaining._
@@ -43,9 +43,12 @@ object ValentineItemData {
    */
   def isUsableCookie(item: ItemStack): Boolean = {
     val now = LocalDateTime.now()
-    val exp = Option(
-      new NBTItem(item).getObject(NBTTagConstants.expiryDateTimeTag, classOf[LocalDateTime])
-    ).getOrElse(return false)
+    val exp = LocalDateTime.ofEpochSecond(
+      Option(new NBTItem(item).getLong(NBTTagConstants.expiryDateTimeTag))
+        .getOrElse(return false),
+      0,
+      ZoneOffset.of("+9")
+    )
     now.isBefore(exp) || now.isEqual(exp)
   }
 
@@ -74,7 +77,10 @@ object ValentineItemData {
       .tap { item =>
         import item._
         setByte(NBTTagConstants.typeIdTag, droppedCookieTypeId.toByte)
-        setObject(NBTTagConstants.expiryDateTimeTag, EVENT_DURATION.to)
+        setLong(
+          NBTTagConstants.expiryDateTimeTag,
+          EVENT_DURATION.to.toEpochSecond(ZoneOffset.of("+9"))
+        )
       }
       .pipe(_.getItem)
   }
@@ -113,8 +119,11 @@ object ValentineItemData {
       .tap { item =>
         import item._
         setByte(NBTTagConstants.typeIdTag, giftedCookieTypeId.toByte)
-        setObject(NBTTagConstants.expiryDateTimeTag, EVENT_DURATION.to)
-        setObject(NBTTagConstants.producerUuidTag, playerUuid)
+        setLong(
+          NBTTagConstants.expiryDateTimeTag,
+          EVENT_DURATION.to.toEpochSecond(ZoneOffset.of("+9"))
+        )
+        setUUID(NBTTagConstants.producerUuidTag, playerUuid)
         setString(NBTTagConstants.producerNameTag, playerName)
       }
       .pipe(_.getItem)
@@ -128,7 +137,7 @@ object ValentineItemData {
    * @return UUIDが設定されていれば[[Some]]、なければ[[None]]
    */
   def ownerOf(item: ItemStack): Option[UUID] =
-    Option(new NBTItem(item).getObject(NBTTagConstants.producerUuidTag, classOf[UUID]))
+    Option(new NBTItem(item).getOrNull[UUID](NBTTagConstants.producerUuidTag, classOf[UUID]))
 
   def deathMessages(playerName: String, cookieProducerName: String): Seq[String] = Seq(
     s"${playerName}は${cookieProducerName}のチョコチップクッキーを食べた!猟奇的な味だった。",
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/valentine/ValentineListener.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/valentine/ValentineListener.scala
index 689ed38b76..3c2050bfca 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/valentine/ValentineListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seasonalevents/valentine/ValentineListener.scala
@@ -10,11 +10,11 @@ import com.github.unchama.seichiassist.subsystems.seasonalevents.valentine.Valen
 import com.github.unchama.seichiassist.subsystems.seasonalevents.valentine.ValentineCookieEffectsHandler._
 import com.github.unchama.seichiassist.subsystems.seasonalevents.valentine.ValentineItemData._
 import com.github.unchama.seichiassist.util.InventoryOperations.grantItemStacksEffect
-import com.github.unchama.seichiassist.util.SendMessageEffect.sendMessageToEveryoneIgnoringPreference
+import com.github.unchama.seichiassist.util.SendMessageEffect.sendMessageToEveryoneIgnoringPreferenceIO
 import com.github.unchama.targetedeffect.commandsender.MessageEffect
 import com.github.unchama.targetedeffect.player.FocusedSoundEffect
 import com.github.unchama.targetedeffect.{SequentialEffect, TargetedEffect}
-import de.tr7zw.itemnbtapi.NBTItem
+import de.tr7zw.nbtapi.NBTItem
 import org.bukkit.ChatColor._
 import org.bukkit.Sound
 import org.bukkit.attribute.Attribute
@@ -56,7 +56,7 @@ class ValentineListener[F[_]: ConcurrentEffect: NonServerThreadContextShift](
     val damager = event.getDamager
     if (damager == null || damager.getType != EntityType.CREEPER) return
 
-    val excludedMonsters = Set(EntityType.WITCH, EntityType.PIG_ZOMBIE)
+    val excludedMonsters = Set(EntityType.WITCH, EntityType.ZOMBIFIED_PIGLIN)
     event.getEntity match {
       case damaged: Monster if !excludedMonsters.contains(damaged.getType) =>
         val entityMaxHealth = damaged.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue
@@ -139,7 +139,8 @@ class ValentineListener[F[_]: ConcurrentEffect: NonServerThreadContextShift](
         player.getName,
         new NBTItem(item).getString(NBTTagConstants.producerNameTag)
       )
-      sendMessageToEveryoneIgnoringPreference(messages(new Random().nextInt(messages.size)))
+      sendMessageToEveryoneIgnoringPreferenceIO(messages(new Random().nextInt(messages.size)))
+        .unsafeRunAsyncAndForget()
     }
     player.playSound(player.getLocation, Sound.ENTITY_WITCH_DRINK, 1.0f, 1.2f)
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seichilevelupgift/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seichilevelupgift/System.scala
index abbaca504c..aab6684b24 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seichilevelupgift/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seichilevelupgift/System.scala
@@ -1,7 +1,6 @@
 package com.github.unchama.seichiassist.subsystems.seichilevelupgift
 
 import cats.effect.Async
-import com.github.unchama.generic.ContextCoercion
 import com.github.unchama.generic.effect.stream.StreamExtra
 import com.github.unchama.minecraft.actions.{OnMinecraftServerThread, SendMinecraftMessage}
 import com.github.unchama.seichiassist.subsystems.breakcount.BreakCountReadAPI
@@ -17,9 +16,7 @@ import org.bukkit.inventory.ItemStack
 
 object System {
 
-  def backGroundProcess[F[_]: OnMinecraftServerThread: ErrorLogger: Async, G[
-    _
-  ]: ContextCoercion[*[_], F]](
+  def backGroundProcess[F[_]: OnMinecraftServerThread: ErrorLogger: Async, G[_]](
     implicit breakCountReadApi: BreakCountReadAPI[F, G, Player],
     send: SendMinecraftMessage[F, Player],
     gachaPrizeAPI: GachaPrizeAPI[F, ItemStack, Player],
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/seichilevelupgift/bukkit/BukkitGrantLevelUpGift.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/seichilevelupgift/bukkit/BukkitGrantLevelUpGift.scala
index b5437bdd97..473fa15998 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/seichilevelupgift/bukkit/BukkitGrantLevelUpGift.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/seichilevelupgift/bukkit/BukkitGrantLevelUpGift.scala
@@ -1,8 +1,6 @@
 package com.github.unchama.seichiassist.subsystems.seichilevelupgift.bukkit
 
 import cats.data.Kleisli
-import cats.effect.Sync
-import com.github.unchama.generic.ContextCoercion
 import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.data.ItemData
 import com.github.unchama.seichiassist.subsystems.gacha.GachaDrawAPI
@@ -17,9 +15,7 @@ import com.github.unchama.seichiassist.util.InventoryOperations.grantItemStacksE
 import org.bukkit.entity.Player
 import org.bukkit.inventory.ItemStack
 
-class BukkitGrantLevelUpGift[F[_]: Sync: OnMinecraftServerThread, G[_]: ContextCoercion[*[
-  _
-], F]](
+class BukkitGrantLevelUpGift[F[_]: OnMinecraftServerThread, G[_]](
   implicit gachaPointApi: GachaPointApi[F, G, Player],
   gachaPrizeAPI: GachaPrizeAPI[F, ItemStack, Player],
   gachaDrawAPI: GachaDrawAPI[F, Player]
@@ -43,7 +39,7 @@ class BukkitGrantLevelUpGift[F[_]: Sync: OnMinecraftServerThread, G[_]: ContextC
 
 object BukkitGrantLevelUpGift {
 
-  implicit def apply[F[_]: Sync: OnMinecraftServerThread, G[_]: ContextCoercion[*[_], F]](
+  implicit def apply[F[_]: OnMinecraftServerThread, G[_]](
     implicit gachaPrizeAPI: GachaPrizeAPI[F, ItemStack, Player],
     gachaPointApi: GachaPointApi[F, G, Player],
     gachaDrawAPI: GachaDrawAPI[F, Player]
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/System.scala
index f9758db42b..9c8ca2dbab 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/System.scala
@@ -1,6 +1,7 @@
 package com.github.unchama.seichiassist.subsystems.sharedinventory
 
 import cats.effect.{Concurrent, ConcurrentEffect, Timer}
+import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.meta.subsystem.Subsystem
 import com.github.unchama.seichiassist.subsystems.sharedinventory.bukkit.command.ShareInventoryCommand
 import com.github.unchama.seichiassist.subsystems.sharedinventory.domain.bukkit.InventoryContents
@@ -23,7 +24,8 @@ object System {
 
   import cats.implicits._
 
-  def wired[F[_]: ConcurrentEffect: Timer, G[_]: Concurrent]: G[System[F]] = {
+  def wired[F[_]: ConcurrentEffect: Timer: OnMinecraftServerThread, G[_]: Concurrent]
+    : G[System[F]] = {
     implicit val persistence: SharedInventoryPersistence[F] =
       new JdbcSharedInventoryPersistence[F]
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/bukkit/command/ShareInventoryCommand.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/bukkit/command/ShareInventoryCommand.scala
index 93347afcdd..7cf7009c98 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/bukkit/command/ShareInventoryCommand.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/bukkit/command/ShareInventoryCommand.scala
@@ -1,106 +1,104 @@
 package com.github.unchama.seichiassist.subsystems.sharedinventory.bukkit.command
 
-import cats.effect.ConcurrentEffect.ops.toAllConcurrentEffectOps
-import cats.effect.{ConcurrentEffect, IO, Sync}
+import cats.data.Kleisli
+import cats.effect.{ConcurrentEffect, Sync}
+import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.commands.contextual.builder.BuilderTemplates.playerCommandBuilder
-import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts.onMainThread
 import com.github.unchama.seichiassist.subsystems.sharedinventory.SharedInventoryAPI
 import com.github.unchama.seichiassist.subsystems.sharedinventory.domain.SharedFlag
 import com.github.unchama.seichiassist.subsystems.sharedinventory.domain.bukkit.InventoryContents
 import com.github.unchama.seichiassist.util.InventoryOperations
-import com.github.unchama.targetedeffect.commandsender.MessageEffect
-import com.github.unchama.targetedeffect.player.CommandEffect
-import com.github.unchama.targetedeffect.{SequentialEffect, TargetedEffect}
+import com.github.unchama.targetedeffect.commandsender.MessageEffectF
+import com.github.unchama.targetedeffect.player.CommandEffectF
+import com.github.unchama.targetedeffect.{SequentialEffect, TargetedEffectF}
 import org.bukkit.ChatColor._
 import org.bukkit.command.TabExecutor
 import org.bukkit.entity.Player
 import org.bukkit.inventory.ItemStack
 import org.bukkit.{Bukkit, Material}
 
-class ShareInventoryCommand[F[_]: ConcurrentEffect](
+class ShareInventoryCommand[F[_]: ConcurrentEffect: OnMinecraftServerThread](
   implicit sharedInventoryAPI: SharedInventoryAPI[F, Player]
 ) {
 
   import cats.implicits._
 
   val executor: TabExecutor = playerCommandBuilder
-    .buildWithExecutionF { context =>
+    .buildWithExecutionCSEffect { context =>
       val sender = context.sender
-      for {
-        // TODO: this `toIO` is not needed
-        sharedFlag <- sharedInventoryAPI.sharedFlag(sender).toIO
-        eff <-
-          if (sharedFlag == SharedFlag.Sharing) {
-            withdrawFromSharedInventory(sender)
-          } else {
-            depositToSharedInventory(sender)
-          }
-      } yield eff
+
+      Kleisli.liftF(sharedInventoryAPI.sharedFlag(sender)).flatMap { sharedFlag =>
+        if (sharedFlag == SharedFlag.Sharing) {
+          withdrawFromSharedInventory(sender)
+        } else {
+          depositToSharedInventory(sender)
+        }
+      }
     }
     .asNonBlockingTabExecutor()
 
-  private def withdrawFromSharedInventory(player: Player): IO[TargetedEffect[Player]] = {
+  private def withdrawFromSharedInventory(player: Player): TargetedEffectF[F, Player] = {
     val uuid = player.getUniqueId
-    val eff = for {
-      oldSharedFlag <- sharedInventoryAPI.sharedFlag(player)
-      loadedInventory <- sharedInventoryAPI.load(uuid)
-      _ <- sharedInventoryAPI.clear(uuid)
-      newSharedFlag <- sharedInventoryAPI.sharedFlag(player)
-      _ <- Sync[F]
-        .delay {
-          val playerInventory = player.getInventory
-          val inventoryContents = loadedInventory.get.inventoryContents
-          // 手持ちのアイテムをドロップする
-          playerInventory
-            .getContents
-            .filterNot(itemStack => itemStack == null || itemStack.getType == Material.AIR)
-            .foreach(itemStack => dropIfNotEmpty(Some(itemStack), player))
-          // 取り出したアイテムをセットする
-          playerInventory.setContents(inventoryContents.toArray)
-          Bukkit.getLogger.info(s"${player.getName}がアイテム取り出しを実施(DB)書き換え成功")
-        }
-        .whenA(oldSharedFlag != newSharedFlag && loadedInventory.nonEmpty)
+    (for {
+      oldSharedFlag <- Kleisli.liftF(sharedInventoryAPI.sharedFlag(player))
+      loadedInventory <- Kleisli.liftF(sharedInventoryAPI.load(uuid))
+      _ <- Kleisli.liftF(sharedInventoryAPI.clear(uuid))
+      newSharedFlag <- Kleisli.liftF(sharedInventoryAPI.sharedFlag(player))
+      _ <- Kleisli.liftF(
+        Sync[F]
+          .delay {
+            val playerInventory = player.getInventory
+            val inventoryContents = loadedInventory.get.inventoryContents
+            // 手持ちのアイテムをドロップする
+            playerInventory
+              .getContents
+              .filterNot(itemStack => itemStack == null || itemStack.getType == Material.AIR)
+              .foreach(itemStack => dropIfNotEmpty(Some(itemStack), player))
+            // 取り出したアイテムをセットする
+            playerInventory.setContents(inventoryContents.toArray)
+            Bukkit.getLogger.info(s"${player.getName}がアイテム取り出しを実施(DB)書き換え成功")
+          }
+          .whenA(oldSharedFlag != newSharedFlag && loadedInventory.nonEmpty)
+      )
     } yield {
       if (oldSharedFlag != newSharedFlag && loadedInventory.nonEmpty)
-        MessageEffect(s"${GREEN}アイテムを取得しました。手持ちにあったアイテムはドロップしました。")
+        MessageEffectF(s"${GREEN}アイテムを取得しました。手持ちにあったアイテムはドロップしました。")
       else if (oldSharedFlag == newSharedFlag)
-        MessageEffect(s"$RESET$RED${BOLD}もう少し待ってからアイテム取り出しを行ってください。")
+        MessageEffectF(s"$RESET$RED${BOLD}もう少し待ってからアイテム取り出しを行ってください。")
       else
-        MessageEffect(s"$RESET$RED${BOLD}収納アイテムが存在しません。")
-    }
-
-    eff.toIO
+        MessageEffectF(s"$RESET$RED${BOLD}収納アイテムが存在しません。")
+    }).flatten
   }
 
-  private def depositToSharedInventory(player: Player): IO[TargetedEffect[Player]] = {
+  private def depositToSharedInventory(player: Player): TargetedEffectF[F, Player] = {
     val uuid = player.getUniqueId
     val playerInventory = player.getInventory
     val inventoryContents = playerInventory.getContents.toList
 
     if (inventoryContents.forall(_ == null))
-      return IO.pure(MessageEffect(s"$RESET$RED${BOLD}収納アイテムが存在しません。"))
+      return MessageEffectF(s"$RESET$RED${BOLD}収納アイテムが存在しません。")
 
-    val eff = for {
-      oldSharedFlag <- sharedInventoryAPI.sharedFlag(player)
-      _ <- sharedInventoryAPI.save(uuid, InventoryContents(inventoryContents))
-      newSharedFlag <- sharedInventoryAPI.sharedFlag(player)
-      _ <- Sync[F]
-        .delay {
-          playerInventory.clear()
-          Bukkit.getLogger.info(s"${player.getName}がアイテム収納を実施(SQL送信成功)")
-        }
-        .whenA(oldSharedFlag != newSharedFlag)
+    (for {
+      oldSharedFlag <- Kleisli.liftF(sharedInventoryAPI.sharedFlag(player))
+      _ <- Kleisli.liftF(sharedInventoryAPI.save(uuid, InventoryContents(inventoryContents)))
+      newSharedFlag <- Kleisli.liftF(sharedInventoryAPI.sharedFlag(player))
+      _ <- Kleisli.liftF(
+        Sync[F]
+          .delay {
+            playerInventory.clear()
+            Bukkit.getLogger.info(s"${player.getName}がアイテム収納を実施(SQL送信成功)")
+          }
+          .whenA(oldSharedFlag != newSharedFlag)
+      )
     } yield {
       if (oldSharedFlag == newSharedFlag)
-        MessageEffect(s"$RESET$RED${BOLD}もう少し待ってからアイテムを収納してください。")
+        MessageEffectF(s"$RESET$RED${BOLD}もう少し待ってからアイテムを収納してください。")
       else
         SequentialEffect(
-          CommandEffect("stick"),
-          MessageEffect(s"${GREEN}アイテムを収納しました。10秒以上あとに、手持ちを空にして取り出してください。")
+          CommandEffectF("stick"),
+          MessageEffectF(s"${GREEN}アイテムを収納しました。10秒以上あとに、手持ちを空にして取り出してください。")
         )
-    }
-
-    eff.toIO
+    }).flatten
   }
 
   private def dropIfNotEmpty(itemStackOption: Option[ItemStack], to: Player): Unit =
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/infrastracture/JdbcSharedInventoryPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/infrastracture/JdbcSharedInventoryPersistence.scala
index cb918de45a..5571d88a93 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/infrastracture/JdbcSharedInventoryPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/infrastracture/JdbcSharedInventoryPersistence.scala
@@ -17,9 +17,7 @@ class JdbcSharedInventoryPersistence[F[_]: Sync] extends SharedInventoryPersiste
    */
   override def clear(targetUuid: UUID): F[Unit] = Sync[F].delay {
     DB.localTx { implicit session =>
-      sql"UPDATE playerdata SET shareinv = NULL WHERE uuid = ${targetUuid.toString}"
-        .execute()
-        .apply()
+      sql"UPDATE playerdata SET shareinv = NULL WHERE uuid = ${targetUuid.toString}".execute()
     }
   }
 
@@ -32,7 +30,6 @@ class JdbcSharedInventoryPersistence[F[_]: Sync] extends SharedInventoryPersiste
         sql"SELECT shareinv FROM playerdata WHERE uuid = ${targetUuid.toString}"
           .map(rs => rs.string("shareinv"))
           .single()
-          .apply()
 
       serializedInventoryOpt.map(serializedInventory =>
         InventoryContents.ofNonEmpty(
@@ -56,7 +53,6 @@ class JdbcSharedInventoryPersistence[F[_]: Sync] extends SharedInventoryPersiste
           ItemListSerialization.serializeToBase64(inventoryContents.inventoryContents.asJava)
         sql"UPDATE playerdata SET shareinv = $serializedInventory WHERE uuid = ${targetUuid.toString}"
           .execute()
-          .apply()
       }
     }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gachatrade/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gachatrade/System.scala
index 5c636362f7..df917093cc 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gachatrade/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gachatrade/System.scala
@@ -1,6 +1,6 @@
 package com.github.unchama.seichiassist.subsystems.tradesystems.subsystems.gachatrade
 
-import cats.effect.ConcurrentEffect
+import cats.effect.{ConcurrentEffect, IO}
 import com.github.unchama.seichiassist.meta.subsystem.Subsystem
 import com.github.unchama.seichiassist.subsystems.gachapoint.GachaPointApi
 import com.github.unchama.seichiassist.subsystems.gachaprize.GachaPrizeAPI
@@ -8,6 +8,7 @@ import com.github.unchama.seichiassist.subsystems.gachaprize.domain.{
   CanBeSignedAsGachaPrize,
   GachaPrizeTableEntry
 }
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.tradesystems.subsystems.gachatrade.bukkit.listeners.GachaTradeListener
 import com.github.unchama.seichiassist.subsystems.tradesystems.subsystems.gachatrade.bukkit.traderules.BukkitTrade
 import com.github.unchama.seichiassist.subsystems.tradesystems.subsystems.gachatrade.domain.{
@@ -22,7 +23,8 @@ object System {
 
   def wired[F[_]: ConcurrentEffect, G[_]](
     implicit gachaPrizeAPI: GachaPrizeAPI[F, ItemStack, Player],
-    gachaPointApi: GachaPointApi[F, G, Player]
+    gachaPointApi: GachaPointApi[F, G, Player],
+    playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   ): Subsystem[F] = {
     implicit val canBeSignedAsGachaPrize: CanBeSignedAsGachaPrize[ItemStack] =
       gachaPrizeAPI.canBeSignedAsGachaPrize
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gachatrade/bukkit/listeners/GachaTradeListener.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gachatrade/bukkit/listeners/GachaTradeListener.scala
index dc31b743fe..4cb3e1dfce 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gachatrade/bukkit/listeners/GachaTradeListener.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gachatrade/bukkit/listeners/GachaTradeListener.scala
@@ -39,7 +39,7 @@ class GachaTradeListener[F[_]: ConcurrentEffect, G[_]](rule: GachaTradeRule[Item
     // インベントリサイズが6列でない時終了
     if (inventory.row != 6) return
 
-    if (inventory.getTitle != s"$LIGHT_PURPLE${BOLD}交換したい景品を入れてください") return
+    if (event.getView.getTitle != s"$LIGHT_PURPLE${BOLD}交換したい景品を入れてください") return
 
     // 交換後の情報
     val tradedInformation =
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gachatrade/bukkit/traderules/BukkitTrade.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gachatrade/bukkit/traderules/BukkitTrade.scala
index 9bfae53479..a56d2389c9 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gachatrade/bukkit/traderules/BukkitTrade.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gachatrade/bukkit/traderules/BukkitTrade.scala
@@ -1,6 +1,6 @@
 package com.github.unchama.seichiassist.subsystems.tradesystems.subsystems.gachatrade.bukkit.traderules
 
-import com.github.unchama.generic.ListExtra
+import cats.effect.IO
 import com.github.unchama.seichiassist.subsystems.gachaprize.bukkit.factories.BukkitGachaSkullData
 import com.github.unchama.seichiassist.subsystems.gachaprize.domain.GachaRarity.GachaRarity
 import com.github.unchama.seichiassist.subsystems.gachaprize.domain.GachaRarity.GachaRarity._
@@ -8,11 +8,13 @@ import com.github.unchama.seichiassist.subsystems.gachaprize.domain.{
   CanBeSignedAsGachaPrize,
   GachaPrizeTableEntry
 }
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.tradesystems.domain.{
   TradeResult,
   TradeRule,
   TradeSuccessResult
 }
+import org.bukkit.entity.Player
 import org.bukkit.inventory.ItemStack
 
 sealed trait BigOrRegular
@@ -26,7 +28,8 @@ object BigOrRegular {
 }
 
 class BukkitTrade(owner: String, gachaPrizeTable: Vector[GachaPrizeTableEntry[ItemStack]])(
-  implicit canBeSignedAsGachaPrize: CanBeSignedAsGachaPrize[ItemStack]
+  implicit canBeSignedAsGachaPrize: CanBeSignedAsGachaPrize[ItemStack],
+  playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
 ) extends TradeRule[ItemStack, (BigOrRegular, Int)] {
 
   /**
@@ -44,7 +47,7 @@ class BukkitTrade(owner: String, gachaPrizeTable: Vector[GachaPrizeTableEntry[It
     }
 
     val (nonTradable, tradable) =
-      ListExtra.partitionWith(contents) { itemStack =>
+      contents.partitionMap { itemStack =>
         if (bigList.exists(_.isSimilar(itemStack)))
           Right(BigOrRegular.Big -> itemStack.getAmount)
         else if (regularList.exists(_.isSimilar(itemStack)))
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gttosiina/bukkit/BukkitStaticTradeItemFactory.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gttosiina/bukkit/BukkitStaticTradeItemFactory.scala
index 58b97594fb..aaa05f58b2 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gttosiina/bukkit/BukkitStaticTradeItemFactory.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gttosiina/bukkit/BukkitStaticTradeItemFactory.scala
@@ -11,9 +11,8 @@ import scala.util.chaining.scalaUtilChainingOps
 object BukkitStaticTradeItemFactory extends StaticTradeItemFactory[ItemStack] {
 
   override val getMaxRingo: String => ItemStack = (name: String) =>
-    new ItemStack(Material.GOLDEN_APPLE, 1).tap { itemStack =>
+    new ItemStack(Material.ENCHANTED_GOLDEN_APPLE, 1).tap { itemStack =>
       import itemStack._
-      setDurability(1.toShort)
       val meta = getItemMeta
       meta.setDisplayName(s"$YELLOW$BOLD${ITALIC}椎名林檎")
       meta.setLore(
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gttosiina/bukkit/listeners/GtToSiinaringo.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gttosiina/bukkit/listeners/GtToSiinaringo.scala
index e09ac172a9..1b1b1c65e4 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gttosiina/bukkit/listeners/GtToSiinaringo.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/tradesystems/subsystems/gttosiina/bukkit/listeners/GtToSiinaringo.scala
@@ -36,7 +36,7 @@ class GtToSiinaringo[F[_]: ConcurrentEffect](
     // インベントリサイズが4列でない時終了
     if (inventory.row != 4) return
 
-    if (inventory.getTitle != s"$GOLD${BOLD}椎名林檎と交換したい景品を入れてネ") return
+    if (event.getView.getTitle != s"$GOLD${BOLD}椎名林檎と交換したい景品を入れてネ") return
     // 交換後の情報
     val tradedInformation =
       new BukkitTrade(name, gachaPrizeAPI.allGachaPrizeList.toIO.unsafeRunSync())
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/System.scala
index 6ddec4ac5c..a12e0ca6a1 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/System.scala
@@ -1,10 +1,11 @@
 package com.github.unchama.seichiassist.subsystems.vote
 
 import cats.data.Kleisli
-import cats.effect.{ConcurrentEffect, SyncEffect}
+import cats.effect.{ConcurrentEffect, IO, SyncEffect}
 import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.meta.subsystem.Subsystem
 import com.github.unchama.seichiassist.subsystems.breakcount.BreakCountAPI
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.vote.application.actions.ReceiveVoteBenefits
 import com.github.unchama.seichiassist.subsystems.vote.bukkit.actions.BukkitReceiveVoteBenefits
 import com.github.unchama.seichiassist.subsystems.vote.bukkit.command.VoteCommand
@@ -24,7 +25,8 @@ trait System[F[_], Player] extends Subsystem[F] {
 object System {
 
   def wired[F[_]: ConcurrentEffect: OnMinecraftServerThread, G[_]: SyncEffect](
-    implicit breakCountAPI: BreakCountAPI[F, G, Player]
+    implicit breakCountAPI: BreakCountAPI[F, G, Player],
+    playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
   ): System[F, Player] = {
     implicit val _votePersistence: VotePersistence[F] = new JdbcVotePersistence[F]
     val _receiveVoteBenefits: ReceiveVoteBenefits[F, Player] =
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/bukkit/actions/BukkitReceiveVoteBenefits.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/bukkit/actions/BukkitReceiveVoteBenefits.scala
index 5ce674f990..2a9c04d100 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/bukkit/actions/BukkitReceiveVoteBenefits.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/bukkit/actions/BukkitReceiveVoteBenefits.scala
@@ -1,11 +1,12 @@
 package com.github.unchama.seichiassist.subsystems.vote.bukkit.actions
 
-import cats.effect.{Sync, SyncEffect}
+import cats.effect.{IO, Sync, SyncEffect}
 import com.github.unchama.generic.ContextCoercion
 import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.data.ItemData
 import com.github.unchama.seichiassist.subsystems.breakcount.BreakCountAPI
 import com.github.unchama.seichiassist.subsystems.gachaprize.bukkit.factories.BukkitGachaSkullData
+import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
 import com.github.unchama.seichiassist.subsystems.vote.application.actions.ReceiveVoteBenefits
 import com.github.unchama.seichiassist.subsystems.vote.domain.{
   EffectPoint,
@@ -19,7 +20,8 @@ class BukkitReceiveVoteBenefits[F[_]: OnMinecraftServerThread: Sync, G[
   _
 ]: SyncEffect: ContextCoercion[*[_], F]](
   implicit votePersistence: VotePersistence[F],
-  breakCountAPI: BreakCountAPI[F, G, Player]
+  breakCountAPI: BreakCountAPI[F, G, Player],
+  playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
 ) extends ReceiveVoteBenefits[F, Player] {
 
   import cats.implicits._
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/infrastructure/JdbcVotePersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/infrastructure/JdbcVotePersistence.scala
index 622fb63773..4ee45b8eb2 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/infrastructure/JdbcVotePersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/infrastructure/JdbcVotePersistence.scala
@@ -16,7 +16,7 @@ class JdbcVotePersistence[F[_]: Sync] extends VotePersistence[F] {
       sql"""INSERT IGNORE INTO vote 
            | (uuid, vote_number, chain_vote_number, effect_point, given_effect_point, last_vote)
            | VALUES
-           | (${uuid.toString}, 0, 0, 0, 0, NULL)""".stripMargin.execute().apply()
+           | (${uuid.toString}, 0, 0, 0, 0, NULL)""".stripMargin.execute()
     }
   }
 
@@ -24,7 +24,6 @@ class JdbcVotePersistence[F[_]: Sync] extends VotePersistence[F] {
     DB.localTx { implicit session =>
       sql"UPDATE vote SET vote_number = vote_number + 1 WHERE uuid = (SELECT uuid FROM playerdata WHERE uuid = ${uuid.toString})"
         .execute()
-        .apply()
     }
   }
 
@@ -33,7 +32,6 @@ class JdbcVotePersistence[F[_]: Sync] extends VotePersistence[F] {
       val votePoint = sql"SELECT vote_number FROM vote WHERE uuid = ${uuid.toString}"
         .map(_.int("vote_number"))
         .single()
-        .apply()
         .get
       VoteCount(votePoint)
     }
@@ -54,7 +52,6 @@ class JdbcVotePersistence[F[_]: Sync] extends VotePersistence[F] {
            | WHERE uuid = (SELECT uuid FROM playerdata WHERE uuid = ${uuid.toString})"""
         .stripMargin
         .execute()
-        .apply()
     }
   }
 
@@ -65,7 +62,6 @@ class JdbcVotePersistence[F[_]: Sync] extends VotePersistence[F] {
           sql"SELECT chain_vote_number FROM vote WHERE uuid = ${uuid.toString}"
             .map(_.int("chain_vote_number"))
             .single()
-            .apply()
             .get
         ChainVoteDayNumber(chainVoteDays)
       }
@@ -76,7 +72,6 @@ class JdbcVotePersistence[F[_]: Sync] extends VotePersistence[F] {
       DB.localTx { implicit session =>
         sql"UPDATE vote SET effect_point = effect_point + ${effectPoint.value} WHERE uuid = ${uuid.toString}"
           .execute()
-          .apply()
       }
     }
 
@@ -85,7 +80,6 @@ class JdbcVotePersistence[F[_]: Sync] extends VotePersistence[F] {
       DB.localTx { implicit session =>
         sql"UPDATE vote SET effect_point = effect_point - ${effectPoint.value} WHERE uuid = ${uuid.toString}"
           .execute()
-          .apply()
       }
     }
 
@@ -94,7 +88,6 @@ class JdbcVotePersistence[F[_]: Sync] extends VotePersistence[F] {
       val effectPoints = sql"SELECT effect_point FROM vote WHERE uuid = ${uuid.toString}"
         .map(_.int("effect_point"))
         .single()
-        .apply()
         .get
       EffectPoint(effectPoints)
     }
@@ -104,7 +97,6 @@ class JdbcVotePersistence[F[_]: Sync] extends VotePersistence[F] {
     DB.localTx { implicit session =>
       sql"UPDATE vote SET given_effect_point = given_effect_point + ${benefit.value} WHERE uuid = ${uuid.toString}"
         .execute()
-        .apply()
     }
   }
 
@@ -113,7 +105,6 @@ class JdbcVotePersistence[F[_]: Sync] extends VotePersistence[F] {
       val benefits = sql"SELECT given_effect_point FROM vote WHERE uuid = ${uuid.toString}"
         .map(_.int("given_effect_point"))
         .single()
-        .apply()
         .get
       ReceivedVoteCount(benefits)
     }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairy/infrastructure/JdbcFairyPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairy/infrastructure/JdbcFairyPersistence.scala
index f7f39eb8f9..e7a5f91d2e 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairy/infrastructure/JdbcFairyPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairy/infrastructure/JdbcFairyPersistence.scala
@@ -14,13 +14,12 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
       sql"SELECT COUNT(*) as c FROM vote_fairy where uuid = ${player.toString}"
         .map(_.int("c"))
         .single()
-        .apply()
         .getOrElse(0)
     }
 
     if (playerDataCount == 0) {
       DB.localTx { implicit session =>
-        sql"INSERT INTO vote_fairy (uuid) VALUES (${player.toString})".execute().apply()
+        sql"INSERT INTO vote_fairy (uuid) VALUES (${player.toString})".execute()
       }
     }
   }
@@ -33,7 +32,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
       DB.localTx { implicit session =>
         sql"UPDATE vote_fairy SET apple_open_state = ${openState.serializedValue} WHERE uuid = ${player.toString}"
           .execute()
-          .apply()
       }
     }
 
@@ -43,7 +41,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
         sql"SELECT apple_open_state FROM vote_fairy WHERE uuid = ${player.toString}"
           .map(_.int("apple_open_state"))
           .single()
-          .apply()
           .get
       }
       FairyAppleConsumeStrategy.values.find(_.serializedValue == serializedValue).get
@@ -54,7 +51,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
       DB.localTx { implicit session =>
         sql"UPDATE vote_fairy SET fairy_summon_cost = ${fairySummonCost.value} WHERE uuid = ${player.toString}"
           .execute()
-          .apply()
       }
     }
 
@@ -64,7 +60,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
         sql"SELECT fairy_summon_cost FROM vote_fairy WHERE uuid = ${player.toString}"
           .map(_.int("fairy_summon_cost"))
           .single()
-          .apply()
           .get
       FairySummonCost(fairySummonCost)
     }
@@ -77,7 +72,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
              | SET is_fairy_using = $isFairyUsing WHERE uuid = ${player.toString}"""
           .stripMargin
           .execute()
-          .apply()
       }
     }
 
@@ -86,7 +80,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
       sql"SELECT is_fairy_using FROM vote_fairy WHERE uuid = ${player.toString}"
         .map(_.boolean("is_fairy_using"))
         .single()
-        .apply()
     }.get
   }
 
@@ -97,7 +90,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
     DB.localTx { implicit session =>
       sql"UPDATE vote_fairy SET fairy_recovery_mana_value = ${fairyRecoveryMana.recoveryMana} WHERE uuid = ${player.toString}"
         .execute()
-        .apply()
     }
   }
 
@@ -107,7 +99,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
         sql"SELECT fairy_recovery_mana_value FROM vote_fairy WHERE uuid = ${player.toString}"
           .map(_.int("fairy_recovery_mana_value"))
           .single()
-          .apply()
           .get
       FairyRecoveryMana(recoveryMana)
     }
@@ -118,7 +109,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
       DB.localTx { implicit session =>
         sql"UPDATE vote_fairy SET fairy_end_time = ${fairyEndTime.endTime} WHERE uuid = ${player.toString}"
           .execute()
-          .apply()
       }
     }
 
@@ -127,7 +117,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
       val dateOpt = sql"SELECT fairy_end_time FROM vote_fairy WHERE uuid = ${player.toString}"
         .map(_.localDateTime("fairy_end_time"))
         .single()
-        .apply()
       dateOpt.map(FairyEndTime)
     }
   }
@@ -140,7 +129,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
       DB.localTx { implicit session =>
         sql"UPDATE vote_fairy SET given_apple_amount = given_apple_amount + ${appleAmount.amount} WHERE uuid = ${player.toString}"
           .execute()
-          .apply()
       }
     }
 
@@ -151,7 +139,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
           sql"SELECT given_apple_amount FROM vote_fairy WHERE uuid = ${player.toString}"
             .map(_.int("given_apple_amount"))
             .single()
-            .apply()
         appleAmountOpt.map(AppleAmount)
       }
     }
@@ -176,7 +163,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
             )
           )
           .toList()
-          .apply()
           .find(_._1 == player.toString)
           .map(_._2)
       }
@@ -200,7 +186,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
             AppleConsumeAmountRank(name, rank, AppleAmount(givenAppleAmount))
           }
           .toList()
-          .apply()
           .toVector
       }
     }
@@ -210,7 +195,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
       val amount = sql"SELECT SUM(given_apple_amount) AS allAppleAmount FROM vote_fairy;"
         .map(_.int("allAppleAmount"))
         .single()
-        .apply()
         .get
       AppleAmount(amount)
     }
@@ -221,7 +205,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
       DB.localTx { implicit session =>
         sql"UPDATE vote_fairy SET is_play_fairy_speech_sound = $playOnSpeech WHERE uuid = ${player.toString}"
           .execute()
-          .apply()
       }
     }
 
@@ -231,7 +214,6 @@ class JdbcFairyPersistence[F[_]: Sync] extends FairyPersistence[F] {
         sql"SELECT is_play_fairy_speech_sound FROM vote_fairy WHERE uuid=${player.toString}"
           .map(_.boolean("is_play_fairy_speech_sound"))
           .single()
-          .apply()
           .get
       }
     }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairyspeech/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairyspeech/System.scala
index df672e185d..004a5794ce 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairyspeech/System.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairyspeech/System.scala
@@ -43,7 +43,7 @@ object System {
         override def togglePlaySoundOnSpeech: Kleisli[F, Player, Unit] = Kleisli { player =>
           for {
             fairyPlaySound <- playSoundOnSpeech(player.getUniqueId)
-            _ <- persistence.setPlaySoundOnSpeech(player.getUniqueId, fairyPlaySound)
+            _ <- persistence.setPlaySoundOnSpeech(player.getUniqueId, !fairyPlaySound)
           } yield ()
         }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairyspeech/bukkit/BukkitFairySpeechGateway.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairyspeech/bukkit/BukkitFairySpeechGateway.scala
index 5cee695de1..9f6b05cb6c 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairyspeech/bukkit/BukkitFairySpeechGateway.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairyspeech/bukkit/BukkitFairySpeechGateway.scala
@@ -24,11 +24,11 @@ class BukkitFairySpeechGateway[F[_]: Sync: Timer](player: Player)
   import cats.implicits._
 
   override def playSpeechSound: F[Unit] = for {
-    _ <- FocusedSoundEffectF(Sound.BLOCK_NOTE_PLING, 2.0f, 1.0f).run(player)
+    _ <- FocusedSoundEffectF(Sound.BLOCK_NOTE_BLOCK_PLING, 2.0f, 1.0f).run(player)
     _ <- Timer[F].sleep(100.millis)
-    _ <- FocusedSoundEffectF(Sound.BLOCK_NOTE_PLING, 2.0f, 1.5f).run(player)
+    _ <- FocusedSoundEffectF(Sound.BLOCK_NOTE_BLOCK_PLING, 2.0f, 1.5f).run(player)
     _ <- Timer[F].sleep(100.millis)
-    _ <- FocusedSoundEffectF(Sound.BLOCK_NOTE_PLING, 2.0f, 2.0f).run(player)
+    _ <- FocusedSoundEffectF(Sound.BLOCK_NOTE_BLOCK_PLING, 2.0f, 2.0f).run(player)
   } yield {}
 
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairyspeech/infrastructure/JdbcFairySpeechPersistence.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairyspeech/infrastructure/JdbcFairySpeechPersistence.scala
index d73acc49c7..c7e6a82ca2 100644
--- a/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairyspeech/infrastructure/JdbcFairySpeechPersistence.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/vote/subsystems/fairyspeech/infrastructure/JdbcFairySpeechPersistence.scala
@@ -13,7 +13,6 @@ class JdbcFairySpeechPersistence[F[_]: Sync] extends FairySpeechPersistence[F] {
       DB.localTx { implicit session =>
         sql"UPDATE vote_fairy SET is_play_fairy_speech_sound = $playOnSpeech WHERE uuid = ${player.toString}"
           .execute()
-          .apply()
       }
     }
 
@@ -22,7 +21,6 @@ class JdbcFairySpeechPersistence[F[_]: Sync] extends FairySpeechPersistence[F] {
       sql"SELECT is_play_fairy_speech_sound FROM vote_fairy WHERE uuid=${player.toString}"
         .map(_.boolean("is_play_fairy_speech_sound"))
         .single()
-        .apply()
         .get
     }
   }
diff --git a/src/main/scala/com/github/unchama/seichiassist/task/GiganticBerserkTask.scala b/src/main/scala/com/github/unchama/seichiassist/task/GiganticBerserkTask.scala
index 37ee8ffdb4..fc74f93b88 100644
--- a/src/main/scala/com/github/unchama/seichiassist/task/GiganticBerserkTask.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/task/GiganticBerserkTask.scala
@@ -1,7 +1,6 @@
 package com.github.unchama.seichiassist.task
 
 import cats.effect.{ConcurrentEffect, IO, SyncIO}
-import com.github.unchama.concurrent.NonServerThreadContextShift
 import com.github.unchama.seichiassist.data.player.PlayerData
 import com.github.unchama.seichiassist.subsystems.discordnotification.DiscordNotificationAPI
 import com.github.unchama.seichiassist.subsystems.mana.ManaApi
@@ -15,9 +14,7 @@ import org.bukkit.entity.Player
 import scala.util.Random
 
 class GiganticBerserkTask {
-  def PlayerKillEnemy[F[
-    _
-  ]: ConcurrentEffect: NonServerThreadContextShift: DiscordNotificationAPI](
+  def PlayerKillEnemy[F[_]: ConcurrentEffect: DiscordNotificationAPI](
     p: Player
   )(implicit manaApi: ManaApi[IO, SyncIO, Player]): Unit = {
     val player = p
@@ -35,7 +32,7 @@ class GiganticBerserkTask {
 
     // 確率でマナを回復させる
     val d = Math.random
-    if (d < playerdata.giganticBerserk.manaRegenerationProbability) {
+    if (d < playerdata.giganticBerserk.manaRegenerationProbability()) {
       if (playerdata.giganticBerserk.reachedLimit()) {
         manaApi.manaAmount(p).restoreCompletely.unsafeRunSync()
         player.sendMessage(
@@ -92,9 +89,8 @@ class GiganticBerserkTask {
         val program = List(
           DiscordNotificationAPI[F].sendPlainText(messageWithoutColor).toIO,
           IO {
-            SendSoundEffect.sendEverySound(Sound.ENTITY_ENDERDRAGON_DEATH, 1, 1.2f)
-            SendMessageEffect.sendMessageToEveryoneIgnoringPreference(messageWithColor)
-          }
+            SendSoundEffect.sendEverySound(Sound.ENTITY_ENDER_DRAGON_DEATH, 1, 1.2f)
+          } >> SendMessageEffect.sendMessageToEveryoneIgnoringPreferenceIO(messageWithColor)
         ).sequence
 
         program.unsafeRunAsyncAndForget()
diff --git a/src/main/scala/com/github/unchama/seichiassist/task/PlayerDataSaveTask.scala b/src/main/scala/com/github/unchama/seichiassist/task/PlayerDataSaveTask.scala
index 98f9160091..361712165e 100644
--- a/src/main/scala/com/github/unchama/seichiassist/task/PlayerDataSaveTask.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/task/PlayerDataSaveTask.scala
@@ -166,19 +166,20 @@ object PlayerDataSaveTask {
           .delay {
             println(s"$RED${playerdata.name}のプレイヤーデータ保存失敗")
           }
-          .as(Right(ActionStatus.Fail))
-      } else
+          .as(Right(()))
+      } else {
         commitUpdate.flatMap { result =>
           if (result == ActionStatus.Ok) {
             Sync[F]
               .delay {
                 println(s"$GREEN${player.getName}のプレイヤーデータ保存完了")
               }
-              .as(Right(ActionStatus.Ok))
+              .as(Right(()))
           } else {
             Monad[F].pure(Left(remaining - 1))
           }
         }
+      }
     }
   }
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/task/global/PlayerDataBackupRoutine.scala b/src/main/scala/com/github/unchama/seichiassist/task/global/PlayerDataBackupRoutine.scala
index 957646237c..ab5653c732 100644
--- a/src/main/scala/com/github/unchama/seichiassist/task/global/PlayerDataBackupRoutine.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/task/global/PlayerDataBackupRoutine.scala
@@ -27,8 +27,10 @@ object PlayerDataBackupRoutine {
         import scala.jdk.CollectionConverters._
 
         for {
+          _ <- SendMessageEffect.sendMessageToEveryoneIgnoringPreferenceIO(
+            s"${AQUA}プレイヤーデータセーブ中…"
+          )
           _ <- IO {
-            SendMessageEffect.sendMessageToEveryoneIgnoringPreference(s"${AQUA}プレイヤーデータセーブ中…")
             Bukkit.getLogger.info(s"${AQUA}プレイヤーデータセーブ中…")
           }
           players <- IO {
@@ -38,8 +40,10 @@ object PlayerDataBackupRoutine {
             PlayerDataSaveTask
               .savePlayerData[IO](player, SeichiAssist.playermap(player.getUniqueId))
           }
+          _ <- SendMessageEffect.sendMessageToEveryoneIgnoringPreferenceIO(
+            s"${AQUA}プレイヤーデータセーブ完了"
+          )
           _ <- IO {
-            SendMessageEffect.sendMessageToEveryoneIgnoringPreference(s"${AQUA}プレイヤーデータセーブ完了")
             Bukkit.getLogger.info(s"${AQUA}プレイヤーデータセーブ完了")
           }
         } yield ()
diff --git a/src/main/scala/com/github/unchama/seichiassist/task/global/PlayerDataRecalculationRoutine.scala b/src/main/scala/com/github/unchama/seichiassist/task/global/PlayerDataRecalculationRoutine.scala
index b7ed284b9f..bbaf2b5823 100644
--- a/src/main/scala/com/github/unchama/seichiassist/task/global/PlayerDataRecalculationRoutine.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/task/global/PlayerDataRecalculationRoutine.scala
@@ -5,6 +5,7 @@ import com.github.unchama.concurrent.{RepeatingRoutine, RepeatingTaskContext}
 import com.github.unchama.minecraft.actions.OnMinecraftServerThread
 import com.github.unchama.seichiassist.SeichiAssist
 import com.github.unchama.seichiassist.achievement.SeichiAchievement
+import com.github.unchama.seichiassist.achievement.hierarchy.AchievementGroup
 import org.bukkit.Bukkit
 
 import scala.concurrent.duration.FiniteDuration
@@ -48,13 +49,22 @@ object PlayerDataRecalculationRoutine {
           .toList
           .sequence
           .map(_.flatMap {
-            case (achievementId, true) => Some(achievementId)
-            case _                     => None
+            case (achievementId, true) =>
+              val displayGroupName =
+                AchievementGroup.getGroupNameByEntryId(achievementId).getOrElse("未実装")
+              Some((achievementId, displayGroupName))
+            case _ => None
           })
           .flatMap(unlockTargets =>
             IO {
-              playerData.TitleFlags.addAll(unlockTargets)
-              unlockTargets.map("実績No" + _ + "が解除されました!おめでとうございます!").foreach(player.sendMessage)
+              val achievementIds = unlockTargets.map(_._1)
+              playerData.TitleFlags.addAll(achievementIds)
+              unlockTargets.foreach {
+                case (achievementId, displayGroupName) =>
+                  player.sendMessage(
+                    s"[${displayGroupName}]実績No${achievementId}が解除されました!おめでとうございます!"
+                  )
+              }
             }
           )
           .unsafeRunSync()
diff --git a/src/main/scala/com/github/unchama/seichiassist/util/BreakUtil.scala b/src/main/scala/com/github/unchama/seichiassist/util/BreakUtil.scala
index 4ad89f1da6..29edc3a824 100644
--- a/src/main/scala/com/github/unchama/seichiassist/util/BreakUtil.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/util/BreakUtil.scala
@@ -3,7 +3,6 @@ package com.github.unchama.seichiassist.util
 import cats.Monad
 import cats.effect.{IO, SyncIO}
 import com.github.unchama.generic.ApplicativeExtra.whenAOrElse
-import com.github.unchama.generic.effect.unsafe.EffectEnvironment
 import com.github.unchama.seichiassist.MaterialSets.{BlockBreakableBySkill, BreakTool}
 import com.github.unchama.seichiassist._
 import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts
@@ -19,18 +18,16 @@ import com.github.unchama.seichiassist.subsystems.breakcount.domain.level.Seichi
 import com.github.unchama.seichiassist.subsystems.breakskilltargetconfig.domain.BreakSkillTargetConfigKey
 import com.github.unchama.targetedeffect.player.ActionBarMessageEffect
 import com.github.unchama.util.bukkit.ItemStackUtil
-import com.github.unchama.util.external.ExternalPlugins
+import com.github.unchama.util.external.{ExternalPlugins, WorldGuardWrapper}
 import org.bukkit.ChatColor._
-import org.bukkit.World.Environment
 import org.bukkit._
-import org.bukkit.block.Block
+import org.bukkit.block.{Block, Container}
 import org.bukkit.enchantments.Enchantment
 import org.bukkit.entity.{Entity, EntityType, Player}
-import org.bukkit.inventory.ItemStack
-import org.bukkit.material.Dye
 
 import java.util.Random
 import java.util.stream.IntStream
+import scala.jdk.CollectionConverters._
 
 object BreakUtil {
 
@@ -66,7 +63,7 @@ object BreakUtil {
     val playerData = SeichiAssist.playermap(player.getUniqueId)
 
     // 壊されるブロックがワールドガード範囲だった場合処理を終了
-    if (!ExternalPlugins.getWorldGuard.canBuild(player, checkTarget.getLocation)) {
+    if (!WorldGuardWrapper.canBuild(player, checkTarget.getLocation)) {
       if (playerData.settings.shouldDisplayWorldGuardLogs) {
         player.sendMessage(s"${RED}ワールドガードで保護されています。")
       }
@@ -102,9 +99,8 @@ object BreakUtil {
       }
 
       val isBlockProtectedSlab =
-        checkTarget.getType == Material.STEP &&
-          checkTarget.getY == halfBlockLayerYCoordinate &&
-          checkTarget.getData == 0.toByte
+        checkTarget.getType == Material.STONE_SLAB &&
+          checkTarget.getY == halfBlockLayerYCoordinate
 
       if (isBlockProtectedSlab) return false
     }
@@ -125,26 +121,26 @@ object BreakUtil {
   }
 
   def isProtectedChest(player: Player, checkTarget: Block): Boolean = {
-    checkTarget.getType match {
-      case Material.CHEST | Material.TRAPPED_CHEST =>
-        if (
-          !SeichiAssist
-            .instance
-            .breakSkillTargetConfigSystem
-            .api
-            .breakSkillTargetConfig(player, BreakSkillTargetConfigKey.Chest)
-            .unsafeRunSync()
-        ) {
-          ActionBarMessageEffect(s"${RED}スキルでのチェスト破壊は無効化されています").run(player).unsafeRunSync()
-          true
-        } else if (!player.getWorld.isSeichi) {
-          ActionBarMessageEffect(s"${RED}スキルでのチェスト破壊は整地ワールドでのみ有効です").run(player).unsafeRunSync()
-          true
-        } else {
-          false
-        }
-      case _ => false
-    }
+    if (
+      checkTarget.getType == Material.CHEST || checkTarget.getType == Material.TRAPPED_CHEST
+    ) {
+      if (
+        !SeichiAssist
+          .instance
+          .breakSkillTargetConfigSystem
+          .api
+          .breakSkillTargetConfig(player, BreakSkillTargetConfigKey.Chest)
+          .unsafeRunSync()
+      ) {
+        ActionBarMessageEffect(s"${RED}スキルでのチェスト破壊は無効化されています").run(player).unsafeRunSync()
+        true
+      } else if (!player.getWorld.isSeichi) {
+        ActionBarMessageEffect(s"${RED}スキルでのチェスト破壊は整地ワールドでのみ有効です").run(player).unsafeRunSync()
+        true
+      } else {
+        false
+      }
+    } else false
   }
 
   /**
@@ -157,9 +153,8 @@ object BreakUtil {
     val materialType = targetBlock.getType
     val isNotQuartzBlockAndQuartzStairs =
       materialType != Material.QUARTZ_BLOCK && materialType != Material.QUARTZ_STAIRS
-    // NOTE: targetBlock#getDataが7は下つきハーフブロック、15は上つきハーフブロック
     val isNotQuartzSlab =
-      materialType != Material.STEP || (targetBlock.getData != 7.toByte && targetBlock.getData != 15.toByte)
+      materialType != Material.QUARTZ_SLAB
     val isNotMadeFromQuartz = isNotQuartzBlockAndQuartzStairs && isNotQuartzSlab
     if (isNotMadeFromQuartz) {
       return true
@@ -185,214 +180,6 @@ object BreakUtil {
     world.shouldMuteCoreProtect
   }
 
-  // ブロックを破壊する処理、ドロップも含む、統計増加も含む
-  def breakBlock(
-    player: Player,
-    targetBlock: BlockBreakableBySkill,
-    dropLocation: Location,
-    tool: BreakTool,
-    shouldPlayBreakSound: Boolean
-  )(implicit effectEnvironment: EffectEnvironment): Unit =
-    effectEnvironment.unsafeRunEffectAsync(
-      "単一ブロックを破壊する",
-      massBreakBlock(player, Set(targetBlock), dropLocation, tool, shouldPlayBreakSound)
-    )
-
-  sealed trait BlockBreakResult
-
-  object BlockBreakResult {
-
-    case class ItemDrop(itemStack: ItemStack) extends BlockBreakResult
-
-    case class SpawnSilverFish(location: Location) extends BlockBreakResult
-
-  }
-
-  /**
-   * ブロックをツールで破壊した時のドロップを計算する
-   *
-   * Bukkit/Spigotが提供するBlock.getDropsは信頼できる値を返さない。 本来はNMSのメソッドを呼ぶのが確実らしいが、一時的な実装として使用している。 参考:
-   * https://www.spigotmc.org/threads/getdrops-on-crops-not-functioning-as-expected.167751/#post-1779788
-   */
-  def dropItemOnTool(
-    tool: BreakTool
-  )(blockInformation: (Location, Material, Byte)): Option[BlockBreakResult] = {
-    val fortuneLevel = tool.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS)
-
-    val (blockLocation, blockMaterial, blockData) = blockInformation
-
-    blockMaterial match {
-      case Material.GRASS_PATH | Material.SOIL =>
-        return Some(BlockBreakResult.ItemDrop(new ItemStack(Material.DIRT)))
-      case Material.MOB_SPAWNER | Material.ENDER_PORTAL_FRAME | Material.ENDER_PORTAL =>
-        return None
-      case _ =>
-    }
-
-    val rand = Math.random()
-    val bonus = Math.max(1, rand * (fortuneLevel + 2)).toInt
-
-    val blockDataLeast4Bits = (blockData & 0x0f).toByte
-    val b_tree = (blockData & 0x03).toByte
-
-    val silkTouch = tool.getEnchantmentLevel(Enchantment.SILK_TOUCH)
-
-    if (silkTouch > 0) {
-      // シルクタッチの処理
-      Some {
-        BlockBreakResult.ItemDrop {
-          blockMaterial match {
-            case Material.GLOWING_REDSTONE_ORE =>
-              new ItemStack(Material.REDSTONE_ORE)
-            case Material.LOG | Material.LOG_2 | Material.LEAVES | Material.LEAVES_2 =>
-              new ItemStack(blockMaterial, 1, b_tree.toShort)
-            case Material.MONSTER_EGGS =>
-              new ItemStack(Material.STONE)
-            case Material.WOOD_STEP | Material.STEP | Material.STONE_SLAB2 |
-                Material.PURPUR_SLAB if (blockDataLeast4Bits & 8) != 0 =>
-              // 上付きハーフブロックのmissing texture化を防ぐ
-              new ItemStack(blockMaterial, 1, (blockDataLeast4Bits & 7).toShort)
-            case Material.QUARTZ_BLOCK if (blockData >= 2 && blockData <= 4) =>
-              // 柱状クォーツブロックのmissing texture化を防ぐ
-              new ItemStack(blockMaterial, 1, 2.toShort)
-            case _ =>
-              new ItemStack(blockMaterial, 1, blockDataLeast4Bits.toShort)
-          }
-        }
-      }
-    } else if (fortuneLevel > 0 && MaterialSets.fortuneMaterials.contains(blockMaterial)) {
-      // 幸運の処理
-      Some {
-        BlockBreakResult.ItemDrop {
-          blockMaterial match {
-            case Material.COAL_ORE =>
-              new ItemStack(Material.COAL, bonus)
-            case Material.DIAMOND_ORE =>
-              new ItemStack(Material.DIAMOND, bonus)
-            case Material.EMERALD_ORE =>
-              new ItemStack(Material.EMERALD, bonus)
-            case Material.QUARTZ_ORE =>
-              new ItemStack(Material.QUARTZ, bonus)
-            // レッドストーン鉱石, グロウストーン, スイカブロック, シーランタン, ラピスラズリ鉱石は、
-            // ドロップアイテムの個数を求める計算が通常の鉱石の扱いと異なるため、特別な処理が必要である。
-            case Material.REDSTONE_ORE | Material.GLOWING_REDSTONE_ORE =>
-              val withBonus = (rand * (fortuneLevel + 2) + 4).toInt
-              new ItemStack(Material.REDSTONE, withBonus)
-            case Material.LAPIS_ORE =>
-              val dye = new Dye()
-              dye.setColor(DyeColor.BLUE)
-              // 幸運エンチャントなしで掘った時のアイテムが得られる個数(4~9)に、幸運ボーナスを掛ける
-              val withBonus = (rand * 6 + 4).toInt * bonus
-              dye.toItemStack(withBonus)
-            // グロウストーンは幸運エンチャントがついていると高確率でより多くのダストをドロップする
-            // しかし、最大でも4個までしかドロップしない
-            case Material.GLOWSTONE =>
-              val withBonus = (rand * (fortuneLevel + 3) + 2).toInt
-              val amount = if (withBonus > 4) 4 else withBonus
-              new ItemStack(Material.GLOWSTONE_DUST, amount)
-            // 同様に、メロンブロックは幸運エンチャントがついている場合、9個までしかドロップしない
-            case Material.MELON_BLOCK =>
-              val withBonus = (rand * (fortuneLevel + 5) + 3).toInt
-              val amount = if (withBonus > 9) 9 else withBonus
-              new ItemStack(Material.MELON, amount)
-            case Material.SEA_LANTERN =>
-              val withBonus = (rand * (fortuneLevel + 2) + 2).toInt
-              val amount = if (withBonus > 5) 5 else withBonus
-              new ItemStack(Material.PRISMARINE_CRYSTALS, amount)
-            case _ =>
-              // unreachable
-              new ItemStack(blockMaterial, bonus)
-          }
-        }
-      }
-    } else {
-      // シルク幸運なしの処理
-      blockMaterial match {
-        case Material.COAL_ORE =>
-          Some(BlockBreakResult.ItemDrop(new ItemStack(Material.COAL)))
-        case Material.DIAMOND_ORE =>
-          Some(BlockBreakResult.ItemDrop(new ItemStack(Material.DIAMOND)))
-        case Material.LAPIS_ORE =>
-          val dye = new Dye()
-          dye.setColor(DyeColor.BLUE)
-          Some(BlockBreakResult.ItemDrop(dye.toItemStack((rand * 6 + 4).toInt)))
-        case Material.EMERALD_ORE =>
-          Some(BlockBreakResult.ItemDrop(new ItemStack(Material.EMERALD)))
-        case Material.REDSTONE_ORE | Material.GLOWING_REDSTONE_ORE =>
-          Some(
-            BlockBreakResult.ItemDrop(new ItemStack(Material.REDSTONE, ((rand * 2) + 4).toInt))
-          )
-        case Material.QUARTZ_ORE =>
-          Some(BlockBreakResult.ItemDrop(new ItemStack(Material.QUARTZ)))
-        // グロウストーンは、2から4個のグロウストーンダストをドロップする
-        case Material.GLOWSTONE =>
-          Some(
-            BlockBreakResult
-              .ItemDrop(new ItemStack(Material.GLOWSTONE_DUST, (rand * 3 + 2).toInt))
-          )
-        // スイカブロックは、3から7個のスイカをドロップする
-        case Material.MELON_BLOCK =>
-          Some(BlockBreakResult.ItemDrop(new ItemStack(Material.MELON, (rand * 5 + 3).toInt)))
-        // シーランタンは、2から3個のプリズマリンクリスタルをドロップする
-        case Material.SEA_LANTERN =>
-          Some(
-            BlockBreakResult
-              .ItemDrop(new ItemStack(Material.PRISMARINE_CRYSTALS, (rand * 2 + 2).toInt))
-          )
-        case Material.STONE =>
-          Some {
-            BlockBreakResult.ItemDrop {
-              if (blockData.toInt == 0x00) {
-                // 焼き石の処理
-                new ItemStack(Material.COBBLESTONE)
-              } else {
-                // 他の石の処理
-                new ItemStack(blockMaterial, 1, blockDataLeast4Bits.toShort)
-              }
-            }
-          }
-        case Material.GRASS =>
-          Some(BlockBreakResult.ItemDrop(new ItemStack(Material.DIRT)))
-        case Material.GRAVEL =>
-          val p = fortuneLevel match {
-            case 1 => 0.14
-            case 2 => 0.25
-            case 3 => 1.00
-            case _ => 0.1
-          }
-          val dropMaterial = if (p > rand) Material.FLINT else Material.GRAVEL
-
-          Some(BlockBreakResult.ItemDrop(new ItemStack(dropMaterial, bonus)))
-        case Material.LEAVES | Material.LEAVES_2 =>
-          None
-        case Material.CLAY =>
-          Some(BlockBreakResult.ItemDrop(new ItemStack(Material.CLAY_BALL, 4)))
-        case Material.MONSTER_EGGS =>
-          Some(BlockBreakResult.SpawnSilverFish(blockLocation))
-        case Material.LOG | Material.LOG_2 =>
-          Some(BlockBreakResult.ItemDrop(new ItemStack(blockMaterial, 1, b_tree.toShort)))
-        case Material.WOOD_STEP | Material.STEP | Material.STONE_SLAB2 | Material.PURPUR_SLAB
-            if (blockDataLeast4Bits & 8) != 0 =>
-          // 上付きハーフブロックをそのままドロップするとmissing textureとして描画されるため、下付きの扱いとする
-          Some(
-            BlockBreakResult
-              .ItemDrop(new ItemStack(blockMaterial, 1, (blockDataLeast4Bits & 7).toShort))
-          )
-        case Material.QUARTZ_BLOCK if (blockData >= 2 && blockData <= 4) =>
-          // 柱状クォーツブロックのmissing texture化を防ぐ (柱状クォーツのData valueは2, 3, 4のいずれか)
-          Some(BlockBreakResult.ItemDrop(new ItemStack(blockMaterial, 1, 2.toShort)))
-        case Material.BOOKSHELF =>
-          // 本棚を破壊すると、本が3つドロップする
-          Some(BlockBreakResult.ItemDrop(new ItemStack(Material.BOOK, 3)))
-        case _ =>
-          Some(
-            BlockBreakResult
-              .ItemDrop(new ItemStack(blockMaterial, 1, blockDataLeast4Bits.toShort))
-          )
-      }
-    }
-  }
-
   /**
    * TODO: これはビジネスロジックである。breakcountシステムによって管理されるべき。
    *
@@ -417,10 +204,10 @@ object BreakUtil {
   def totalBreakCount(materials: Seq[Material]): Long =
     materials
       .filter(MaterialSets.materialsToCountBlockBreak.contains)
-      .map {
+      .map { m =>
         // 氷塊とマグマブロックの整地量を2倍
-        case Material.PACKED_ICE | Material.MAGMA => 2L
-        case _                                    => 1L
+        if (m == Material.PACKED_ICE || m == Material.MAGMA_BLOCK) 2L
+        else 1L
       }
       .sum
 
@@ -446,34 +233,38 @@ object BreakUtil {
       targetBlocksInformation <- PluginExecutionContexts
         .onMainThread
         .runAction(SyncIO {
-          val seq: Seq[(Location, Material, Byte)] = targetBlocks
+          val seq: Seq[(Location, Block)] = targetBlocks
             .toSeq
-            .filter { block =>
-              block.getType match {
-                case Material.AIR =>
-                  if (SeichiAssist.DEBUG)
-                    Bukkit.getLogger.warning(s"AIRの破壊が${block.getLocation.toString}にて試行されました。")
-                  false
-                case _ => true
-              }
-            }
-            .map(block => (block.getLocation.clone(), block.getType, block.getData))
-
-          // ブロックをすべて[[toMaterial]]に変える
-          targetBlocks.foreach(_.setType(toMaterial))
+            .filterNot(_.getType == Material.AIR)
+            .map(block => (block.getLocation.clone(), block))
 
           seq
         })
 
+      notContainerBlocks <- PluginExecutionContexts
+        .onMainThread
+        .runAction(SyncIO {
+          targetBlocksInformation.filterNot(_._2.getState.isInstanceOf[Container])
+        })
+
       breakResults = {
-        val plainBreakResult = targetBlocksInformation.flatMap(dropItemOnTool(miningTool))
+        val plainBreakResult =
+          notContainerBlocks.map {
+            case (location, block) =>
+              val clonedTool = miningTool.clone()
+              clonedTool.setType(Material.NETHERITE_PICKAXE)
+              (location, block.getDrops(clonedTool, player).asScala)
+          }
         val drops = plainBreakResult.mapFilter {
-          case BlockBreakResult.ItemDrop(itemStack) => Some(itemStack)
-          case BlockBreakResult.SpawnSilverFish(_)  => None
-        }
+          case (_, drops) if drops.nonEmpty => Some(drops)
+          case _                            => None
+        }.flatten
         val silverFishLocations = plainBreakResult.mapFilter {
-          case BlockBreakResult.ItemDrop(_)               => None
-          case BlockBreakResult.SpawnSilverFish(location) => Some(location)
+          case (location, _)
+              if location.getBlock.getType == Material.INFESTED_STONE && !miningTool
+                .containsEnchantment(Enchantment.SILK_TOUCH) =>
+            Some(location)
+          case _ => None
         }
 
         // 纏めなければ、FAWEの干渉を受け勝手に消される危険性などがある
@@ -502,18 +293,30 @@ object BreakUtil {
           ).map(Option.unless(_)(itemStack))
         }
 
+      // NOTE: SpigotのBlockはLocationを保存しているため、Blockを置き換える前にMaterialとして
+      //  保存しておかないとすべてMaterial.AIRとして取得されてしまう
+      breakMaterials = targetBlocksInformation.map { case (_, block) => block.getType }
+
+      _ <- PluginExecutionContexts
+        .onMainThread
+        .runAction(SyncIO {
+          // ブロックをすべて[[toMaterial]]に変える
+          targetBlocks.filter(_.getState.isInstanceOf[Container]).foreach(_.breakNaturally())
+          targetBlocks.foreach(_.setType(toMaterial))
+        })
+
       _ <- IO {
         // 壊した時の音を再生する
         if (shouldPlayBreakSound) {
           targetBlocksInformation.foreach {
-            case (location, material, _) =>
-              dropLocation.getWorld.playEffect(location, Effect.STEP_SOUND, material)
+            case (location, block) =>
+              dropLocation.getWorld.playEffect(location, Effect.STEP_SOUND, block)
           }
         }
       }
 
       // プレイヤーの統計を増やす
-      totalCount = totalBreakCount(targetBlocksInformation.map { case (_, m, _) => m })
+      totalCount = totalBreakCount(breakMaterials)
       blockCountWeight <- blockCountWeight[IO](player.getWorld)
       expIncrease = SeichiExpAmount.ofNonNegative(totalCount * blockCountWeight)
 
@@ -531,6 +334,7 @@ object BreakUtil {
           // アイテムドロップは非同期スレッドで行ってはならない
           itemsToBeDropped
             .flatten
+            .filterNot(_.getType == Material.AIR)
             .foreach(dropLocation.getWorld.dropItemNaturally(dropLocation, _))
           breakResults._2.foreach { location =>
             location.getWorld.spawnEntity(location, EntityType.SILVERFISH)
@@ -569,11 +373,9 @@ object BreakUtil {
    *    ref: [バージョン1.12.x時の最新記事アーカイブ](https://minecraft.fandom.com/wiki/Solid_block?oldid=1132868)
    */
   private def isAffectedByGravity(material: Material): Boolean = {
-    material match {
-      case Material.BEDROCK                                          => false
-      case m if MaterialSets.fluidMaterials.contains(m) || m.isSolid => true
-      case _                                                         => false
-    }
+    if (material == Material.BEDROCK) false
+    else if (MaterialSets.fluidMaterials.contains(material)) true
+    else material.isSolid
   }
 
   /**
@@ -670,7 +472,7 @@ object BreakUtil {
     /**
      * 最大ループ数
      */
-    val maxY = if (player.getWorld.getEnvironment == Environment.NETHER) 121 else 255
+    val maxY = player.getWorld.getMaxHeight
     val maxOffsetY = maxY - blockRelativeHeight
 
     // NOTE: `1 until 0`など、`x > y`が満たされる`x until y`はイテレーションが行われない
diff --git a/src/main/scala/com/github/unchama/seichiassist/util/EnemyEntity.scala b/src/main/scala/com/github/unchama/seichiassist/util/EnemyEntity.scala
index 10de3f680f..bb72bc2cc3 100644
--- a/src/main/scala/com/github/unchama/seichiassist/util/EnemyEntity.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/util/EnemyEntity.scala
@@ -5,15 +5,20 @@ import org.bukkit.entity.EntityType.{
   BLAZE,
   CAVE_SPIDER,
   CREEPER,
+  DROWNED,
   ELDER_GUARDIAN,
   ENDERMAN,
   ENDERMITE,
   EVOKER,
   GHAST,
   GUARDIAN,
+  HOGLIN,
   HUSK,
   MAGMA_CUBE,
-  PIG_ZOMBIE,
+  PIGLIN,
+  PIGLIN_BRUTE,
+  PILLAGER,
+  RAVAGER,
   SHULKER,
   SILVERFISH,
   SKELETON,
@@ -24,8 +29,10 @@ import org.bukkit.entity.EntityType.{
   VINDICATOR,
   WITCH,
   WITHER_SKELETON,
+  ZOGLIN,
   ZOMBIE,
-  ZOMBIE_VILLAGER
+  ZOMBIE_VILLAGER,
+  ZOMBIFIED_PIGLIN
 }
 
 object EnemyEntity {
@@ -41,7 +48,7 @@ object EnemyEntity {
     GUARDIAN,
     HUSK,
     MAGMA_CUBE,
-    PIG_ZOMBIE,
+    ZOMBIFIED_PIGLIN,
     SHULKER,
     SILVERFISH,
     SKELETON,
@@ -53,6 +60,13 @@ object EnemyEntity {
     WITCH,
     WITHER_SKELETON,
     ZOMBIE,
-    ZOMBIE_VILLAGER
+    ZOMBIE_VILLAGER,
+    PIGLIN,
+    HOGLIN,
+    DROWNED,
+    PIGLIN_BRUTE,
+    PILLAGER,
+    RAVAGER,
+    ZOGLIN
   ).contains(entityType)
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/util/ItemInformation.scala b/src/main/scala/com/github/unchama/seichiassist/util/ItemInformation.scala
index afdfeab6f9..015b1a0510 100644
--- a/src/main/scala/com/github/unchama/seichiassist/util/ItemInformation.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/util/ItemInformation.scala
@@ -1,8 +1,10 @@
 package com.github.unchama.seichiassist.util
 
+import com.github.unchama.itemstackbuilder.SkullOwnerUuid
+import com.github.unchama.seichiassist.SkullOwners
 import org.bukkit.ChatColor.GREEN
-import org.bukkit.block.{Block, Skull}
-import org.bukkit.{Material, SkullType}
+import org.bukkit.block.Block
+import org.bukkit.Material
 import org.bukkit.inventory.ItemStack
 import org.bukkit.inventory.meta.SkullMeta
 
@@ -11,61 +13,44 @@ import java.util.stream.IntStream
 object ItemInformation {
 
   import scala.jdk.CollectionConverters._
-  import scala.util.chaining._
 
   def isGachaTicket(itemStack: ItemStack): Boolean = {
     val containsRightClickMessage: String => Boolean = _.contains(s"${GREEN}右クリックで使えます")
 
-    if (itemStack.getType != Material.SKULL_ITEM) return false
+    if (itemStack.getType != Material.PLAYER_HEAD) return false
 
     val skullMeta = itemStack.getItemMeta.asInstanceOf[SkullMeta]
 
-    if (!(skullMeta.hasOwner && skullMeta.getOwner == "unchama")) return false
+    /*
+      Note: skullMeta.getOwner == "unchama"という条件は、後方互換性を保つためのコードである。
+            1.12.2のバージョンでskullMeta.getOwnerで頭のオーナーを取得できていたが、
+            1.18.2ではsetOwner、getOwnerともに使用できない。
+            そのため、1.18.2からはPlayerProfileにUUIDを書き込み、UUIDを利用した判定を行うことになった。
+
+            1.18.2の環境で、1.12.2から持ってきたガチャ券(1.12.2の環境でItemStack化されたもの)からgetOwnerすることが
+            できなければ該当のコードを削除して良い。
+     */
+    if (
+      !(skullMeta.hasOwner && (SkullOwnerUuid(
+        skullMeta.getOwningPlayer.getPlayerProfile.getUniqueId
+      ) == SkullOwners.unchama || skullMeta.getOwner == "unchama"))
+    ) return false
 
     skullMeta.hasLore && skullMeta.getLore.asScala.exists(containsRightClickMessage)
   }
 
   def isMineHeadItem(itemstack: ItemStack): Boolean = {
-    itemstack.getType == Material.CARROT_STICK &&
+    itemstack.getType == Material.CARROT_ON_A_STICK &&
     loreIndexOf(itemstack.getItemMeta.getLore.asScala.toList, "頭を狩り取る形をしている...") >= 0
   }
 
   def getSkullDataFromBlock(block: Block): Option[ItemStack] = {
-    if (block.getType != Material.SKULL) return None
-
-    val skull = block.getState.asInstanceOf[Skull]
-    val itemStack = new ItemStack(Material.SKULL_ITEM)
+    if (block.getType != Material.PLAYER_HEAD) return None
 
-    // SkullTypeがプレイヤー以外の場合,SkullTypeだけ設定して終わり
-    if (skull.getSkullType != SkullType.PLAYER) {
-      val durability = skull.getSkullType match {
-        case SkullType.CREEPER  => SkullType.CREEPER.ordinal.toShort
-        case SkullType.DRAGON   => SkullType.DRAGON.ordinal.toShort
-        case SkullType.SKELETON => SkullType.SKELETON.ordinal.toShort
-        case SkullType.WITHER   => SkullType.WITHER.ordinal.toShort
-        case SkullType.ZOMBIE   => SkullType.ZOMBIE.ordinal.toShort
-        case _                  => itemStack.getDurability
-      }
-      return Some(itemStack.tap(_.setDurability(durability)))
-    }
     // プレイヤーの頭の場合,ドロップアイテムからItemStackを取得.データ値をPLAYERにして返す
-    Some(block.getDrops.asScala.head.tap(_.setDurability(SkullType.PLAYER.ordinal.toShort)))
+    Some(block.getDrops.asScala.head)
   }
 
-  /**
-   * 指定された`String`が指定された[[ItemStack]]のloreに含まれているかどうか
-   *
-   * @param itemStack
-   *   確認する`ItemStack`
-   * @param sentence
-   *   探す文字列
-   * @return
-   *   含まれていれば`true`、含まれていなければ`false`。ただし、`ItemStack`に`ItemMeta`と`Lore`のいずれかがなければfalse
-   */
-  def isContainedInLore(itemStack: ItemStack, sentence: String): Boolean =
-    if (!itemStack.hasItemMeta || !itemStack.getItemMeta.hasLore) false
-    else loreIndexOf(itemStack.getItemMeta.getLore.asScala.toList, sentence) >= 0
-
   /**
    * loreを捜査して、要素の中に`find`が含まれているかを調べる。
    *
diff --git a/src/main/scala/com/github/unchama/seichiassist/util/ItemMetaFactory.java b/src/main/scala/com/github/unchama/seichiassist/util/ItemMetaFactory.java
index 6df78bcc77..56811061fa 100644
--- a/src/main/scala/com/github/unchama/seichiassist/util/ItemMetaFactory.java
+++ b/src/main/scala/com/github/unchama/seichiassist/util/ItemMetaFactory.java
@@ -9,5 +9,5 @@
 @SuppressWarnings("UtilityClassCanBeEnum")
 public final class ItemMetaFactory {
     private static final ItemFactory FACTORY = Bukkit.getItemFactory();
-    public static final ValueHolder<SkullMeta> SKULL = new ValueHolder<>((SkullMeta) FACTORY.getItemMeta(Material.SKULL_ITEM), SkullMeta::clone);
+    public static final ValueHolder<SkullMeta> SKULL = new ValueHolder<>((SkullMeta) FACTORY.getItemMeta(Material.PLAYER_HEAD), SkullMeta::clone);
 }
diff --git a/src/main/scala/com/github/unchama/seichiassist/util/PlayerSendable.scala b/src/main/scala/com/github/unchama/seichiassist/util/PlayerSendable.scala
index 7b14dcc0a7..a448f5da32 100644
--- a/src/main/scala/com/github/unchama/seichiassist/util/PlayerSendable.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/util/PlayerSendable.scala
@@ -21,7 +21,7 @@ object PlayerSendable {
   implicit def forStringArray[F[_]: OnMinecraftServerThread]
     : PlayerSendable[Array[String], F] = { (player, content) =>
     OnMinecraftServerThread[F].runAction(SyncIO {
-      player.sendMessage(content)
+      player.sendMessage(content.mkString("\n"))
     })
   }
 
diff --git a/src/main/scala/com/github/unchama/seichiassist/util/SendMessageEffect.scala b/src/main/scala/com/github/unchama/seichiassist/util/SendMessageEffect.scala
index 23887c61e2..534cc1c6e5 100644
--- a/src/main/scala/com/github/unchama/seichiassist/util/SendMessageEffect.scala
+++ b/src/main/scala/com/github/unchama/seichiassist/util/SendMessageEffect.scala
@@ -1,25 +1,15 @@
 package com.github.unchama.seichiassist.util
 
 import cats.Monad
-import cats.effect.IO
+import cats.effect.{IO, LiftIO}
 import com.github.unchama.minecraft.actions.GetConnectedPlayers
 import com.github.unchama.minecraft.bukkit.actions.GetConnectedBukkitPlayers
 import com.github.unchama.seichiassist.SeichiAssist
 import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts.onMainThread
-import org.bukkit.Bukkit
 import org.bukkit.entity.Player
 
 object SendMessageEffect {
 
-  import scala.jdk.CollectionConverters._
-
-  @deprecated("It's side-effectful")
-  def sendMessageToEveryoneIgnoringPreference[T](
-    content: T
-  )(implicit send: PlayerSendable[T, IO]): Unit = {
-    sendMessageToEveryoneIgnoringPreferenceIO(content).unsafeRunAsyncAndForget()
-  }
-
   def sendMessageToEveryoneIgnoringPreferenceIO[T: PlayerSendable[*, IO]](
     content: T
   ): IO[Unit] = {
@@ -38,23 +28,23 @@ object SendMessageEffect {
     } yield ()
   }
 
-  @deprecated("It's side-effectful")
-  def sendMessageToEveryone[T](content: T)(implicit ev: PlayerSendable[T, IO]): Unit = {
+  def sendMessageToEveryone[T, F[_]: Monad: LiftIO: GetConnectedPlayers[*[_], Player]](
+    content: T
+  )(implicit ev: PlayerSendable[T, F]): F[Unit] = {
     import cats.implicits._
 
-    Bukkit
-      .getOnlinePlayers
-      .asScala
-      .toList
-      .traverse { player =>
+    for {
+      players <- GetConnectedPlayers[F, Player].now
+      _ <- players.traverse { player =>
         for {
           playerSettings <- SeichiAssist
             .playermap(player.getUniqueId)
             .settings
             .getBroadcastMutingSettings
-          _ <- IO { if (!playerSettings.shouldMuteMessages) ev.send(player, content) }
+            .to[F]
+          _ <- ev.send(player, content).unlessA(playerSettings.shouldMuteMessages)
         } yield ()
       }
-      .unsafeRunSync()
+    } yield ()
   }
 }
diff --git a/src/main/scala/com/github/unchama/targetedeffect/commandsender/MessageEffect.scala b/src/main/scala/com/github/unchama/targetedeffect/commandsender/MessageEffect.scala
index 424880affd..32667be2be 100644
--- a/src/main/scala/com/github/unchama/targetedeffect/commandsender/MessageEffect.scala
+++ b/src/main/scala/com/github/unchama/targetedeffect/commandsender/MessageEffect.scala
@@ -26,6 +26,6 @@ object MessageEffectF {
     TargetedEffect.delay(_.sendMessage(string))
 
   def apply[F[_]: Sync](stringList: List[String]): Kleisli[F, CommandSender, Unit] =
-    TargetedEffect.delay(_.sendMessage(stringList.toArray))
+    TargetedEffect.delay(_.sendMessage(stringList.mkString("\n")))
 
 }
diff --git a/src/main/scala/com/github/unchama/targetedeffect/player/CommandEffect.scala b/src/main/scala/com/github/unchama/targetedeffect/player/CommandEffect.scala
index 1da9b76645..fe4e75fd1d 100644
--- a/src/main/scala/com/github/unchama/targetedeffect/player/CommandEffect.scala
+++ b/src/main/scala/com/github/unchama/targetedeffect/player/CommandEffect.scala
@@ -18,3 +18,12 @@ object CommandEffect {
       })
     }
 }
+
+object CommandEffectF {
+  def apply[F[_]: OnMinecraftServerThread](string: String): Kleisli[F, Player, Unit] =
+    Kleisli { player =>
+      OnMinecraftServerThread[F].runAction(SyncIO {
+        player.chat(s"/$string")
+      })
+    }
+}
diff --git a/src/main/scala/com/github/unchama/targetedeffect/player/PlayerEffects.scala b/src/main/scala/com/github/unchama/targetedeffect/player/PlayerEffects.scala
index 564eaaab65..6709c76cdd 100644
--- a/src/main/scala/com/github/unchama/targetedeffect/player/PlayerEffects.scala
+++ b/src/main/scala/com/github/unchama/targetedeffect/player/PlayerEffects.scala
@@ -9,7 +9,17 @@ import org.bukkit.entity.Player
 import org.bukkit.inventory.Inventory
 
 object PlayerEffects {
-  val closeInventoryEffect: TargetedEffect[Player] = TargetedEffect.delay(_.closeInventory())
+
+  def closeInventoryEffect(
+    implicit onMainThread: OnMinecraftServerThread[IO]
+  ): TargetedEffect[Player] = {
+    Kleisli { player =>
+      // インベントリを閉じる操作はサーバースレッドでなければならない(Spigot 1.18.2)
+      onMainThread.runAction(SyncIO {
+        player.closeInventory()
+      })
+    }
+  }
 
   def openInventoryEffect(
     inventory: => Inventory
diff --git a/src/main/scala/com/github/unchama/util/bukkit/ItemStackUtil.scala b/src/main/scala/com/github/unchama/util/bukkit/ItemStackUtil.scala
index d75eec2460..f0007d3c21 100644
--- a/src/main/scala/com/github/unchama/util/bukkit/ItemStackUtil.scala
+++ b/src/main/scala/com/github/unchama/util/bukkit/ItemStackUtil.scala
@@ -8,7 +8,7 @@ object ItemStackUtil {
    * `stacks` に含まれるアイテムスタックをできるだけマージしたような新たな `Seq` を返す
    */
   def amalgamate(stacks: Seq[ItemStack]): Seq[ItemStack] = {
-    val originals = stacks.map(_.clone())
+    val originals = stacks.filterNot(_ == null).map(_.clone())
 
     val result = scala.collection.mutable.ArrayBuffer.empty[ItemStack]
 
diff --git a/src/main/scala/com/github/unchama/util/bukkit/WorldUtil.scala b/src/main/scala/com/github/unchama/util/bukkit/WorldUtil.scala
index 985501bf8e..8ceb0b3b11 100644
--- a/src/main/scala/com/github/unchama/util/bukkit/WorldUtil.scala
+++ b/src/main/scala/com/github/unchama/util/bukkit/WorldUtil.scala
@@ -6,10 +6,12 @@ import org.bukkit.World.Environment
 object WorldUtil {
   def getAbsoluteWorldFolder(world: World): String = {
     val base = world.getWorldFolder.getAbsolutePath
+
     world.getEnvironment match {
       case Environment.NORMAL  => base
       case Environment.NETHER  => s"$base/DIM-1"
       case Environment.THE_END => s"$base/DIM1"
+      case Environment.CUSTOM  => s"$base/COSTOM"
     }
   }
 }
diff --git a/src/main/scala/com/github/unchama/util/external/CoreProtectWrapper.scala b/src/main/scala/com/github/unchama/util/external/CoreProtectWrapper.scala
index cfae476980..eda19fff99 100644
--- a/src/main/scala/com/github/unchama/util/external/CoreProtectWrapper.scala
+++ b/src/main/scala/com/github/unchama/util/external/CoreProtectWrapper.scala
@@ -7,14 +7,11 @@ import org.bukkit.entity.Player
 class CoreProtectWrapper(val backbone: CoreProtectAPI) {
 
   def queueBlockRemoval(who: Player, where: Block): Boolean = {
-    // where.getDataが非推奨になっていますが、現在これ以外の方法でByteデータを取得する方法がないようです。
-    backbone.logRemoval(who.getName, where.getLocation, where.getType, where.getData)
+    backbone.logRemoval(who.getName, where.getLocation, where.getType, where.getBlockData)
   }
 
-  /*
-  // For >= 1.13
-  def queueBlockRemoval(who: Player, where: Location, data: BlockData): Boolean = {
-    return backbone.logRemoval(who.getName, where, where.getBlock.getType, data)
+  def isNotEditedBlock(where: Block): Boolean = {
+    backbone.blockLookup(where, Int.MaxValue).isEmpty
   }
-   */
+
 }
diff --git a/src/main/scala/com/github/unchama/util/external/WorldEditWrapper.scala b/src/main/scala/com/github/unchama/util/external/WorldEditWrapper.scala
index 15812be9e3..8b40674e36 100644
--- a/src/main/scala/com/github/unchama/util/external/WorldEditWrapper.scala
+++ b/src/main/scala/com/github/unchama/util/external/WorldEditWrapper.scala
@@ -1,7 +1,7 @@
 package com.github.unchama.util.external
 
 import com.sk89q.worldedit.bukkit.WorldEditPlugin
-import com.sk89q.worldedit.bukkit.selections.Selection
+import com.sk89q.worldedit.math.BlockVector3
 import org.bukkit.entity.Player
 
 object WorldEditWrapper {
@@ -14,6 +14,7 @@ object WorldEditWrapper {
   /**
    * @return `player`が選択している範囲
    */
-  def getSelection(player: Player): Option[Selection] = Option(plugin.getSelection(player))
+  def getSelection(player: Player): BlockVector3 =
+    plugin.getSession(player).getPlacementPosition(plugin.wrapPlayer(player))
 
 }
diff --git a/src/main/scala/com/github/unchama/util/external/WorldGuardWrapper.scala b/src/main/scala/com/github/unchama/util/external/WorldGuardWrapper.scala
index e4e407a0b7..3ffee61781 100644
--- a/src/main/scala/com/github/unchama/util/external/WorldGuardWrapper.scala
+++ b/src/main/scala/com/github/unchama/util/external/WorldGuardWrapper.scala
@@ -1,12 +1,11 @@
 package com.github.unchama.util.external
 
-import com.sk89q.worldedit.BlockVector
-import com.sk89q.worldguard.LocalPlayer
-import com.sk89q.worldguard.bukkit.commands.AsyncCommandHelper
-import com.sk89q.worldguard.bukkit.commands.task.RegionAdder
+import com.sk89q.worldedit.bukkit.BukkitAdapter
+import com.sk89q.worldguard.bukkit.WorldGuardPlugin
+import com.sk89q.worldguard.protection.flags.Flags
 import com.sk89q.worldguard.protection.managers.RegionManager
-import com.sk89q.worldguard.protection.regions.{ProtectedCuboidRegion, ProtectedRegion}
-import com.sk89q.worldguard.protection.util.DomainInputResolver
+import com.sk89q.worldguard.protection.regions.ProtectedRegion
+import com.sk89q.worldguard.{LocalPlayer, WorldGuard}
 import org.bukkit.entity.Player
 import org.bukkit.{Location, World}
 
@@ -19,141 +18,89 @@ import scala.jdk.CollectionConverters._
  */
 object WorldGuardWrapper {
 
-  /**
-   * WorldGuardのインスタンス
-   */
-  private val plugin = ExternalPlugins.getWorldGuard
+  private val worldGuard = WorldGuard.getInstance()
 
   /**
    * [[LocalPlayer]]を返す
    */
-  private def wrapPlayer(player: Player): LocalPlayer = plugin.wrapPlayer(player)
-
-  /**
-   * [[RegionManager]]を返す
-   */
-  def getRegionManager(world: World): Option[RegionManager] = Option(
-    // The expression is nullable: WorldConfiguration#useRegions is false => null
-    plugin.getRegionManager(world)
-  )
-
-  /**
-   * [[Player]]が[[World]]の中で持っている保護の数を返す
-   *
-   * @return [[Player]]が[[World]]の中で持っている保護の数。[[getRegionManager]]が[[None]]であれば0。
-   */
-  def getRegionCountOfPlayer(player: Player, world: World): Int =
-    getRegionManager(world).map(_.getRegionCountOfPlayer(wrapPlayer(player))).getOrElse(0)
-
-  /**
-   * [[World]]における[[Player]] の最大保護可能数を取得します.
-   * @return [[Player]]の[[World]] における最大保護可能数
-   */
-  def getMaxRegionCount(player: Player, world: World): Int =
-    // TODO: migrate this to OptionalInt
-    plugin.getGlobalStateManager.get(world).getMaxRegionCount(player)
-
-  /**
-   * 現在[[Player]]が[[World]]でオーナーになっている保護の数を返す。
-   * @param who 誰か
-   * @param where どのワールドか
-   * @return オーナーになっている保護の数。どこのオーナーでもない場合は0
-   */
-  def getNumberOfRegions(who: Player, where: World): Int =
-    // TODO: migrate this to OptionalInt
-    plugin.getRegionContainer.get(where).getRegionCountOfPlayer(wrapPlayer(who))
-
-  /**
-   * 現在[[Player]]が[[Location]]の座標でOwnerになっている保護があるかどうかを返す。
-   * @param player 調べる対象であるPlayer
-   * @param location どの座標か
-   * @return Ownerである保護が1つだけあればtrue、ないか保護が2個以上重なっていて判定できなければfalse
-   */
-  def isRegionOwner(player: Player, location: Location): Boolean =
-    getOneRegion(location).exists(_.isOwner(wrapPlayer(player)))
-
-  /**
-   * [[Player]]が[[Location]]の座標でMemberになっている保護があるかどうかを返す。
-   * NOTE: Ownerでもある場合も含まれる。
-   * @param player 調べる対象であるPlayer
-   * @param location どの座標か
-   * @return Memberである保護が1つだけあればtrue、ないか保護が2個以上重なっていて判定できなければfalse
-   */
-  def isRegionMember(player: Player, location: Location): Boolean =
-    getOneRegion(location).exists(_.isMember(wrapPlayer(player)))
+  private def wrapPlayer(player: Player): LocalPlayer =
+    WorldGuardPlugin.inst().wrapPlayer(player)
+
+  def getRegionManager(world: World): RegionManager =
+    worldGuard.getPlatform.getRegionContainer.get(BukkitAdapter.adapt(world))
+
+  def getRegion(loc: Location): List[ProtectedRegion] = {
+    val container =
+      worldGuard.getPlatform.getRegionContainer.get(BukkitAdapter.adapt(loc.getWorld))
+    container
+      .getApplicableRegions(BukkitAdapter.adapt(loc).toVector.toBlockPoint)
+      .getRegions
+      .asScala
+      .toList
+  }
 
-  /**
-   * [[Location]]の座標にある保護を1つだけ取得する
-   * @param location どの座標か
-   * @return [[ProtectedRegion]]。保護が1個もないか、2個以上ある場合は[[None]]
-   */
-  def getOneRegion(location: Location): Option[ProtectedRegion] = {
-    val regions = getRegions(location)
+  def getRegions(world: World): List[ProtectedRegion] = {
+    worldGuard
+      .getPlatform
+      .getRegionContainer
+      .get(BukkitAdapter.adapt(world))
+      .getRegions
+      .values()
+      .asScala
+      .toList
+  }
 
-    Option.when(regions.size == 1)(regions.head)
+  def canBuild(p: Player, loc: Location): Boolean = {
+    worldGuard
+      .getPlatform
+      .getRegionContainer
+      .createQuery()
+      .testState(BukkitAdapter.adapt(loc), wrapPlayer(p), Flags.BUILD)
   }
 
-  /**
-   * [[Location]]の座標にある保護をすべて取得する
-   * @param location どの座標か
-   * @return [[ProtectedRegion]]の[[Set]]
-   */
-  def getRegions(location: Location): Set[ProtectedRegion] =
-    getRegionManager(location.getWorld)
-      .map(_.getApplicableRegions(location).getRegions.asScala.toSet)
-      .getOrElse(Set.empty)
+  def findByRegionName(name: String): Option[RegionManager] =
+    worldGuard
+      .getPlatform
+      .getRegionContainer
+      .getLoaded
+      .asScala
+      .find(_.getRegions.asScala.exists(_._1 == name))
+
+  def removeByProtectedRegionRegion(world: World, region: ProtectedRegion): Unit = {
+    worldGuard
+      .getPlatform
+      .getRegionContainer
+      .get(BukkitAdapter.adapt(world))
+      .removeRegion(region.getId)
+  }
 
-  /**
-   * `minimumPoint`と`maximumPoint`の範囲内にある保護の数を取得する
-   * @param world 調べたいワールド
-   * @param regionName 保護名
-   * @param minimumPoint 範囲の対角の1つ
-   * @param maximumPoint 範囲の対角の1つ
-   * @return 指定した範囲の保護の数を返す作用
-   */
-  def getApplicableRegionCount(
-    world: World,
-    regionName: String,
-    minimumPoint: BlockVector,
-    maximumPoint: BlockVector
-  ): Int = {
-    val region = new ProtectedCuboidRegion(regionName, minimumPoint, maximumPoint)
-    getRegionManager(world).map(_.getApplicableRegions(region).size).getOrElse(0)
+  def getMaxRegion(player: Player, world: World): Int = {
+    worldGuard
+      .getPlatform
+      .getGlobalStateManager
+      .get(BukkitAdapter.adapt(world))
+      .getMaxRegionCount(wrapPlayer(player))
   }
 
-  /**
-   * @param regionName 保護名
-   * @param regionOwner 保護のオーナー
-   * @param world 保護をしたいワールド
-   * @param minimumPoint 保護範囲の対角の1つ
-   * @param maximumPoint 保護範囲の対角の1つ
-   * @return 保護の作成を試みることができればtrue、できなければfalse
-   *         ただし、trueでも確実に保護が作成できるとは限らない
-   */
-  def tryCreateRegion(
-    regionName: String,
-    regionOwner: Player,
-    world: World,
-    minimumPoint: BlockVector,
-    maximumPoint: BlockVector
-  ): Boolean = {
-    val region = new ProtectedCuboidRegion(regionName, minimumPoint, maximumPoint)
-
-    getRegionManager(world) match {
-      case Some(manager) =>
-        val task = new RegionAdder(plugin, manager, region)
-        task.setLocatorPolicy(DomainInputResolver.UserLocatorPolicy.UUID_ONLY)
-        task.setOwnersInput(Array(regionOwner.getName))
-        val future = plugin.getExecutorService.submit(task)
-
-        AsyncCommandHelper
-          .wrap(future, plugin, regionOwner)
-          .formatUsing(regionName)
-          .registerWithSupervisor("保護申請中")
-          .thenRespondWith("保護申請完了。保護名: '%s'", "保護作成失敗")
-        true
-      case None => false
-    }
+  def getNumberOfRegions(player: Player, world: World): Int =
+    worldGuard
+      .getPlatform
+      .getRegionContainer
+      .get(BukkitAdapter.adapt(world))
+      .getRegionCountOfPlayer(wrapPlayer(player))
+
+  def getWorldMaxRegion(world: World): Int = {
+    worldGuard
+      .getPlatform
+      .getGlobalStateManager
+      .get(BukkitAdapter.adapt(world))
+      .maxRegionCountPerPlayer
   }
 
+  def isRegionMember(player: Player, location: Location): Boolean =
+    getRegion(location).exists(_.isMember(wrapPlayer(player)))
+
+  def canProtectionWorld(world: World): Boolean =
+    worldGuard.getPlatform.getGlobalStateManager.get(BukkitAdapter.adapt(world)).useRegions
+
 }
diff --git a/src/main/scala/com/github/unchama/util/nms/v1_12_2/world/WorldChunkSaving.scala b/src/main/scala/com/github/unchama/util/nms/v1_18_2/world/WorldChunkSaving.scala
similarity index 92%
rename from src/main/scala/com/github/unchama/util/nms/v1_12_2/world/WorldChunkSaving.scala
rename to src/main/scala/com/github/unchama/util/nms/v1_18_2/world/WorldChunkSaving.scala
index 4b048b1366..442d24c239 100644
--- a/src/main/scala/com/github/unchama/util/nms/v1_12_2/world/WorldChunkSaving.scala
+++ b/src/main/scala/com/github/unchama/util/nms/v1_18_2/world/WorldChunkSaving.scala
@@ -1,4 +1,4 @@
-package com.github.unchama.util.nms.v1_12_2.world
+package com.github.unchama.util.nms.v1_18_2.world
 
 import cats.effect.{Concurrent, Sync}
 
@@ -7,12 +7,12 @@ object WorldChunkSaving {
   import scala.jdk.CollectionConverters._
 
   private object Reflection {
-    private val nmsPackage_1_12_R1 = "net.minecraft.server.v1_12_R1"
-    private val craftBukkitPackage_1_12_R1 = "org.bukkit.craftbukkit.v1_12_R1"
+    private val nmsPackage_1_18_R2 = "net.minecraft.server.v1_18_R1"
+    private val craftBukkitPackage_1_18_R2 = "org.bukkit.craftbukkit.v1_18_R2"
 
     object FileIOThread {
       private[Reflection] lazy val clazz: Class[_] =
-        Class.forName(s"$nmsPackage_1_12_R1.FileIOThread")
+        Class.forName(s"$nmsPackage_1_18_R2.FileIOThread")
 
       // public static FileIOThread method()
       lazy val getInstance: () => AnyRef = {
@@ -32,7 +32,7 @@ object WorldChunkSaving {
 
     object Entity {
       private[Reflection] lazy val clazz: Class[_] =
-        Class.forName(s"$nmsPackage_1_12_R1.Entity")
+        Class.forName(s"$nmsPackage_1_18_R2.Entity")
 
       // public int field
       lazy val chunkX: AnyRef => Int = {
@@ -56,7 +56,7 @@ object WorldChunkSaving {
     }
 
     object Chunk {
-      private[Reflection] lazy val clazz: Class[_] = Class.forName(s"$nmsPackage_1_12_R1.Chunk")
+      private[Reflection] lazy val clazz: Class[_] = Class.forName(s"$nmsPackage_1_18_R2.Chunk")
 
       // public void method(Entity)
       lazy val untrackEntity: AnyRef => AnyRef => Unit = {
@@ -66,7 +66,7 @@ object WorldChunkSaving {
     }
 
     object World {
-      private[Reflection] lazy val clazz: Class[_] = Class.forName(s"$nmsPackage_1_12_R1.World")
+      private[Reflection] lazy val clazz: Class[_] = Class.forName(s"$nmsPackage_1_18_R2.World")
 
       // public final List<Entity> field
       lazy val entityList: AnyRef => java.util.List[_ <: AnyRef] = {
@@ -121,7 +121,7 @@ object WorldChunkSaving {
 
     object CraftWorld {
       private[Reflection] lazy val clazz: Class[_] =
-        Class.forName(s"$craftBukkitPackage_1_12_R1.CraftWorld")
+        Class.forName(s"$craftBukkitPackage_1_18_R2.CraftWorld")
 
       // public final nms.WorldServer (<: nms.World)
       // originally
diff --git a/src/scalafix/scala/fix/MatchForMaterialToErrorForPerformance.scala b/src/scalafix/scala/fix/MatchForMaterialToErrorForPerformance.scala
new file mode 100644
index 0000000000..a1d058274a
--- /dev/null
+++ b/src/scalafix/scala/fix/MatchForMaterialToErrorForPerformance.scala
@@ -0,0 +1,31 @@
+package fix
+
+import scalafix.v1._
+
+import scala.meta._
+
+/**
+ * Lints on string interpolation where its variable part contains `case class` without `toString`.
+ */
+// noinspection ScalaUnusedSymbol; referred from scalafix implicitly
+// NOTE: see AST on https://xuwei-k.github.io/scalameta-ast/ or https://astexplorer.net
+class MatchForMaterialToErrorForPerformance extends SemanticRule("MatchForMaterialToErrorForPerformance") {
+  override def fix(implicit doc: SemanticDocument): Patch = {
+    doc.tree.collect {
+      case t @ Term.Match.After_4_4_5(term, _, _) =>
+        term.symbol.info match {
+          case Some(info) if info.signature.toString == "Material" =>
+            info.signature match {
+              case ValueSignature(TypeRef(_, symbol, _)) if SymbolMatcher.normalized("org/bukkit/Material").matches(symbol) =>
+                val message =
+                  s"""
+                     |Don't use org.bukkit.Material in scrutinee of match expressions!
+                     |See https://github.com/GiganticMinecraft/SeichiAssist/issues/2226 for more detail.""".stripMargin
+                Patch.lint(Diagnostic("error", message, t.pos))
+              case _ => Patch.empty
+            }
+          case _ => Patch.empty
+        }
+    }.asPatch
+  }
+}
diff --git a/src/test/scala/com/github/unchama/generic/effect/ResourceScopeSpec.scala b/src/test/scala/com/github/unchama/generic/effect/ResourceScopeSpec.scala
index a06b51d455..041c51b15b 100644
--- a/src/test/scala/com/github/unchama/generic/effect/ResourceScopeSpec.scala
+++ b/src/test/scala/com/github/unchama/generic/effect/ResourceScopeSpec.scala
@@ -138,7 +138,7 @@ class ResourceScopeSpec extends AnyWordSpec with Matchers with MockFactory {
           useTracked(firstResourceScope, NumberedObject(0), finalizer) { o =>
             // noinspection ZeroIndexToHead
             runImpureFunction(o) >>
-              blockerList(0).await >>
+              blockerList(0).await() >>
               IO.never
           }.start
         _ <- blockerList(1).await()
@@ -253,7 +253,7 @@ class ResourceScopeSpec extends AnyWordSpec with Matchers with MockFactory {
           useTrackedForSome(firstResourceScope, NumberedObject(0), finalizer) { o =>
             // noinspection ZeroIndexToHead
             runImpureFunction(o) >>
-              blockerList(0).await >>
+              blockerList(0).await() >>
               IO.never
           }.start
         _ <- blockerList(1).await()
diff --git a/src/test/scala/com/github/unchama/seichiassist/ManagedWorldSpec.scala b/src/test/scala/com/github/unchama/seichiassist/ManagedWorldSpec.scala
index 74e5550757..41c080ddf1 100644
--- a/src/test/scala/com/github/unchama/seichiassist/ManagedWorldSpec.scala
+++ b/src/test/scala/com/github/unchama/seichiassist/ManagedWorldSpec.scala
@@ -6,6 +6,8 @@ import org.scalamock.scalatest.MockFactory
 import org.scalatest.Inspectors.forAll
 import org.scalatest.wordspec.AnyWordSpec
 
+import scala.annotation.nowarn
+
 /**
  * Created by karayuu on 2020/10/07
  */
@@ -40,6 +42,7 @@ class ManagedWorldSpec extends AnyWordSpec with MockFactory {
     "return the appropriate truth-value" in {
       forAll(blockLineUpSkillEnableMap) {
         case (worldName, value) =>
+          @nowarn
           val world = mock[World]
           (world.getName _).expects().returning(worldName)
           assert(world.isBlockLineUpSkillEnabled == value)
@@ -51,6 +54,7 @@ class ManagedWorldSpec extends AnyWordSpec with MockFactory {
     "return the appropriate truth-value" in {
       forAll(inTrackedWorldMap) {
         case (worldName, value) =>
+          @nowarn
           val world = mock[World]
           (world.getName _).expects().returning(worldName)
           assert(world.shouldTrackBuildBlock == value)