Skip to content

随机数机制

这一页解释三个问题:种子串如何决定一局游戏,哪些内容会消耗地牢全局随机序列,以及每场战斗的起手手牌怎么抽出来。

先看结论游戏里同时存在地牢全局随机和战斗内随机。读档后尚未保存、并且依赖地牢全局随机序列的技能或事件会重新抽;如果战斗被重新创建,战斗内随机也会重新初始化,所以起手手牌可能变化。

1. 种子串和创建游戏

种子串是用来复现开局的可读文本。它不是单纯的一个随机数字,而是把这局游戏的关键初始条件打包在一起:职业、难度、账号解锁状态快照、初始随机种子,以及后续用来生成楼层和升级奖励的种子状态。

显示给玩家时,种子串会按 5 个字符一组加短横;输入时短横和空格只是排版,会被去掉。真正参与解码的是清理后的固定长度字符。

随机序列什么时候生成影响什么
初始随机种子创建新局时先生成;用种子串开局时则从种子串还原。决定这局游戏后续可复现的起点。
第 1 / 2 / 3 层楼层种子创建新局时从初始随机流程继续取出;用种子串开局时按同一规则还原。每层地图、墙、怪物、Boss、奖励建筑和地牢对象的位置。
升级奖励种子创建新局时单独保存;它和楼层生成分开。升级奖励这类流程不会被楼层生成完全吞掉随机进度。
地牢全局随机序列会被楼层生成临时设到指定种子,也会被部分地牢行动继续消耗;存档保存种子字段,但不保存这条序列的完整当前位置。地图生成、奖励放置、怪物选择、变形术的新怪物等。
战斗内随机序列当前战斗对象自己持有,用于战斗过程中的随机;如果没有显式设置战斗种子,首次使用时会创建新的运行时随机状态。战斗洗牌、起手手牌、随机弃牌、怪物随机行动等。

楼层生成是最容易误解的部分:进入某一层时,游戏会临时切到这一层自己的楼层种子,把地图和该层内容生成出来;生成完成后,再切到另一个继续用的随机状态。这样同一个种子串可以稳定复现楼层结构,但之后某些地牢行动仍然取决于这条全局随机序列后来被消耗到了哪里。

哪些行为互不影响

判断原则很简单:同一条随机序列会互相推进;不同种子或不同随机对象之间不会互相推进。结果如果已经生成并写进地牢状态,后面的随机也不会再改它。

行为不会影响什么原因
当前楼层的移动、战斗、开宝箱路线不会改变第 1 / 2 / 3 层已经由楼层种子决定的地图结构、墙、基础怪物和 Boss 生成。每层生成时会切到该层自己的楼层种子;楼层种子在创建游戏时已经确定。
楼层生成消耗了大量随机不会把升级奖励的随机进度吞掉。升级奖励有单独保存的种子,和楼层生成分开。
战斗内洗牌、起手手牌、随机弃牌、随机放逐不会推进地牢全局随机序列,也不会直接改变宝箱、商店、变形术、寻宝等地牢随机结果。这些通常使用当前战斗对象或牌组自己的随机状态;但如果强退后重新创建战斗,这条战斗内随机本身可能重新初始化。
已经打开并保存的宝箱、商店、建筑候选或事件偏好不会被后续 Polymorph、Find Treasure、战斗随机或其他行动重新改写。结果已经成为地牢状态;之后只是在读取已有结果。
玩家手动选择的结果不会消耗随机序列。例如 Mushroom Patch 完成后复制自己选定的牌、删除牌、升级指定牌。这些是玩家选择,不是随机抽取。

互不影响只表示“不会推进同一条随机流”,不表示每个结果都会在强退重开后固定。起手手牌就是典型例子:它不消耗地牢全局随机,但战斗对象重新创建后,自己的战斗内随机状态可能不是原来的状态。

反过来,只要两个行为都还没有保存结果,并且都依赖地牢全局随机序列,它们就会互相影响先后顺序。例如先用 Polymorph、先触发 Find Treasure、先生成商店商品、先结算 Brain Sucker 奖励或绿色 Mushroom 效果,都会把同一条全局随机序列往后推进,导致后面的全局随机结果变化。

2. 哪些会消耗地牢全局随机序列

不是所有“随机”都会动到这条全局序列。卡牌战斗内的随机弃牌、随机伤害、部分职业技能随机,通常走当前战斗对象自己的随机状态;但下面这些会直接或间接消耗全局随机序列。

