Drop? garrison? carrier loss question

thecombat calculator is very simple, and has no way of calculating carrier losses.

but the orders submitted (drop all, collect all) definitely have an impact on carrier losses for the victorious party (the loser obviously loses all carriers)
In the battle that started this conversation,

all carriers arrived at the star at the same time. I already owned the star, and had ordered both of my carriers to drop all ships. in the combat system this would eliminate carrier losses completely for this battle. as the garrison would either fight first or be considered my largest ā€˜fleetā€™
but in this new system, I sustained a double carrier loss.

but if the victor is the attacker, and they are bringing multiple fleets to a battle, carrier losses are almost inevitable,
whereas defenders can all but eliminate losses.
with a carrier in orbit (or a carrier arriving at the same time as the enemy to reinforce)
the victorious defender can mitigate carrier losses by collecting all ships and their combat occuring from one large fleetā€¦

so youre saying the carrier losses are tallied retrospectively for the winner of the combat after the combat has occured, taking into account the orders that were submitted.?
if thats the case the orders submitted by the attacker may still be ratified by the carrier losses calculation

or are you saying that losses of carriers is now simply a mathematical equation?
IE if I lose 1 ship more than half my entire fleet I lose more than half my carriers rounded up?
as thats the only way the combat that started this thread could occur.

I may be wrong, and it may have changed, But I dont belive this to be the case. id have to test it.
if you have 5 carriers on a star, 4 with 1 ship each and 1 carrier with 1000 ships, it was my understanding that in this new combat system your largest fleet fights first.your smaller fleets second, and your garrison last.

In your OP screenshot,
GhostLegion has before combat
star garrison 28 ships

  • carrier empty 1 ship
  • carrier empty 1 ship

You lost 18 ships = 16 + 1 + 1

So your loss ratio is 0.600 = 18 ships / 30 ships to begin with .
I do not know how Jay wrote the code, but I would guess he starts distribution with the smallest group.
So empty carrier 1 ship loss ratio of 0.6 rounding = lose 1 ship, that carrier is destroyed.
Repeat procedure again for the next smallest group, your other empty carrier.
Final largest group, 28 ships must lose the remainder of scheduled loss ships = 18 ships = 16 + 1 + 1

Do some tests.
If you drop or collect on ticks before attacker arrive, these do not count as test.

1
Defender fully heavy loaded carrier drop all arriving at same tick as attacker
read battle report , and count ships after combat
2
Defender empty carrier collect all arriving at same tick as attacker
remember the name of this carrier, should be lost after combat.
read battle report , and count ships after combat

Try some carriers loaded average low or average high

Trust the test results. Peopleā€™s perceptions or pre-conceptions are not always accurate.

If the attacker wins the battle, owns the star, then he may perform carrier transfers after combat.

Why would the defender be allowed two carrier transfer opportunities ? both before and after combat ?

ill try to test, its just very time consuming. and I need multiple accounts etc.

not before and after combat, a drop and a pickup from different carriers following their arrival orders.
carrier A drops all, drops happen first
carrier B picks up all,

I think all carrier transfers happen after combat, and after Industry manufactures new ships.

If it happened before combat, then that was a previous tick before combat.

OK, well that was definately not how it previously worked before allied combat, dropping all ships on arrival meant NO carrier losses at all.
and largest fleets always fought first, till all ships were expended they were then destroyed.
then the next largest fleet engaged etc etc.

I have always been a little hazy on how ship losses are distributed amongst attackers when two enemy fleets arrive at a star controlled and defended by a third player.

Player A and B (enemies) arrive simultaneously at star controlled by player C
according to the current description on codex, A and B become a team against C
C fires first.
who loses those ships?
A? B? both of them at the same time? the one who flew shortest distance? half each?
If its half what if the defenders weapons level is an odd number like 2+1?
A and B lose 1.5 ships?
or does the defender shoot A on the first firing round then B on his second?
what if there is no second?

Jay changed the code around 2015 March. Click and Read this thread. The codex is out of date.

New Rules for Combat for Ships in Formal Alliances

Jayā€™s explanation for the new combat algorithm is that combat is always two sided, defender vs attacker, even when three or more empires arrive for the melee. This is repeated until one empire owns the star.

I have not yet been lucky enough to be in a three way combat, so really IDK.
My gut instinct is that Jay probably wanted to keep it simple, so what worked for two empires is expanded to three empires. Damage could be spread proportionally from smallest carrier or garrison to largest carrier or garrison.

Are you using a Mac ? not a Windows ? I ask because I had to manually insert carriage returns when I quote you. strange ?

That part of the codex is not precise, and is an issue concerning unclaimed stars, which is unrelated to combat.

When a star is unclaimed, WG are not operative, so carriers fly towards it 1/3 LY per tick.
When two empires arrive the unclaimed star at the same tick, the carrier which flew the shortest distance, which is the same as saying the carrier which arrived the earlier fraction of a tick, becomes the owner of the star, who then becomes the defender in the ensuing combat.

