楼层规则 floors.yml
floors.yml 决定每一层怎么排:走几间房、门后面会出现什么、最后打哪个首领,以及怪物每往下一层变强多少。
这个文件是选用的:没有 floors.yml 时用下面 default: 的内置规则。
一层是怎么排的
第 N 层 = 第 1 间(只有一扇门)→ 选门 → 第 2 间 → 选门 → … → 第 rooms 间 → 首领房
rooms是首领房之前要走几间(含第一间);rooms: 4-6= 每层随机 4~6 间,再加上最后的首领房。- 起点房不算在任何一层里:它的那扇门就是第 1 层第 1 间。
- 每层的第 1 间只有一扇门(种类由
first决定),之后每次出现doors扇门。 - 首领打完 = 这一层结束:层奖励、魂晶、补血、选祝福,然后出现下一层第 1 间的门(无限层每
retreat-every层多一扇撤退之门)。
完整写法
下面的 floors、every、names 借用了范例「深渊回廊」的内容:boss_lich 和楼层名称(潮湿地窖……)都是范例自己的。复制到自己的副本时,boss_lich 要换成你自己的首领房 ID(/cd admin create --roguelike 建立的范本是 boss_1),否则后台会提示 boss-pool 的房间「boss_lich」不存在或不是首领房,并略过。
default:
rooms: 4-6 # 首领房之前要走几个房间(含第一间)
first: combat # 每层第一间(只有一扇门)的种类;random = 照 types 权重
doors: 2-3 # 不写 = config.yml 的 roguelike.door.choices
types: { combat: 60, elite: 12, reward: 8, shop: 8, rest: 6, event: 6 } # 门后面是什么房间(权重)
max: { elite: 2, reward: 1, shop: 1, rest: 1, event: 1 } # 这一层最多「走进」几次
guarantee: {} # 这一层至少「出现在门上」几次,例如 { shop: 1 }
before-boss: [] # 首领前最后一次选门只出现这些种类(空 = 照权重),例如 [rest, shop]
no-repeat: 3 # 最近几间出现过的房间不再抽到(池子不够时自动放宽)
boss: true # 这一层最后有首领房
boss-pool: [] # 这层的首领房 ID(空 = floors 包含这一层的所有首领房)
draft: true # 首领打完选祝福(cards.yml 的 draft.when 也要包含 boss)
floors: # 指定某一层,只写要改的
"1": { rooms: 3, types: { combat: 70, reward: 20, event: 10 }, max: { elite: 0 } }
"3": { boss-pool: [boss_lich] }
every: # 每 N 层套用一次(无限层常用)
"5": { guarantee: { shop: 1 } }
"10": { boss-pool: [boss_lich] }
last: {} # 有限层的最后一层额外套用,例如 { boss-pool: [boss_lich], draft: false }
scaling: # 每往下一层怪物变强(和人数加成、难度模式相乘)
level: "{floor} - 1" # MythicMobs 等级加成(原版怪没有等级)
health: "1 + 0.12 * ({floor} - 1)"
damage: "1 + 0.08 * ({floor} - 1)"
amount: "1 + 0.03 * ({floor} - 1)" # 怪物数量倍率(不会超过房间的 max-mobs)
elite: { health: 1.5, damage: 1.2, glow: true } # 精英房的怪额外倍率
boss: { health: 1.0, damage: 1.0 } # 标记 boss 的怪额外倍率
mythic: level # MythicMobs 怪:level 只加等级 / both 等级和倍率都加
cap: { level: 200, health: 50, damage: 10, amount: 2 } # 上限(避免无限层数字爆掉)
names: # 每层的名字(标题、计分板)
"1": "&7潮湿地窖"
"2": "&8枯骨回廊"
"3": "&5巫妖王座"
default: "&7深渊 第 {floor} 层"
on-floor-start: [] # 每层开始时执行的脚本({floor} 可用)
on-floor-clear: [] # 每层打完时执行的脚本
每层的规则
default:、floors."N":、every."N":、last: 里都可以写这些键:
| 键 | 内置默认 | 说明 |
|---|---|---|
rooms | 4-6 | 首领房之前走几间(含第一间),写 3 或 4-6 |
first | combat | 每层第 1 间的种类;random(随机)= 照 types 的权重抽 |
doors | config.yml 的 roguelike.door.choices | 第 2 间起每次几扇门,1~3 |
types | combat: 60, elite: 12, reward: 8, shop: 8, rest: 6, event: 6 | 门后面的房间种类与权重;权重 0 = 不会出现 |
max | elite: 2, reward: 1, shop: 1, rest: 1, event: 1 | 这一层最多走进几次,到了上限就不再出现在门上 |
guarantee | 无 | 这一层至少出现在门上几次(不保证玩家会选),快没有机会时一定会排进门里 |
before-boss | 无 | 首领前最后一次选门只出现这些种类,例如 [rest, shop] 让玩家打首领前补给;空 = 照权重 |
no-repeat | 3 | 最近走过的几间房不会再被抽到;能用的房间不够时自动放宽 |
boss | true | 这一层最后有首领房;false = 走完 rooms 间就算这层打完 |
boss-pool | 无 | 这一层只从这些首领房里抽(要是 type: boss 的房间 ID);空 = floors 包含这一层的所有首领房 |
draft | true | 首领打完选祝福(cards.yml 的 draft.when 也要有 boss) |
能写在 types、max、guarantee、first、before-boss 里的种类:combat、elite、reward、shop、rest、event(中文名称也可以,例如 战斗、商店)。boss 和 start 不能写在这里:首领房固定在每层最后,起点房只在开场出现。
门后面会是哪一间,是在这个种类、出现楼层包含这一层(room.yml 的 floors)、还没超过 max-per-run 的房间里,照 room.yml 的 weight 抽。同一组门里两扇门同种类的机会比较低。
套用顺序
第 N 层的规则这样算出来:
- 从
default:开始(没写的键用上表的内置默认); - 套上每个整除 N 的
every."M":,M 小的先套、M 大的后套(后套的覆盖); - 套上
floors."N":; - 有限层的最后一层,再套上
last:。
合并方式:
- 数值、
first、boss、draft直接覆盖; types、max、guarantee逐项合并(只写{ elite: 0 }就只改精英,其他种类照旧);before-boss、boss-pool整个取代。
floors: 的键要是层数("5"),every: 的键要是 2 以上的数字。写错的键、打错字的设置会在后台提示,并猜你想写的是哪一个(例如「是不是要写 types?」)。
规则要求有首领的每一层,都要有至少一间能用的首领房(room.yml 的 floors 包含那一层,或那一层写了 boss-pool)。有限层检查第 1 层到最后一层,无限层检查前 200 层;不符合时这个随机地牢不能开始,提示会告诉你是第几层。
怪物成长 scaling
每往下一层,房间里生出来的怪变强。四个数值都是运算式,可以用:
| 变量 | 内容 |
|---|---|
{floor} | 第几层 |
{floors} | 总层数(无限层 = -1) |
{players} | 这一层开始时在场的人数 |
| 键 | 默认 | 说明 |
|---|---|---|
level | {floor} - 1 | MythicMobs 等级加成(原版怪没有等级) |
health | 1 + 0.12 * ({floor} - 1) | 血量倍率(第 5 层 = 1.48 倍) |
damage | 1 + 0.08 * ({floor} - 1) | 伤害倍率 |
amount | 1 + 0.03 * ({floor} - 1) | 怪物数量倍率;小数部分按概率多一只,最少 1 只,不会超过房间的 max-mobs |
elite | health: 1.5, damage: 1.2, glow: true | 精英房的怪再乘这个倍率;glow = 发光(MythicMobs 的怪在 mythic: level 时不套用) |
boss | health: 1.0, damage: 1.0 | 怪物组里标记 boss 的怪再乘这个倍率(MythicMobs 的怪在 mythic: level 时不套用) |
mythic | level | MythicMobs 的怪:level = 只加等级,血量与伤害交给 MythicMobs;both = 等级和倍率都加 |
cap | level: 200, health: 50, damage: 10, amount: 2 | 上限:算出来超过就用上限 |
最终倍率 = 一般副本的人数加成 × 难度模式 × 楼层成长 × 精英 / 首领倍率 × 房间 room.yml 的 scaling × 脚本 rogue scale。运算式算不出数字时会在后台提示并改用默认值。
默认 mythic: level 时,MythicMobs 的怪只吃等级(楼层的 level + 房间 scaling.level + rogue scale 的 level)与数量 amount。health / damage、elite / boss 倍率、精英发光、房间与 rogue scale 的 health / damage 都只对原版怪生效。要让这些倍率也套到 MythicMobs 的怪上,改成 mythic: both。
- 血量超过服务器的血量上限时,多出来的部分会换成「耐打」:玩家打它的伤害按比例减少,王条显示的血量照算,所以感觉起来一样。
- 伤害倍率、祝福的伤害加成作用在直接攻击(近战、弹射物)上。MythicMobs 技能造成的伤害不会被放大;无限层很深的楼层建议用 MythicMobs 的等级成长(
mythic: level),让怪物自己的技能变强。
楼层名称 names
names:
"1": "&7潮湿地窖"
default: "&7深渊 第 {floor} 层"
每层开始的大标题、计分板的 {floor_name} 用这个。键是层数;没有写那一层就用 default,再没有就是「第 N 层」。
每层开始 / 打完的脚本
on-floor-start:
- "title &c第 {floor} 层||&7怪物又变强了"
on-floor-clear:
- "message &a第 {floor} 层突破!"
脚本写法和一般副本一样,整场有效(换房间不会中断)。也可以在 trigger.yml 用 floor-start / floor-clear 触发,能指定某一层,见 触发种类。
范例:一个有节奏的无限层
boss_lich 是范例「深渊回廊」的首领房,换成你自己的首领房 ID(范本是 boss_1)。
default:
rooms: 3-4
before-boss: [rest, shop] # 打首领前一定能补给
floors:
"1": { rooms: 3, types: { combat: 70, reward: 20, event: 10 }, max: { elite: 0 } } # 第一层轻松一点
every:
"5": { guarantee: { shop: 1 } } # 每 5 层一定看得到商店
"10": { boss-pool: [boss_lich] } # 每 10 层的首领是巫妖王
scaling:
cap: { level: 100, health: 30, damage: 6, amount: 2 }
用 /cd admin rogue preview <副本> [种子] floors=10 [模式] 可以先看看前 10 层会怎么排(每一步都选第 1 扇门)。