欢迎光临散文网 会员登陆 & 注册

Seed Finding by Java [1] 介绍与示例

2023-07-07 11:31 作者:Xinyuiiiiiii  | 我要投稿

一、筛种库介绍:

筛种库列表

如果你按照上期专栏做好了IDEA的准备工作,那么你会知道你导入了如图的几个库,我将一一介绍它们并且附上Github链接

mc_math:https://github.com/SeedFinding/mc_math_java

       从名称我们可以知道,这是个和数学有关的库。它的作用有世界生成、种子查找和种子破解

mc_seed:https://github.com/SeedFinding/mc_seed_java

        这个库用于LCG(代表线性同余生成器,Linear Congruential Generator)和种子查找,LCG是一种伪随机数生成算法,用于生成看似随机但实际上是基于某个初始种子值的序列,它确定了世界生成的方式,也就是为什么使用相同的种子,可以确保生成相同的世界

mc_core:https://github.com/SeedFinding/mc_core_java

        用于以纯Java存储所有Minecraft实用程序和数据(用作核心库),作用过多,不一一介绍

mc_terrain:https://github.com/SeedFinding/mc_terrain_java

        一个用纯Java模拟Minecraft地形的非常简单的库,目前仅支持1.14+,用于地形方面的处理,比如判断一个废门是否在地底,得到某个具体坐标是什么方块等

mc_biome:https://github.com/SeedFinding/mc_biome_java

        这个库旨在方便地访问Minecraft的不同生物群系,它不是Minecraft源代码的直接副本,因为它是在考虑优化的情况下从头开始重写的,目前仅支持到1.16.5(不含快照版本),它的作用有判断一个结构能否生成、得到某个坐标具体是什么群系等

mc_feature:https://github.com/SeedFinding/mc_feature_java

        一个提供结构以及它们的生成和各自战利品的库,还提供了一些实用功能,如获取出生点的坐标等

mc_reversal:https://github.com/SeedFinding/mc_reversal_java

        一个用于在纯Java中反转所有Minecraft内部random函数的库,比如你在某个区块进行了随机数处理,根据结果可以反转出原来的种子等(或许,我也不常用)

seed-checker:https://github.com/jellejurre/seed-checker

        一个几乎万能的库,因为它会生成整个世界,你可以得到某个具体坐标的方块甚至它的状态(例如传送门方块是否填充末影之眼),以及加载某个特定范围内的所有箱子等,但是因为它是加载整个世界,所以会很慢

VillageGenerator:https://github.com/profotoce59/VillageGenerator

        这个库可以代替mc_feature中未完成(有bug)的VillageGenerator,模拟村庄的生成,在1.14-1.17版本支持得到房屋的位置,1.16和1.17两个版本支持战利品

二、递增筛种与结构生成知识


新建软件包

首先在src-main-java中新建一个软件包,你可以把它命名为自己的名字(比如我命名为XinyuQi)

新建Java类

在新建的软件包中新建一个类(我把它叫做test,你可以把它叫做example等等)

接下来我先介绍第一种筛种方式,递增筛种.什么意思呢,说已知Minecraft中有2的64次方个种子,也就是18,446,744,073,709,551,616个,即-9223372036854775808~9223372036854775807.那么我们只需要用for循环递增即可,如图 

递增


在本专栏中,将用递增筛种做一些项目示范,后面的专栏会介绍剩下两种(随机筛和通过文本文件来筛)

初始化设置.1

首先在图中所示位置输入psvm四个字符,再按Tab键,就会弹出如图所示的main方法

初始化设置.2

接下来,按照前文介绍的递增筛种的设置方法,声明seed_start和seed_end变量(long是一种数据类型,需要在后面加L),再创建ChunkRand对象,命名为rand(名称随意),这是一个Minecraft随机数的对象,它可以用来在确定某个结构的位置(能否生成还要再由群系决定)等

初始化设置.3

long seed_start = -9223372036854775808L;
long seed_end = 9223372036853775807L;
ChunkRand rand = new ChunkRand();
for (long seed = seed_start;seed <= seed_end;seed++) {

}

复制上去后ChunkRand或许会显示红色,只需要指针对着它按Alt+Tab导入即可

