T4组D·断言与探针换代(敌人表行集多行批): smoke_all expect_pools断言换(L,D,enemy_id)三元键逐行精确比对[十九行九种池模板文案随F7换代];L2/L3定点行集断言改行集构成口径({敌种集}恰一行集+首行甲型);双表精确行契约断言改精确行集口径(294-311主段+3518/3555两复述段);新增混编运行面正反断言六条(注入(1,5)/(1,6)避开全部扫描面·断言后还原零污染):混编spawn受理正向+各行数量求和+生成序=文件行序+各行行值独立投影+总数守卫>4拒绝fail-fast+表还原19行复核;config_db_test新增行集纪律套五条(EnemyTable资源直构validate正反:混编相邻合法+Boss坐标混编合法P4乙+同坐标行隔断rowset_rule定位到坐标R6+同敌种第二行dup_key拦+单行数量域[1,3]不回归);skill_rhythm_probe/damage_probe取数面T2已适配本轮直跑验证(rhythm正常输出;damage 7项1失败=A1攻击链健康·stash对照实证基线既有与本批零相关·探针非闸门工具如实登记);L2记录=池模板键值换代连续3轮红(坐标敌种映射臆断错4键+3_7池值手抄错·第4轮以离线tres对账法收敛)——教训=三元键换代先离线全量对账再落码;断言数805→811净增6随批追认;轻闸=冒烟811/0三闸全过+run_all 17套全绿

This commit is contained in:
DKChan committed 2026-10-07 02:36:23 +08:00
1 parent bc73fa3212
commit c583940400
2 files changed
+133 -40

No files matched your search

@@ -23,6 +23,7 @@ func _init() -> void:
_test_shop_accessors(db)
_test_meta_accessors(db)
_test_manifest_dir_sync(db)
_test_rowset_discipline()
quit(Kit.finish("config_db_test"))
@@ -191,3 +192,52 @@ func _test_manifest_dir_sync(db) -> void:
if not disk_files.has(String(manifest[key])):
synced = false
Kit.check("TABLE_MANIFEST 与 data/tables 目录逐文件同步(无缺登/无悬登)", synced)
# ---- 行集构成纪律(2026-10-07 敌人表行集多行批——EnemyTable.validate 正反验证;资源直构不碰生产表)----
# 纪律三条(敌人系统 v0.15):①行集内 enemy_id 唯一(dup_key 既有通道)②同坐标多行文件内相邻
# (rowset_rule——行序即契约,R6 加载期兜底)③行集实例总数 ≤4(骰后值运行面,spawn 守卫——冒烟侧验证)。
func _test_rowset_discipline() -> void:
const EnemyTableScript := preload("res://data/schemas/enemy_table.gd")
var mk_row := func(l: int, d: int, eid: String) -> Dictionary:
return {"level_index": l, "node_depth": d, "enemy_id": eid, "display_name": eid + "名",
"unit_count": 1, "hp": 10, "atk": 2, "pool": [{"skill_id": "attack", "weight": 9}]}
# 正向:同坐标两行不同敌种(相邻)= 混编合法,validate 零错
var t_mix = EnemyTableScript.new()
t_mix.rows = [mk_row.call(1, 5, "goblin"), mk_row.call(1, 5, "bugbear")]
var errs: Array = t_mix.validate()
Kit.check("混编行集加载通过(同坐标两行不同敌种相邻——行集恰一敌种校验退役的正向面)", errs.is_empty())
# 正向:Boss 坐标两行同构合法(P4 乙——Boss 行集校验同样放开,加载层无 Boss 单行硬闸)
var t_boss = EnemyTableScript.new()
t_boss.rows = [mk_row.call(2, 9, "drider"), mk_row.call(2, 9, "bugbear")]
errs = t_boss.validate()
Kit.check("Boss 坐标混编行集加载通过(P4 乙——Boss 多行合法,无硬闸)", errs.is_empty())
# 负向:同坐标行不相邻 = rowset_rule 且报错定位到坐标(R6 行序纪律 + R3 错误类别可定位)
var t_gap = EnemyTableScript.new()
t_gap.rows = [mk_row.call(1, 5, "goblin"), mk_row.call(1, 9, "hobgoblin"), mk_row.call(1, 5, "bugbear")]
errs = t_gap.validate()
var gap_hit := false
for e in errs:
if String(e.get("category", "")) == "rowset_rule" and String(e.get("message", "")).contains("(1,5)"):
gap_hit = true
Kit.check("行序相邻校验:同坐标行被隔断报 rowset_rule 且定位坐标(R6——行序即契约加载期兜底)", gap_hit)
# 负向:同敌种第二行仍被 dup_key 拦(键含 enemy_id——纪律①既有通道不回归)
var t_dup = EnemyTableScript.new()
t_dup.rows = [mk_row.call(1, 5, "goblin"), mk_row.call(1, 5, "goblin")]
errs = t_dup.validate()
var dup_hit := false
for e in errs:
if String(e.get("category", "")) == "dup_key":
dup_hit = true
Kit.check("行集内同敌种第二行仍被 dup_key 拦(纪律①——enemy_id 唯一)", dup_hit)
# 负向:域校验不回归(单行 unit_count 越域仍拦——UNIT_COUNT_MAX 单种数语义下的同款域闸)
var t_dom = EnemyTableScript.new()
t_dom.rows = [mk_row.call(1, 5, "goblin")]
t_dom.rows[0]["unit_count"] = 4
errs = t_dom.validate()
var dom_hit := false
for e in errs:
if String(e.get("category", "")) == "domain" and String(e.get("message", "")).contains("unit_count"):
dom_hit = true
Kit.check("单行数量域 [1,3] 域闸不回归(UNIT_COUNT_MAX 语义 = 单种数)", dom_hit)