我的世界路径是什么?
在Java版本(1.8及以上)中,游戏使用的是Lua脚本进行逻辑判断和指令下发,而Lua脚本的加载是依赖于数据文件来进行的。也就是说在游戏中实际上存在着多个数据文件,每个数据文件都包含着一个独立的游戏世界。这些文件之间通常以路径的方式相互连接着,以此来实现整个游戏世界中各种实体的相关数据(生物、物品、结构等等)。
例如,在我的世界java版客户端中,数据文件一般存在以下位置: 可以看到,我安装我的世界的时候按照惯例把游戏放在了D盘的“我的文档”里,所以数据文件也就自然在这个目录下。不过这里需要说明的是,因为游戏运行是需要导入Jar包的,所以这些数据文件其实是在Mojang的官方服务器上。
每一个世界都有一个独立的Data文件夹,里面的路径就是该世界的地图加载路径。例如我在上面图中所截下的那个世界就有两个Data文件夹,即意味着我有两个不同的世界。如果我把其中一个世界删除的话,那么该世界的所有路径都会消失,删除以后重新创造的世界又会赋予一个新的ID,这样就能实现不同世界之间的分割了。当然,如果我把一个已经存在的数据文件复制到另一个世界中,则这两个世界的内容就一致了,这样做可以方便测试新加的代码对某个具体世界的影响。
以上说的都只是Java版本的,对于基岩版本(1.15及之前)来说,游戏的数据结构和Java版本是完全不同的,数据文件也并没有按照世界划分,而是全部整合在一起。要讲清楚这一点得讲很多内容,而且没个说清这些东西都需要很多代码来进行解释,所以我就在这里简单讲讲。
首先,在基岩版本中,游戏的加载机制是通过主程序不断读取数据区块来实现的,而在每一次加载新数据区块的时候,都会尝试加载对应数据区块的Lua脚本,如果有相应的脚本就会执行其中的命令,这样就可以通过命令来实现各种游戏行为。
其次,虽然基岩版本没有像Java版本那样按世界划分数据,但是它的数据还是有着非常清晰的层次结构的(从加载顺序来看,数据首先被载入到Chunk中,然后每个Chunk又被载入到Block中,最后再根据玩家的操作以及时间的流逝来加载不同的事件数据),并且可以在任意两个层级之间自由跳转。另外值得一提的是,在基岩版本中,事件这一概念发生了变化,不再是按时间序列来执行一系列已加载的Lua脚本,而是允许同时加载多个Lua脚本来执行,而且它们之间互不干扰,就像是一个个并发执行的线程一样。
由于基岩版本的数据加载机制比较复杂,而且相关的代码也很不好理解,因此我就也没有深入去研究过。不过我发现了这个加载机制的一个小漏洞,即在某一帧时间内(一帧时间为0.1秒,可调),如果向主程序发出多次加载数据的请求,那么最终只会执行一次加载完成的Lua脚本来实现所有请求的操作。利用这个特性,我可以实现让玩家连续跳帧的功能,虽然效率很低,每60帧(一帧持续时间)只能跳2帧。