454 lines
19 KiB
C#
454 lines
19 KiB
C#
using System.Collections.Generic;
|
|
|
|
namespace IdleSpectator;
|
|
|
|
/// <summary>
|
|
/// Built-in agent playtest scenarios expanded by <c>action=scenario</c>.
|
|
/// </summary>
|
|
internal static class HarnessScenarios
|
|
{
|
|
public static List<HarnessCommand> Build(string name)
|
|
{
|
|
switch ((name ?? "").Trim().ToLowerInvariant())
|
|
{
|
|
case "smoke":
|
|
return Smoke();
|
|
case "tip_match":
|
|
return TipMatch();
|
|
case "critical":
|
|
case "critical_smoke":
|
|
return CriticalSmoke();
|
|
case "settings_full":
|
|
return SettingsFull();
|
|
case "ghost_guard":
|
|
return GhostGuard();
|
|
case "retarget_stability":
|
|
return RetargetStability();
|
|
case "input_exit":
|
|
return InputExit();
|
|
case "director_tiers":
|
|
return DirectorTiers();
|
|
case "discovery":
|
|
return Discovery();
|
|
case "world_log":
|
|
return WorldLog();
|
|
case "chronicle":
|
|
case "chronicle_smoke":
|
|
return ChronicleSmoke();
|
|
case "regression":
|
|
case "full":
|
|
return Regression();
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Full regression meta-suite (nested scenarios keep assert counters).
|
|
/// Battle / map-gen paths stay out of gate.
|
|
/// </summary>
|
|
private static List<HarnessCommand> Regression()
|
|
{
|
|
return new List<HarnessCommand>
|
|
{
|
|
Nested("reg_critical", "critical_smoke"),
|
|
Nested("reg_settings", "settings_full"),
|
|
Nested("reg_ghost", "ghost_guard"),
|
|
Nested("reg_retarget", "retarget_stability"),
|
|
Nested("reg_input", "input_exit"),
|
|
Nested("reg_director", "director_tiers"),
|
|
Nested("reg_discovery", "discovery"),
|
|
Nested("reg_worldlog", "world_log"),
|
|
Nested("reg_chronicle", "chronicle_smoke"),
|
|
Step("reg_end", "fast_timing", value: "false"),
|
|
Step("reg_snap", "snapshot"),
|
|
};
|
|
}
|
|
|
|
private static List<HarnessCommand> Smoke()
|
|
{
|
|
return new List<HarnessCommand>
|
|
{
|
|
Step("s0", "dismiss_windows"),
|
|
Step("s1", "wait_world"),
|
|
Step("s2", "reset_counters"),
|
|
Step("s3", "pick_unit", asset: "auto"),
|
|
Step("s4", "spectator", value: "off"),
|
|
Step("s5", "assert", expect: "idle", value: "false"),
|
|
Step("s6", "spectator", value: "on"),
|
|
Step("s7", "focus", asset: "auto"),
|
|
Step("s8", "wait", wait: 0.35f),
|
|
Step("s9", "assert", expect: "health"),
|
|
Step("s10", "snapshot"),
|
|
};
|
|
}
|
|
|
|
private static List<HarnessCommand> TipMatch()
|
|
{
|
|
return new List<HarnessCommand>
|
|
{
|
|
Step("t0", "dismiss_windows"),
|
|
Step("t1", "wait_world"),
|
|
Step("t2", "reset_counters"),
|
|
Step("t3", "pick_unit", asset: "auto"),
|
|
Step("t4", "spectator", value: "on"),
|
|
Step("t5", "watch", asset: "auto", label: "New species: {asset}", tier: "Curiosity"),
|
|
Step("t6", "wait", wait: 0.3f),
|
|
Step("t7", "assert", expect: "tip_matches_unit"),
|
|
Step("t8", "assert", expect: "unit_asset", asset: "auto"),
|
|
Step("t9", "assert", expect: "power_bar", value: "false"),
|
|
Step("t10", "snapshot"),
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Critical E2E against already-living map units (no fragile miracle spawns).
|
|
/// </summary>
|
|
private static List<HarnessCommand> CriticalSmoke()
|
|
{
|
|
return new List<HarnessCommand>
|
|
{
|
|
Step("c00", "dismiss_windows"),
|
|
Step("c01", "wait_world"),
|
|
Step("c02", "reset_counters"),
|
|
|
|
Step("c05", "pick_unit", asset: "auto"),
|
|
Step("c06", "wait", wait: 0.25f),
|
|
|
|
Step("c10", "set_setting", expect: "enabled", value: "false"),
|
|
Step("c11", "assert", expect: "enabled", value: "false"),
|
|
Step("c12", "spectator", value: "on", expect: "blocked"),
|
|
Step("c13", "assert", expect: "idle", value: "false"),
|
|
Step("c14", "set_setting", expect: "enabled", value: "true"),
|
|
Step("c15", "assert", expect: "enabled", value: "true"),
|
|
|
|
Step("c20", "spectator", value: "off"),
|
|
Step("c21", "assert", expect: "idle", value: "false"),
|
|
Step("c22", "spectator", value: "on"),
|
|
Step("c23", "focus", asset: "auto"),
|
|
Step("c24", "reset_counters"),
|
|
Step("c25", "wait", wait: 0.35f),
|
|
Step("c26", "assert", expect: "health"),
|
|
Step("c27", "assert", expect: "power_bar", value: "false"),
|
|
Step("c28", "assert", expect: "no_bad"),
|
|
|
|
Step("c30", "watch", asset: "auto", label: "New species: {asset}", tier: "Curiosity"),
|
|
Step("c31", "wait", wait: 0.3f),
|
|
Step("c32", "assert", expect: "tip_matches_unit"),
|
|
Step("c33", "assert", expect: "unit_asset", asset: "auto"),
|
|
Step("c34", "assert", expect: "tip_contains", value: "auto"),
|
|
Step("c35", "assert", expect: "power_bar", value: "false"),
|
|
Step("c36", "assert", expect: "no_bad"),
|
|
|
|
Step("c40", "watch", asset: "auto", label: "Retarget A: {asset}", tier: "Curiosity"),
|
|
Step("c41", "wait", wait: 0.25f),
|
|
Step("c42", "focus", asset: "auto"),
|
|
Step("c43", "wait", wait: 0.25f),
|
|
Step("c44", "watch", asset: "auto", label: "Retarget B: {asset}", tier: "Curiosity"),
|
|
Step("c45", "wait", wait: 0.35f),
|
|
Step("c46", "assert", expect: "health"),
|
|
Step("c47", "assert", expect: "no_bad"),
|
|
Step("c48", "assert", expect: "power_bar", value: "false"),
|
|
|
|
Step("c50", "simulate_input"),
|
|
Step("c51", "wait", wait: 0.25f),
|
|
Step("c52", "assert", expect: "idle", value: "false"),
|
|
Step("c53", "assert", expect: "no_bad"),
|
|
|
|
Step("c99", "snapshot"),
|
|
};
|
|
}
|
|
|
|
private static List<HarnessCommand> SettingsFull()
|
|
{
|
|
return new List<HarnessCommand>
|
|
{
|
|
Step("sf0", "dismiss_windows"),
|
|
Step("sf1", "wait_world"),
|
|
Step("sf2", "set_setting", expect: "enabled", value: "true"),
|
|
Step("sf3", "pick_unit", asset: "auto"),
|
|
|
|
Step("sf10", "set_setting", expect: "enabled", value: "false"),
|
|
Step("sf11", "assert", expect: "enabled", value: "false"),
|
|
Step("sf12", "spectator", value: "on", expect: "blocked"),
|
|
Step("sf13", "assert", expect: "idle", value: "false"),
|
|
|
|
Step("sf20", "set_setting", expect: "enabled", value: "true"),
|
|
Step("sf21", "spectator", value: "on"),
|
|
Step("sf22", "focus", asset: "auto"),
|
|
Step("sf23", "assert", expect: "idle", value: "true"),
|
|
|
|
// Disable while active must turn idle off (settings callback).
|
|
Step("sf30", "set_setting", expect: "enabled", value: "false"),
|
|
Step("sf31", "assert", expect: "idle", value: "false"),
|
|
Step("sf32", "assert", expect: "enabled", value: "false"),
|
|
|
|
Step("sf40", "set_setting", expect: "enabled", value: "true"),
|
|
Step("sf41", "set_setting", expect: "show_watch_reasons", value: "false"),
|
|
Step("sf42", "assert", expect: "show_watch_reasons", value: "false"),
|
|
Step("sf43", "set_setting", expect: "show_watch_reasons", value: "true"),
|
|
Step("sf44", "assert", expect: "show_watch_reasons", value: "true"),
|
|
|
|
Step("sf99", "snapshot"),
|
|
};
|
|
}
|
|
|
|
private static List<HarnessCommand> GhostGuard()
|
|
{
|
|
return new List<HarnessCommand>
|
|
{
|
|
Step("g0", "dismiss_windows"),
|
|
Step("g1", "wait_world"),
|
|
Step("g2", "set_setting", expect: "enabled", value: "true"),
|
|
Step("g3", "pick_unit", asset: "auto"),
|
|
Step("g4", "spectator", value: "on"),
|
|
Step("g5", "focus", asset: "auto"),
|
|
Step("g6", "reset_counters"),
|
|
Step("g7", "remember_focus"),
|
|
Step("g8", "watch_ghost"),
|
|
Step("g9", "wait", wait: 0.25f),
|
|
Step("g10", "assert", expect: "focus_same"),
|
|
Step("g11", "assert", expect: "health"),
|
|
Step("g12", "assert", expect: "no_bad"),
|
|
Step("g13", "assert", expect: "power_bar", value: "false"),
|
|
Step("g99", "snapshot"),
|
|
};
|
|
}
|
|
|
|
private static List<HarnessCommand> RetargetStability()
|
|
{
|
|
return new List<HarnessCommand>
|
|
{
|
|
Step("rs0", "dismiss_windows"),
|
|
Step("rs1", "wait_world"),
|
|
Step("rs2", "set_setting", expect: "enabled", value: "true"),
|
|
Step("rs3", "pick_unit", asset: "auto"),
|
|
Step("rs4", "spectator", value: "on"),
|
|
Step("rs5", "focus", asset: "auto"),
|
|
Step("rs6", "reset_counters"),
|
|
|
|
Step("rs10", "watch", asset: "auto", label: "Stab 1: {asset}", tier: "Curiosity"),
|
|
Step("rs11", "wait", wait: 0.2f),
|
|
Step("rs12", "watch", asset: "auto", label: "Stab 2: {asset}", tier: "Curiosity"),
|
|
Step("rs13", "wait", wait: 0.2f),
|
|
Step("rs14", "watch", asset: "auto", label: "Stab 3: {asset}", tier: "Curiosity"),
|
|
Step("rs15", "wait", wait: 0.2f),
|
|
Step("rs16", "watch", asset: "auto", label: "Stab 4: {asset}", tier: "Curiosity"),
|
|
Step("rs17", "wait", wait: 0.25f),
|
|
|
|
Step("rs20", "assert", expect: "health"),
|
|
Step("rs21", "assert", expect: "no_bad"),
|
|
Step("rs22", "assert", expect: "power_bar", value: "false"),
|
|
Step("rs23", "assert", expect: "unit_asset", asset: "auto"),
|
|
Step("rs99", "snapshot"),
|
|
};
|
|
}
|
|
|
|
private static List<HarnessCommand> InputExit()
|
|
{
|
|
return new List<HarnessCommand>
|
|
{
|
|
Step("ie0", "dismiss_windows"),
|
|
Step("ie1", "wait_world"),
|
|
Step("ie2", "set_setting", expect: "enabled", value: "true"),
|
|
Step("ie3", "fast_timing", value: "true"),
|
|
Step("ie4", "pick_unit", asset: "auto"),
|
|
Step("ie5", "spectator", value: "off"),
|
|
Step("ie6", "spectator", value: "on"),
|
|
Step("ie7", "focus", asset: "auto"),
|
|
|
|
// Still inside post-enable grace: drag must not exit.
|
|
Step("ie10", "assert", expect: "in_grace", value: "true"),
|
|
Step("ie11", "simulate_input", value: "drag", expect: "grace"),
|
|
Step("ie12", "assert", expect: "idle", value: "true"),
|
|
|
|
Step("ie20", "expire_grace"),
|
|
Step("ie21", "assert", expect: "in_grace", value: "false"),
|
|
Step("ie22", "simulate_input", value: "drag"),
|
|
Step("ie23", "assert", expect: "idle", value: "false"),
|
|
Step("ie24", "assert", expect: "no_bad"),
|
|
|
|
Step("ie90", "fast_timing", value: "false"),
|
|
Step("ie99", "snapshot"),
|
|
};
|
|
}
|
|
|
|
private static List<HarnessCommand> DirectorTiers()
|
|
{
|
|
return new List<HarnessCommand>
|
|
{
|
|
Step("dt0", "dismiss_windows"),
|
|
Step("dt1", "wait_world"),
|
|
Step("dt2", "set_setting", expect: "enabled", value: "true"),
|
|
Step("dt3", "fast_timing", value: "true"),
|
|
Step("dt4", "pick_unit", asset: "auto"),
|
|
Step("dt5", "spectator", value: "off"),
|
|
Step("dt6", "spectator", value: "on"),
|
|
Step("dt7", "focus", asset: "auto"),
|
|
Step("dt8", "reset_counters"),
|
|
|
|
// Curiosity can replace ambient after rotate window.
|
|
Step("dt10", "trigger_interest", asset: "auto", label: "CurioA", tier: "Curiosity"),
|
|
Step("dt11", "age_current", wait: 2f),
|
|
Step("dt12", "director_run", wait: 1.2f),
|
|
Step("dt13", "assert", expect: "current_tier", value: "Curiosity"),
|
|
Step("dt14", "assert", expect: "tip_contains", value: "CurioA"),
|
|
|
|
// Action interrupts curiosity after high-tier window.
|
|
Step("dt20", "trigger_interest", asset: "auto", label: "ActionA", tier: "Action"),
|
|
Step("dt21", "age_current", wait: 1.2f),
|
|
Step("dt22", "director_run", wait: 1.2f),
|
|
Step("dt23", "assert", expect: "current_tier", value: "Action"),
|
|
Step("dt24", "assert", expect: "tip_contains", value: "ActionA"),
|
|
|
|
// Curiosity must not be accepted while Action holds the camera (no director_run:
|
|
// ambient rotate would otherwise steal Action after dwell).
|
|
Step("dt30", "trigger_interest", asset: "auto", label: "CurioBlocked", tier: "Curiosity"),
|
|
Step("dt31", "assert", expect: "current_tier", value: "Action"),
|
|
Step("dt32", "assert", expect: "tip_contains", value: "ActionA"),
|
|
Step("dt33", "assert", expect: "would_accept_curiosity", value: "false"),
|
|
Step("dt34", "assert", expect: "health"),
|
|
Step("dt35", "assert", expect: "no_bad"),
|
|
|
|
Step("dt90", "fast_timing", value: "false"),
|
|
Step("dt99", "snapshot"),
|
|
};
|
|
}
|
|
|
|
private static List<HarnessCommand> Discovery()
|
|
{
|
|
return new List<HarnessCommand>
|
|
{
|
|
Step("d0", "dismiss_windows"),
|
|
Step("d1", "wait_world"),
|
|
Step("d2", "set_setting", expect: "enabled", value: "true"),
|
|
Step("d3", "fast_timing", value: "true"),
|
|
Step("d4", "discovery_reset"),
|
|
Step("d5", "pick_unit", asset: "auto"),
|
|
Step("d6", "spectator", value: "off"),
|
|
Step("d7", "spectator", value: "on"),
|
|
Step("d8", "focus", asset: "auto"),
|
|
Step("d9", "reset_counters"),
|
|
|
|
// Live-path dedupe: mark presented drops buffered copy.
|
|
Step("d10", "discovery_note", asset: "auto"),
|
|
Step("d11", "assert", expect: "pending_discovery", value: "1"),
|
|
Step("d12", "discovery_mark", asset: "auto"),
|
|
Step("d13", "assert", expect: "pending_discovery", value: "0"),
|
|
Step("d14", "assert", expect: "presented", asset: "auto", value: "true"),
|
|
|
|
// Force drain path once curiosity is acceptable.
|
|
Step("d20", "discovery_reset"),
|
|
Step("d21", "discovery_note", asset: "auto"),
|
|
Step("d22", "assert", expect: "pending_discovery", value: "1"),
|
|
Step("d23", "age_current", wait: 2f),
|
|
Step("d24", "assert", expect: "would_accept_curiosity", value: "true"),
|
|
Step("d25", "discovery_drain"),
|
|
Step("d26", "assert", expect: "pending_discovery", value: "0"),
|
|
Step("d27", "assert", expect: "presented", asset: "auto", value: "true"),
|
|
Step("d28", "director_run", wait: 1.2f),
|
|
Step("d29", "assert", expect: "tip_matches_unit"),
|
|
Step("d30", "assert", expect: "no_bad"),
|
|
|
|
Step("d90", "fast_timing", value: "false"),
|
|
Step("d99", "snapshot"),
|
|
};
|
|
}
|
|
|
|
private static List<HarnessCommand> WorldLog()
|
|
{
|
|
return new List<HarnessCommand>
|
|
{
|
|
Step("wl0", "dismiss_windows"),
|
|
Step("wl1", "wait_world"),
|
|
Step("wl2", "set_setting", expect: "enabled", value: "true"),
|
|
Step("wl3", "fast_timing", value: "true"),
|
|
Step("wl4", "pick_unit", asset: "auto"),
|
|
Step("wl5", "spectator", value: "off"),
|
|
Step("wl6", "spectator", value: "on"),
|
|
Step("wl7", "focus", asset: "auto"),
|
|
Step("wl8", "reset_counters"),
|
|
|
|
Step("wl10", "trigger_interest", asset: "auto", label: "Story: kingdom_new", tier: "Story"),
|
|
Step("wl11", "age_current", wait: 1.2f),
|
|
Step("wl12", "director_run", wait: 1.2f),
|
|
Step("wl13", "assert", expect: "current_tier", value: "Story"),
|
|
Step("wl14", "assert", expect: "tip_contains", value: "kingdom_new"),
|
|
|
|
Step("wl20", "trigger_interest", asset: "auto", label: "Epic: diplomacy_war_started", tier: "Epic"),
|
|
Step("wl21", "age_current", wait: 1.2f),
|
|
Step("wl22", "director_run", wait: 1.2f),
|
|
Step("wl23", "assert", expect: "current_tier", value: "Epic"),
|
|
Step("wl24", "assert", expect: "tip_contains", value: "diplomacy_war_started"),
|
|
Step("wl25", "assert", expect: "health"),
|
|
Step("wl26", "assert", expect: "no_bad"),
|
|
|
|
Step("wl90", "fast_timing", value: "false"),
|
|
Step("wl99", "snapshot"),
|
|
};
|
|
}
|
|
|
|
private static List<HarnessCommand> ChronicleSmoke()
|
|
{
|
|
return new List<HarnessCommand>
|
|
{
|
|
Step("ch0", "dismiss_windows"),
|
|
Step("ch1", "wait_world"),
|
|
Step("ch2", "set_setting", expect: "enabled", value: "true"),
|
|
Step("ch3", "set_setting", expect: "show_dossier_caption", value: "true"),
|
|
Step("ch4", "set_setting", expect: "chronicle_enabled", value: "true"),
|
|
Step("ch5", "pick_unit", asset: "auto"),
|
|
Step("ch6", "spectator", value: "off"),
|
|
Step("ch7", "spectator", value: "on"),
|
|
Step("ch8", "focus", asset: "auto"),
|
|
Step("ch9", "wait", wait: 0.35f),
|
|
Step("ch10", "assert", expect: "health"),
|
|
Step("ch11", "assert", expect: "dossier_contains", value: "auto"),
|
|
Step("ch12", "assert", expect: "caption_contains", value: "auto"),
|
|
Step("ch13", "chronicle_force", label: "Slew"),
|
|
Step("ch14", "assert", expect: "chronicle_count", value: "1", label: "min"),
|
|
Step("ch15", "assert", expect: "chronicle_latest_contains", value: "Slew"),
|
|
Step("ch15b", "assert", expect: "chronicle_latest_contains", value: "auto"),
|
|
Step("ch16", "chronicle_open"),
|
|
Step("ch17", "wait", wait: 0.25f),
|
|
Step("ch18", "assert", expect: "focus", value: "true"),
|
|
Step("ch19", "assert", expect: "health"),
|
|
Step("ch20", "chronicle_jump"),
|
|
Step("ch21", "wait", wait: 0.25f),
|
|
Step("ch22", "assert", expect: "focus", value: "true"),
|
|
Step("ch23", "assert", expect: "dossier_contains", value: "auto"),
|
|
Step("ch24", "assert", expect: "no_bad"),
|
|
Step("ch99", "snapshot"),
|
|
};
|
|
}
|
|
|
|
private static HarnessCommand Nested(string id, string scenario)
|
|
{
|
|
return Step(id, "scenario", value: scenario, expect: "keep");
|
|
}
|
|
|
|
private static HarnessCommand Step(
|
|
string id,
|
|
string action,
|
|
string value = "",
|
|
string asset = "",
|
|
string label = "",
|
|
string tier = "",
|
|
string expect = "",
|
|
int count = 1,
|
|
float wait = 0f)
|
|
{
|
|
return new HarnessCommand
|
|
{
|
|
id = id,
|
|
action = action,
|
|
value = value,
|
|
asset = asset,
|
|
label = label,
|
|
tier = tier,
|
|
expect = expect,
|
|
count = count,
|
|
wait = wait
|
|
};
|
|
}
|
|
}
|