by おがさくら » 2022年1月12日(水) 08:10
ざっくりと言うと、clientSideは描画や音などのインプット/アウトプットに関する処理、serverSideはそれ以外の処理といった感じです。ブロックやエンティティのテクスチャ・レンダラ、GUI・チャット、環境音、キー処理といったものがclientSideで処理されるものの例になります。
マルチ鯖を立てたことがあるなら、clientSideは各々のPCで、serverSideはサーバー機で処理されるというとわかりやすいかもしれません。
で、プログラムコードの話ですが
- プロキシシステムについて
client側で処理されるようなクラスの多くはserverにはありません。なので、ブロックのレンダーなどをserverSideでも読み込めるようにすると大抵の場合不具合を起こします(クラスがないよっていうエラーが出る)。そのため、プロキシシステムを使ってclient側、server側で処理する項目を分ける必要があります。
具体的なコードについては以下参照。
https://mcmodding.jp/modding/index.php/ ... 4%E3%81%A6
基本的にブロックやエンティティのレンダラ登録に関することや、"MinecraftForgeClient"・"ClientRegistry"などの"Client"とついているようなものが出たらこっちに書けばいいと思っておけば大丈夫かと。
- GUIについて
IGuiHandlerを継承したクラスを用意します。そうするとgetClientGuiElementとgetServerGuiElementというメソッドが出てきます。getClientGuiElementはGUIの描画処理を書いたクラスのインスタンス、getServerGuiElementはGUIの内部処理などを書いたクラスのインスタンスを返します。
例えばgetServerGuiElementで返すクラスには、GUIでのスロットの位置やシフトクリック時のアイテムの移動などの処理を書き、getClientGuiElementで返すクラスにはGUIのテクスチャやGUI内の文字などの処理を書きます。
1.7のGUI関係は以下参照。
https://www.tntmodders.com/tutorial/gui-1710/
- SideOnlyアノテーションについて
@SideOnlyを使うと、clientSideまたはserverSideのどちらかでしか使えないようなクラスやメソッドを作ることができます。クラス宣言やメソッド宣言の前に@SideOnly(Side.CLIENT)をつけると、そのクラスやメソッドはclientSideでしか使えません。
基本的にそんなに気にしなくていいです。レンダラやGUI関係のクラスの先頭につけておくと、エラーが出た時の原因究明がやや楽になるかもしれない、といった感じです。あまり変な所につけるとバグります(経験談)。
- World.isRemoteについて
ブロック、アイテム、エンティティでの処理は、clientSideでもserverSideでも実行されるものがあります。例えばメソッド内であるプログラムを書くと、テストプレイしたときにその処理が2回実行されることがあります。これはclientSideとserverSideの両方で処理されているためです。
これを回避するために、World.isRemoteを使います。clientSideだとtrueを返し、serverSideだとfalseが返されるので、条件分岐を用いることでclientSideとserverSideのどちらか一方で処理されることになります。
よくわからなければ、テストプレイ時にもし同じ処理が同時に2回起きたら、その部分をif(!world.isRemote){}で囲ってしまえばいいと思っておいてください。
私は基本1.7でしかModdingをしないので、もしかしたらほかのバージョンだと違うコードを書く必要があるかもしれないです。おそらく1.12くらいまではほぼ同じ感じで書いておけばいいかと。
ざっくりと言うと、clientSideは描画や音などのインプット/アウトプットに関する処理、serverSideはそれ以外の処理といった感じです。ブロックやエンティティのテクスチャ・レンダラ、GUI・チャット、環境音、キー処理といったものがclientSideで処理されるものの例になります。
マルチ鯖を立てたことがあるなら、clientSideは各々のPCで、serverSideはサーバー機で処理されるというとわかりやすいかもしれません。
で、プログラムコードの話ですが
[spoiler=長いので格納]
[list]
[*][b]プロキシシステムについて[/b]
client側で処理されるようなクラスの多くはserverにはありません。なので、ブロックのレンダーなどをserverSideでも読み込めるようにすると大抵の場合不具合を起こします(クラスがないよっていうエラーが出る)。そのため、プロキシシステムを使ってclient側、server側で処理する項目を分ける必要があります。
具体的なコードについては以下参照。
https://mcmodding.jp/modding/index.php/%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
基本的にブロックやエンティティのレンダラ登録に関することや、"MinecraftForgeClient"・"ClientRegistry"などの"Client"とついているようなものが出たらこっちに書けばいいと思っておけば大丈夫かと。
[*][b]GUIについて[/b]
IGuiHandlerを継承したクラスを用意します。そうするとgetClientGuiElementとgetServerGuiElementというメソッドが出てきます。getClientGuiElementはGUIの描画処理を書いたクラスのインスタンス、getServerGuiElementはGUIの内部処理などを書いたクラスのインスタンスを返します。
例えばgetServerGuiElementで返すクラスには、GUIでのスロットの位置やシフトクリック時のアイテムの移動などの処理を書き、getClientGuiElementで返すクラスにはGUIのテクスチャやGUI内の文字などの処理を書きます。
1.7のGUI関係は以下参照。
https://www.tntmodders.com/tutorial/gui-1710/
[*][b]SideOnlyアノテーションについて[/b]
@SideOnlyを使うと、clientSideまたはserverSideのどちらかでしか使えないようなクラスやメソッドを作ることができます。クラス宣言やメソッド宣言の前に@SideOnly(Side.CLIENT)をつけると、そのクラスやメソッドはclientSideでしか使えません。
基本的にそんなに気にしなくていいです。レンダラやGUI関係のクラスの先頭につけておくと、エラーが出た時の原因究明がやや楽になるかもしれない、といった感じです。あまり変な所につけるとバグります(経験談)。
[*][b]World.isRemoteについて[/b]
ブロック、アイテム、エンティティでの処理は、clientSideでもserverSideでも実行されるものがあります。例えばメソッド内であるプログラムを書くと、テストプレイしたときにその処理が2回実行されることがあります。これはclientSideとserverSideの両方で処理されているためです。
これを回避するために、World.isRemoteを使います。clientSideだとtrueを返し、serverSideだとfalseが返されるので、条件分岐を用いることでclientSideとserverSideのどちらか一方で処理されることになります。
よくわからなければ、テストプレイ時にもし同じ処理が同時に2回起きたら、その部分をif(!world.isRemote){}で囲ってしまえばいいと思っておいてください。
[/list]
私は基本1.7でしかModdingをしないので、もしかしたらほかのバージョンだと違うコードを書く必要があるかもしれないです。おそらく1.12くらいまではほぼ同じ感じで書いておけばいいかと。
[/spoiler]