Help us understand the problem. What is going on with this article?

【Modding】Minecraftで重要なSideの概念

はまったこと

world.createExplosion()を実行したときに、表示されていないが当たり判定だけが残っている、いわゆるゴーストブロック現象が発生してしまった。いろいろ調べたところ、ServerClientという、サイドの概念がForgeには存在しているらしい。で、それぞれのサイドでプログラムが実行されていることが分かった。こちらのリファレンスを参考にした。

サイドの種類について

大体の認識だと、クライアントというものはプレーヤーに影響するもので、サーバーというものはマルチプレイをするときに接続するものだという認識だろう。

さてここで、この二つのサイドのあいまいな点を解説していこう。

物理サーバー

物理サーバーというのは、よくdedicated server(専用サーバー)といわれるものだ。専用サーバーはminecraft_server.jarのような種類のプログラム全体のことで、操作できる画面を持たない。

物理クライアント

物理クライアントというのは、Minecraftをランチャーから起動するプログラム全体のことだ。ゲームの描画や画面操作などを担っているすべてのスレッドやプロセス、そしてサービスは物理クライアントの一部だといえる。

論理サーバー

論理サーバーはゲームの統括をする。モブのスポーン、天候、インベントリの更新、モブの知能など、ゲームの仕組みすべてを担っている。論理サーバーは物理サーバーの中にあるものだが、シングルプレイのときは物理クライアントの中で論理クライアントと一緒に実行することができる。これはServer Threadという名前で実行される。

論理クライアント

論理クライアントはプレーヤーからの入力を受け取って、それを論理サーバーに送信する役目を持っている。加えて論理クライアントは論理サーバーから情報を受け取り、その情報をプレーヤーが見えるように画面に表示する。これは、Client Threadという名前で実行される。

サイドに合わせたプログラムの実行

world.isRemote

この真偽値はどちらのサイドでプログラムが実行されているかを調べるものである。この真偽値で調べられるのは、論理サーバーか論理クライアントかどうかだ。論理クライアントだったらtrueを返し、論理サーバーだったらfalseを返す。これは、物理サーバーでは常にfalseを返すため、物理クライアントの論理サーバーと値が被っている。原則、それが物理サーバーか論理サーバーか、この値からではわからない。
この真偽値の使いどころは、ゲームのルールやそのほかの仕組みを実行したいときである。例えば、

  • あるブロックに触れている間は、ずっとダメージを受け続ける
  • ある機械に土を入れると、それをダイヤモンドに変える

などである。これらはworld.isRemoteの値がfalseの時に実行するべきだ。これらを論理クライアントで実行してしまうと、論理サーバーとの整合性が取れなくなり、軽いバグの場合、モブのゴースト現象や体力の不一致などが発生する。重いバグの場合はゲームがクラッシュしてしまうこともある。

getEffectiveSide

FMLCommonHandler.getEffectiveSide()は何らかの理由によって、world.isRemoteが使えない時に使われる。これはどっちのサイドかを、推測する。なぜ推測かというと、これはスレッドの名前(Server ThreadもしくはClient Thread)から、どちらのサイドかを判断するからだ。worldが使用可能の時は、できるだけworld.isRemoteを使うようにして、これはその方法が使えないときの代替手段として使うべきだ。

解決

なるほど、どうやらワールドのブロックなどの管理をしているのは論理サーバーらしいから、論理クライアントと論理サーバーでworld.createExplosion()を実行してしまうと、サーバーにあるブロック情報とクライアントにあるブロック情報が食い違ってしまうから、ゴーストブロック現象が起こるらしい。爆発で破壊するブロックはランダムで決めているから、クライアントでは破壊したことになっているブロックもサーバーでは爆発を免れているかもしれない。ここで、存在しないブロックに対する当たり判定が発生していたのだ。よって、この問題の解決方法は、

if (!world.isRemote)
    world.createExplosion(...);

となる。当たり判定やゴーストエンティティで悩んでいるModderは論理サーバーのみ、論理クライアントのみでの実行を一回試してみたら幸せになれるだろう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした