选择 僵尸 阵容
按索引选择、加权填充与最终波补入。
约 3 分钟
预算决定一波能花多少点数。两种不同的选择规则决定它买什么:先按索引选择种类,再在仍然买得起的种类中反复进行加权抽取。
01 / 种类
先 选择 种类
从世界的基础僵尸 和配置池 开始。生成器每次使用一次有界整数抽取,从池中不放回地选择 个条目。Weight 不参与这个选择。11按索引选择池条目构建器先加入场景的基础种类,再从配置池中选择 ZombieTypeCount 个条目。每个选中的向量条目在下一次有界抽取前移除。基线数量为 4。这个选择流程不读取 Weight。0x101ab6840
移除向量条目,可以防止同一个池条目被再次选中。Weight 较大的类型在这次初始抽取中并不占有更长区间:每个剩余池条目只贡献一个索引。
选中的种类与 一起,从第一波起就可供普通填充流程使用。因此,是否进入候选种类与最终出现多少次,是两个不同的问题。
当 时,额外规则会检查已选种类中是否有成本至少为 1500 点的类型。如果没有,就从剩余池中随机选择一个满足该成本阈值的种类,替换最后一次池选择。这检查的是 Wave,而不是 Gargantuar 类。22高成本替换超过 BigZombieSureExistLevel(基线为 50)后,辅助函数检查已选种类中是否有 WavePointCost 至少为 1500 的类型。若没有,就从剩余池中符合条件的条目里抽取,替换最后一次池选择。这个谓词检查成本,而非某个特定的运行时僵尸类。0x101ab6d78
02 / 抽取
成本 决定 准 入 , 权 重 决定 选择
令 为当前可用种类。对种类 ,以 表示 Wave,以 表示 Weight。剩余 点时,正权重候选集合为
每个候选在大小为 的抽签袋中,占据长度为 的整数区间。对于给定顺序,令 为 之前的累计权重。一次抽取选择包含 的唯一区间:33整数权重抽签袋普通填充流程去掉 WavePointCost 超过剩余预算的候选,通过整数权重袋抽取,追加选中种类,并扣除其成本。FirstWave 和单独的 Cost 属性不参与这些辅助函数。有界整数抽取使用模约减;袋内份额描述区间长度,并不声称随机数余数严格均匀。0x101ce7f080x100366650
候选在袋中的名义份额为 。随着可负担范围改变,抽签袋也会重建;即使权重很高,种类也可能不再进入候选范围。当没有正权重候选符合预算时,填充结束,因此预算可以有余数。
这个填充流程既不使用 First,也不使用单独名为 Cost 的属性。因此,条目声明的首波编号不是这条路径上的额外门槛。
阵容:基础类型与四个池选择,附成本与权重
- 木乃伊僵尸100 · 1000
- 骆驼僵尸300 · 3000
- 法老僵尸450 · 3000
- 埃及巨人僵尸(无尽)1500 · 3000
- 路障木乃伊僵尸200 · 3000
- 1,825d = 11848 / 13000路障木乃伊僵尸d = 11848 / 13000
- 1,625d = 10487 / 13000路障木乃伊僵尸d = 10487 / 13000
- 1,425d = 2301 / 10000骆驼僵尸d = 2301 / 10000
- 1,125d = 3896 / 10000骆驼僵尸d = 3896 / 10000
- 825d = 8710 / 10000路障木乃伊僵尸d = 8710 / 10000
- 625d = 8331 / 10000路障木乃伊僵尸d = 8331 / 10000
- 425d = 2442 / 7000骆驼僵尸d = 2442 / 7000
- 125d = 515 / 1000木乃伊僵尸d = 515 / 1000
剩余 25 点:没有种类付得起,填充结束。
03 / 最终波
最后 一次 补 入 尝试
波次转换流程追踪哪些已选种类已经出现在更早的指令中。在正常填充最终波之前,它按活动集合的顺序访问剩余尚未出现的种类。它尝试按顺序插入,并从剩余预算中扣除每个获准种类的成本。这个流程使用严格不等式:44严格的最终波补入条件在普通最终波填充前,波次转换流程访问尚未出现的已选种类。只有成本严格小于当前剩余预算时才追加。每次插入都会减少预算,因此顺序和更早的插入会影响后续资格。0x101ce8598
成本恰好相等时,普通填充可以接受,补入流程却会拒绝。跳过补入并不会把该类型从之后的加权袋中移除。较早被接受的补入,也会减少后续条目的可用余额。
对于按顺序排列、成本为 200 和 400 的两个尚未出现类型,若剩余 600 点,第一次插入会使第二个类型恰好匹配剩余预算,因此补入会跳过它。反转顺序会改变哪个类型获得补入。之后,填充器仍可以抽到可负担的被跳过类型。
补入流程:成本 < 剩余点数
- 路障木乃伊僵尸200 < 600补入→ 400
- 铁桶木乃伊僵尸400 < 400跳过
加权填充:成本 ≤ 剩余点数,种子 3
- 铁桶木乃伊僵尸400 ≤ 400抽中→ 0
按插入顺序花费的预算
指令:路障木乃伊僵尸 · 铁桶木乃伊僵尸
04 / 结果
阵容 仍然 只是 起点
加权抽签袋的顺序会影响抽取值与种类之间的对应关系。原生集合按类型指针排序;因此,即使成本和权重相同,任意替换顺序也不能复现相同的种子序列。55顺序与组件示例原生有序集合比较器比较类型指针值。网站使用所显示的已选顺序和重建的整数抽取。独立填充器展示预算消耗;构建与音乐视图生成此前各波、最终波预留、各指令等级,以及每关一次的首领尝试。0x100c03c8c
从第 4 关起,生成流程为整个关卡进行额外财神条目和额外首领条目的尝试,再把成功的条目分配到选定波次。这不是每一波都重新进行一次 0.4 的首领概率判断。基线首领概率为 0.4;其类型从成本严格大于 100 的种类中按权重选择。
基线财神概率为零,但仍消耗这次概率抽取。如果两个特性均启用且成功,另一次抽取会抑制其中一个。保留下来的额外条目在普通填充之后追加,不从普通预算中扣除成本。随后世界处理仍可替换它;例如 Jam 构造替换指令时,不会保留被移除首领的标记。66额外首领条目波次转换流程从显示关卡 4 起尝试额外条目。共享基线声明 LeaderProbability = 0.4、LeaderMinWaveCost = 100。首领资格使用成本严格大于阈值的检查,随后加权选择。成功条目在普通填充预算之外追加。该基线中的财神概率为零,但仍消耗其概率抽取。0x101ce8a540x101ab6840
这些规则与波次方案一起,解释了一份点数额度如何变成有序的普通出怪指令列表。位置、强度与时机,是之后在这个结果之上继续处理的内容。
05 / 随机状态
为什么 一个 种子 不能 代表 整个 关 卡
抽签袋公式使用所检查的整数随机流:MT 式状态、31 位结果,以及有界抽取的模约减。零种子会变为 4357。生成过程的不同部分拥有不同的随机流状态:77独立的随机状态消耗者全新 DangerRoom 初始化构建设计器状态、转换波次、运行世界后处理、安装运行时动作与掉落标记,随后重新播种 WaveManager。Jam 使用全局 RNG;摩登世界队列打乱调用导入的 C++ 机制。网站使用重建的整数抽取、明确输入的种子与各情境独立的状态。0x101d476240x101c79bec0x101ce66dc0x100121044
GetSeed(1) 读取 time(NULL),但仅有时间戳,并不能确定每个随机流的状态或此前消耗。被拒绝的重复选择、零概率尝试,以及最终被丢弃的计算结果,仍可能推进随机流。组件控件公开各自的输入种子,使这些单独规则可以重复检验。
注释
每条论断的依据:代码路径,以及追踪到它的原生地址。
- 1
按索引选择池条目
构建器先加入场景的基础种类,再从配置池中选择 ZombieTypeCount 个条目。每个选中的向量条目在下一次有界抽取前移除。基线数量为 4。这个选择流程不读取 Weight。
0x101ab6840 - 2
高成本替换
超过 BigZombieSureExistLevel(基线为 50)后,辅助函数检查已选种类中是否有 WavePointCost 至少为 1500 的类型。若没有,就从剩余池中符合条件的条目里抽取,替换最后一次池选择。这个谓词检查成本,而非某个特定的运行时僵尸类。
0x101ab6d78 - 3
整数权重抽签袋
普通填充流程去掉 WavePointCost 超过剩余预算的候选,通过整数权重袋抽取,追加选中种类,并扣除其成本。FirstWave 和单独的 Cost 属性不参与这些辅助函数。有界整数抽取使用模约减;袋内份额描述区间长度,并不声称随机数余数严格均匀。
0x101ce7f080x100366650 - 4
严格的最终波补入条件
在普通最终波填充前,波次转换流程访问尚未出现的已选种类。只有成本严格小于当前剩余预算时才追加。每次插入都会减少预算,因此顺序和更早的插入会影响后续资格。
0x101ce8598 - 5
顺序与组件示例
原生有序集合比较器比较类型指针值。网站使用所显示的已选顺序和重建的整数抽取。独立填充器展示预算消耗;构建与音乐视图生成此前各波、最终波预留、各指令等级,以及每关一次的首领尝试。
0x100c03c8c - 6
额外首领条目
波次转换流程从显示关卡 4 起尝试额外条目。共享基线声明 LeaderProbability = 0.4、LeaderMinWaveCost = 100。首领资格使用成本严格大于阈值的检查,随后加权选择。成功条目在普通填充预算之外追加。该基线中的财神概率为零,但仍消耗其概率抽取。
0x101ce8a540x101ab6840 - 7
独立的随机状态消耗者
全新 DangerRoom 初始化构建设计器状态、转换波次、运行世界后处理、安装运行时动作与掉落标记,随后重新播种 WaveManager。Jam 使用全局 RNG;摩登世界队列打乱调用导入的 C++ 机制。网站使用重建的整数抽取、明确输入的种子与各情境独立的状态。
0x101d476240x101c79bec0x101ce66dc0x100121044