读档时怎么判断先看结果是否已经写进存档或当前地牢状态;已经保存就直接沿用结果。没有保存时,再看它是否依赖地牢全局随机序列。依赖全局随机的技能或事件,会在读档后按重建出的固定位置重新抽;反复读取同一个档并重复同样操作,结果也会固定。
范围会消耗什么读档时怎么看
楼层生成地图造墙遍历顺序、每格是否变墙、怪物等级表、怪物是否出现、怪物类型、怪物环境、Boss 属性、建筑和奖励位置。创建楼层时会临时切到该层楼层种子;同一种子楼层稳定,但会大量推进全局序列。
奖励与卡池奖励层级、随机奖励名、卡牌奖励加权选择、生成奖励后对可出现次数的扣减。宝箱、升级、商店、地牢奖励、Find Treasure、Brain Sucker 奖励只要重新计算,就会受当前全局位置影响。
金币与商店金币目标值的上下浮动、商店预算、商店商品选择、商店商品最终顺序。进入商店或生成商品前强退,读档后可能重新走固定但不同的位置。
宝箱物品数量、后续奖励是金币还是卡牌、卡牌奖励选择、金币数值、最终展示顺序。如果宝箱结果已经保存就固定;如果只是看过但没保存,读档后会重算。
怪物创建普通怪物选择、Boss 选择、变形术的新怪物、德鲁伊 Wild Shape 变怪、Find Monster 创建怪物时的实际怪物选择。这是变形术读档变化的主要来源。
地牢建筑与事件Brain Sucker 的偏好生成和奖励换牌、Tavern 的歌曲候选、Mushroom Patch 任务期间绿色蘑菇的效果。建筑本身已经保存时,已生成的偏好、候选或蘑菇效果不会重抽;但尚未结算的随机分支会按读档后的固定位置继续抽。
卡牌生成类效果从全卡池随机拿非装备卡或装备卡,例如 Wild Mana、Wild Strike,以及龙的 Hoard 这类随机装备来源。这些效果虽然发生在卡牌、天赋或职业机制里,但会推进全局随机序列。
AI 随机选择AI 的随机行动、同优先级动作打平、随机目标、随机目标组顺序。代码静态上确认走全局序列;具体战斗读档边界还要看当时战斗状态是否已经保存。
通用洗牌工具地图候选格、奖励列表、商店商品、部分候选列表的洗牌。它本身也会反复调用全局整数随机,所以列表长度越长,推进越多。

下面这些是玩家最容易主动触发、也最容易误判为“只和当前操作有关”的入口。

入口会消耗的随机读档时怎么看
Polymorph / 变形术按目标怪物等级、环境和排除列表重新加权选择怪物。如果变形结果没保存,强退后会从读档重建的位置重新抽。
Find Treasure先抽金币目标的正态波动,再进入奖励生成;后续可能继续抽奖励类型、卡牌、金币和展示顺序。它不是只生成一个固定宝箱,而是接到完整奖励链。
Find Monster先用当前游戏对象的随机状态选一个可用邻格;真正创建怪物时再走地牢怪物选择链。选格和选怪物不是同一条随机来源,改变前置操作可能影响后续怪物。
Brain Sucker / Brainsucker生成建筑偏好时会抽喜欢/讨厌条件;交牌结算为正奖励时会进入卡牌奖励选择。已经保存的偏好固定;尚未领取的奖励卡仍可能受全局序列位置影响。
Tavern从可用歌曲列表里随机挑 3 首候选歌。如果酒馆候选已保存就固定;如果入口状态重建后才生成,会按读档后的序列抽。
Mushroom Patch任务期间的绿色蘑菇会从默认效果池中随机效果;完成任务后的牌组处理是从自己牌组选择 1 张并复制。完成奖励不是随机抽卡;读档判断主要看绿色蘑菇效果是否已经生成或结算。
Treasure Chest / Shop宝箱物品数、卡牌/金币分支、商店 1/3/5 阶商品、去重重抽和最终洗牌。打开或进入前是否已保存,决定读档后是沿用结果还是重算。
Wild Mana / Wild Strike / 龙的 Hoard分别从非装备牌池或装备牌池随机取牌。这些虽然看起来像战斗、天赋或职业效果,但底层接到全局卡牌奖励选择。

