moddingのclientとserverについて

Modやプラグインの制作/開発に関する質問はこちらへどうぞ。
アバター
KNSN92
ID: 3W0XZA6GOT
記事: 2
登録日時: 2022年1月10日(月) 18:05
お住まい: 兵庫県
Minecraft ID: kenpasomai
連絡する:

moddingのclientとserverについて

投稿記事 by KNSN92 » 2022年1月11日(火) 19:33

はじめまして。
modding初心者なのですが、いろいろなサイトを見ても、clientSideとserverSideの概念がいまいち分かりません。
また、結局どのようにコードを書いて行けばいいのかを
わかりやすく教えてもらえないでしょうか。
0



アバター
おがさくら
ID: 2B6LCHA53W
記事: 9
登録日時: 2021年10月06日(水) 20:18
お住まい: あいち
Minecraft ID: ogasakura
いいねされた回数: 2回
連絡する:

Re: moddingのclientとserverについて

投稿記事 by おがさくら » 2022年1月12日(水) 08:10

ざっくりと言うと、clientSideは描画や音などのインプット/アウトプットに関する処理、serverSideはそれ以外の処理といった感じです。ブロックやエンティティのテクスチャ・レンダラ、GUI・チャット、環境音、キー処理といったものがclientSideで処理されるものの例になります。
マルチ鯖を立てたことがあるなら、clientSideは各々のPCで、serverSideはサーバー機で処理されるというとわかりやすいかもしれません。

で、プログラムコードの話ですが
長いので格納
Show
  • プロキシシステムについて
    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くらいまではほぼ同じ感じで書いておけばいいかと。
0
桜と月をこよなく愛する自称プログラマ&イラストレータ
1.2.5&1.7.10マイクラModder・クラフター
Twitterで進捗をたまにつぶやいてる

連絡はTwitterかDiscordのDMもしくはフォーラムのPMまで
Modを使うときはこれを読んでください↓
https://docs.google.com/document/d/18oV ... sp=sharing

アバター
KNSN92
ID: 169XKNO1D9
記事: 2
登録日時: 2022年1月10日(月) 18:05
お住まい: 兵庫県
Minecraft ID: kenpasomai
連絡する:

Re: moddingのclientとserverについて

投稿記事 by KNSN92 » 2022年1月12日(水) 17:48

おがさくら さんが書きました: 2022年1月12日(水) 08:10 ざっくりと言うと、clientSideは描画や音などのインプット/アウトプットに関する処理、serverSideはそれ以外の処理といった感じです。ブロックやエンティティのテクスチャ・レンダラ、GUI・チャット、環境音、キー処理といったものがclientSideで処理されるものの例になります。
マルチ鯖を立てたことがあるなら、clientSideは各々のPCで、serverSideはサーバー機で処理されるというとわかりやすいかもしれません。

で、プログラムコードの話ですが
長いので格納
Show
  • プロキシシステムについて
    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くらいまではほぼ同じ感じで書いておけばいいかと。
ありがとうございます。
この説明も参考にして、頑張ります。
0

返信する