Animation Balancer EDU

Thread: Animation Balancer EDU

  1. tornnight's Avatar

    tornnight said:

    Default Animation Balancer EDU

    File Updated: Feb 21, 2007 9:30pm EST

    The past couple of weeks I've been investigating how to solve the issue with unit animations.
    For those not aware, animation speeds have a very big effect on how fast a unit can kill another.
    I've found the solution to balancing the damage rates between units by using the attack delay property.

    I've written a program that creates a equalized unit EDU with the only difference between units are the attack delays

    ATTACHED is a animation balanced test EDU.
    *The attached file should only be used by people trying to balance units.*

    Using this file, units should be equally powered.
    Note:
    1. If you test cavalry vs infantry, make sure you control the cavalry and don't allow them to charge. If they charge, they will destroy the infantry unit.
    2. Missile Units have only been balanced in melee

    The following example shows that all the important combat variables have been equalized. The attack delay's in bold have been adjusted from emphirical data gathered by using this EDU in order to balance the units.

    I didn't have to go through each unit because many units share the same animation.

    This data can be gathered using the following files
    export_descr_unit.txt
    battle_models.modeldb
    descr_skeleton.txt

    type Highland Nobles
    dictionary Highland_Nobles ; Highland Nobles
    category infantry
    class heavy
    voice_type Heavy
    banner faction main_infantry
    banner holy crusade
    soldier Highland_Nobles, 60, 0, 1.0
    attributes sea_faring, hide_forest, can_withdraw
    formation 1.2, 1.2, 2.4, 2.4, 4, square
    stat_health 1, 0
    stat_pri 1, 0, no, 0, 0, melee, melee_blade, slashing, sword, 500, 1.0
    ;stat_pri_ex 0, 0, 0
    stat_pri_attr no
    stat_sec 0, 0, no, 0, 0, no, melee_simple, blunt, none, 0, 0.35
    ;stat_sec_ex 0, 0, 0
    stat_sec_attr no
    stat_pri_armour 0, 0, 0, metal
    ;stat_armour_ex 5, 7, 0, 0, 4, 0, 0, metal
    stat_sec_armour 0, 0, flesh
    stat_heat 2
    stat_ground 1, -2, 3, 2
    stat_mental 15, disciplined, highly_trained
    stat_charge_dist 30
    stat_fire_delay -2500
    stat_food 60, 300
    stat_cost 1, 60, 20, 90, 70, 60, 4, 120
    armour_ug_levels 2, 3
    armour_ug_models Highland_Nobles, Highland_Nobles_ug1
    ownership scotland
    era 1 scotland
    era 2 scotland
    ;unit_info 14, 0, 9


    type Voulgier
    dictionary Voulgier ; Voulgier
    category infantry
    class heavy
    voice_type Heavy
    banner faction main_infantry
    banner holy crusade
    soldier Voulgier, 60, 0, 1.0
    attributes sea_faring, hide_forest, can_withdraw
    formation 1.2, 1.2, 2.4, 2.4, 4, square
    stat_health 1, 0
    stat_pri 1, 0, no, 0, 0, melee, melee_blade, piercing, axe, 3000, 1.0
    ;stat_pri_ex 0, 0, 0
    stat_pri_attr no
    stat_sec 1, 0, no, 0, 0, melee, melee_blade, piercing, axe, 1500, 1.0
    ;stat_sec_ex 0, 0, 0
    stat_sec_attr no
    stat_pri_armour 0, 0, 0, metal
    ;stat_armour_ex 5, 7, 8, 0, 3, 0, 0, metal
    stat_sec_armour 0, 0, flesh
    stat_heat 2
    stat_ground 1, -2, 3, 2
    stat_mental 15, disciplined, highly_trained
    stat_charge_dist 30
    stat_fire_delay -2500
    stat_food 60, 300
    stat_cost 1, 60, 20, 75, 55, 60, 4, 120
    armour_ug_levels 2, 3, 4
    armour_ug_models Voulgier, Voulgier_ug1, Voulgier_ug2
    ownership france
    era 2 france
    ;unit_info 7, 0, 8


    From battle_models.modeldb:

    The value in bold are the attack animations.

    16 -0.090000004 0 0 -0.34999999 0.80000001 0.60000002
    11 swiss_guard
    1 4
    57 unit_models/_Units/RN_Half_3Q_Plate/swiss_guard_lod0.mesh 121
    57 unit_models/_Units/RN_Half_3Q_Plate/swiss_guard_lod1.mesh 900
    57 unit_models/_Units/RN_Half_3Q_Plate/swiss_guard_lod2.mesh 2500
    57 unit_models/_Units/RN_Half_3Q_Plate/swiss_guard_lod3.mesh 6400 1
    12 papal_states
    82 unit_models/_Units/RN_Half_3Q_Plate/textures/rn_half_3q_plate_papal_states.texture
    76 unit_models/_Units/RN_Half_3Q_Plate/textures/rn_half_3q_plate_normal.texture
    48 unit_sprites/papal_states_Swiss_Guard_sprite.spr 1
    12 papal_states
    73 unit_models/AttachmentSets/Final European Light_papal_states_diff.texture
    73 unit_models/AttachmentSets/Final European Light_papal_states_norm.texture 0
    1
    4 None
    20 MTW2_Halberd_Primary
    22 MTW2_Halberd_Secondary 1
    17 MTW2_Pike_primary 1
    17 MTW2_Pike_primary

    Those of you interested in the actual animation delays I've found, see below.

    /* ------------------------------------------------------ */
    /* Mounted Animations Below */
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_HR_Lance";
    animationInfo.equalizerDelay = 0;
    animationInfo.attackBase = 5;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_HR_Sword";
    animationInfo.equalizerDelay = 40000;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_CR_Sword";
    animationInfo.equalizerDelay = 40000;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_HR_Mace";
    animationInfo.equalizerDelay = 3000;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_HR_Non_Shield";
    animationInfo.equalizerDelay = 6000;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_HR_Spear";
    animationInfo.equalizerDelay = 40000;
    animationInfo.attackBase = 3;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_CR_Spear";
    animationInfo.equalizerDelay = 40000;
    animationInfo.attackBase = 3;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    /* Mounted Missile Animations Below */
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_HR_Javelin";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 5;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_HR_Crossbow";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 3;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_HR_Bow";
    animationInfo.equalizerDelay = 0;
    animationInfo.attackBase = 3;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_CR_Bow";
    animationInfo.equalizerDelay = 0;
    animationInfo.attackBase = 3;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_HR_Pistol";
    animationInfo.equalizerDelay = 0;
    animationInfo.attackBase = 5;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_CR_Arquebus";
    animationInfo.equalizerDelay = 0;
    animationInfo.attackBase = 7;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    /* Infantry Animations Below */
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Knifeman";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Fast_Knifeman";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Crew_Bombard";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Crew_Monster_Ribault";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Crew_Cannon";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Crew_Mortar";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Crew_Ribault";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Crew_Culverin";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Crew_Serpentine";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Crew_Basilisk";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Crew_Huge_Bombard";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Elephant_Rockett_Crew";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Elephant_Artillery_Crew";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Ballista";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Catapult";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Trebuchet";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 2;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Mace";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Fast_Mace";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Slow_Mace";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Pike";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Slow_Pike";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Swordsman";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Slow_Swordsman";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Fast_Swordsman";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Non_Shield";
    animationInfo.equalizerDelay = 30000;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Non_Shield_Fast";
    animationInfo.equalizerDelay = 30000;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    /* Broken 1.1 Animation */
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_2H_Axe";
    animationInfo.equalizerDelay = -1500;
    animationInfo.attackBase = 5;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Fast_2H_Axe";
    animationInfo.equalizerDelay = -1500;
    animationInfo.attackBase = 5;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Slow_2HSwordsman";
    animationInfo.equalizerDelay = 500;
    animationInfo.attackBase = 5;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_2HSwordsman";
    animationInfo.equalizerDelay = 500;
    animationInfo.attackBase = 5;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Halberd_Primary";
    animationInfo.equalizerDelay = 3000;
    animationInfo.attackBase = 5;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Halberd_Secondary";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 5;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Spear";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 3;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Fast_Spear";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 3;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    /* Missile Animations Below */
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Fast_Javelin";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 5;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Crossbow";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Fast_Crossbow";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Pavise_Crossbow";
    animationInfo.equalizerDelay = 1500;
    animationInfo.attackBase = 4;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Bowman";
    animationInfo.equalizerDelay = 0;
    animationInfo.attackBase = 3;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Fast_Bowman";
    animationInfo.equalizerDelay = 0;
    animationInfo.attackBase = 3;
    animationInfoList.add(animationInfo);
    /* ------------------------------------------------------ */
    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Fast_Musket";
    animationInfo.equalizerDelay = 0;
    animationInfo.attackBase = 8;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Fast_Arquebus";
    animationInfo.equalizerDelay = 0;
    animationInfo.attackBase = 7;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Elephant_Crew";
    animationInfo.equalizerDelay = 500;
    animationInfo.attackBase = 7;
    animationInfoList.add(animationInfo);

    animationInfo = new AnimationInfo();
    animationInfo.animationName = "MTW2_Handgun";
    animationInfo.equalizerDelay = 0;
    animationInfo.attackBase = 5;
    animationInfoList.add(animationInfo);
    Last edited by tornnight; May 15, 2007 at 03:03 PM.
    "The first casualty when war comes, is truth." - Hiram Johnson
    Developer of The Long Road Modification
     
  2. Averroës's Avatar

    Averroës said:

    Default Re: Animation Balancer EDU

    Wow, Tornnight. Are you going to integrate this into the final 1.9? Will you still be able to balance missile and cavalry charge troops? How does this effect things like spear walls? Amazing stuff. Well, done.
     
  3. tornnight's Avatar

    tornnight said:

    Default Re: Animation Balancer EDU

    I'm going to use it as the basis for TLR's EDU. Using this method, unit cards will actually mean something. Now that animations are out mostly of the picture, I can easily balance the units by just playing with their attributes and attack/defense scores.

    Missiles, cavalry charges, spear walls are a different problem with a different solution which shouldn't be nearly as difficult.
    Last edited by tornnight; February 10, 2007 at 02:01 PM.
    "The first casualty when war comes, is truth." - Hiram Johnson
    Developer of The Long Road Modification
     
  4. Jush's Avatar

    Jush said:

    Default Re: Animation Balancer EDU

     
  5. ziher said:

    Default Re: Animation Balancer EDU

    My guess is that combining it with Realcombat mod logic would create best EDU
     
  6. Chicken Man said:

    Default Re: Animation Balancer EDU

    Yup^^^
     
  7. The Sweeper's Avatar

    The Sweeper said:

    Default Re: Animation Balancer EDU

    How do we integrate this in our game? Sorry for the stupid question, I just have no idea..
     
  8. tornnight's Avatar

    tornnight said:

    Default Re: Animation Balancer EDU

    You don't.

    It is research for Modder use. I'm using it to create the EDU (Unit Specifications) for the next Beta of 1.9.
    "The first casualty when war comes, is truth." - Hiram Johnson
    Developer of The Long Road Modification