yeah I understood that, but couldnt think of another fair way to determine who a defender would choose to attack first if two enemies present themselves at the same time.
or who would gain the star if after grouped combat with the defender enemy fleets had the same fleet strength

yeah it just doesnt make it very easy to understand whats going to happen, especially when ship counts are very low,
for instance
A arrives with weap2 and 11 ships`
B arrives with weap2 and 11 ships
C has weap1+1 defender and 14 ships

I can put 22 vs 14 in the calculator, but thats not going to tell me who will have what when A+B face off for round 2. or who will be defender, and one ship can make the difference.

if damage is incurred evenly as a team, A and B will end up with 4 ships each. who then assumes the star for the second combat?
if A is fired upon first, then B in the second firing round the outcome could be totally different.

It being unable to predict what will happen and having no calculator changes the strategy immensely.
even the most mathematically savvy player who uses the calc extensively, factors in production rates and times travelled has absolutely no way of knowing how a battle will turn out.

if im faced with the 3 options of arriving before, at the same time or after, which is best?
is it better to knock out the defender C in collaboration with my enemy, splitting the losses?
only if i can understand who will have the larger fleet and assume the star for defence

or arrive before and battle defender C alone at 1+1, and face B with the certainty of 2+1 defenders advantage,

or arrive after B and C have sustained casualties and try against B as an attacker.

That is an interesting infrequent corner case question with a big impact, that only @JayKyburz can answer.

Either A or B will defend the star in the second round of combat with 4 ships each.
Does it make any difference whether carrier A or B arrived in a shorter distance ?
Does defender C attack carrier A first or carrier B first ?

Apologies if I missed stuff, Iā€™ve not read the entire thread.

There is no ā€˜second combatā€™ - if I understand what you are saying correctly. Only one battle can be fought at a single star per turn.

If multiple players arrive at the same time then it shoves everyone into the same battle, whenever all the remaining players are allies then one of them takes ownership.

I have no idea what happens if some of the attackers are allies with some of the other attackers. Lets say we have attackers ABC and defender D. If A is ally with B, and B is ally with C but A and C are enemies.

My best guess is damage will keep being applied until all players are allies of each other.

noone is allied in this situation. its 3 enemies meeting on a star. at the same time.
we know A nd B will engage in combat as a team against Defender C until he dies, then one of them will assume the star and a second combat is fought between Aand B we just dont know how the damage from C is dealt to the initial attackers.
evenly? sequentially?

The player who was nearest the star will take ownership. Then battle is fought with that player getting the defence bonus. Damage is applied to each attacker then the defender.

  1. First attacker takes damage
  2. Second attacker takes damage
  3. Defender takes damage
  4. ^Repeat

When only one player is left that player takes control of the star.

I think thereā€™s a small bug currently where both attackers will share Weapon tech level. Itā€™s best not to think of fleets doing damage but instead of fleets taking damage each round.

(at least this is how it used to work)

def combat(universe, star):
    fleets = star.fleets_in_orbit

    # if the star is not owned, give the star bonus to the fleet who was
    # closest to the star before moving.
    # we can now assume that the star is owned by _somebody_
    if not star.player:
        closest_fleet = fleets[0]
        for f in fleets:
            if f.last_jump_dist < closest_fleet.last_jump_dist:
                closest_fleet = f
        star.player = closest_fleet.player

    # begin a report that tells the state of the star before the battle
    recipients = [star.player.user_id]
    for fleet in fleets:
        if fleet.player.user_id not in recipients:
            recipients.append(fleet.player.user_id)

    star_report = {}
    star_report["name"] = star.name
    star_report["uid"] = star.uid
    star_report["ss"] = star.strength
    star_report["es"] = 0  # end strength will be filled in after the battle
    star_report["puid"] = star.player.uid
    star_report["w"] = star.player.weapons.value

    # Sort all ships into teams.
    # Defenders are all ships allied with the owner of the star.
    # Attackers are all ships not allies with the star owner.
    attackers = []
    defenders = [star]
    attacker_total_strength = 0
    defender_total_strength = star.strength
    for fleet in fleets:
        if fleet.player.is_at_war(star.player):
            attackers.append(fleet)
            attacker_total_strength += fleet.strength
        else:
            defenders.append(fleet)
            defender_total_strength += fleet.strength

    if not len(attackers):
        # everybody is friends here so there is no need for combat
        return

    universe.log_hostility(star.player, attackers[0].player)

    # Calculate the defenders WS which is the best of all defenders +1
    # Calculate the attackers WS which is the best of all attackers.
    attacker_weapons = attackers[0].player.weapons.value
    for attacker in attackers:
        if attacker.player.weapons.value > attacker_weapons:
            attacker_weapons = attacker.player.weapons.value

    defender_weapons = star.player.weapons.value
    for defender in defenders:
        if defender.player.weapons.value > defender_weapons:
            defender_weapons = defender.player.weapons.value

    # defenders get home star ws advantage.
    defender_weapons += 1

    # begin a report that tells the state of each fleet before the battle
    attacker_report = {}
    defender_report = {}
    def report_fleet(fleet):
        report = {}
        report["n"] = fleet.name
        report["ss"] = fleet.strength
        report["es"] = 0
        report["puid"] = fleet.player.uid
        report["w"] = fleet.player.weapons.value
        return report

    for attacker in attackers:
        attacker_report[attacker.uid] = report_fleet(attacker)
    for defender in defenders:
        if isinstance(defender, Fleet):
            defender_report[defender.uid] = report_fleet(defender)

    # work out who won and which team won and what how many ships in the
    # winner should lose in damage.
    attacker_rounds_survived = math.ceil(attacker_total_strength / defender_weapons)
    defender_rounds_survived = math.ceil(defender_total_strength / attacker_weapons)

    attackers_win = False
    if defender_rounds_survived >= attacker_rounds_survived:
        winners = defenders
        winner_total_strength = defender_total_strength
        losers = attackers
        damage = (attacker_rounds_survived - 1) * attacker_weapons
    else:
        attackers_win = True
        winners = attackers
        winner_total_strength = attacker_total_strength
        losers = defenders
        damage = (defender_rounds_survived ) * defender_weapons

    # kill all the losers
    for loser in losers:
        loser.strength = 0

    # sort the winners by strength
    winners = sorted(winners, key=lambda f: (f.strength))

    # iterate though the winning carriers distributing damage fairly
    damage_to_distribute = int(damage)
    for winner in winners:
        if not damage_to_distribute or winner.strength < 1: continue
        winners_damage = int(math.floor(damage / (winner_total_strength / winner.strength)))

        # if this winners damage is more that what is left to be distributed,
        # reduce it.
        if damage_to_distribute < winners_damage:
            winners_damage = damage_to_distribute

        if winner.strength < winners_damage:
            damage_to_distribute -= winners.strength
            winner.strength = 0
        else:
            winner.strength -= winners_damage
            damage_to_distribute -= winners_damage

    # handle the case where rounding meant that not all damage was dealt
    while damage_to_distribute > 0:
        for winner in winners:
            if damage_to_distribute <= 0:
                break
            if winner.strength > 0:
                # don't allow any strength to go lower than 0
                winner.strength -= 1
            damage_to_distribute -= 1

    # give the star to the winning player with the most ships remaining.
    total_player_strengths = {}
    for winner in winners:
        if winner.player not in total_player_strengths:
            total_player_strengths[winner.player] = winner.strength
        else:
            total_player_strengths[winner.player] += winner.strength

    largest_player = None
    largest_strength = 0
    for player, strength in total_player_strengths.iteritems():
        if not largest_player:
            largest_player = player
            largest_strength = strength
        if strength > largest_strength:
            largest_player = player
            largest_strength = strength

    loot = 0
    if attackers_win:
        star.player = largest_player
        loot = star.economy * 10
        largest_player.cash += loot
        star.economy = 0
        star.calc_resources()

    # the final strength of the star.
    star_report["es"] = star.strength

    # the final strengths of the fleets.
    for attacker in attackers:
        attacker_report[attacker.uid]["es"] = attacker.strength
    for defender in defenders:
        if isinstance(defender, Fleet):
            defender_report[defender.uid]["es"] = defender.strength

    # The combat report
    data = {"template": "combat_mk_ii",
            "star": star_report,
            "attackers": attacker_report,
            "defenders": defender_report,
            "dw": defender_weapons,
            "aw": attacker_weapons,
            "loot": loot,
            "looter": star.player.uid,
            }

    universe.create_event(recipients, data)

    return True

this is the relevant bit

# sort the winners by strength
winners = sorted(winners, key=lambda f: (f.strength))

# iterate though the winning carriers distributing damage fairly
damage_to_distribute = int(damage)
for winner in winners:
    if not damage_to_distribute or winner.strength < 1: continue
    winners_damage = int(math.floor(damage / (winner_total_strength / winner.strength)))

    # if this winners damage is more that what is left to be distributed,
    # reduce it.
    if damage_to_distribute < winners_damage:
        winners_damage = damage_to_distribute

    if winner.strength < winners_damage:
        damage_to_distribute -= winners.strength
        winner.strength = 0
    else:
        winner.strength -= winners_damage
        damage_to_distribute -= winners_damage

# handle the case where rounding meant that not all damage was dealt
while damage_to_distribute > 0:
    for winner in winners:
        if damage_to_distribute <= 0:
            break
        if winner.strength > 0:
            # don't allow any strength to go lower than 0
            winner.strength -= 1
        damage_to_distribute -= 1

damage goes to the largest carrier first.

the best way to ensure carriers survive is to get them out of there!

sorry I was not clear, 2 enemies meeting on a third players star.