# Dark Forest 出生点和地图随机性

By [EliteMetaverse](https://paragraph.com/@elitemetaverse) · 2021-12-06

---

**Dark Forest 游戏的乐趣很大程度上来源于随机性，游戏中内建的随机主要来源于以下几方面**

*   玩家的出生点
    
*   游戏内地图的随机分布
    
*   多个玩家间的不可预知互动
    
*   不同效果神器的随机开出
    

上一篇文章中，我们讨论了[神器挖掘随机性被玩家攻破的例子](https://mirror.xyz/elitemetaverse.eth/4GM-DrXTLZcnzUr4rA4BqRdVLVzPBw9aS0zqp_IRnI4)，这一次我们再来讨论前面两个随机性：玩家出生点、游戏内地图的随机分布这两个问题，在Dark ForestV0.6R3 以前的版本中，这两个随机性也是能够被玩家攻破的，并且在游戏初期能够为玩家创造优势。

1、地图随机性
-------

玩家[phated](https://twitter.com/BlaineBublitz)公布了一个可以提前探索地图，并在游戏开始时自由选择出生点的方法，并提供了一个[提前探索地图的网站](https://explore.projectsophon.com/)。通过这种方法，玩家在游戏中取得了一些[先发优势](https://discord.com/channels/793602508311232542/793605193056256020/858375082304471070)，这种优势对于游戏整体性的影响还有待评估。

既然游戏中的地图可以被提前探索，出生点可以被选择，那么肯定，还是随机性出现了问题，从游戏代码中，我们能够找到问题出在哪儿了。

Dark Forest游戏中最有魅力的地方，我想就在于战争迷雾（Fog of War）,虽然战争迷雾并不是一个新概念，但是Dark Forest用Zero-Knowledge 的方式将战争迷雾和区块链结合起来，将这两个性质相反（隐藏与公开）的东西结合到一起，才造就了Dark Forest无与伦比的独特魅力。

由于Dark Forest是一个Cryto-Native 游戏，所有的数据和操作全部存储在链上，这也就意味着所有的星球坐标和玩家的操作都能够在链上查询到，但是这样就变成了一个全信息对称的游戏，失去了很多趣味，因此Dark Forest并没有直接在链上存储星球坐标，而是存储了星球坐标的hash值，可以认为Dark Forest通过hash计算的方式对星球坐标进行了加密。

由于链上存储的星球坐标是通过hash加密的，那么当一个新玩家进入游戏时，除了自己的home plant之外无法查询到任何星球的坐标(其他区域均被战争迷雾所掩盖)，因此玩家需要通过不断的进行hash计算来对宇宙进行探索，其基本原理是玩家在client上对宇宙中的每一个坐标值(x,y)进行hash计算，并得出一个hash值，当这个hash值小于某个特定值时，则代表该坐标处存在星球， Dark Forest中对hash值的判断代码如下：

    hash.lesser(LOCATION_ID_UB.divide(planetRarityBI))
    

其中LOCATION\_ID\_UB为一个定值，目前合约中LOCATION\_ID\_UB=“21888242871839275222246405745257275088548364400416034343698204186575808495617”

planetRarityBI是一个在合约部署时可调节的值，通过调节该值的大小，可以改变宇宙中星球出现的密度，例如在V0.6R2中，该值为16384，我们可以在控制台输入df.planetRarity来获取这个值，由于hash函数可以看作一个随机预言机(即hash函数生成的数值是均匀分布的)，

那么我们可以计算出当hash值小于以下这个数时，表明这个坐标点存在一颗星球：0000c19139cb84c680a6e14116da06056174a0cfa121e6e5c2450f87d64fc000

因为前面有4个0，因此单个坐标出现星球的概率大约是十的4次方之一，也就是万分之一，对于一个半径为3万的圆形宇宙，其面积为π\*r²，再除以出现星球的概率，其中大约会出现28万颗星球。

确定哪些位置存在星球后，下一步需要确定星球的类型和等级，Dark Forest采用了Perlin函数来生成不同的空间和生物类型，Perlin函数的输入主要有两个，一个是坐标(x,y)，另外一个是key值，包括SPACETYPE\_KEY(用于空间类型生成)和BIOMEBASE\_KEY(用于生物类型生成)，通过下列代码，可以计算出一个星球的Perlin数：

    perlin: perlin({x, y }, spaceTypePerlinOpts),
    biomebase: perlin({ x, y }, biomebasePerlinOpts),
    

通过Perlin数再得出星球的类型和等级：

    planetLevelFromHexPerlin(hex: LocationId, perlin: number)
    planetTypeFromHexPerlin(hex: LocationId, perlin: number)
    

从上述分析我们可以知道，知道了星球坐标和Perlin函数的Key之后，就能得出星球的类型和等级，因此影响整个地图随机性分布的，就只有df.planetRarity和两个Key值，知道了这几个值后，整个宇宙的地图就能够计算出来，因此只要合约部署后能查到这几个值，玩家就能够通过自己架设的服务器来进行地图探索，这也是[phated](https://twitter.com/BlaineBublitz)能够进行提前探索的原因。现在的版本中，合约部署后会重新设置这几个值，因此，也就无法提前进行探索了。

2、出生点随机性
--------

这个问题相对简单一点，选择出生点星球的代码如下：

    planetPerlin < initPerlinMax && 
    planetPerlin >= initPerlinMin && 
    distFromOrigin < this.worldRadius && 
    distFromOrigin > spawnInnerRadius && 
    planetLevel === MIN_PLANET_LEVEL && 
    planetType === PlanetType.PLANET && 
    (!planet || !planet.isInContract) 
    

可以看到出生点星球需要满足几个条件，首先星球的Perlin值需要在一定范围内，另外星球的距离宇宙中心的半径需要在当前宇宙半径和内层宇宙半径之间(保护新进入的玩家，避免进入内圈)，Dark Forest会边开图边搜索符合要求的星球，找到之后就将其设置为玩家的HomePlant。

从上述代码来看，玩家的出生点是无法自由指定的，但是Dark Forest的代码中留了一个接口：

    /* when setting up a new account in development mode, you can tell the game where to start searching for planets using this query string parameter. for example: */
    // 
    // ?searchCenter=2866,5627 
    // 
    const params = new URLSearchParams(window.location.search); 
    if (params.has('searchCenter')) { 
        const parts = params.get('searchCenter')?.split(','); 
        if (parts) { 
            x = parseInt(parts[0], 10); 
            y = parseInt(parts[1], 10); 
            } 
    }
    

也就是说玩家可以指定一个坐标值，让Dark Forest从指定的坐标值开始搜索符合要求的HomePlant，这就是指定出生点的方法~尚不知道这部分代码在新版本中是否会被移除。

3、关于出生点和地图的思考
-------------

随着Dark Forest进行到V0.6R4，慢慢的大家对Dark Forest的游戏模式也有了更多的思考，通常来讲，Dark Forest的游戏时间是一周左右，最近一轮的闪电战将时间缩短到了4天。但总体而言每一轮的游戏时间还是要比通常意义上的竞技游戏要长，而作为建设营造类游戏时间又太短，如果仅保持当前的状态，作为一款分期打榜的竞技游戏存在也是可行的，但是总感觉缺少了点什么。

后续游戏模式的发展不外乎两个方向，第一个是向竞技游戏发展，修改游戏参数，使得对抗性更强，游戏节奏更快。但是这样做会产生几个问题：

*   目前已经有非常成熟的竞技游戏，Dark Forest的游戏模式有一定创新，但也仅此而已，发挥不出Dark Forest的独特魅力
    
*   作为竞技游戏，参加游戏的人数不会太多，否则无法对选手进行筛选、分层级举行比赛
    
*   Dark Forest的地图随机性太强，很难构建一个较为公平的竞技环境
    

第二个方向也就是将Dark Forest建设为一个环境更宏大、内容更丰富、周期更长的链上多人策略游戏，游戏中有激烈的争夺战也有无人打扰的自由发展，有探索不尽的宇宙和星球，有历尽艰险的远征，有宇宙间的寻宝人，有繁华的宇宙都市，有隐秘而不为人知的秘密组织和基地。

目前Dark Forest的地图和宇宙是二维的，仿佛被二向箔拍扁了一般，狭窄、憋闷，按照目前的星球密度，半径3万的宇宙间，有28万颗星球，但是除去低级星球，可供发展的区域并不多，经过一段时间的发展，很快就会充满。虽然通过扩展半径可以增加宇宙的面积，但是仍然非常有限，并且平铺的宇宙移动起来很不方便。更大的问题是，在目前GPU开图百万Hash的算力下，宇宙很快会变得没有秘密可言，也就失去了Dark Forest最大的魅力。

如果我们把Dark Forest的地图增加一维会怎么样，星球坐标由（x,y,z）构成，z表示垂向坐标，其他的机制都不需要更改，我们就拥有了一个更为广阔的宇宙，目前宇宙中单个坐标出现星球的概率是万分之一，在保证二维叠加显示时不会有太多星球重合的情形下，z向分层可以达到1万，那么半径3万的宇宙，将会有28亿颗星球，半径为20万的宇宙，将会有1256亿颗星球，几乎与银河系星球数量相当，而且让通过Hash计算探明全部宇宙变得不可能。由于Dark Forest并不会在游戏开始时把宇宙内所有的星球全部存到链上，只有那些被占领的星球才会产生链上数据，而其他的星球仿佛不存在一样，静静的等待探索者去发现，只有去到了哪里，才会在出现在链上，因此链上数据存储相比于现在并不会有太大变化。

回想刚进入Dark Forest的那一刻，最吸引人的是什么？难道不是一步步解开宇宙的面纱，发现一颗高等级星球，一步步规划自己帝国的发展路径吗？

在这个更为宽广的宇宙中，有了更多的可行性，工会可以划定自己的发展范围，可以在宇宙中指定竞技场，可以为未来的神器、建设提供场地，有太多太多可以去构想。。。

彩蛋：文章封图为[@alanw\_luo](https://twitter.com/alanw_luo)的作品，也是Dark Forest中神器的原型。

By:[EliteMetaverse.eth](https://twitter.com/amolisi_)

![](https://storage.googleapis.com/papyrus_images/84b3f1a0781c3262e16326ba62c0ba8df8480d3dd4857a24b9cb6c8d02bb47e2.jpg)

---

*Originally published on [EliteMetaverse](https://paragraph.com/@elitemetaverse/dark-forest-2)*
