WOS Sim
← Back to Runs

Compare Runs

A (baseline)
bf9bc036-d8111747ac315/08/2026, 05:15:04
B (current)
6dbe4393-2267130304825/08/2026, 19:58:46
Avg Error A0.18%
Avg Error B0.18%
Δ Avg Error-0.00%
Changed7
Improved5
Regressed2
Added0
Retired1

Testcase Delta

288 / 288
FileCase#AdjA%B%Δ%Status
testcases/emulator_verified/gwen_norah_combo_nc.jsongwen_norah_combo_nc0-0.02%0.46%+0.44%regressed
testcases/emulator_verified/norah_s2_inf_only_A.jsonnorah_s2_inf_only_A0-0.19%0.40%+0.21%regressed
testcases/emulator_verified/sergey_norah_zinman_combo_nc.jsonsergey_norah_zinman_combo_nc0-1.55%-1.36%-0.19%improved
testcases/emulator_verified/bahiti_norah_combo_nc.jsonbahiti_norah_combo_nc0-3.54%-3.36%-0.18%improved
testcases/emulator_verified/renee_gwen_bucket_retry_nc.jsonrenee_gwen_bucket_retry_nc0-0.05%0.29%0.21%-0.08%improved
testcases/emulator_verified/gwen_solo_nc.jsongwen_solo0-0.05%-0.09%0.04%-0.05%improved
testcases/emulator_verified/renee_ahmose_damage_taken_overlap_attacker_nc.jsonrenee_ahmose_damage_taken_overlap_attacker_nc0+0.05%-0.12%-0.11%-0.01%improved
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_1010.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_1120.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_123+0.033%0.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_134+0.05%-0.04%-0.04%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_145+0.01%0.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_156+0.013%0.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_167+0.029%0.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_178+0.014%0.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_189+0.025%0.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_19100.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_2011+0.043%0.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_2112+0.017%0.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_2213+0.015%0.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_23140.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_2415+0.05%0.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_2516+0.008%0.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_2617+0.015%0.00%0.00%0.00%unchanged
testcases/1-testcases_no-heroes_t6_single-type_nc.jsondaut_viper_90+0.025%0.00%0.00%0.00%unchanged
testcases/2-testcases_no-heroes_t6_mixed_nc.jsondaut_viper_10+0.05%-0.38%-0.38%0.00%unchanged
testcases/2-testcases_no-heroes_t6_mixed_nc.jsondaut_viper_21+0.05%-0.06%-0.06%0.00%unchanged
testcases/2-testcases_no-heroes_t6_mixed_nc.jsondaut_viper_32+0.05%-0.48%-0.48%0.00%unchanged
testcases/2-testcases_no-heroes_t6_mixed_nc.jsondaut_viper_43+0.05%-0.56%-0.56%0.00%unchanged
testcases/2-testcases_no-heroes_t6_mixed_nc.jsondaut_viper_54+0.05%-0.15%-0.15%0.00%unchanged
testcases/2-testcases_no-heroes_t6_mixed_nc.jsondaut_viper_65+0.05%-0.07%-0.07%0.00%unchanged
testcases/3-testcases_mixed-heroes-not-verified.jsondaut_viper_10+0.041%0.06%0.06%0.00%unchanged
testcases/3-testcases_mixed-heroes-not-verified.jsondaut_viper_210.00%0.00%0.00%unchanged
testcases/3-testcases_mixed-heroes-not-verified.jsondaut_viper_32-0.40%-0.40%0.00%unchanged
testcases/3-testcases_mixed-heroes-not-verified.jsondaut_viper_430.02%0.02%0.00%unchanged
testcases/3-testcases_mixed-heroes-not-verified.jsondaut_viper_540.57%0.57%0.00%unchanged
testcases/3-testcases_mixed-heroes-not-verified.jsondaut_viper_750.17%0.17%0.00%unchanged
testcases/4-testcases_no-heroes_infantry_fc5.jsonNitro_Beast_30_100.18%0.18%0.00%unchanged
testcases/emulator_verified/ahmose_solo_nc.jsonahmose_solo0+0.05%-0.41%-0.41%0.00%unchanged
testcases/emulator_verified/alonso_attacker_600_all.jsonalonso_attacker_600_all0-0.12%-0.12%0.00%unchanged
testcases/emulator_verified/alonso_attacker_900_inf_lancer.jsonalonso_attacker_900_inf_lancer00.04%0.04%0.00%unchanged
testcases/emulator_verified/alonso_attacker_900_inf_lancer.jsonalonso_attacker_900_inf_lancer10.02%0.02%0.00%unchanged
testcases/emulator_verified/alonso_minxxx_defender.jsonalonso_minxxx_defender00.30%0.30%0.00%unchanged
testcases/emulator_verified/alonso_norah_combo.jsonalonso_norah_combo0-0.04%-0.04%0.00%unchanged
testcases/emulator_verified/alonso_norah_combo.jsonalonso_norah_combo1-0.26%-0.26%0.00%unchanged
testcases/emulator_verified/alonso_norah_combo.jsonalonso_norah_combo2-0.19%-0.19%0.00%unchanged
testcases/emulator_verified/alonso_solo.jsonalonso_solo02.83%2.83%0.00%unchanged
testcases/emulator_verified/alonso_solo_v2.jsonalonso_solo_v201.65%1.65%0.00%unchanged
testcases/emulator_verified/alonso_solo_v2.jsonalonso_solo_v21-1.49%-1.49%0.00%unchanged
testcases/emulator_verified/alonso_vs_alonso.jsonalonso_vs_alonso0-0.02%-0.02%0.00%unchanged
testcases/emulator_verified/alonso_vs_alonso_inf_lancer.jsonalonso_vs_alonso_inf_lancer0-0.01%-0.01%0.00%unchanged
testcases/emulator_verified/alonso_wip_attacker.jsonalonso_wip_attacker00.05%0.05%0.00%unchanged
testcases/emulator_verified/army_term_precision_002i_003l.jsonarmy_term_precision_002i_003l00.00%0.00%0.00%unchanged
testcases/emulator_verified/attdef_jasser_patrick_minxxx_attacks_nc.jsonattdef_jasser_patrick_minxxx_attacks00.00%0.00%0.00%unchanged
testcases/emulator_verified/attdef_jasser_patrick_nc.jsonattdef_jasser_patrick00.00%0.00%0.00%unchanged
testcases/emulator_verified/attdef_jasser_patrick_swap_nc.jsonattdef_jasser_patrick_swap00.00%0.00%0.00%unchanged
testcases/emulator_verified/attdef_jasser_patrick_wip_attacks_nc.jsonattdef_jasser_patrick_wip_attacks00.00%0.00%0.00%unchanged
testcases/emulator_verified/attdef_jasser_patrick_wip_attacks_nc.jsonattdef_jasser_patrick_wip_attacks10.00%0.00%0.00%unchanged
testcases/emulator_verified/attdef_test_minxxx_attacks_nc.jsonattdef_test_minxxx_attacks_nc0-0.05%0.08%0.08%0.00%unchanged
testcases/emulator_verified/attdef_test_wip_attacks_nc.jsonattdef_test_wip_attacks_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/bahiti_solo.jsonbahiti_solo00.26%0.26%0.00%unchanged
testcases/emulator_verified/bahiti_solo_nc.jsonbahiti_solo_nc00.04%0.04%0.00%unchanged
testcases/emulator_verified/damage_precision_325l_008i_325m.jsondamage_precision_325l_008i_325m0-0.05%0.15%0.15%0.00%unchanged
testcases/emulator_verified/damage_precision_325l_009i_325m.jsondamage_precision_325l_009i_325m0-0.05%0.00%0.00%0.00%unchanged
testcases/emulator_verified/damage_precision_875i_026i_875m.jsondamage_precision_875i_026i_875m00.00%0.00%0.00%unchanged
testcases/emulator_verified/determinism_test_normal_nc.jsondeterminism_test_normal0+0.05%0.00%0.00%0.00%unchanged
testcases/emulator_verified/determinism_test_swapped_nc.jsondeterminism_test_swapped0-0.05%0.00%0.00%0.00%unchanged
testcases/emulator_verified/flint_reina_zinman_combo.jsonflint_reina_zinman_combo0-0.15%-0.15%0.00%unchanged
testcases/emulator_verified/flint_solo_nc.jsonflint_solo0+0.05%-0.02%-0.02%0.00%unchanged
testcases/emulator_verified/flint_zinman_combo_nc.jsonflint_zinman_combo_nc0+0.05%0.00%0.00%0.00%unchanged
testcases/emulator_verified/gordon_wayne_s1_extra_overlap_lvl2.jsongordon_wayne_s1_extra_overlap_nc0-0.05%0.24%0.24%0.00%unchanged
testcases/emulator_verified/gordon_wayne_s1_extra_overlap_nc.jsongordon_wayne_s1_extra_overlap_nc0-0.05%1.03%1.03%0.00%unchanged
testcases/emulator_verified/greg_mia_defender_current.jsongreg_mia_defender_current00.00%0.00%0.00%unchanged
testcases/emulator_verified/greg_mia_nohero_control_current.jsongreg_mia_nohero_control_current0+0.05%0.00%0.00%0.00%unchanged
testcases/emulator_verified/greg_mia_nohero_control_current.jsongreg_mia_nohero_control_current1+0.05%0.00%0.00%0.00%unchanged
testcases/emulator_verified/greg_only_defender_current.jsongreg_only_defender_current00.00%0.00%0.00%unchanged
testcases/emulator_verified/greg_only_defender_current.jsongreg_only_defender_current10.01%0.01%0.00%unchanged
testcases/emulator_verified/greg_only_defender_current.jsongreg_only_defender_current2-0.02%-0.02%0.00%unchanged
testcases/emulator_verified/greg_solo.jsongreg_solo00.15%0.15%0.00%unchanged
testcases/emulator_verified/hector_patrick_combo.jsonhector_patrick_combo0-0.05%-0.05%0.00%unchanged
testcases/emulator_verified/hector_renee_wayne.jsonhector_renee_wayne0-0.46%-0.46%0.00%unchanged
testcases/emulator_verified/hector_solo.jsonhector_solo00.11%0.11%0.00%unchanged
testcases/emulator_verified/jasser_solo_nc.jsonjasser_solo0+0.05%-0.02%-0.02%0.00%unchanged
testcases/emulator_verified/jessie_solo_nc.jsonjessie_solo0+0.027%-0.24%-0.24%0.00%unchanged
testcases/emulator_verified/ling_xue_solo_nc.jsonling_xue_solo0+0.05%0.00%0.00%0.00%unchanged
testcases/emulator_verified/ling_xue_solo_nc.jsonling_xue_solo1+0.05%-0.02%-0.02%0.00%unchanged
testcases/emulator_verified/logan_bahiti_combo_nc.jsonlogan_bahiti_combo_nc00.54%0.54%0.00%unchanged
testcases/emulator_verified/logan_gwen_combo_nc.jsonlogan_gwen_combo_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/logan_lynn_combo.jsonlogan_lynn_combo00.08%0.08%0.00%unchanged
testcases/emulator_verified/logan_lynn_combo.jsonlogan_lynn_combo10.03%0.03%0.00%unchanged
testcases/emulator_verified/logan_lynn_combo.jsonlogan_lynn_combo20.00%0.00%0.00%unchanged
testcases/emulator_verified/logan_reina_bahiti_combo_nc.jsonlogan_reina_bahiti_combo_nc0-0.65%-0.65%0.00%unchanged
testcases/emulator_verified/logan_solo_minxxx_nc.jsonlogan_solo_minxxx00.00%0.00%0.00%unchanged
testcases/emulator_verified/logan_solo_v2_nc.jsonlogan_solo_v200.00%0.00%0.00%unchanged
testcases/emulator_verified/lumak_bokan_solo_nc.jsonlumak_bokan_solo0+0.05%0.00%0.00%0.00%unchanged
testcases/emulator_verified/lumak_bokan_solo_nc.jsonlumak_bokan_solo1+0.05%-0.02%-0.02%0.00%unchanged
testcases/emulator_verified/lynn_solo.jsonlynn_solo0-0.06%-0.06%0.00%unchanged
testcases/emulator_verified/mia_only_defender_current.jsonmia_only_defender_current00.01%0.01%0.00%unchanged
testcases/emulator_verified/mia_only_defender_current.jsonmia_only_defender_current1-0.13%-0.13%0.00%unchanged
testcases/emulator_verified/mia_solo.jsonmia_solo0-0.20%-0.20%0.00%unchanged
testcases/emulator_verified/mia_solo.jsonmia_solo10.24%0.24%0.00%unchanged
testcases/emulator_verified/mia_solo.jsonmia_solo2-0.15%-0.15%0.00%unchanged
testcases/emulator_verified/mia_solo.jsonmia_solo30.04%0.04%0.00%unchanged
testcases/emulator_verified/mia_solo.jsonmia_solo40.23%0.23%0.00%unchanged
testcases/emulator_verified/molly_lynn_combo.jsonmolly_lynn_combo00.02%0.02%0.00%unchanged
testcases/emulator_verified/molly_solo.jsonmolly_solo0-0.06%-0.06%0.00%unchanged
testcases/emulator_verified/natalia_solo.jsonnatalia_solo0+0.05%-1.08%-1.08%0.00%unchanged
testcases/emulator_verified/norah_greg_combo.jsonnorah_greg_combo0-0.01%-0.01%0.00%unchanged
testcases/emulator_verified/norah_hector_zinman_combo.jsonnorah_hector_zinman_combo00.08%0.08%0.00%unchanged
testcases/emulator_verified/norah_s2_inf_only_B_nc.jsonnorah_s2_inf_only_B0+0.05%-0.24%-0.24%0.00%unchanged
testcases/emulator_verified/norah_s2_splash_A.jsonnorah_s2_splash_A00.21%0.21%0.00%unchanged
testcases/emulator_verified/norah_s2_splash_B_nc.jsonnorah_s2_splash_B00.00%0.00%0.00%unchanged
testcases/emulator_verified/norah_s2_splash_C_nc.jsonnorah_s2_splash_C0+0.05%-0.06%-0.06%0.00%unchanged
testcases/emulator_verified/norah_s2_splash_D.jsonnorah_s2_splash_D00.01%0.01%0.00%unchanged
testcases/emulator_verified/norah_solo.jsonnorah_solo0-0.29%-0.29%0.00%unchanged
testcases/emulator_verified/norah_zinman_combo_nc.jsonnorah_zinman_combo_nc00.07%0.07%0.00%unchanged
testcases/emulator_verified/patrick_solo_nc.jsonpatrick_solo0+0.004%-0.04%-0.04%0.00%unchanged
testcases/emulator_verified/philly_bahiti_combo.jsonphilly_bahiti_combo0-0.14%-0.14%0.00%unchanged
testcases/emulator_verified/philly_bahiti_combo.jsonphilly_bahiti_combo10.20%0.20%0.00%unchanged
testcases/emulator_verified/philly_solo.jsonphilly_solo00.16%0.16%0.00%unchanged
testcases/emulator_verified/philly_solo.jsonphilly_solo10.02%0.02%0.00%unchanged
testcases/emulator_verified/plateau_boundary_700m_006i_700l.jsonplateau_boundary_700m_006i_700l00.00%0.00%0.00%unchanged
testcases/emulator_verified/plateau_boundary_700m_007i_700l.jsonplateau_boundary_700m_007i_700l00.00%0.00%0.00%unchanged
testcases/emulator_verified/plateau_boundary_700m_008i_700l.jsonplateau_boundary_700m_008i_700l00.00%0.00%0.00%unchanged
testcases/emulator_verified/plateau_boundary_700m_009i_700l.jsonplateau_boundary_700m_009i_700l00.00%0.00%0.00%unchanged
testcases/emulator_verified/reina_attacker_wip.jsonreina_attacker_wip00.01%0.01%0.00%unchanged
testcases/emulator_verified/reina_bahiti_combo_nc.jsonreina_bahiti_combo_nc01.01%1.01%0.00%unchanged
testcases/emulator_verified/reina_logan_combo_simulator.jsonreina_logan_combo_simulator00.15%0.15%0.00%unchanged
testcases/emulator_verified/reina_solo_wip.jsonreina_solo_wip0-0.02%-0.02%0.00%unchanged
testcases/emulator_verified/renee_charge_single_target_bucket_nc.jsonrenee_charge_single_target_bucket_nc0+0.05%-0.25%-0.25%0.00%unchanged
testcases/emulator_verified/renee_hendrik_defense_bucket_nc.jsonrenee_hendrik_defense_bucket_nc0+0.05%0.00%0.00%0.00%unchanged
testcases/emulator_verified/renee_solo_nc.jsonrenee_solo_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/renee_wayne_mixed_510_vs_888.jsonrenee_wayne_mixed_510_vs_8880-0.04%-0.04%0.00%unchanged
testcases/emulator_verified/retarget_lancer_screen_nc.jsonretarget_lancer_screen_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/seo_yoon_solo_nc.jsonseo_yoon_solo0-0.05%0.10%0.10%0.00%unchanged
testcases/emulator_verified/sergey_reina_combo_nc.jsonsergey_reina_combo_nc0-0.35%-0.35%0.00%unchanged
testcases/emulator_verified/sergey_solo_nc.jsonsergey_solo00.00%0.00%0.00%unchanged
testcases/emulator_verified/simple_001_nc.jsonsimple_00100.00%0.00%0.00%unchanged
testcases/emulator_verified/troop_check_nc.jsontroop_check00.00%0.00%0.00%unchanged
testcases/emulator_verified/type_triangle_A_nc.jsontype_triangle_A_nc0+0.05%0.00%0.00%0.00%unchanged
testcases/emulator_verified/type_triangle_B_nc.jsontype_triangle_B_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/wayne_mixed_solo.jsonwayne_mixed_solo0-0.65%-0.65%0.00%unchanged
testcases/emulator_verified/wayne_mixed_solo.jsonwayne_mixed_solo1+0.05%-2.21%-2.21%0.00%unchanged
testcases/emulator_verified/wayne_reina_combo.jsonwayne_reina_combo0-0.39%-0.39%0.00%unchanged
testcases/emulator_verified/wayne_reina_wuming_combo.jsonwayne_reina_wuming_combo00.17%0.17%0.00%unchanged
testcases/emulator_verified/wayne_s1_solo.jsonwayne_s1_solo00.10%0.10%0.00%unchanged
testcases/emulator_verified/wayne_s2_solo.jsonwayne_s2_solo00.14%0.14%0.00%unchanged
testcases/emulator_verified/wos425_wip_nohero_control_nc.jsonwos425_wip_nohero_control_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos425_wip_patrick_health_nc.jsonwos425_wip_patrick_health_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos425_wip_philly_defense.jsonwos425_wip_philly_defense0-0.03%-0.03%0.00%unchanged
testcases/emulator_verified/wos425_wip_sergey_damage_taken_nc.jsonwos425_wip_sergey_damage_taken_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos425_wip_sergey_patrick_combo_nc.jsonwos425_wip_sergey_patrick_combo_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos425_wip_sergey_philly_combo.jsonwos425_wip_sergey_philly_combo0-0.05%-0.05%0.00%unchanged
testcases/emulator_verified/wos427_wip_sergey_philly_840.jsonwos427_wip_sergey_philly_8400-0.85%-0.85%0.00%unchanged
testcases/emulator_verified/wos444_bradley_s3_all_troops_damage_control_nc.jsonwos444_bradley_s3_all_troops_damage_control_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos444_bradley_s3_all_troops_damage_control_nc.jsonwos444_bradley_s3_all_troops_damage_control_nc1+0.025%0.00%0.00%0.00%unchanged
testcases/emulator_verified/wos444_bradley_s3_all_troops_damage_hero_nc.jsonwos444_bradley_s3_all_troops_damage_hero_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos444_edith_s11_mark_damage_taken_control_nc.jsonwos444_edith_s11_mark_damage_taken_control_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos444_edith_s11_mark_damage_taken_control_nc.jsonwos444_edith_s11_mark_damage_taken_control_nc1+0.05%0.00%0.00%0.00%unchanged
testcases/emulator_verified/wos444_edith_s11_mark_damage_taken_hero_nc.jsonwos444_edith_s11_mark_damage_taken_hero_nc0+0.05%0.00%0.00%0.00%unchanged
testcases/emulator_verified/wos444_edith_s12_lancer_damage_dealt_control_nc.jsonwos444_edith_s12_lancer_damage_dealt_control_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos444_edith_s12_lancer_damage_dealt_hero_nc.jsonwos444_edith_s12_lancer_damage_dealt_hero_nc0+0.05%0.00%0.00%0.00%unchanged
testcases/emulator_verified/wos444_gordon_s22_all_enemy_damage_dealt_control_nc.jsonwos444_gordon_s22_all_enemy_damage_dealt_control_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos444_gordon_s22_all_enemy_damage_dealt_control_nc.jsonwos444_gordon_s22_all_enemy_damage_dealt_control_nc10.00%0.00%0.00%unchanged
testcases/emulator_verified/wos444_gordon_s22_all_enemy_damage_dealt_hero_nc.jsonwos444_gordon_s22_all_enemy_damage_dealt_hero_nc00.12%0.12%0.00%unchanged
testcases/emulator_verified/wos451_bradley_s21_lancer_damage_up_bucket.jsonwos451_bradley_s21_lancer_damage_up_bucket00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos451_bradley_s21_lancer_damage_up_control.jsonwos451_bradley_s21_lancer_damage_up_control00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos451_bradley_s22_infantry_damage_up_bucket.jsonwos451_bradley_s22_infantry_damage_up_bucket00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos451_bradley_s22_infantry_damage_up_control.jsonwos451_bradley_s22_infantry_damage_up_control0+0.025%0.00%0.00%0.00%unchanged
testcases/emulator_verified/wos451_bradley_s3_all_damage_up_bucket.jsonwos451_bradley_s3_all_damage_up_bucket00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos451_bradley_s3_all_damage_up_control.jsonwos451_bradley_s3_all_damage_up_control00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos451_gordon_s11_lancer_damage_up_bucket.jsonwos451_gordon_s11_lancer_damage_up_bucket0-0.05%0.03%0.03%0.00%unchanged
testcases/emulator_verified/wos451_gordon_s11_lancer_damage_up_control.jsonwos451_gordon_s11_lancer_damage_up_control00.00%0.00%0.00%unchanged
testcases/emulator_verified/wos451_gordon_s21_lancer_damage_up_bucket.jsonwos451_gordon_s21_lancer_damage_up_bucket0-0.05%0.04%0.04%0.00%unchanged
testcases/emulator_verified/wos451_gordon_s21_lancer_damage_up_control.jsonwos451_gordon_s21_lancer_damage_up_control00.00%0.00%0.00%unchanged
testcases/emulator_verified/wu_ming_bradley_current_nc.jsonwu_ming_bradley_current_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/wu_ming_marksman_vs_infantry_nc.jsonwu_ming_marksman_vs_infantry_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/wu_ming_rounding_followup_nc.jsonwu_ming_rounding_followup_nc0-0.05%0.07%0.07%0.00%unchanged
testcases/emulator_verified/wu_ming_s1_isolation_nc.jsonwu_ming_s1_isolation_nc00.00%0.00%0.00%unchanged
testcases/emulator_verified/wu_ming_s2_isolation_nc.jsonwu_ming_s2_isolation_nc0+0.025%0.00%0.00%0.00%unchanged
testcases/emulator_verified/wu_ming_solo_current_nc.jsonwu_ming_solo_current_nc0+0.05%-1.42%-1.42%0.00%unchanged
testcases/emulator_verified/wu_ming_solo_nc.jsonwu_ming_solo0+0.05%0.00%0.00%0.00%unchanged
testcases/emulator_verified/zinman_solo_nc.jsonzinman_solo0+0.05%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s1-4900-vs-1000.jsons1-4900-vs-100000.00%0.00%0.00%unchanged
testcases/gatot_verified/s1-4950-vs-1000.jsons1-4950-vs-10000-0.015%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s1-5000-vs-1000.jsons1-5000-vs-10000-0.009%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s1-5050-vs-1000.jsons1-5050-vs-10000-0.004%0.02%0.02%0.00%unchanged
testcases/gatot_verified/s10-bradley-1000-inf-125-marksman-vs-5000-inf.jsons10-bradley-1000-inf-125-marksman-vs-5000-inf0-0.016%-0.02%-0.02%0.00%unchanged
testcases/gatot_verified/s15.2-secondary-heroes-1000-inf-125-lancer-125-marksman.jsons15.2-secondary-heroes-1000-inf-125-lancer-125-marksman0+0.05%-0.19%-0.19%0.00%unchanged
testcases/gatot_verified/s15.3-1000-inf-0-lancer-1000-marksman.jsons15.3-1000-inf-0-lancer-1000-marksman0-0.05%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s15.3-1000-inf-1000-lancer-0-marksman.jsons15.3-1000-inf-1000-lancer-0-marksman0-0.05%0.01%0.01%0.00%unchanged
testcases/gatot_verified/s15.3-1000-inf-1000-lancer-1000-marksman.jsons15.3-1000-inf-1000-lancer-1000-marksman0-0.05%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s15.3-2000-inf-0-lancer-1000-marksman.jsons15.3-2000-inf-0-lancer-1000-marksman0-0.032%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s15.3-2000-inf-1000-lancer-0-marksman.jsons15.3-2000-inf-1000-lancer-0-marksman0-0.043%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s16-1500-inf-1500-marksman-vs-1000-inf.jsons16-1500-inf-1500-marksman-vs-1000-inf00.00%0.00%0.00%unchanged
testcases/gatot_verified/s16-2000-inf-2000-marksman-vs-1000-inf.jsons16-2000-inf-2000-marksman-vs-1000-inf00.00%0.00%0.00%unchanged
testcases/gatot_verified/s16-2000-inf-2000-marksman-vs-5000-inf.jsons16-2000-inf-2000-marksman-vs-5000-inf0-0.004%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s16-7500-inf-vs-5000-inf.jsons16-7500-inf-vs-5000-inf0+0.013%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s2-health-1.1-4950-vs-1000.jsons2-health-1.1-4950-vs-10000-0.015%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s2-health-1.1-5000-vs-1000.jsons2-health-1.1-5000-vs-10000-0.009%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s2-health-1.1-5050-vs-1000.jsons2-health-1.1-5050-vs-10000-0.005%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s2-health-1.1-5100-vs-1000.jsons2-health-1.1-5100-vs-10000-0.002%-0.02%-0.02%0.00%unchanged
testcases/gatot_verified/s2-health-1.1-5150-vs-1000.jsons2-health-1.1-5150-vs-100000.00%0.00%0.00%unchanged
testcases/gatot_verified/s25-1000-inf-3000-marksman-vs-5000-inf.jsons25-1000-inf-3000-marksman-vs-5000-inf00.00%0.00%0.00%unchanged
testcases/gatot_verified/s25-2000-inf-2000-marksman-vs-2000-inf.jsons25-2000-inf-2000-marksman-vs-2000-inf0+0.05%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s25-2000-inf-2000-marksman-vs-3000-inf.jsons25-2000-inf-2000-marksman-vs-3000-inf00.00%0.00%0.00%unchanged
testcases/gatot_verified/s25-2000-inf-2000-marksman-vs-4000-inf.jsons25-2000-inf-2000-marksman-vs-4000-inf00.00%0.00%0.00%unchanged
testcases/gatot_verified/s25-3000-inf-1000-marksman-vs-5000-inf.jsons25-3000-inf-1000-marksman-vs-5000-inf0+0.019%0.01%0.01%0.00%unchanged
testcases/gatot_verified/s3-5000-inf-vs-1000-inf-10-lancer.jsons3-5000-inf-vs-1000-inf-10-lancer0-0.05%7.04%7.04%0.00%unchanged
testcases/gatot_verified/s31-current-2000-inf-2000-marksman-vs-5000-inf.jsons31-current-2000-inf-2000-marksman-vs-5000-inf0+0.025%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s32-current-750-marksman-wayne-vs-3000-inf.jsons32-current-750-marksman-wayne-vs-3000-inf0-0.05%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s33-current-500-marksman-wayne3-vs-5000-gatot3-inf.jsons33-current-500-marksman-wayne3-vs-5000-gatot3-inf00.10%0.10%0.00%unchanged
testcases/gatot_verified/s34-current-2100-lancer-2100-marksman-vs-1100-gatot3-inf.jsons34-current-2100-lancer-2100-marksman-vs-1100-gatot3-inf00.00%0.00%0.00%unchanged
testcases/gatot_verified/s35-current-3000-lancer-1000-marksman-vs-1100-gatot3-inf.jsons35-current-3000-lancer-1000-marksman-vs-1100-gatot3-inf00.00%0.00%0.00%unchanged
testcases/gatot_verified/s36-current-600-lancer-600-marksman-vs-1100-gatot3-inf.jsons36-current-600-lancer-600-marksman-vs-1100-gatot3-inf0-0.05%0.00%0.00%0.00%unchanged
testcases/gatot_verified/s37-current-bilateral-gatot-2000-inf-2000-marksman-vs-5000-inf.jsons37-current-bilateral-gatot-2000-inf-2000-marksman-vs-5000-inf00.00%0.00%0.00%unchanged
testcases/gatot_verified/s38-current-bilateral-gatot-800-inf-800-marksman-vs-1100-inf.jsons38-current-bilateral-gatot-800-inf-800-marksman-vs-1100-inf0-0.05%0.04%0.04%0.00%unchanged
testcases/gatot_verified/s39-1000-lancer-400-marksman-vs-500-gatot3-inf.jsons39-1000-lancer-400-marksman-vs-500-gatot3-inf00.00%0.00%0.00%unchanged
testcases/gatot_verified/s4-fc9-gatot-10000.jsons4-fc9-gatot-1000000.01%0.01%0.00%unchanged
testcases/gatot_verified/s4-fc9-gatot-20000.jsons4-fc9-gatot-2000000.01%0.01%0.00%unchanged
testcases/gatot_verified/s4-fc9-gatot-40000.jsons4-fc9-gatot-4000000.14%0.14%0.00%unchanged
testcases/gatot_verified/s4-fc9-gatot-90000.jsons4-fc9-gatot-900000-0.11%-0.11%0.00%unchanged
testcases/gatot_verified/s40-2000-inf-1000-marksman-vs-5000-inf.jsons40-2000-inf-1000-marksman-vs-5000-inf00.00%0.00%0.00%unchanged
testcases/gatot_verified/s41-300-inf-200-lancer-600-marksman-vs-500-inf.jsons41-300-inf-200-lancer-600-marksman-vs-500-inf00.00%0.00%0.00%unchanged
testcases/gatot_verified/s42-current-wayne-skill-shield-scope-200-inf-vs-450-inf.jsons42-current-wayne-skill-shield-scope-200-inf-vs-450-inf0-0.02%-0.02%0.00%unchanged
testcases/gatot_verified/s43-current-reciprocal-shield-cap-450-inf-vs-200-inf.jsons43-current-reciprocal-shield-cap-450-inf-vs-200-inf00.00%0.00%0.00%unchanged
testcases/gatot_verified/s44-current-reciprocal-shield-cap-2500-inf-vs-500-inf.jsons44-current-reciprocal-shield-cap-2500-inf-vs-500-inf00.00%0.00%0.00%unchanged
testcases/gatot_verified/s5-fc9-gatot-lumak-20000.jsons5-fc9-gatot-lumak-2000000.01%0.01%0.00%unchanged
testcases/gatot_verified/s5-fc9-gatot-lumak-40000.jsons5-fc9-gatot-lumak-4000000.00%0.00%0.00%unchanged
testcases/gatot_verified/s5-fc9-gatot-lumak-90000.jsons5-fc9-gatot-lumak-9000000.01%0.01%0.00%unchanged
testcases/gatot_verified/s7-10000-t6-marksmen-vs-one-t1-fc10-infantry.jsons7-10000-t6-marksmen-vs-one-t1-fc10-infantry00.00%0.00%0.00%unchanged
testcases/gatot_verified/s8-10000-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-10000-t9-marksmen-vs-one-t1-fc10-infantry00.00%0.00%0.00%unchanged
testcases/gatot_verified/s8-11548-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-11548-t9-marksmen-vs-one-t1-fc10-infantry0-0.05%0.76%0.76%0.00%unchanged
testcases/gatot_verified/s8-11791-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-11791-t9-marksmen-vs-one-t1-fc10-infantry0-0.05%0.54%0.54%0.00%unchanged
testcases/gatot_verified/s8-12000-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-12000-t9-marksmen-vs-one-t1-fc10-infantry00.36%0.36%0.00%unchanged
testcases/gatot_verified/s8-20000-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-20000-t9-marksmen-vs-one-t1-fc10-infantry00.00%0.00%0.00%unchanged
testcases/gatot_verified/s8-25000-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-25000-t9-marksmen-vs-one-t1-fc10-infantry00.14%0.14%0.00%unchanged
testcases/gatot_verified/s8-30116-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-30116-t9-marksmen-vs-one-t1-fc10-infantry00.02%0.02%0.00%unchanged
testcases/gatot_verified/s8-30139-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-30139-t9-marksmen-vs-one-t1-fc10-infantry0-0.02%-0.02%0.00%unchanged
testcases/gatot_verified/s8-30179-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-30179-t9-marksmen-vs-one-t1-fc10-infantry00.04%0.04%0.00%unchanged
testcases/gatot_verified/s8-30205-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-30205-t9-marksmen-vs-one-t1-fc10-infantry0-0.01%-0.01%0.00%unchanged
testcases/gatot_verified/s8-30228-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-30228-t9-marksmen-vs-one-t1-fc10-infantry0-0.02%-0.02%0.00%unchanged
testcases/gatot_verified/s8-33427-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-33427-t9-marksmen-vs-one-t1-fc10-infantry00.00%0.00%0.00%unchanged
testcases/gatot_verified/s8-33452-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-33452-t9-marksmen-vs-one-t1-fc10-infantry00.00%0.00%0.00%unchanged
testcases/gatot_verified/s8-33481-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-33481-t9-marksmen-vs-one-t1-fc10-infantry00.01%0.01%0.00%unchanged
testcases/gatot_verified/s8-33510-t9-marksmen-vs-one-t1-fc10-infantry.jsons8-33510-t9-marksmen-vs-one-t1-fc10-infantry00.01%0.01%0.00%unchanged
testcases/gatot_verified/s9-1500-t9-lancers-vs-146-t1-fc10-lancers.jsons9-1500-t9-lancers-vs-146-t1-fc10-lancers00.00%0.00%0.00%unchanged
testcases/gatot_verified/s9-1950-t9-lancers-vs-146-t1-fc10-lancers.jsons9-1950-t9-lancers-vs-146-t1-fc10-lancers0-0.07%-0.07%0.00%unchanged
testcases/gatot_verified/s9-2100-t9-lancers-vs-146-t1-fc10-lancers.jsons9-2100-t9-lancers-vs-146-t1-fc10-lancers00.55%0.55%0.00%unchanged
testcases/gatot_verified/s9-2200-t9-lancers-vs-146-t1-fc10-lancers.jsons9-2200-t9-lancers-vs-146-t1-fc10-lancers01.98%1.98%0.00%unchanged
testcases/gatot_verified/s9-2201-t9-lancers-vs-146-t1-fc10-lancers.jsons9-2201-t9-lancers-vs-146-t1-fc10-lancers0-0.73%-0.73%0.00%unchanged
testcases/gatot_verified/s9-3000-t9-lancers-vs-146-t1-fc10-lancers.jsons9-3000-t9-lancers-vs-146-t1-fc10-lancers00.15%0.15%0.00%unchanged
testcases/heroes_unittests/Flint_tc.jsondaut_viper_10+0.05%-0.01%-0.01%0.00%unchanged
testcases/heroes_unittests/Flint_tc.jsondaut_viper_21-0.05%0.37%0.37%0.00%unchanged
testcases/heroes_unittests/Hector_tc.jsondaut_viper_10-0.01%-0.01%0.00%unchanged
testcases/heroes_unittests/Jessie_tc_nc.jsondaut_viper_10+0.05%-0.06%-0.06%0.00%unchanged
testcases/heroes_unittests/Jessie_tc_nc.jsondaut_viper_21+0.05%-0.07%-0.07%0.00%unchanged
testcases/heroes_unittests/Jessie_tc_nc.jsondaut_viper_32+0.05%-0.09%-0.09%0.00%unchanged
testcases/heroes_unittests/Jessie_tc_nc.jsondaut_viper_43+0.05%-0.28%-0.28%0.00%unchanged
testcases/heroes_unittests/Jessie_tc_nc.jsondaut_viper_54+0.05%-0.19%-0.19%0.00%unchanged
testcases/heroes_unittests/Jessie_tc_nc.jsondaut_viper_65+0.05%-0.06%-0.06%0.00%unchanged
testcases/heroes_unittests/Jessie_tc_nc.jsondaut_viper_76+0.05%-0.05%-0.05%0.00%unchanged
testcases/heroes_unittests/Jessie_tc_nc.jsondaut_viper_870.00%0.00%0.00%unchanged
testcases/heroes_unittests/Mia_tc.jsondaut_viper_100.21%0.21%0.00%unchanged
testcases/heroes_unittests/Mia_tc.jsondaut_viper_21+0.05%-0.68%-0.68%0.00%unchanged
testcases/heroes_unittests/Mia_tc.jsondaut_viper_320.07%0.07%0.00%unchanged
testcases/heroes_unittests/Mia_tc.jsondaut_viper_43-0.38%-0.38%0.00%unchanged
testcases/heroes_unittests/Mia_tc.jsondaut_viper_54-0.08%-0.08%0.00%unchanged
testcases/heroes_unittests/Molly_tc.jsondaut_viper_10+0.05%-0.06%-0.06%0.00%unchanged
testcases/heroes_unittests/Molly_tc.jsondaut_viper_21+0.05%-0.07%-0.07%0.00%unchanged
testcases/heroes_unittests/Molly_tc.jsondaut_viper_32+0.05%-0.09%-0.09%0.00%unchanged
testcases/heroes_unittests/Molly_tc.jsondaut_viper_430.33%0.33%0.00%unchanged
testcases/heroes_unittests/Molly_tc.jsondaut_viper_54-0.01%-0.01%0.00%unchanged
testcases/heroes_unittests/Reina_tc.jsondaut_viper_100.00%0.00%0.00%unchanged
testcases/heroes_unittests/Reina_tc.jsondaut_viper_210.00%0.00%0.00%unchanged
testcases/heroes_unittests/Reina_tc.jsondaut_viper_42-0.74%-0.74%0.00%unchanged
testcases/heroes_unittests/Reina_tc.jsondaut_viper_530.01%0.01%0.00%unchanged
testcases/heroes_unittests/Seo-yoon_tc_nc.jsondaut_viper_10+0.05%-0.06%-0.06%0.00%unchanged
testcases/heroes_unittests/Seo-yoon_tc_nc.jsondaut_viper_32+0.05%-0.09%-0.09%0.00%unchanged
testcases/heroes_unittests/Seo-yoon_tc_nc.jsondaut_viper_43+0.05%-0.04%-0.04%0.00%unchanged
testcases/heroes_unittests/Seo-yoon_tc_nc.jsondaut_viper_54+0.05%-0.08%-0.08%0.00%unchanged
testcases/heroes_unittests/Seo-yoon_tc_nc.jsondaut_viper_61+0.05%-0.07%-0.07%0.00%unchanged
testcases/heroes_unittests/Seo-yoon_tc_nc.jsondaut_viper_65+0.05%0.00%0.00%0.00%unchanged
testcases/heroes_unittests/Seo-yoon_tc_nc.jsondaut_viper_76+0.033%0.00%0.00%0.00%unchanged
testcases/heroes_unittests/Zinman_tc.jsondaut_viper_10-0.05%0.00%0.00%0.00%unchanged
testcases/heroes_unittests/Zinman_tc.jsondaut_viper_21+0.007%0.00%0.00%0.00%unchanged
testcases/heroes_unittests/Zinman_tc.jsondaut_viper_320.00%0.00%0.00%unchanged
testcases/emulator_verified/greg_mia_combo.jsongreg_mia_combo00.98%retired

