merge: U2返工批落地——C1两刀终态+AC v1硬梯度重投+节点图池两规则重生成(模板0随重排)+完美L1杠杆提案+终态双窗读数(普通L2 10.6/13.6%完美L2 22/32.3%越带待批点丙);冒烟576/0五探针PASS doc三闸零新增 熵增闸PASS(design/qa图像白名单收编)
No files matched your search
@@ -0,0 +1,50 @@
|
||||
# M-3 迭代 5 返工批——U2 裁决终态读数报告(T-A/T-C,2026-09-29)
|
||||
|
||||
- **被测构建**:worktree iter5-rework-20260929 @ c3c1725(C1 两刀 + AC v1 硬梯度 + 节点图池 U2 重生成终态)
|
||||
- **读数源**:MC N=200/策略 · 种子 79000 unique · route=min(`sim-data/m3iter5-rework-mc-final-20260929.stdout.log`,400 局);verifier na=150/k=100 · 种子 9500 · hp_first(500 局,本报告 §三)
|
||||
- **判定带**:C4 冻结不动(普通 L1 [35,55] / L2 [25,45]、完美 [35,65]、F4 Boss 承伤 ≤50% provisional)
|
||||
- **裁动上下文**:U2 三推翻(a 甲 / b C1 / c v1)+ 池重生成两规则——本报告 = 该组合的**首次测量**(事先无任何先测)
|
||||
|
||||
## 一、逐关条件通关率(MC 双窗单窗,N=200/策略)
|
||||
|
||||
| 层 | 画像 | 读数 | 现行带 | 判 |
|
||||
|---|---|---|---|---|
|
||||
| L1 | 普通 | 42.5% (85/200) | [35,55] | **落带** |
|
||||
| L2 | 普通 | **10.6%** (9/85) | [25,45] | **越下带 14.4 点** |
|
||||
| L1 | 完美 | 84.0% (168/200) | [35,65] | 越上带(**甲挂账**——T-B 杠杆提案待批,本批不动) |
|
||||
| L2 | 完美 | **22.0%** (37/168) | [35,65] | **越下带 13 点** |
|
||||
| L3 | 普通 / 完美 | 0% (0/9) / 8.1% (3/37) | 无带 | 只测不判 |
|
||||
|
||||
## 二、对照与归因
|
||||
|
||||
| 状态 | 普通L1 | 普通L2 | 完美L1 | 完美L2 |
|
||||
|---|---|---|---|---|
|
||||
| C3 锁值+无 AC+旧池(迭代 5 落籍态) | 46.5% ✓ | 31.2% ✓ | 83.0%(丙) | 56.6% ✓ |
|
||||
| v1 AC 叠 C3(T4 首版实测) | 42.0% ✓ | 14.3% ✗ | 84.0% | 53.6% ✓ |
|
||||
| **C1+v1+新池(本批终态)** | 42.5% ✓ | **10.6% ✗** | 84.0%(甲) | **22.0% ✗** |
|
||||
|
||||
归因三轴(方向性,未做单轴拆解实验):
|
||||
|
||||
1. **C1 vs C3**(占比回 5% + 卓尔回 130):T3 扫描口径下该两行 ≈ −5~−6pp(C3 24.0 → C1 22.0 普通档,完美 56.2 → 43.8)。
|
||||
2. **AC v1 硬梯度**:T4 实测 v1-on-C3 普通 −16.9pp(31.2→14.3);杂鱼梯度恢复(0→1~5 带内)与重击手 8/重装手 9 再叠加。
|
||||
3. **池重生成(本批新变量,最大未知)**:新网状图最短路径战斗节点数 3(旧图 4)——同路线战斗数变少=入 Boss 前养成变薄,L2 双画像同步下移(完美 53.6→22.0 的主落差在此轴,方向证据=完美档对难度变化最敏感)。
|
||||
|
||||
> ⚠ 归因注意:三轴同批落地,本报告只有终态读数——轴间拆解须补丁即跑即还原扫描(归调参批/迭代 7 标定批,本批不做)。
|
||||
|
||||
## 三、verifier 全段(独立种子窗 9500 · N=150+100 · 行键行数双核对 500 局)
|
||||
|
||||
- **双窗对拍同向**:普通 L1 44.0% / L2 13.6% / L3 0%;完美 L1 82.7% / L2 32.3% / L3 17.5%——与 MC 窗(42.5/10.6/84.0/22.0)同向同量级,非窗口彩票。完美 L2 双窗 22.0–32.3%(均低于带下缘 35,窗口波动 ~10pp 如实记录)。
|
||||
- **止步归因**:普通档主败退 = **第一层·节点6·Boss ×47**(食人魔酋长 AC 8 在 L1 收口位成为普通档第一墙)+ 第一层·节点2·战斗 ×23;完美档主败退 = **第二层·节点9·Boss ×40**(卓尔 130 血 + AC 10 长战)+ 第二层·节点1·战斗 ×17——Boss 收口位税负集中,与 AC v1 设计语义一致。
|
||||
- **营地循环(换算率 6/9/1 驱动复验)**:注入逐档生效无断链;普通档 ~60–90 局进稳态(滑窗 100%/100%/90-100%)、完美档收敛更快——对比上一基线(普通 ~36 局)**爬升放缓 ≈2 倍**(L2 难度上调的镜像后果),曲线形状健康。**换算率重标判读:锚功能正常无需急改,重标数字候选归迭代 7 标定批**(本批不动 6/9/1)。判定端报告 sim-data/balance-verifier-20260929-rework.raw.md。
|
||||
|
||||
## 四、伴生复算
|
||||
|
||||
- **r_boss 锚**(回退卓尔 130 后):L2 130/389 ≈ 0.33 · L3 140/415 ≈ 0.34——仍低于注册域 [0.5,1.1] 下限,**挂账维持**(收锚归调参批)。
|
||||
- **L3 变异密度**:5%+0/关(旧 5%+2 → C3 4%+0 → 本批 5%+0)——介于 9%(并流前口径)与 4%(C3)之间;L3 读数普通 0%/完美 8.1%,带外观察态不变。
|
||||
- **模板抽取分布**:15 张全被抽中(L1 五张 395–562 次、L2 五张 162–236 次、L3 五张 8–74 次=条件于到达),无死模板。
|
||||
|
||||
## 五、判读与移交
|
||||
|
||||
1. **普通 L2 10.6% / 完美 L2 22.0% 双越下带 = U2 组合的知情后果**(用户裁决链:b C1 少两刀减难 + c v1 加 AC 税 + ③ 池加宽连带短路径)——按返工计划书待批点丙呈报,**数字待用户追认**(追认前行值维持 provisional)。
|
||||
2. 完美 L1 84.0% → T-B 杠杆提案(design/research/perfect-l1-lever-proposal-2026-09-29.md,荆棘外延推荐)待批后另跑扫描。
|
||||
3. 换算率重标判读、r_boss 收锚、刷新阈值、护栏 B——维持挂账序列不变。
|
||||
@@ -0,0 +1,19 @@
|
||||
# T5 骨架 15 张目检清单(U2 人闸第三件,2026-09-29)
|
||||
|
||||
数据源=game/data/tables/level.tres;逐张给「过/不过+原因」,回填记台账。
|
||||
|
||||
- [ ] L1-模板0-地精洞窟主线洞道现行.png(地精洞窟·主线洞道(现行))
|
||||
- [ ] L1-模板1-地精洞窟先赏后整.png(地精洞窟·先赏后整)
|
||||
- [ ] L1-模板2-地精洞窟先整后赏.png(地精洞窟·先整后赏)
|
||||
- [ ] L1-模板3-地精洞窟赏战整.png(地精洞窟·赏战整)
|
||||
- [ ] L1-模板4-地精洞窟整战赏.png(地精洞窟·整战赏)
|
||||
- [ ] L2-模板0-幽暗地域五岔环廊现行.png(幽暗地域·五岔环廊(现行))
|
||||
- [ ] L2-模板1-幽暗地域四岔宽门.png(幽暗地域·四岔宽门)
|
||||
- [ ] L2-模板2-幽暗地域深层四岔.png(幽暗地域·深层四岔)
|
||||
- [ ] L2-模板3-幽暗地域宽门赏后置.png(幽暗地域·宽门赏后置)
|
||||
- [ ] L2-模板4-幽暗地域双干汇流.png(幽暗地域·双干汇流)
|
||||
- [ ] L3-模板0-灰矮人矿城五岔主竖井现行.png(灰矮人矿城·五岔主竖井(现行))
|
||||
- [ ] L3-模板1-灰矮人矿城四岔宽门.png(灰矮人矿城·四岔宽门)
|
||||
- [ ] L3-模板2-灰矮人矿城深层四岔.png(灰矮人矿城·深层四岔)
|
||||
- [ ] L3-模板3-灰矮人矿城宽门赏后置.png(灰矮人矿城·宽门赏后置)
|
||||
- [ ] L3-模板4-灰矮人矿城双干汇流.png(灰矮人矿城·双干汇流)
|
||||
|
After Width: | Height: | Size: 184 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 25 KiB |
@@ -0,0 +1,203 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""T5 节点图骨架 15 张一次性目检预览(M-3 迭代 5 U2 人闸第三件,2026-09-29)。
|
||||
|
||||
数据源 = game/data/tables/level.tres(游戏内实际落表,非生成器重算)。
|
||||
产物 = 本目录 15 张单图 + 00-总览拼图.png + 0-目检清单.md。一次性工具,随产物留档可删。
|
||||
用法:python design/qa/t5-skeleton-preview-20260929/render_preview.py(仓库根执行)
|
||||
"""
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
import re
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
ROOT = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", ".."))
|
||||
TRES = os.path.join(ROOT, "game", "data", "tables", "level.tres")
|
||||
FONT = os.path.join(ROOT, "game", "assets", "fonts", "ui_font_fusion_pixel_zh_hans.ttf")
|
||||
OUT = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
BG = (30, 27, 34)
|
||||
INK = (240, 234, 220)
|
||||
DIM = (150, 142, 132)
|
||||
EDGE = (168, 158, 142)
|
||||
TYPE_STYLE = {
|
||||
"battle": {"label": "战斗", "fill": (62, 86, 113), "border": (120, 148, 180)},
|
||||
"reward": {"label": "奖励", "fill": (176, 127, 44), "border": (222, 178, 96)},
|
||||
"rest": {"label": "休整", "fill": (74, 124, 89), "border": (128, 186, 148)},
|
||||
"shop": {"label": "商店", "fill": (58, 110, 140), "border": (118, 172, 200)},
|
||||
"boss": {"label": "Boss", "fill": (122, 44, 72), "border": (226, 120, 150)},
|
||||
}
|
||||
|
||||
|
||||
def parse_rows(path):
|
||||
text = open(path, encoding="utf-8").read()
|
||||
body = text.split("rows = [", 1)[1].rsplit("\n]", 1)[0]
|
||||
rows = []
|
||||
depth, start = 0, None
|
||||
for i, ch in enumerate(body):
|
||||
if ch == "{":
|
||||
if depth == 0:
|
||||
start = i
|
||||
depth += 1
|
||||
elif ch == "}":
|
||||
depth -= 1
|
||||
if depth == 0 and start is not None:
|
||||
rows.append(json.loads(body[start:i + 1]))
|
||||
start = None
|
||||
return rows
|
||||
|
||||
|
||||
def f(size):
|
||||
return ImageFont.truetype(FONT, size)
|
||||
|
||||
|
||||
def arrow(d, p0, p1, color, w=3):
|
||||
d.line([p0, p1], fill=color, width=w)
|
||||
ang = math.atan2(p1[1] - p0[1], p1[0] - p0[0])
|
||||
L, W = 14, 5
|
||||
a1 = (p1[0] - L * math.cos(ang) + W * math.sin(ang), p1[1] - L * math.sin(ang) - W * math.cos(ang))
|
||||
a2 = (p1[0] - L * math.cos(ang) - W * math.sin(ang), p1[1] - L * math.sin(ang) + W * math.cos(ang))
|
||||
d.polygon([p1, a1, a2], fill=color)
|
||||
|
||||
|
||||
def polyline_arrow(d, pts, color, w=3):
|
||||
d.line(pts, fill=color, width=w)
|
||||
ang = math.atan2(pts[-1][1] - pts[-2][1], pts[-1][0] - pts[-2][0])
|
||||
L, W = 14, 5
|
||||
a1 = (pts[-1][0] - L * math.cos(ang) + W * math.sin(ang), pts[-1][1] - L * math.sin(ang) - W * math.cos(ang))
|
||||
a2 = (pts[-1][0] - L * math.cos(ang) - W * math.sin(ang), pts[-1][1] - L * math.sin(ang) + W * math.cos(ang))
|
||||
d.polygon([pts[-1], a1, a2], fill=color)
|
||||
|
||||
|
||||
def node_box(d, cx, cy, ntype, depth, big=False):
|
||||
st = TYPE_STYLE[ntype]
|
||||
w, h = (132, 72) if big else (112, 60)
|
||||
x0, y0, x1, y1 = cx - w // 2, cy - h // 2, cx + w // 2, cy + h // 2
|
||||
d.rounded_rectangle([x0, y0, x1, y1], radius=10, fill=st["fill"],
|
||||
outline=st["border"], width=4 if big else 2)
|
||||
label = st["label"]
|
||||
fnt = f(24 if big else 21)
|
||||
bb = d.textbbox((0, 0), label, font=fnt)
|
||||
d.text((cx - (bb[2] - bb[0]) // 2, cy - (bb[3] - bb[1]) // 2 - 4), label, font=fnt, fill=INK)
|
||||
if depth is not None:
|
||||
tag = "#%d" % depth
|
||||
fnt2 = f(15)
|
||||
bb2 = d.textbbox((0, 0), tag, font=fnt2)
|
||||
tw, th = bb2[2] - bb2[0], bb2[3] - bb2[1]
|
||||
bx, by = x0 + 2, y0 - 12
|
||||
d.rounded_rectangle([bx, by, bx + tw + 12, by + th + 8], radius=7, fill=BG,
|
||||
outline=st["border"], width=1)
|
||||
d.text((bx + 6, by + 4), tag, font=fnt2, fill=INK)
|
||||
return (x0, y0, x1, y1)
|
||||
|
||||
|
||||
def render_chain(name, level_name, nodes, path):
|
||||
W, H = 1280, 320
|
||||
img = Image.new("RGB", (W, H), BG)
|
||||
d = ImageDraw.Draw(img)
|
||||
d.text((24, 18), "%s — %s" % (level_name, name), font=f(30), fill=INK)
|
||||
d.text((24, 64), "单链:自左向右依次推进|#N = 遭遇表行(战斗深度序)|入口 = 最左", font=f(17), fill=DIM)
|
||||
n = len(nodes)
|
||||
xs = [140 + i * ((W - 280) // (n - 1)) for i in range(n)]
|
||||
cy = 190
|
||||
boxes = [node_box(d, xs[i], cy, nd["type"], nd.get("node_depth"),
|
||||
big=nd["type"] == "boss") for i, nd in enumerate(nodes)]
|
||||
for i in range(n - 1):
|
||||
arrow(d, (boxes[i][2] + 2, cy), (boxes[i + 1][0] - 3, cy), EDGE)
|
||||
d.text((xs[0] - 62, cy + 46), "▶ 入口", font=f(17), fill=DIM)
|
||||
img.save(path)
|
||||
|
||||
|
||||
def render_graph(name, level_name, nodes, path):
|
||||
ids = [nd["node_depth"] for nd in nodes]
|
||||
inbound = {}
|
||||
for nd in nodes:
|
||||
for t in nd.get("next", []):
|
||||
inbound.setdefault(t, []).append(nd["node_depth"])
|
||||
layer = {}
|
||||
|
||||
def lay(i):
|
||||
if i in layer:
|
||||
return layer[i]
|
||||
layer[i] = 0 if i not in inbound else max(lay(p) for p in inbound[i]) + 1
|
||||
return layer[i]
|
||||
|
||||
for i in ids:
|
||||
lay(i)
|
||||
maxl = max(layer.values())
|
||||
W, H = 1280, 480
|
||||
img = Image.new("RGB", (W, H), BG)
|
||||
d = ImageDraw.Draw(img)
|
||||
d.text((24, 18), "%s — %s" % (level_name, name), font=f(30), fill=INK)
|
||||
d.text((24, 64), "网状:箭头=可走的下一节点|#N = 遭遇表行(战斗深度)|入口 = 最左|商店→Boss 必经",
|
||||
font=f(17), fill=DIM)
|
||||
cols = {}
|
||||
for i in sorted(ids, key=lambda x: (layer[x], x)):
|
||||
cols.setdefault(layer[i], []).append(i)
|
||||
xs = {l: 150 + l * ((W - 300) / max(maxl, 1)) for l in cols}
|
||||
pos = {}
|
||||
for l, members in cols.items():
|
||||
k = len(members)
|
||||
for j, i in enumerate(members):
|
||||
sp = min(120, 330 / max(k - 1, 1))
|
||||
y = 280 + (j - (k - 1) / 2.0) * (sp if k > 1 else 0)
|
||||
pos[i] = (int(xs[l]), int(y))
|
||||
for nd in nodes:
|
||||
i = nd["node_depth"]
|
||||
for t in nd.get("next", []):
|
||||
(x0, y0), (x1, y1) = pos[i], pos[t]
|
||||
if x1 - x0 >= 120:
|
||||
arrow(d, (x0 + 60, y0), (x1 - 62, y1), EDGE, w=3)
|
||||
else:
|
||||
bow = 40 if y1 >= y0 else -40
|
||||
pts = [(x0 + (x1 - x0) * u / 20.0,
|
||||
y0 + (y1 - y0) * u / 20.0 + bow * math.sin(math.pi * u / 20.0))
|
||||
for u in range(21)]
|
||||
polyline_arrow(d, pts, EDGE)
|
||||
entry = [i for i in ids if i not in inbound][0]
|
||||
for nd in nodes:
|
||||
i = nd["node_depth"]
|
||||
node_box(d, pos[i][0], pos[i][1], nd["type"], i, big=nd["type"] == "boss")
|
||||
if i == entry:
|
||||
d.text((pos[i][0] - 32, pos[i][1] + 42), "▶ 入口", font=f(17), fill=DIM)
|
||||
img.save(path)
|
||||
|
||||
|
||||
def main():
|
||||
rows = parse_rows(TRES)
|
||||
assert len(rows) == 3, "rows=%d" % len(rows)
|
||||
files = []
|
||||
for row in rows:
|
||||
li = row["level_index"]
|
||||
for ti, tpl in enumerate(row["templates"]):
|
||||
nodes = tpl["nodes"]
|
||||
fn = "L%d-模板%d-%s.png" % (li, ti, re.sub(r"[\\/:*?\"<>|()·]", "", tpl["display_name"]))
|
||||
path = os.path.join(OUT, fn)
|
||||
is_graph = any("next" in n for n in nodes)
|
||||
if is_graph:
|
||||
render_graph(tpl["display_name"], row["display_name"], nodes, path)
|
||||
else:
|
||||
render_chain(tpl["display_name"], row["display_name"], nodes, path)
|
||||
files.append((li, ti, tpl["display_name"], fn))
|
||||
assert len(files) == 15, len(files)
|
||||
CW, CH = 388, 178
|
||||
sheet = Image.new("RGB", (CW * 5 + 8, 40 + CH * 3), BG)
|
||||
sd = ImageDraw.Draw(sheet)
|
||||
sd.text((16, 8), "T5 骨架池总览(行=关 L1/L2/L3,列=模板 0-4;逐张单图见同目录)", font=f(22), fill=INK)
|
||||
for li, ti, name, fn in files:
|
||||
im = Image.open(os.path.join(OUT, fn))
|
||||
im.thumbnail((CW - 6, CH - 6))
|
||||
sheet.paste(im, (4 + ti * CW, 36 + (li - 1) * CH))
|
||||
sheet.save(os.path.join(OUT, "00-总览拼图.png"))
|
||||
body = "\n".join("- [ ] %s(%s)" % (fn, name) for li, ti, name, fn in files)
|
||||
open(os.path.join(OUT, "0-目检清单.md"), "w", encoding="utf-8").write(
|
||||
"# T5 骨架 15 张目检清单(U2 人闸第三件,2026-09-29)\n\n"
|
||||
"数据源=game/data/tables/level.tres;逐张给「过/不过+原因」,回填记台账。\n\n" + body + "\n")
|
||||
print("rendered %d files + sheet" % len(files))
|
||||
for li, ti, name, fn in files:
|
||||
print(" L%d-模板%d %s -> %s" % (li, ti, name, fn))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -104,8 +104,8 @@ entities:
|
||||
owner: design/gdd/systems/排雷循环/地形变异.md
|
||||
attributes:
|
||||
table: VariationTable(数据配置 承载,键 = variant_id;地形变异 回填 owner,2026-09-08 定稿回填;2026-09-20 首批类型定稿批字段集枚举化重写)
|
||||
fields: variant_id(String 主键唯一)/ display_name / unlock_level(int [1,999],knob)/ scope(enum region|global,global 预留 难度曲线与Boss)/ effect(enum none|flat_damage|hide_number,词表可扩充)/ effect_value(int [1,9],仅 flat_damage 消费,加法核小整数 knob)/ trigger(enum on_open|on_number_shown,词表可扩充)/ placement(enum closed_only|any,词表可扩充)/ board_types(StringList,∅=通配,knob——2026-09-20 用户裁定由 biome_tag 更名对齐 board_type 词表)/ counter_item_ids(StringList,魔法道具 预留,非 knob——首批四行恒空,Alpha 反制批回填)/ 表头布置参数 percent_of_cells=4 · per_level_bonus=0 · pack_max=4(knob,难度曲线与Boss——2026-09-28 迭代 5 判读锁值批自 5/2 收带,读数 design/qa/m3-iter5-lever-scan-2026-09-28.md)
|
||||
mvp_content: 六行两轴×三关(2026-09-20 首批类型定稿批四行 + **第三关内容批两行**)——thorn 荆棘丛(flat_damage/on_open/closed_only/dungeon/1)· vine 藤蔓缠绕(hide_number/on_number_shown/any/dungeon)· magma 岩浆(flat_damage/on_open/closed_only/underdark/1,登记名沿用——2026-09-28 迭代 5 判读锁值批自 2 收带)· ash 烬覆(hide_number/on_number_shown/any/underdark)· rockfall 落石(flat_damage/on_open/closed_only/deep_underdark/3——伤害型关间递进 1→2→3)· mine_dust 矿尘(hide_number/on_number_shown/any/deep_underdark/3,信息型);counter_items 恒空(反制归 Alpha 反制批);布量走既有公式(4%+per_level_bonus×0——2026-09-21 基数修正批:百分比基数=候选池格数〔安全格−初始展开区〕非总格数,percent 语义=占可挖格比例);行值 provisional 归 难度曲线与Boss;冰冻占位名退役
|
||||
fields: variant_id(String 主键唯一)/ display_name / unlock_level(int [1,999],knob)/ scope(enum region|global,global 预留 难度曲线与Boss)/ effect(enum none|flat_damage|hide_number,词表可扩充)/ effect_value(int [1,9],仅 flat_damage 消费,加法核小整数 knob)/ trigger(enum on_open|on_number_shown,词表可扩充)/ placement(enum closed_only|any,词表可扩充)/ board_types(StringList,∅=通配,knob——2026-09-20 用户裁定由 biome_tag 更名对齐 board_type 词表)/ counter_item_ids(StringList,魔法道具 预留,非 knob——首批四行恒空,Alpha 反制批回填)/ 表头布置参数 percent_of_cells=5 · per_level_bonus=0 · pack_max=4(knob,难度曲线与Boss——2026-09-28 迭代 5 判读锁值批自 5/2 收带〔读数 design/qa/m3-iter5-lever-scan-2026-09-28.md〕;2026-09-29 返工批 U2 推翻 C3 裁 C1 两刀,percent 自 4 回退 5——裁断 design/qa/m3-iter5-u2-gate-2026-09-29.md)
|
||||
mvp_content: 六行两轴×三关(2026-09-20 首批类型定稿批四行 + **第三关内容批两行**)——thorn 荆棘丛(flat_damage/on_open/closed_only/dungeon/1)· vine 藤蔓缠绕(hide_number/on_number_shown/any/dungeon)· magma 岩浆(flat_damage/on_open/closed_only/underdark/1,登记名沿用——2026-09-28 迭代 5 判读锁值批自 2 收带)· ash 烬覆(hide_number/on_number_shown/any/underdark)· rockfall 落石(flat_damage/on_open/closed_only/deep_underdark/3——伤害型关间递进 1→2→3)· mine_dust 矿尘(hide_number/on_number_shown/any/deep_underdark/3,信息型);counter_items 恒空(反制归 Alpha 反制批);布量走既有公式(5%+per_level_bonus×0——2026-09-21 基数修正批:百分比基数=候选池格数〔安全格−初始展开区〕非总格数,percent 语义=占可挖格比例;2026-09-29 返工批回退 5%——C1 终态);行值 provisional 归 难度曲线与Boss;冰冻占位名退役
|
||||
zero_special_casing: 连锁/数字计数/清图/旗/价目/结算零特判——既有系统行为不感知变异状态(排雷玩法 执行逻辑无变异分支;地形变异 Rule 3 的推论);读取方按 effect/trigger/placement 枚举路由(战斗结算 兑付段 / 呈现层 遮蔽回调),不按类型名分支
|
||||
rule4_exemption: 定义表非进度成长表,键 = variant_id,进度语义承载于 unlock_level 列(数据配置 Rule 4 豁免,schema 注释承载)
|
||||
cross_field_validation: flat_damage ⇒ trigger=on_open ∧ placement=closed_only ∧ effect_value∈[1,9];hide_number ⇒ trigger=on_number_shown——VariationTable schema validate() 跨字段类别,违规加载期致命(2026-09-20 首批类型定稿批重立;旧 hide_numbers⇒safe_nonzero 闸随字段集退役)
|
||||
@@ -279,7 +279,7 @@ entities:
|
||||
atk: int [0,999](knob——attack 行为伤害基值;MVP 4 provisional 出处待查;0 合法不拒——2026-09-20 八型批去"纯伏击伤敌种"旧注)
|
||||
pool: Array of {skill_id, weight}(**2026-09-16 敌人技能池批——池模板**,定义层;weight ∈ (0,9999] knob、池内 skill_id 不重复;每池恰一行普通攻击 + 增益技 ≤1 + skill_id 悬空致命〔加载校验在 config_db.validate_skill_pool_links 跨表通道〕;实例池〔快照+冷却状态〕在 单位容器 spawn——三敌种建议池构成与权重不列于本 registry,读 data/tables/enemy.tres(provisional 归 难度曲线与Boss;EV 锚与含闸长期速率实测读数随验收批另测登记〔2026-09-18 指路化收口〕))。**历史(2026-09-16 退役)**:heavy_multiplier int [1,16](重击倍率归技能行 damage_mult)与 pattern StringList(行为环环数组)两字段随行为环整体退役——固定出招剧本废除
|
||||
rowset_rule: 每行集恰一敌种(行集内 enemy_id 唯一 = 表结构校验,违规加载期致命)——同层多遭遇已由节点编号消解(2026-09-17 关卡节点地图 v1.0:node_depth 语义 = 关卡内唯一节点编号,同层不同节点各查各行、键结构零改动);同场多敌种(同一编号行集多行)行集校验放开归 敌人表行集多行批(混编伏击上限取值口径随 2026-09-20 上限删除消解)(战斗侧,排技能池实施批落地后;06-待办清单 敌人系统节同名条目单点登记);精英/Boss 不设编码位——Boss = 最大编号节点(图唯一终点)、精英 P2 内容承载(强敌行集)
|
||||
mvp_content: **八敌种(2026-09-14 难度曲线与Boss 修订批转正 goblin / bugbear / ogre_chief 三敌种〔DND 更名批用户指令:grub→goblin / ambusher→bugbear / boss_guardian→ogre_chief〕;2026-09-17 分支节点图批新增 giant_spider / drider,本条 2026-09-18 补收编;2026-09-20 第三关内容批新增 duergar / hook_horror / duergar_king,本条随批补收编;敌人系统 物种集断言随批更新为 {goblin, bugbear, ogre_chief, giant_spider, drider, duergar, hook_horror, duergar_king})**:goblin(地精,armor=light)/ bugbear(熊地精,armor=ward)/ ogre_chief(食人魔酋长,armor=heavy)/ giant_spider(巨蜘蛛)/ drider(蛛化卓尔精灵,Boss = 最大编号节点图唯一终点)/ duergar(灰矮人,单体重甲中坚——重甲首次登台,armor=heavy)/ hook_horror(钩爪恐魔,群行捕食者,armor=light)/ duergar_king(灰矮人石君王,L3 Boss,重甲收束「轻甲→魔法甲→重甲」教学梯度)。技能池构成与权重、armor_type 行映射**不列于本 registry**——〔**2026-09-28 M-3 迭代 5 T4 AC 投值批**:armor_class 全表投值=杂鱼全 0·Boss 台阶 8/9/12(Boss-only 终版——v1 硬/v2 软梯度普通 L2 越下带挂账,演化链见 design/qa/m3-iter5-t4-ac-2026-09-28.md;普通 L2 17.1% 挂账与完美 L1 丙并列 U2 追认);冒烟新断言守带宽+台阶〕读 data/tables/enemy.tres(L3 行值语义:duergar 关间台阶 ≈L2 单体 ×1.5 落 [1.3,1.6] 域、hook_horror 复用 bite 共享技能行、两敌种首遇位〔节点 0/1〕固定数量不加骰、Boss 血 75 = Σ普通战生命期望 91 × r_boss≈0.82 provisional 锚;行值全 provisional 归 难度曲线与Boss)。**2026-09-17 数值压缩批·文档同步——hp/atk 等数值列改指路存根**:L1/L2 节点编号行集(D0–D8)共 12 行的 hp · atk · atk_min · atk_max · unit_count · unit_count_max · advantage_per_round_cap · armor_class 等现行值**不列于本 registry**——读 `data/tables/enemy.tres`(数值压缩批注释登记:`L1 D0 24/7 → 8/2`、`L1 D1 13/5 → 4/2`、`L1 D2 40/9 → 13/3`、`L1 D3 18/6 → 6/2`、`L1 D4 150/9 → 50/3` Boss、`L2 D0 30/7 → 10/2`、`L2 D1 15/5 → 5/2`、`L2 D4 14/5 → 5/2`、`L2 D5 38/8 → 13/3`、`L2 D6 12/4 → 4/1`、`L2 D7 13/5 → 4/2`、`L2 D8 175/8 → 58/3` drider);armor_type / armor_class / unit_count 区间 / 技能池权重 / advantage_per_round_cap 不压缩(相对轴与概率轴)。**2026-09-16 敌人技能池批**:行为环拍序列([attack] 单拍环 / [attack,charge,heavy] 三拍环 / [attack,attack,charge,heavy] 四拍环)与 heavy_multiplier=2 退役,改池模板 + 技能表共享技能行(重击倍率 2 = 技能行 damage_mult);出处 = 切片 enemy.tres(技能池批改型),曲线数值与池权重归 难度曲线与Boss
|
||||
mvp_content: **八敌种(2026-09-14 难度曲线与Boss 修订批转正 goblin / bugbear / ogre_chief 三敌种〔DND 更名批用户指令:grub→goblin / ambusher→bugbear / boss_guardian→ogre_chief〕;2026-09-17 分支节点图批新增 giant_spider / drider,本条 2026-09-18 补收编;2026-09-20 第三关内容批新增 duergar / hook_horror / duergar_king,本条随批补收编;敌人系统 物种集断言随批更新为 {goblin, bugbear, ogre_chief, giant_spider, drider, duergar, hook_horror, duergar_king})**:goblin(地精,armor=light)/ bugbear(熊地精,armor=ward)/ ogre_chief(食人魔酋长,armor=heavy)/ giant_spider(巨蜘蛛)/ drider(蛛化卓尔精灵,Boss = 最大编号节点图唯一终点)/ duergar(灰矮人,单体重甲中坚——重甲首次登台,armor=heavy)/ hook_horror(钩爪恐魔,群行捕食者,armor=light)/ duergar_king(灰矮人石君王,L3 Boss,重甲收束「轻甲→魔法甲→重甲」教学梯度)。技能池构成与权重、armor_type 行映射**不列于本 registry**——〔**2026-09-28 M-3 迭代 5 T4 AC 投值批→2026-09-29 返工批 U2 裁 v1 重投**:初版 Boss-only(杂鱼全 0·Boss 8/9/12)被 U2 推翻——终版 **v1 硬梯度**=杂鱼按 T4 报告 §一 软梯度恢复(0~5 带内)+重击手 8/重装手 9(逐行手设值,非精英编码位——解读 A 追认)+Boss 台阶 8/10/12;v1 中间态未入 git,杂鱼行按报告表值代拟恢复(台账 247);演化链与三版读数见 design/qa/m3-iter5-t4-ac-2026-09-28.md,裁断全录 design/qa/m3-iter5-u2-gate-2026-09-29.md;冒烟带宽断言随新形态更新(杂鱼 0~5·重击手/重装手 8~9·Boss 8~12 台阶)〕读 data/tables/enemy.tres(L3 行值语义:duergar 关间台阶 ≈L2 单体 ×1.5 落 [1.3,1.6] 域、hook_horror 复用 bite 共享技能行、两敌种首遇位〔节点 0/1〕固定数量不加骰、Boss 血 75 = Σ普通战生命期望 91 × r_boss≈0.82 provisional 锚;行值全 provisional 归 难度曲线与Boss)。**2026-09-17 数值压缩批·文档同步——hp/atk 等数值列改指路存根**:L1/L2 节点编号行集(D0–D8)共 12 行的 hp · atk · atk_min · atk_max · unit_count · unit_count_max · advantage_per_round_cap · armor_class 等现行值**不列于本 registry**——读 `data/tables/enemy.tres`(数值压缩批注释登记:`L1 D0 24/7 → 8/2`、`L1 D1 13/5 → 4/2`、`L1 D2 40/9 → 13/3`、`L1 D3 18/6 → 6/2`、`L1 D4 150/9 → 50/3` Boss、`L2 D0 30/7 → 10/2`、`L2 D1 15/5 → 5/2`、`L2 D4 14/5 → 5/2`、`L2 D5 38/8 → 13/3`、`L2 D6 12/4 → 4/1`、`L2 D7 13/5 → 4/2`、`L2 D8 175/8 → 58/3` drider);armor_type / armor_class / unit_count 区间 / 技能池权重 / advantage_per_round_cap 不压缩(相对轴与概率轴)。**2026-09-16 敌人技能池批**:行为环拍序列([attack] 单拍环 / [attack,charge,heavy] 三拍环 / [attack,attack,charge,heavy] 四拍环)与 heavy_multiplier=2 退役,改池模板 + 技能表共享技能行(重击倍率 2 = 技能行 damage_mult);出处 = 切片 enemy.tres(技能池批改型),曲线数值与池权重归 难度曲线与Boss
|
||||
load_bearing_rules: 多敌模型(1–3 同敌种单位,增益状态 单敌假设回验不成立——见 status_effect.single_enemy_assumption)· 行为环确定性轮转(零随机;先作用后推进;死亡即不动手——轮到前被杀本拍不打指针冻结;同步轮转定理)· 效果 side-wide(原伏击池 = side 共享、增益状态 零接口变更——伏击池随 2026-09-20 八型批退役,side-wide 承载改由增益状态 alert 行承接)· 行值快照抗热重载(增益状态 EC9 同款——池模板同在快照范围,实例池冷却全零起步)· **技能池摇号出招(2026-09-16 敌人技能池批改写——原"行为环确定性轮转/同步轮转定理"退役)**:每拍做什么 = 实例池权重摇号〔开轮时点,随机消费在 战斗结算 换算层 behavior_roll 封闭流;本系统语义零随机不变、单位容器收确定值〕;两道闸 = 全技能各自冷却 + 保底 M;死亡即不动手(摇定后兑现前死亡 → 本拍作废不进账);拍结构保留(每结算每存活敌恰行动一次/行序/先作用后推进)· 零随机零 UI 零事件订阅(排雷玩法 事件面不含 敌人系统——事实经 战斗结算 转化)
|
||||
settlement_obligations: 六项(敌人系统 GDD 门禁评审缺项即 blocking)——① 行动每结算恰一次(敌单位专属——主角无环)+ 结算内调用序成文 按摇定技能行兑现→apply_damage→commit_action〔2026-09-16 技能池批改型——原 query_attack→apply_damage→advance 随行为环退役〕 ② 雷→伏击恰一次转化 ③ clamp/负值/溢杀与死亡判定时机成文 ④ F1 条款 3 闭合对账(cap 表值 + 量纲 + 棋盘生成 actuals p10 非 target 参数)⑤ 默认目标消费与单体/AOE 分流 ⑥ 伏击 cap 溢出"溢出未生效"明细行协议。**履行回执(2026-09-10)**:六项已全数落位 战斗结算 GDD(Core Rules 5/6/9/10/12 + Formulas F3/F4——落位映射 = 战斗结算 AC 覆盖矩阵)。**2026-09-20 修订**:④⑥ 随伏击单轮上限删除(用户拍板)退役——对账面去 cap 表值、溢出行协议作废;八型批再修订(2026-09-20 格面资源八型批):② 雷→伏击恰一次转化改 雷→警觉恰一次转化
|
||||
hud_obligations: 四项(视觉推测型呈现,缺项即 blocking)——① enemy_id→图像线索映射清单成文(预告时序=下一拍预告、挖掘期全程可见;含强度档位/环长直觉编码说明;形状+色相双通道)② 映射全局恒定(enemy_id 键——跨 run 禁重掷)③ 顺位与存活可读 ④ 敌方 side 池呈现口径
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# 完美 L1 加难杠杆设计提案(M-3 迭代 5 返工批 T-B,2026-09-29)
|
||||
|
||||
- **裁决来源**:U2 人闸 a 项推翻丙裁**甲=新杠杆授权**;待批点乙两子路按推荐取 **② L1 专属加难内容**(①敌方攻击基线上探会连坐普通档 L1——其落带余量仅 ~15 点,定向性差)。
|
||||
- **本提案状态**:**待用户批准**(行值不在代拍板白名单——批准前零投值)。
|
||||
- **目标**:完美档 L1 条件通关率 85–89% → 带内 [35,65];普通档 L1 保持带内 [35,55](现行读数 46–50%,余量 ~11–15 点)。
|
||||
|
||||
## 一、设计空间复盘(T3 扫描结论为底)
|
||||
|
||||
完美 L1 的强势来源 = 10×10 板形 × 完美画像挖掘效率 × 奖励经济学,不在已注册旋钮的已扫量程内。L1 定向杠杆实测:荆棘 +1 = 完美 −7pp/普通 −2pp(**定向比 3.5:1,全网格最优**);酋长加血对完美无感(L1 Boss 胜率 98%);群战上探被校验域封死。
|
||||
|
||||
## 二、推荐方案:阶段一 = 荆棘 effect_value 扫描外延(零新注册)
|
||||
|
||||
**关键发现**:荆棘(thorn)为 L1 dungeon 池**独占**变异类型(L2/L3 池无 thorn)——effect_value 天然就是 L1 专属杠杆,且 registry 域为 [1,9]、现行值 1。T3 扫描只试了 1→2(「弱」的结论是相对 −24pp 的目标缺口,不是旋钮本身弱)。
|
||||
|
||||
- **投值候选**:effect_value 1→3(预估完美 −14pp → ~75%,可能仍差带缘)或 1→4(预估完美 −21pp → ~68%,贴带上缘;普通 L1 预估 −4~−6pp → 44–46% 仍在带)。
|
||||
- **线性外推警示**:−7pp/格 的斜率按踩雷频次≈常数假设;实际挖掘策略会自适应(完美画像可能少开低价值邻格),真实读数须配对种子扫描实测,外推仅供立项参考。
|
||||
- **配套义务**:荆棘踩雷直伤加大后,与「挖掘风险不等式」风险端定价联动(该挂账本来就在册——风险端定价不足,本投值顺向收窄缺口);恢复数学(恢复概率 1/4 · 恢复量 1/6)不动。
|
||||
- **成本**:一次配对种子 OFAT + 组合扫描(对 C1+v1 现行表态),~1 小时;若 1→4 入带即收口,**零新内容、零新注册**。
|
||||
|
||||
## 三、备用方案:阶段二 = 新增 L1 专属变异类型(仅当阶段一不够)
|
||||
|
||||
若荆棘拉到域内合理上限(建议 ≤5,超过后单格 5 伤在小血量池手感过罚)仍不达带,再立新杠杆——候选形态:**「塌顶」**(rockfall 的 L1 姊妹型:flat_damage on_open,dungeon 池新行,走杠杆注册+类型定稿批流程)。成本 = 新变异类型批(表行+呈现+反制预留),~1 个内容批。
|
||||
|
||||
## 四、否决面(不予推荐)
|
||||
|
||||
- 敌方攻击基线上探(子路①):全敌轴,普通 L1 连坐超余量,且与 AC v1 重投互相叠加难以归因。
|
||||
- L1 Boss 血量/数量:完美对酋长胜率 98%,血量轴已证无感。
|
||||
- 板形回退(L1 恢复混编板):推翻棋盘统一批裁决,代价外溢。
|
||||
|
||||
## 五、批准点
|
||||
|
||||
1. 阶段一荆棘外延是否批准(批准即跑扫描,入带行值随批落表+registry 同步);
|
||||
2. 若阶段一不足,阶段二「塌顶」是否立项(或接受完美 L1 残余越带挂账——届时带缺口数字已知,可再次三选一)。
|
||||