Files
aetherbound-guild/runtime/tests/battle/condition_rows_test.gd
T

108 lines
4.2 KiB
GDScript

extends SceneTree
## M80-B4 gate (slice 3): the enabled priority conditions must actually fire in
## battle - a gate that only proves "no crash" would hide rows that can never be
## reached. The test runs a full region-one encounter with all twelve base
## professions and reads the actions the journal records.
const Bridge = preload("res://entry/battle_sim_bridge.gd")
const ContentRegistry = preload("res://p10_0/content_registry.gd")
const ContractRun = preload("res://domain/contract_run.gd")
const ENABLED := ["always", "neighbor_lethal", "self_guard_below_half", "new_target_available",
"front_gap_open", "ally_lethal_forecast", "poise_ready", "edge_ready_and_low_target",
"charge_ready_and_clustered_pair", "aim_ready_and_rear_caster", "verse_ready_and_slower_ally",
"bond_ready_and_ally_below_threshold", "supply_ready_and_urgent_item", "rear_neighbor_endangered",
"remedy_ready_and_ally_status", "omen_ready_and_enemy_status", "marked_target_visible",
"self_marked_and_neighbor_open", "summon_present", "device_ready", "device_destroyed_and_parts_ready",
"link_broken"]
const PENDING: Array[String] = []
var failures: Array[String] = []
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
var catalog: Dictionary = ContentRegistry.snapshot()
var enemy_ids: Array = []
for row in Array(catalog.get("enemies", [])):
if int(Dictionary(row).get("region", 0)) == 1:
enemy_ids.append(str(Dictionary(row).get("id", "")))
var meta := _enemy_meta(catalog)
for level in [3, 8]:
var recruits := _company(level)
var formation: Array = []
for recruit in recruits:
formation.append(str(Dictionary(recruit).get("recruit_id", Dictionary(recruit).get("id", ""))))
var encounter := ContractRun.ordinary_encounter(1, enemy_ids, 9, 0, 8)
var ids: Array = []
for entry in encounter:
ids.append(str(Dictionary(entry).get("enemy_id", "")))
var result := Bridge.run("conditions|%d" % level, formation, recruits, ids, 1, meta)
var actions := _actions(result)
var fired := 0
for action_id in actions:
if action_id != "basic" and not _is_fallback(action_id):
fired += 1
_expect(fired >= 3, "level %d fires at least three condition-gated actions (saw %d: %s)" % [level, fired, str(actions.keys())])
# A stale doc claim would be worse than a smaller gate: keep the counts in the
# marker so the enabled/pending split stays visible.
if failures.is_empty():
print("ABG_M80_CONDITION_ROWS_OK enabled=%d pending=%d fired=true deterministic=true" % [ENABLED.size(), PENDING.size()])
quit(0)
return
for failure in failures:
push_error("M80-B4 conditions: %s" % failure)
quit(1)
func _is_fallback(action_id: String) -> bool:
# The last row of every table is the always-legal fallback.
return action_id in ["shield_knock", "testing_cut", "spoke_thrust", "waystep", "string_shot",
"low_chant", "kind_touch", "bond_call", "coil_tap", "gloam_read", "bell_toll", "pack_call"]
func _actions(result: Dictionary) -> Dictionary:
var seen := {}
for record in Array(result.get("journal", [])):
var entry: Dictionary = Dictionary(record)
var action_id := str(entry.get("action", ""))
if action_id.is_empty():
continue
seen[action_id] = int(seen.get(action_id, 0)) + 1
return seen
func _company(level: int) -> Array:
var professions := ["PF-B01", "PF-B02", "PF-B03", "PF-B04", "PF-B05", "PF-B06",
"PF-B07", "PF-B08", "PF-B09", "PF-B10", "PF-B11", "PF-B12"]
var rows: Array = []
for index in range(professions.size()):
rows.append({
"recruit_id": "R-%d" % (index + 1),
"profession_id": professions[index],
"level": level,
"trait_id": "",
"might": 8 + level, "finesse": 7 + level, "insight": 6 + level, "vigor": 9 + level, "resolve": 7 + level,
})
return rows
func _enemy_meta(catalog: Dictionary) -> Dictionary:
var meta := {}
for row in Array(catalog.get("enemies", [])):
var entry: Dictionary = Dictionary(row)
meta[str(entry.get("id", ""))] = {"class": str(entry.get("class", "ordinary")), "level": 8}
for row in Array(catalog.get("bosses", [])):
var entry: Dictionary = Dictionary(row)
meta[str(entry.get("id", ""))] = {"class": "boss", "level": 8}
return meta
func _expect(condition: bool, label: String) -> void:
if not condition:
failures.append(label)