在开始示范之前,我要先讲一些和结构生成有关的知识.在Minecraft结构生成中,世界被分割成一系列的区域(region),所有结构(除了宝藏、要塞、矿井)都有相应的区域大小,在每个区域中只会有一个结构的生成点,它由前文说的ChunkRand随机决定,当然这仅仅是生成点,举个例子,某个种子中64,64是沙漠神殿在region(0,0)的生成点,但是因为不是沙漠群系,因此无法生成.我用众所周知的猪堡(以下称bastion)来具体的说明一下

BastionRegion

如图所示,bastion的每个region大小都是432*432个方块,也就是27个区块,但它只能在图中绿色的区域中生成,红色的区域不能生成,比如++象限中它只可以在(0,0)区块至(23,23)区块中选取生成点.

一般来说,我们只需要得到原点附近四个region中的结构就可以满足我们的需求.region(0,0)是++象限(图中右下角),region(-1,0)是-+象限(图中左下角),region(-1,-1)是--象限(图中左上角),region(0,-1)是+-象限(图中右上角).这四个region便是我们一般情况下会用到的,它会在马上到来的示例的getInRegion方法中体现

三、项目示范

spawn

先讲如何获取出生点.创建一个void类型的spawn(名称随意)方法,然后在for循环中调用它,输入参数seed和rand.它的原理是出生点是由群系和地形决定的,所以先加载主世界的生物群系(OverworldBiomeSource),再加载主世界地形(OverworldTerrainGenerator),之后再创建SpawnPoint对象,用getSpawnPoint方法得到出生点,它是BPos类型的,即Block Position(方块坐标).这是基于mc_feature获取出生点的方法,可能会有几格误差(这个误差并不是游戏中离出生点的那几格偏差,而是因为它并不能像seed-checker一样加载整个世界,所以有一些信息不完全,也就是说是这个方法产生的偏差),但是并不大.但它速度很慢(seed-checker更慢),所以一般放到最后处理,比如找到了符合要求的结构,判断它是否在离出生点满意的范围内.

village.1

然后是村庄,创建一个void类型的village(名称随意)方法,然后在for循环里调用它,输入参数seed和rand

village.2

(村庄的region大小是上图bastion432换为512,368换为384)

首先,将世界种子换成结构种子,因为getInRegion方法中需要结构种子.用getInRegion方法得到region(0,0),也就是++象限中离原点最近的村庄的生成点(这里为了方便,只需要++象限的村庄),它是CPos类型,即ChunkPosition(区块坐标),然后用if判断它是否为null,是null则return,检查下一个种子.再加载主世界生物群系,用canSpawn方法检查这个生成点能否生成村庄,如果不能,则检查下一个种子.然后再创建VillageGenerator对象(它需要主世界地形,即OverworldTerrainGenerator,所以也要创建),用generate方法生成这个村庄,再用generateLoot方法加载所有箱子的BPos(方块坐标)以及所包含的Item(物品),存储为chests.用for循环遍历chests列表,也就是说遍历每一个箱子,由于每个箱子的信息都是坐标+物品,所以用getSecond得到物品.然后如果箱子中有黑曜石,就把赋值为0的obsidian变量加上黑曜石的数量,最后判断黑曜石的数量,这里我就看它是否大于10了,如果是,则打印种子和村庄的方块位置(它是CPos,所以用toBlockPos方法)以及黑曜石的数量.

运行

在空白处右键,运行Test.main

运行中

我们可以看见,它在控制它打印了一些种子,我们可以在游戏里查看

停止

如果想停止运行,可以点图中的红色正方形

我们进游戏查看第一个找到的种子-9223372036854775723

村庄图

它有三个铁匠铺

所有战利品

如图,三个铁匠铺的所有战利品,确实有11个黑曜石,good!


出生点和村庄已经被你拿下了,如果想继续拿下更多东西,还请继续支持我的专栏!

所有代码都上传到了github,可以自行复制等

https://github.com/Xinyuuu7/Example

感谢支持!!!

Seed Finding by Java [1] 介绍与示例的评论 (共 条)

分享到微博请遵守国家法律