Skip to main content
1 of 3
user6209
  • 631
  • 2
  • 8
  • 23

TL DR:

(This is a summary of the full answer.)

Against turrets:

  • Caster minions perform the worse when promoted, or promoted+baron.
  • Cannon minions are the best when promoted+baron, and about equally good as melee when they only have promote.

Against minions:

  • Melee are the best with promote, or promote+baron.
  • Cannons with promote+baron are the worse, because baron reduces their attack speed by 50%!

Full answer

[...] it should be fairly trivial to calculate total offensive stats and final dps of a minion.

Not really. It can be quite complex.

Minions get a different bonus from baron and promote based on what whether they are melee, casters, or cannons. To check which one deals more damage per second (dps) we will ignore how long they survive (obviously a ranged cannon would take less damage from enemies than a melee minion).

To do so, we multiply their total attack damage by their final attack speed. Then we apply multiplicative bonuses. Minions deal bonus damage to towers, and have a penalty on champions (but champions aren't examined in this answer).

Any damage reductions (e.g. armor, magic resist, etc) are disregarded, so the dps value is unmitigated.

The results are:

=======================================================================
Minion: caster
----------------------------------------
VS turrets

promote
DPS: 154.2

Baron + promote
DPS: 180.3

----------------------------------------
VS minions

promote
DPS: 102.8

Baron + promote
DPS: 120.2


========================================================================
Minion: melee
----------------------------------------
VS turrets

promote
DPS: 256.5

Baron + promote
DPS: 256.5

----------------------------------------
VS minions

promote
DPS: 171.0

Baron + promote
DPS: 299.2


===========================================================================
Minion: siege
----------------------------------------
VS turrets

promote
DPS: 254.2

Baron + promote
DPS: 329.2

----------------------------------------
VS minions

promote
DPS: 169.5

Baron + promote
DPS: 109.8

Python code used:

raw_minion_stats = dict(
    caster=dict(
        att_dmg=23,
        att_dmg_per_90_sec=1,
        att_speed=0.670,
        multiplicative_dmg_bonus_vs_turrets=1.5),

melee=dict(
    att_dmg=12,
    att_dmg_per_90_sec=0.5,
    att_speed=1.250,
    multiplicative_dmg_bonus_vs_turrets=1.5),

siege=dict(
    att_dmg=39.5,
    att_dmg_per_90_sec=1.5,
    att_speed=1.000,
    multiplicative_dmg_bonus_vs_turrets=1.5))


promote_buff_stats = dict(
    caster=dict(
        att_dmg=75,
        att_speed_bonus=0.3),

    melee=dict(
        att_dmg=50,
        att_speed_bonus=0.9),

    siege=dict(
        att_dmg=100,
        # Since it would deal aoe dmg, we can assume it would hit 3 minions simultaneously.
        multiplicative_dmg_bonus_vs_minions=3))


baron_buff_stats = dict(
    caster=dict(
        att_dmg=20),

    melee=dict(
        extra_percent_dmg_vs_minions=0.75,
    ),

    siege=dict(
        att_dmg=50,
        att_speed_bonus=-0.5,
        extra_percent_dmg_vs_turrets=1))


def final_att_dmg(minion_name, game_time, buffs_dcts):
    """
    Returns total att_dmg after applying all bonuses.

    :param minion_name: 'caster', 'melee' or 'cannon'
    :param game_time: (int) Game time in minutes.
    :param buffs_dcts: (list) List of buff dicts.
    :return: (float)
    """

    # Base attack damage
    val = raw_minion_stats[minion_name]['att_dmg']

    # Bonus by time
    att_dmg_per_min = raw_minion_stats[minion_name]['att_dmg_per_90_sec'] / 1.5
    val += att_dmg_per_min * game_time

    # Bonus by buffs
    for dct in buffs_dcts:
        minion_buff_dct = dct[minion_name]
        if 'att_dmg' in minion_buff_dct:

            val += minion_buff_dct['att_dmg']

    return val


def final_att_speed(minion_name, buffs_dcts):

    # Base attack damage
    val = raw_minion_stats[minion_name]['att_speed']

    # Bonus by buffs
    bonus_val = 0
    for dct in buffs_dcts:
        minion_buff_dct = dct[minion_name]
        if 'att_speed_bonus' in minion_buff_dct:

            bonus_val += minion_buff_dct['att_speed_bonus']

    return val * (1 + bonus_val)


def unmitigated_dps(minion_name, game_time, buffs_dcts, versus):
    """
    Calculates dmg per second of a minion with given buffs versus selected target,
    without taking into account dmg resistances of target.
    (Champion unmitigated_dps not available yet.)

    DPS is irrelevant of combat duration.

    :param versus: 'minions', or 'turrets'
    :return:
    """

    att_dmg = final_att_dmg(minion_name=minion_name, game_time=game_time, buffs_dcts=buffs_dcts)
    att_speed = final_att_speed(minion_name=minion_name, buffs_dcts=buffs_dcts)

    val = att_dmg * att_speed

    extra_percent_dmg_keyword = 'extra_percent_dmg_vs_' + versus

    for dct in buffs_dcts:
        minion_buff_dct = dct[minion_name]
        if extra_percent_dmg_keyword in minion_buff_dct:

            val *= 1 + minion_buff_dct[extra_percent_dmg_keyword]

    # Minions' final dmg gets a bonus vs turrets and a penalty vs champions.
    multiplicative_bonus_keyword = ''
    if versus == 'turrets':
        multiplicative_bonus_keyword = 'multiplicative_dmg_bonus_vs_' + versus
    elif versus == 'minions':
        multiplicative_bonus_keyword = 'multiplicative_dmg_bonus_vs_' + versus

    if multiplicative_bonus_keyword in raw_minion_stats[minion_name]:
        val *= raw_minion_stats[minion_name][multiplicative_bonus_keyword]

    return val

# =====================================================================================================================
# DISPLAY RESULTS
selected_game_time_in_minutes = 30

# All minions:
for _minion_name in sorted(raw_minion_stats):
    msg = '\n' + '='*60
    msg += '\nMinion: {}'.format(_minion_name)

    for tar_name in ('turrets', 'minions'):
        msg += '\n' + '-'*40
        msg += '\nVS {}\n'.format(tar_name)
        # promote
        msg += '\npromote'
        minion_dps = unmitigated_dps(minion_name=_minion_name,
                                     game_time=selected_game_time_in_minutes,
                                     buffs_dcts=[promote_buff_stats, ],
                                     versus=tar_name)

        msg += '\nDPS: {:.1f}'.format(minion_dps)

        msg += '\n'

        # Baron + promote
        msg += '\nBaron + promote'
        minion_dps = unmitigated_dps(minion_name=_minion_name,
                                     game_time=selected_game_time_in_minutes,
                                     buffs_dcts=[baron_buff_stats, promote_buff_stats],
                                     versus=tar_name)

        msg += '\nDPS: {:.1f}\n'.format(minion_dps)

    print(msg)

Although i did check some of the results (and they seemed reasonable) I have not tested everything. In case you find a mistake, please let me know.

user6209
  • 631
  • 2
  • 8
  • 23