Code / Config Changes

Commits (11747ac371303048)

71303048update testcase reportingpiddlyminx25/08/2026, 08:05:01

Code Changes (Run A → Run B)

Index: simulator/config/hero_definitions/Ahmose.json
===================================================================
--- simulator/config/hero_definitions/Ahmose.json prev run
+++ simulator/config/hero_definitions/Ahmose.json this run
@@ -39,13 +39,11 @@
]
},
"duration": {
"turns": {
- "count": 2,
- "delay": 1
+ "count": 2
}
- },
- "same_effect_stacking": "max"
+ }
},
"ViperFormation/3": {
"type": "active.hero.damageTaken.down",
"value": [
@@ -61,13 +59,11 @@
]
},
"duration": {
"turns": {
- "count": 2,
- "delay": 1
+ "count": 2
}
- },
- "same_effect_stacking": "max"
+ }
}
}
},
"PrayerOfFlame": {
Index: simulator/config/hero_definitions/Blanchette.json
===================================================================
--- simulator/config/hero_definitions/Blanchette.json prev run
+++ simulator/config/hero_definitions/Blanchette.json this run
@@ -1,8 +1,7 @@
{
"name": "Blanchette",
"hero_generation": "S10",
- "experimental": true,
"troop_type": "marksman",
"skills": {
"ArmedToTheTeeth": {
"description": "Blanchette increases all Troops' Lethality by X%.",
Index: simulator/config/hero_definitions/Fred.json
===================================================================
--- simulator/config/hero_definitions/Fred.json prev run
+++ simulator/config/hero_definitions/Fred.json this run
@@ -1,8 +1,7 @@
{
"name": "Fred",
"hero_generation": "S9",
- "experimental": true,
"troop_type": "lancer",
"skills": {
"HydraulicSuppression": {
"description": "Fred's water volleys destroy opponent momentum, reducing all enemy troops' Lethality by X%.",
Index: simulator/config/hero_definitions/Freya.json
===================================================================
--- simulator/config/hero_definitions/Freya.json prev run
+++ simulator/config/hero_definitions/Freya.json this run
@@ -1,8 +1,7 @@
{
"name": "Freya",
"hero_generation": "S10",
- "experimental": true,
"troop_type": "lancer",
"skills": {
"FogOfWar": {
"description": "Freya reduces all enemy Troops' Attack by X%.",
Index: simulator/config/hero_definitions/Gregory.json
===================================================================
--- simulator/config/hero_definitions/Gregory.json prev run
+++ simulator/config/hero_definitions/Gregory.json this run
@@ -1,8 +1,7 @@
{
"name": "Gregory",
"hero_generation": "S10",
- "experimental": true,
"troop_type": "infantry",
"skills": {
"LegionOfTheSun": {
"description": "Gregory increases Attack by X% and Defense by Y% for all troops.",
Index: simulator/config/hero_definitions/Gwen.json
===================================================================
--- simulator/config/hero_definitions/Gwen.json prev run
+++ simulator/config/hero_definitions/Gwen.json this run
@@ -5,9 +5,10 @@
"skills": {
"EagleVision": {
"description": "Increasing target's damage taken by X%",
"trigger": {
- "type": "battle_start"
+ "type": "attack",
+ "source": "self.any"
},
"effects": {
"EagleVision/1": {
"type": "active.hero.damageTaken.up",
@@ -19,8 +20,14 @@
25
],
"units": {
"applies_to": "enemy.any"
+ },
+ "duration": {
+ "attacks": {
+ "count": 1,
+ "delay": 1
+ }
}
}
}
},
Index: simulator/config/hero_definitions/Magnus.json
===================================================================
--- simulator/config/hero_definitions/Magnus.json prev run
+++ simulator/config/hero_definitions/Magnus.json this run
@@ -1,8 +1,7 @@
{
"name": "Magnus",
"hero_generation": "S9",
- "experimental": true,
"troop_type": "infantry",
"skills": {
"Rapacious": {
"description": "Magnus rouses his troops with brutal intensity, boosting friendly Troop Attack by X%.",
Index: simulator/config/hero_definitions/Norah.json
===================================================================
--- simulator/config/hero_definitions/Norah.json prev run
+++ simulator/config/hero_definitions/Norah.json this run
@@ -72,8 +72,13 @@
"lancer"
],
"applies_vs": "any"
},
+ "duration": {
+ "turns": {
+ "count": 1
+ }
+ },
"trigger_damage_jobs": [
{
"source": "use.source",
"target": "enemy.living"
@@ -104,10 +109,9 @@
"applies_vs": "trigger.target"
},
"duration": {
"turns": {
- "count": 2,
- "delay": 1
+ "count": 2
}
}
},
"Momentum/2": {
@@ -120,10 +124,9 @@
25
],
"duration": {
"turns": {
- "count": 2,
- "delay": 1
+ "count": 2
}
}
}
}
Index: simulator/config/hero_definitions/README.md
===================================================================
--- simulator/config/hero_definitions/README.md prev run
+++ simulator/config/hero_definitions/README.md this run
@@ -68,10 +68,10 @@
For callers constructing a raw `BattleInput`, generation stats are added only when they explicitly use `applyHeroGenerationStats(...)` or `BattleInputBuilder.addHeroGenerationStats()`. Tournament input builders do this. The dashboard also reads `hero_generation` directly when adding or subtracting hero base stats in its form state, so dashboard inputs can already contain those stats before reaching the core simulator.
When enabled:
-- the stat block from `hero_generation_stats.json` is added to every troop type's player stats;
-- generation stats from all **main** heroes are summed;
+- each main hero's generation stat block is added only to the player-stat block for that hero's troop type;
+- generation stats from multiple main heroes of the same troop type are summed in that troop type's block;
- joiner heroes do not contribute generation stats;
- skill level does not change the generation stat block.
A `hero_generation` value with no matching entry in `hero_generation_stats.json` is reported in `config.diagnostics.unsupportedEffects` as `missing_hero_generation`. Config loading still succeeds; helpers that look up the missing block add zeroes.
Index: simulator/config/hero_definitions/Xura.json
===================================================================
--- simulator/config/hero_definitions/Xura.json prev run
+++ simulator/config/hero_definitions/Xura.json this run
@@ -1,8 +1,7 @@
{
"name": "Xura",
"hero_generation": "S9",
- "experimental": true,
"troop_type": "marksman",
"skills": {
"FungalFog": {
"description": "Xura releases an underground fungi that quickly multiplies to block enemy vision, reducing damage dealt to friendly troops by X%.",
Index: simulator/src/simulator.test.ts
===================================================================
--- simulator/src/simulator.test.ts prev run
+++ simulator/src/simulator.test.ts this run
@@ -61,8 +61,31 @@
assert.throws(() => simulateBattles(input, config, { count: 0 }), /positive integer/i);
assert.throws(() => simulateBattles(input, config, { count: 1.5 }), /positive integer/i);
});
+test("runPrepared terminates immediately when either or both armies start empty", () => {
+ const config = loadSimulatorConfig();
+ const empty: FighterInput = { troops: {}, heroes: {} };
+ const occupied: FighterInput = { troops: { infantry_t6: 20 }, heroes: {} };
+
+ const emptyAttacker = runOnce({ attacker: empty, defender: occupied }, config);
+ assert.equal(emptyAttacker.winner, "defender");
+ assert.equal(emptyAttacker.rounds, 0);
+ assert.equal(emptyAttacker.attacks.length, 0);
+ assert.equal(emptyAttacker.remaining.defender.infantry, 20);
+
+ const emptyDefender = runOnce({ attacker: occupied, defender: empty }, config);
+ assert.equal(emptyDefender.winner, "attacker");
+ assert.equal(emptyDefender.rounds, 0);
+ assert.equal(emptyDefender.attacks.length, 0);
+ assert.equal(emptyDefender.remaining.attacker.infantry, 20);
+
+ const bothEmpty = runOnce({ attacker: empty, defender: empty }, config);
+ assert.equal(bothEmpty.winner, "draw");
+ assert.equal(bothEmpty.rounds, 0);
+ assert.equal(bothEmpty.attacks.length, 0);
+});
+
test("runPrepared returns structured result for a no-hero battle", () => {
const config = loadSimulatorConfig();
const result = runOnce(
{
@@ -499,12 +522,17 @@
assert.equal(result.trace?.rounds[1]?.roundStartTroops.defender.lancer.toFixed(6), "198.013242");
});
test("runPrepared defaults to a 1500 round cap when no explicit maxRounds is provided", () => {
+ const stalemate: FighterInput = {
+ troops: { infantry_t1: 1 },
+ stats: { inf: { attack: 0, defense: 1_000_000, lethality: 0, health: 1_000_000 } },
+ heroes: {}
+ };
const result = runOnce(
{
- attacker: { troops: {}, heroes: {} },
- defender: { troops: {}, heroes: {} }
+ attacker: stalemate,
+ defender: stalemate
},
minimalConfig()
);
Index: simulator/src/simulator.ts
===================================================================
--- simulator/src/simulator.ts prev run
+++ simulator/src/simulator.ts this run
@@ -577,13 +577,14 @@
if (!controlEffects.includes(winningControl)) used.push(winningControl);
chargeUsedEffects(runtime);
}
-function winnerFor(troops: Record<SideId, Record<UnitType, number>>): SideId | undefined {
+function winnerFor(troops: Record<SideId, Record<UnitType, number>>): SideId | "draw" | undefined {
const attackerAlive = total(troops.attacker) > 0;
const defenderAlive = total(troops.defender) > 0;
if (attackerAlive && !defenderAlive) return "attacker";
if (defenderAlive && !attackerAlive) return "defender";
+ if (!attackerAlive && !defenderAlive) return "draw";
return undefined;
}
// Signed battle outcome: positive = attacker survivors, negative = defender survivors, 0 = draw.
Index: simulator/src/tooling/testcases.test.ts
===================================================================
--- simulator/src/tooling/testcases.test.ts prev run
+++ simulator/src/tooling/testcases.test.ts this run
@@ -6,9 +6,9 @@
import { loadSimulatorConfig } from "../config-node";
import { loadCalibrationComparison, readCalibrationCase, testcaseFileLookupVariants } from "./calibration";
import { applyBenjaminiHochberg, compareOutcomeDistribution, type ParityComparisonMetrics } from "./parityMetrics";
-import { adaptTestcaseEntry, applyComparisonQValues, assignDetailArtifactPaths, battleScoreDelta, buildSummaryForOutput, deterministicRoundTolerancePct, discoverTestcaseFiles, runTestcases, type TestcaseSummaryEntry } from "./testcases";
+import { adaptTestcaseEntry, applyComparisonQValues, assignDetailArtifactPaths, battleScoreDelta, buildSummaryForOutput, deterministicRoundTolerancePct, discoverTestcaseFiles, runTestcases, testcaseArmiesFromEntry, type TestcaseSummaryEntry } from "./testcases";
test("discoverTestcaseFiles follows simulator/testcases symlink and skips disabled or stale files by default", () => {
const files = discoverTestcaseFiles();
@@ -45,10 +45,45 @@
assert.equal("result" in (summary as object), false);
assert.ok(detail?.result);
assert.equal(detail?.simulatorStats?.n, 5);
assert.ok(detail?.visibility.attacker.troops.lancer);
+ assert.deepEqual(summary?.armies?.attacker.troops, { lancer_t8: 200 });
+ assert.deepEqual(summary?.armies?.defender.troops, { lancer_t9: 200 });
+ assert.deepEqual(detail?.armies, summary?.armies);
});
+test("testcase artifacts retain exact troop tiers and hero skill levels", () => {
+ const armies = testcaseArmiesFromEntry({
+ attacker: {
+ heroes: { Mia: { skill_1: 2, skill_2: 3, skill_3: 4 } },
+ joiner_heroes: { Jessie: { skill_1: 5, skill_2: 5 } },
+ troops: { infantry_t10_fc5: 12_345, lancer_t9: 678 },
+ },
+ defender: {
+ heroes: {},
+ joiner_heroes: {},
+ troops: { marksman_t11_fc9: 9_876 },
+ },
+ });
+
+ assert.deepEqual(armies.attacker.heroes.Mia, {
+ skill_1: 2,
+ skill_2: 3,
+ skill_3: 4,
+ });
+ assert.deepEqual(armies.attacker.joinerHeroes.Jessie, {
+ skill_1: 5,
+ skill_2: 5,
+ });
+ assert.deepEqual(armies.attacker.troops, {
+ infantry_t10_fc5: 12_345,
+ lancer_t9: 678,
+ });
+ assert.deepEqual(armies.defender.troops, {
+ marksman_t11_fc9: 9_876,
+ });
+});
+
test("runTestcases defaults stochastic cases to 100 samples", () => {
const config = loadSimulatorConfig();
const report = runTestcases({ matching: "simple_001" }, config);
const summary = Object.values(report.testcases)[0];
@@ -255,17 +290,8 @@
assert.equal(fourth?.game?.passes, true);
assert.equal(fifth?.game?.passes, true);
});
-test("runTestcases applies stat rounding correction for stochastic misses", () => {
- const config = loadSimulatorConfig();
- const report = runTestcases({ matching: "greg_mia_combo", repeat: 5, calibrationReportPath: "/tmp/does-not-exist.json" }, config);
- const summaries = Object.values(report.testcases);
-
- assert.ok(summaries.some((summary) => summary.deterministic === false && summary.game?.passes === false));
- assert.ok(summaries.some((summary) => summary.deterministic === false && summary.gameStatAdjustment));
-});
-
test("runTestcases default round cap lets long no-hero baselines reach battle end", () => {
const config = loadSimulatorConfig();
const report = runTestcases({ matching: "1-testcases_no-heroes_t6_single-type_nc.json", repeat: 1 }, config);
const entry = report.details.find((item) => item.testcaseId === "daut_viper_9");
Index: simulator/src/tooling/testcases.ts
===================================================================
--- simulator/src/tooling/testcases.ts prev run
+++ simulator/src/tooling/testcases.ts this run
@@ -29,14 +29,27 @@
seed?: string | number;
workers?: number;
}
+export interface TestcaseArmyDefinition {
+ heroes: Record<string, Record<string, number>>;
+ joinerHeroes: Record<string, Record<string, number>>;
+ troops: Record<string, number>;
+}
+
+export interface TestcaseArmies {
+ attacker: TestcaseArmyDefinition;
+ defender: TestcaseArmyDefinition;
+}
+
export interface TestcaseCaseReport {
file: string;
testcaseId: string;
index: number;
detailArtifact?: string;
diagnostics: string[];
+ armies?: TestcaseArmies;
+ armiesSource?: "testcase" | "retained-result";
gameResult?: unknown;
calibration?: CalibrationCaseComparison;
result?: BattleResult;
simulatorScoreDelta?: number;
@@ -67,8 +80,10 @@
file: string;
testcase_id: string;
idx: number;
detailArtifact?: string;
+ armies?: TestcaseArmies;
+ armiesSource?: "testcase" | "retained-result";
deterministic: boolean;
sampleCount: number;
game: ParityComparisonMetrics | null;
baseline: ParityComparisonMetrics | null;
@@ -204,9 +219,9 @@
entries.forEach((entry, index) => {
const testcaseId = testcaseIdFor(entry, index);
const diagnostics: string[] = [];
- const detail = emptyCaseReport(reportFile, testcaseId, index, diagnostics);
+ const detail = emptyCaseReport(reportFile, testcaseId, index, diagnostics, entry);
const preparedCase: PreparedTestcaseCase = { file, reportFile, entry, testcaseId, index, detail };
try {
preparedCase.input = adaptTestcaseEntry(entry, { seed: options.seed }, diagnostics);
preparedCase.key = snapshotKey(reportFile, index);
@@ -401,8 +416,10 @@
report.testcases[preparedCase.key!] = {
file: reportFile,
testcase_id: testcaseId,
idx: index,
+ armies: detail.armies,
+ armiesSource: detail.armiesSource,
deterministic: execution.deterministic,
sampleCount: execution.sampleCount,
game,
baseline: null,
@@ -735,21 +752,70 @@
files.push(path);
}
}
-function emptyCaseReport(file: string, testcaseId: string, index: number, diagnostics: string[]): TestcaseCaseReport {
+function emptyCaseReport(
+ file: string,
+ testcaseId: string,
+ index: number,
+ diagnostics: string[],
+ entry: unknown,
+): TestcaseCaseReport {
return {
file,
testcaseId,
index,
diagnostics,
+ armies: testcaseArmiesFromEntry(entry),
+ armiesSource: "testcase",
visibility: {
attacker: { heroes: [], troopSkillIds: [], troops: {}, skillEffectActivations: 0 },
defender: { heroes: [], troopSkillIds: [], troops: {}, skillEffectActivations: 0 }
}
};
}
+export function testcaseArmiesFromEntry(entry: unknown): TestcaseArmies {
+ const testcase = asObject(entry);
+ return {
+ attacker: armyDefinition(testcase.attacker),
+ defender: armyDefinition(testcase.defender),
+ };
+}
+
+function armyDefinition(value: unknown): TestcaseArmyDefinition {
+ const army = asObject(value);
+ const heroes: Record<string, Record<string, number>> = {};
+ const joinerHeroes: Record<string, Record<string, number>> = {};
+ for (const [name, skills] of Object.entries(asObject(army.heroes))) {
+ heroes[name] = numericRecord(skills);
+ }
+ for (const [name, skills] of Object.entries(asObject(army.joiner_heroes))) {
+ joinerHeroes[name] = numericRecord(skills);
+ }
+ return {
+ heroes,
+ joinerHeroes,
+ troops: numericRecord(army.troops),
+ };
+}
+
+function numericRecord(value: unknown): Record<string, number> {
+ const numbers: Record<string, number> = {};
+ for (const [key, candidate] of Object.entries(asObject(value))) {
+ if (typeof candidate === "number" && Number.isFinite(candidate)) {
+ numbers[key] = candidate;
+ }
+ }
+ return numbers;
+}
+
+function asObject(value: unknown): Record<string, unknown> {
+ return value && typeof value === "object" && !Array.isArray(value)
+ ? value as Record<string, unknown>
+ : {};
+}
+
function testcaseIdFor(entry: unknown, index: number): string {
const id = (entry as { test_id?: unknown; id?: unknown }).test_id ?? (entry as { id?: unknown }).id;
return id === undefined ? `case_${index}` : String(id);
}
Index: testcases/emulator_verified/greg_mia_combo.json
===================================================================
--- testcases/emulator_verified/greg_mia_combo.json prev run
+++ testcases/emulator_verified/greg_mia_combo.json this run
@@ -1,99 +0,0 @@
-[
- {
- "test_id": "greg_mia_combo",
- "description": "Greg (Infantry class) + Mia (Lancer class) combo defender \u2014 both have chance-based skills (Greg S1 20%, Mia S2 50%/S3 40%). Run 5+ battles for statistical confidence. Tests chance-skill stacking across classes. WIP attacks clean; minxxx defends.",
- "attacker": {
- "name": "[BBQ]XxWIPxX",
- "heroes": {},
- "troops": {
- "infantry_t6": 1500,
- "lancer_t6": 1069,
- "marksman_t6": 1500
- },
- "stats": {
- "inf": {
- "attack": 140.7,
- "defense": 148.2,
- "lethality": 117.0,
- "health": 131.9
- },
- "lanc": {
- "attack": 149.2,
- "defense": 148.2,
- "lethality": 116.5,
- "health": 105.1
- },
- "mark": {
- "attack": 153.7,
- "defense": 143.2,
- "lethality": 121.9,
- "health": 112.3
- }
- },
- "joiner_heroes": {}
- },
- "defender": {
- "name": "[ARK]Piddlyminxxx",
- "heroes": {
- "Mia": {
- "skill_1": 2,
- "skill_2": 2,
- "skill_3": 2
- },
- "Greg": {
- "skill_1": 1,
- "skill_2": 1,
- "skill_3": 0
- }
- },
- "troops": {
- "infantry_t6": 200,
- "lancer_t6": 200,
- "marksman_t6": 200
- },
- "stats": {
- "inf": {
- "attack": 245.9,
- "defense": 240.7,
- "lethality": 177.2,
- "health": 183.3
- },
- "lanc": {
- "attack": 324.9,
- "defense": 325.7,
- "lethality": 176.0,
- "health": 176.5
- },
- "mark": {
- "attack": 325.0,
- "defense": 319.8,
- "lethality": 181.7,
- "health": 176.5
- }
- },
- "joiner_heroes": {}
- },
- "game_report_result": [
- {
- "attacker": 3426,
- "defender": 0
- },
- {
- "attacker": 3404,
- "defender": 0
- },
- {
- "attacker": 3427,
- "defender": 0
- },
- {
- "attacker": 3450,
- "defender": 0
- },
- {
- "attacker": 3457,
- "defender": 0
- }
- ]
- }
-]
Show raw per-run patches
Run B dirty state patch
diff --git a/simulator/config/hero_definitions/README.md b/simulator/config/hero_definitions/README.md
--- a/simulator/config/hero_definitions/README.md
+++ b/simulator/config/hero_definitions/README.md
@@ -69,8 +69,8 @@
When enabled:
-- the stat block from `hero_generation_stats.json` is added to every troop type's player stats;
-- generation stats from all **main** heroes are summed;
+- each main hero's generation stat block is added only to the player-stat block for that hero's troop type;
+- generation stats from multiple main heroes of the same troop type are summed in that troop type's block;
- joiner heroes do not contribute generation stats;
- skill level does not change the generation stat block.