【修改】在Minecraft中的重要附属概念

上瘾了

当执行world.createExplosion()时,虽然没有显示出现,但碰撞检测的判定仍然存在,这种现象被称为幽灵方块现象。经过一系列的研究,我发现Forge中存在Server和Client两个概念,分别表示程序在不同的一侧执行。我参考了这个参考资料。

关于侧面的类型

大致的认识是,客户端是对玩家产生影响的东西,服务器是在进行多人游戏时连接的东西。

现在让我们解释一下这两个方面的模糊点。

物理服务器

物理服务器通常被称为专用服务器。专用服务器是指像minecraft_server.jar这样的程序的整个类型,它没有可操作的界面。

物理客户端

物理客户端是指从启动器启动Minecraft的整个程序。负责游戏渲染、屏幕操作等的所有线程、进程和服务都可视为物理客户端的一部分。

逻辑服务器

逻辑服务器负责游戏的统筹工作。包括怪物的生成、天气系统、背包的更新、怪物的智能等,承担着游戏的所有机制。逻辑服务器存在于物理服务器内,但在单人游戏时可以与物理客户端一起执行,称为“Server Thread”。

逻辑客户

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

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

世界是远程的。

(Note: The translation provided assumes that “world.isRemote” refers to a Boolean value indicating whether the world is remote or not)

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

    • あるブロックに触れている間は、ずっとダメージを受け続ける

 

    ある機械に土を入れると、それをダイヤモンドに変える

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

获取有效的侧面

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

解决问题

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

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

如果那样做的话,苦恼于碰撞判定和虚拟实体的Modder应该尝试一次只在逻辑服务器或逻辑客户端上执行,这样就可以变得幸福了。

bannerAds