反过来,Three Wishes、Chaos Strike、Chaos Prayer、Desperate Prayer、Elemental Surge、Summon Companions、随机弃牌、随机放逐、普通战斗洗牌这类战斗内效果,当前解析结果显示主要走战斗内随机序列或牌组自己的战斗随机,不应简单归到地牢全局随机序列里。它们不会推进宝箱、商店、变形术这些地牢全局随机,但如果战斗本身被重新创建,战斗内随机的初始状态仍可能变化。

3. 每场战斗的起手手牌

这里说的起手手牌,指每场战斗开始后玩家拿到的第一批手牌。它不是从牌组里直接随机挑几张,而是先建立战斗牌库,再按洗牌后的牌库顺序抽牌。

步骤规则随机来源
建立战斗牌库职业初始牌组、当前牌组、装备、天赋、状态和怪物/职业特殊机制先决定这场战斗可抽的牌。这一步主要是按当前角色状态组装牌库。
洗牌牌库从当前抽牌位置到牌库末尾逐位随机交换:每一步都在“当前位置到末尾”之间挑一张牌,和当前位置交换。使用当前战斗对象持有的 InGame 随机状态;如果没有显式战斗种子,会首次创建新的运行时随机状态。
决定抽牌数基础目标是最大手牌数减去当前手牌数;再叠加手牌上限、天赋、装备、状态或职业机制带来的额外抽牌修正。抽几张主要由当前角色属性和效果决定。
抽到手牌按洗好的牌库顺序抽牌进入手牌。后续普通抽牌继续沿用这副牌库的顺序。只有需要重洗剩余牌库时,才继续消耗战斗内随机。

所以,起手手牌属于战斗内随机结果,不会推进地牢全局随机序列。这里要特别区分两件事:它不会改变宝箱、商店、变形术、寻宝这类地牢随机;但强退重开后如果这场战斗重新创建,战斗内随机状态也会重新创建,起手手牌就可能和强退前不同。

为什么强退后起手会变牌库洗牌调用的是 Game.InGameRandomRange。代码里这个随机源存放在当前战斗 Game 对象上;如果还没有被 SetRandom(seed) 明确设置,首次使用时会创建一个新的 MyRandom 默认随机源。这个默认源不是从种子串还原,所以重新打开游戏并重新进入同一场战斗时,起手手牌可能变化。

如果讨论的是整局游戏刚开始的牌组,职业本身有固定起始牌组;随机性主要发生在进入战斗后把这副牌库洗成抽牌顺序,而不是创建角色时随机发起手牌。

4. 具体 RNG 算法

游戏里的随机是伪随机:给定同一个种子或同一个已保存的随机状态,就会按固定顺序产出同一串数字。这里不是标准库的复杂随机表,而是游戏自己的 31 位线性同余算法。

核心公式每次抽取都会先更新:新状态 = (旧状态 × 1103515245 + 12345) 只保留低 31 位。小数结果 = 新状态 / 2147483648。

种子写入时也只保留低 31 位,所以两个只在最高位不同的种子,会进入同一个随机状态。每次调用小数、整数、正态分布或洗牌,都会先推进这一个状态。

游戏层面的随机不是“每个系统各自随便抽”,而是围绕几个基础抽取方式组合出来。

整数抽取基础整数函数本来是上限不包含;游戏包装后会把上限加 1,所以玩家看到的 A 到 B 是首尾都包含。例如 1 到 3 会得到 1、2 或 3。
小数阈值先用核心公式得到 0 到 1 之间的小数,再和概率阈值比较。宝箱分支、怪物放置、墙体生成等经常用这种方式。
加权选择先把候选项权重相加,再按总权重投点。权重越高,被选中的区间越大;权重为 0 的候选不会出现。
洗牌从列表前面开始,每一步在当前位置到列表末尾之间随机挑一个位置交换。每一步都会消耗一次整数随机。
随机取整先取整数部分,再用小数部分当概率决定是否进一。比如 2.25 有 25% 机会取 3。
正态波动抽两个小数,用 Box-Muller 公式转成围绕 0 波动的正态随机数;金币和商店预算会再乘标准差并加上目标值。
随机字母先抽 0 到 25,再加到大写 A 上,所以只会得到 A 到 Z。

这些基础方式会叠加在一起。例如宝箱可能先用小数决定奖励分支,再用加权选择挑候选卡,最后用洗牌决定展示顺序。只要中间多消耗一次随机,后面所有依赖同一条随机状态的结果都可能改变。

Dream Quest 中文玩家 Wiki