日本語 (Japanese) | English
FoliaPhantom は、旧来の Bukkit / Spigot / Paper プラグインを、Folia サーバー(PaperMC のマルチスレッド対応版)で動作させるための画期的な互換性レイヤーです。
プラグインの JAR ファイルをサーバー起動時に動的に解析・修正し、Folia のスレッドモデルに適合しないスケジューラAPI呼び出しを、FoliaネイティブのAPI呼び出しに置き換えます。これにより、開発者が Folia 対応を施していないプラグインでも、多くの場合はそのまま動作させることが可能になります。
- バイトコード変換技術: サーバー起動時にプラグインのクラスファイルを直接解析し、
BukkitScheduler
の呼び出しを Folia のRegionScheduler
やAsyncScheduler
を使うコードに書き換えます。これにより、リフレクションやプロキシ方式よりもクリーンで高速な動作を実現します。 plugin.yml
の自動パッチ: 対象プラグインのplugin.yml
にfolia-supported: true
フラグを自動的に追加・修正し、Folia サーバーに正式対応プラグインとして認識させます。- 幅広いスケジューラ対応:
runTask
,runTaskTimer
といった主要なメソッドに加え、scheduleSyncDelayedTask
などの古いメソッドにも対応。同期・非同期タスクの両方を適切に変換します。 - 設定不要の自動スキャン:
plugins
フォルダ内のプラグインを自動的にスキャンし、Folia未対応のものにパッチを適用します。 - 地形・ワールド生成の互換性:
ChunkGenerator
や同期的なcreateWorld
呼び出しをラップし、Foliaの非同期環境で動作するように試みます。
-
FoliaPhantom のダウンロード: Releasesページから最新版の
FoliaPhantom.jar
をダウンロードし、サーバーのplugins
フォルダに配置します。 -
サーバーの起動: サーバーを起動するだけで、FoliaPhantom は
plugins
フォルダ内のすべてのプラグインを自動的にスキャンし、Foliaに未対応のプラグインに対してパッチを適用します。 -
(任意)パッチ対象から除外: もし、特定のプラグインにパッチを適用したくない場合は、初回起動時に生成される
plugins/FoliaPhantom/config.yml
を編集します。# FoliaPhantom - Configuration auto-scan-plugins: enabled: true # パッチを適用したくないプラグインのリスト excluded-plugins: - "SomePlugin" - "AnotherPlugin"
excluded-plugins
リストにプラグイン名を追加することで、そのプラグインはスキャン対象から除外されます。
- 同期的なワールド生成のリスク:
createWorld
のような、完了までに時間のかかる処理を同期的に呼び出すプラグインをラップした場合、サーバーが一時的にフリーズ(ハングアップ)する可能性があります。Foliaの設計上、これは避けられないリスクであり、Watchdogが警告を出すことがあります。 - NMS/CB依存コード: このプラグインはスケジューラや一部のワールド生成APIの互換性を解決しますが、
net.minecraft.server
(NMS) やorg.bukkit.craftbukkit
(CB) のコードに直接依存するプラグインの互換性までは保証しません。 - 高度なクラスローダー操作: 一部のセキュリティ系プラグインや、特殊なクラスローダー処理を行うプラグインとは競合する可能性があります。
- 100%の互換性保証ではない: このプラグインは多くのケースで有効ですが、全てのプラグインの動作を保証するものではありません。問題が発生した場合は、GitHub Issues での報告をお願いします。
FoliaPhantom は、単なるプロキシやリフレクションとは一線を画す、高度なバイトコードエンジニアリング技術を採用しています。
- JARの解析:
onLoad
フェーズでconfig.yml
に記載されたプラグインのJARを読み込みます。 - 一時JARの生成: パッチを適用するための一時的なJARファイルを
plugins/FoliaPhantom/temp-jars/
内に作成します。 - バイトコード変換 (ASM): 各クラスファイル(
.class
)をバイトコードレベルで解析し、以下のAPI呼び出しを発見すると、それをFoliaPatcher
クラスの静的メソッド呼び出しに置き換えます。org.bukkit.scheduler.BukkitScheduler
の各種メソッドorg.bukkit.plugin.Plugin#getDefaultWorldGenerator
org.bukkit.Server#createWorld
FoliaPatcher
の役割: この内部クラスは、元の呼び出しに対応する Folia のAPIを呼び出すロジックを持っています。- スケジューラ:
RegionScheduler
やAsyncScheduler
を適切に使い分けます。 - ワールド生成:
getDefaultWorldGenerator
が返すChunkGenerator
をラッパーで包み、createWorld
の呼び出しを専用のスレッドで実行してデッドロックを回避します。
- スケジューラ:
plugin.yml
のパッチ:folia-supported: true
をYAMLに追加・上書きします。- パッチ済みJARのロード: 全ての変換とパッチが完了した一時JARを、Bukkit の
PluginManager
を通じてサーバーにロードさせます。
このアプローチにより、ラップ対象のプラグインは自身のコードが一切変更されていないかのように動作しつつ、その実態は Folia に最適化されたスケジューリング処理が実行されることになります。
FoliaPhantom is a groundbreaking compatibility layer designed to run legacy Bukkit, Spigot, and Paper plugins on a Folia server (the multi-threaded version of PaperMC).
It works by dynamically analyzing and patching plugin JAR files at server startup, replacing scheduler API calls incompatible with Folia's threading model with their native Folia equivalents. This allows many plugins, even those not updated by their developers for Folia, to run seamlessly.
- Bytecode Transformation Technology: Directly analyzes plugin class files at startup and rewrites
BukkitScheduler
calls to use Folia'sRegionScheduler
andAsyncScheduler
. This provides a cleaner, faster solution than reflection or proxy-based methods. - Automatic
plugin.yml
Patching: Automatically adds or corrects thefolia-supported: true
flag in the target plugin'splugin.yml
, ensuring it is recognized as a compliant plugin by the Folia server. - Broad Scheduler Compatibility: Supports major methods like
runTask
andrunTaskTimer
, as well as legacy methods likescheduleSyncDelayedTask
, properly converting both synchronous and asynchronous tasks. - Zero-Configuration Auto-Scan: Automatically scans plugins in your
plugins
folder and patches those not yet compatible with Folia. - Terrain & World Gen Compatibility: Attempts to wrap calls to
ChunkGenerator
and synchronouscreateWorld
to work within Folia's asynchronous environment.
-
Download FoliaPhantom: Download the latest
FoliaPhantom.jar
from the Releases page and place it in your server'splugins
folder. -
Start the Server: Simply start your server. FoliaPhantom will automatically scan all plugins in the
plugins
folder and apply compatibility patches to any that are not Folia-native. -
Exclude Plugins (Optional): If you need to prevent a specific plugin from being patched, edit the
config.yml
file generated inplugins/FoliaPhantom/
on the first run.# FoliaPhantom - Configuration auto-scan-plugins: enabled: true # List of plugins to exclude from patching. excluded-plugins: - "SomePlugin" - "AnotherPlugin"
Add the plugin's name to the
excluded-plugins
list to have it ignored by the scanner.
- Risk of Synchronous World Generation: Wrapping a plugin that calls time-consuming methods like
createWorld
synchronously may cause the server to freeze or hang temporarily. This is an unavoidable risk due to Folia's design, and you may see warnings from the Watchdog. - NMS/CB Dependencies: While this plugin resolves scheduler and some world-generation API issues, it does not guarantee compatibility for plugins that depend directly on
net.minecraft.server
(NMS) ororg.bukkit.craftbukkit
(CB) code. - Advanced Class-loading: May conflict with certain security plugins or other plugins that perform complex class-loader manipulations.
- Not a 100% Guarantee: Although effective in many scenarios, this plugin does not guarantee that every plugin will work. If you encounter issues, please report them on our GitHub Issues.
FoliaPhantom employs sophisticated bytecode engineering, setting it apart from simple proxies or reflection.
- JAR Analysis: During the
onLoad
phase, it scans all JARs in theplugins
directory. - Temporary JAR Creation: It creates a temporary JAR file for patching inside
plugins/FoliaPhantom/temp-jars/
. - Bytecode Transformation (ASM): It parses each class file (
.class
) at the bytecode level. When it finds a call to a targeted API, it replaces it with a static method call to theFoliaPatcher
class. Targeted APIs include:- Methods in
org.bukkit.scheduler.BukkitScheduler
org.bukkit.plugin.Plugin#getDefaultWorldGenerator
org.bukkit.Server#createWorld
- Methods in
- The
FoliaPatcher
's Role: This internal class contains the logic to invoke the appropriate Folia-native API.- Schedulers: It intelligently redirects calls to
RegionScheduler
orAsyncScheduler
. - World Generation: It wraps the
ChunkGenerator
returned bygetDefaultWorldGenerator
and dispatchescreateWorld
calls to a dedicated thread to prevent deadlocks.
- Schedulers: It intelligently redirects calls to
plugin.yml
Patching: It adds or overwrites the YAML file to includefolia-supported: true
.- Loading the Patched JAR: The fully transformed and patched temporary JAR is then loaded into the server via Bukkit's
PluginManager
.
This approach allows the wrapped plugin to operate as if its code were unchanged, while its scheduling is actually being handled by Folia-optimized processes.