Fractal Softworks Forum

Please login or register.

Login with username, password and session length
Advanced search  

News:

Starsector 0.97a is out! (02/02/24); New blog post: Simulator Enhancements (03/13/24)

Author Topic: How does damage actually work?  (Read 1762 times)

BaBosa

  • Captain
  • ****
  • Posts: 445
    • View Profile
How does damage actually work?
« on: July 21, 2021, 02:29:49 AM »

So a bit of background, I'm currently learning a programming language (MATLAB) and I figured I could practice by recreating how damage is programed in Starsector and find out roughly how long it actually takes for a ship to die from a weapon.

I thought I knew how damage and armour works in Starsector but I found while trying to recreate it that I actually had no idea.
So I want to share where I am at the moment and what I'm missing and I hope someone can help me.

So what I've picked up is that every ship is split into cells and each cell starts with the armour value of the ship (or 1/8 of it, I remember seeing that somewhere but can't find it again) and then when a projectile hits a ship, SS checks what cell it hit, finds what cells are in the 8 neighbouring spots and what cells are in the 12 adjacent but not diagonal spots from those. This gives a maximum of 9 and 12 of what I'm going to call major cells and minor cells respectfully.

Once the cells are found, it sums together the current value of the major cells and half of the current value of the minor cells, (unless the current value is less than 5% of the original value in which case it uses that 5%, maybe?). Then it divides that sum by the number of major cells contributing plus half the number of minor cells contributing.
This gives the average armour value. Add here any bonuses to armour.

That's used in the damage calculation, (damage squared divided by damage plus armour (Edit; unless that would result in less than 15% of the damage dealt, in which case it uses damage times 0.15)).
The resulting damage is then subtracted from the value of every major cell and minor cells take half that damage.

Then I'm not sure how hull damage works, I know how it works if all the armour cells are stripped but I haven't noticed any mention of how it works if some cells are gone but others are still there, but my guess is that
If the damage takes a cell below a value of 0, that number is recorded and then after the damage to each cell has been calculated, the excess damage past 0 from each cell is added together and then divided by the number of major cells and half minor cells and that average is dealt to the hull.

With HE damage, the damage in the armour damage calculation is doubled but then the excess hull damage is halved to compensate due to only doing 100% damage to hull not 200% like armour and the opposite for kinetic and similar to that for frag.

Is that right or did I hur dur somewhere? I'm not sure if the 5% minimum armour value is applied to the individual armour cells or the average armour value. And as I said, the hull damage calculation is a complete guess.

Thank you in advance  ;D
« Last Edit: July 22, 2021, 02:26:47 AM by BaBosa »
Logged

Yunru

  • Admiral
  • *****
  • Posts: 1560
    • View Profile
Re: How does damage actually work?
« Reply #1 on: July 21, 2021, 02:43:16 AM »

Armor both has a minimum percentage that will always apply, and a minimum damage (percentage?) that it will always let through, so the latter may throw off your numbers.

SafariJohn

  • Admiral
  • *****
  • Posts: 3010
    • View Profile
Re: How does damage actually work?
« Reply #2 on: July 21, 2021, 07:46:36 AM »

I reverse engineered some of it, based on what has been shared here on the forum over the years. I didn't bother to account for armor cells, so it always comes back with a lower number needed to destroy the target than actually required, assuming no skills. Other than that it is accurate - I have counted shots in-game to confirm it.

Spoiler
Code: java
public class SSArmorDurabilityCalc {
    private static float MAX_HULL = 20000;
    private static float MAX_ARMOR = 2325;

    private static float DAMAGE = 100;

    private static float hull = MAX_HULL;
    private static float armor = MAX_ARMOR;

    public static void main(String args[]) {
        float count = 0;

        while (hull > 0) {
            float dam = DAMAGE * (DAMAGE / (DAMAGE + Math.max(armor, MAX_ARMOR * 0.05f)));
            dam = Math.max(dam, DAMAGE * 0.15f);

            if (armor > 0) armor -= dam;
            else hull -= dam;

            count++;
        }

        System.out.println(count + " shots");
    }

}
[close]
Logged

BaBosa

  • Captain
  • ****
  • Posts: 445
    • View Profile
Re: How does damage actually work?
« Reply #3 on: July 21, 2021, 02:58:08 PM »

Armor both has a minimum percentage that will always apply, and a minimum damage (percentage?) that it will always let through, so the latter may throw off your numbers.

I forgot to mention the minimum 15% damage but it’s in my script. I swear.
The minimum 5% armour is what I’m confused by. Is it the individual cells that have a minimum of 5% or is it the average that has to be at least 5%? It’s not a big difference but I feel like being pedantic.

I reverse engineered some of it, based on what has been shared here on the forum over the years. I didn't bother to account for armor cells, so it always comes back with a lower number needed to destroy the target than actually required, assuming no skills. Other than that it is accurate - I have counted shots in-game to confirm it.

Spoiler
Code: java
public class SSArmorDurabilityCalc {
    private static float MAX_HULL = 20000;
    private static float MAX_ARMOR = 2325;

    private static float DAMAGE = 100;

    private static float hull = MAX_HULL;
    private static float armor = MAX_ARMOR;

    public static void main(String args[]) {
        float count = 0;

        while (hull > 0) {
            float dam = DAMAGE * (DAMAGE / (DAMAGE + Math.max(armor, MAX_ARMOR * 0.05f)));
            dam = Math.max(dam, DAMAGE * 0.15f);

            if (armor > 0) armor -= dam;
            else hull -= dam;

            count++;
        }

        System.out.println(count + " shots");
    }

}
[close]

Are you the one who wrote the explanation on armour? If so thank you, I could not have tested it enough to figure it out.
Your script is like what I’m trying to do but I’m trying to also add the cells and then get it to record every value for armour and hull to make a graph.
Logged

Sutopia

  • Admiral
  • *****
  • Posts: 1005
    • View Profile
Re: How does damage actually work?
« Reply #4 on: July 21, 2021, 03:31:15 PM »

Each cell has 1/15 of the shown armor attribute and serves as damage buffer. When it runs out, hull takes damage.
The damage is distributed among affected cells but not evenly. Each cell then calculates the damage to armor, then to hull if armor runs out.
The minimum armor is used when calculating damage reduction from armor rating, it’s a simple max(remaining affected armor, 5% armor rating)

I may be wrong but this is what I think how the system works.
Logged


Since all my mods have poor reputation, I deem my efforts unworthy thus no more updates will be made.

Vanshilar

  • Admiral
  • *****
  • Posts: 585
    • View Profile
Re: How does damage actually work?
« Reply #5 on: August 08, 2021, 07:18:22 PM »

The forum guide for armor can be found here: https://fractalsoftworks.com/forum/index.php?topic=12268

The ship is divided into cells, with each cell starting with 1/15 of the base armor rating. So if a ship has 1500 base armor, then it means that each cell starts with 1500 * 1/15 = 100 armor.

On a hit to armor or hull, the defending ship's armor value for the hit is the sum of:

1) The center cell where the hit was made.
2) The 8 adjacent cells to that center cell.
3) 1/2 of each of the 12 cells which are "2nd adjacent" to that center cell, not including the diagonals.

Note that this means on a pristine target, you're summing 9 * 1/15 of the armor rating (the inner cells), plus 12 * 1/30 of the armor rating (the outer cells), which equals the base armor rating. So the armor rating accurately represents the armor that a hit "sees" on a pristine target, i.e. 9 * 1/15 + 12 * 1/30 = 1.

Also, note that the adjacent and 2nd adjacent cells extend into the empty space "outside of" each ship's sprite. This is just to make the numbers work out to have the above property.

If this pooled value is less than 5% of the armor rating, then the armor value is set to 5% of the armor rating. Note that this check is of the pooled or summed value, not at the individual cell level. Thus when you're starting to break through and hit some hull and some armor, some of the armor is essentially wasted in making up for the hull cells contributing 0 to that pooled armor value before you get to the 5% above which it starts to matter that there's armor.

Then you get to the hit strength calculation. The hit strength calculation multiplies the incoming damage by ratio of incoming hit to (hit + armor), that is, * hit/(hit + armor). So it always weakens the incoming damage (is always less than 1). For projectiles, the hit strength is the damage per projectile. For beams, it is 1/2 of the damage per second. (It doesn't matter that beams apply their damage every 1/10 of a second or whatever it is, the hit strength stays constant at 1/2 of the damage per second.)

Kinetic weapons have their damage halved vs armor, high explosive damage is doubled vs armor, and frag is 25% vs armor. What's important to note is that this affects their hit strength as well. Also, what's doubly important to note is that because of the 5% minimum armor, all hits to hull count as hitting armor for the hit strength calculation (but not the actual damage). In other words, even on a ship where all the armor is stripped away, frag weapons continue to only have 25% of their hit strength against hull. (However, they do full damage.) So high explosive weapons will still do slightly more damage against hull than their energy damage counterparts, because their hit strength continues to be doubled when doing the hit strength calculation.

The hit strength calculation is where the minimum of 15% applies. That hit / (hit + armor) ratio can only go to a minimum of 15%, skills notwithstanding.

Once this hit strength ratio is calculated and applied, the damage is then spread out to the 21 different cells. Each of the 9 inner cells takes 1/15 of the damage, and each of the 12 outer cells takes 1/30 of the damage. Damage is first applied to any armor on the cell (taking kinetic/HE/frag multipliers into account), then any remaining damage is then applied to hull (note that all weapons do 100% damage to hull). Yes the game properly accounts for the damage spilling over to hull across different weapon types (for example, HE is doubled vs armor, but then goes back to 100% once the remainder spills over to hull).

In this sense FooF's graphs were somewhat incorrect -- it didn't take into account that hits to the same location will break through the armor in the center cells first, then you have some shots where the outer cells still have some armor (because they only took 1/2 of the damage compared with the inner cells so they wear down more slowly) and are still contributing to the effective armor rating, before they're finally stripped away. So the armor remaining is actually somewhat more linear than suddenly falling off a cliff as shown. (His graphs assumed that the damage hits all cells equally, whereas there is actually this inner/outer mechanic which makes armor last somewhat longer.) For example, for 600 armor against shots doing 100 damage, his graph showed the shots breaking through the armor on the 25th hit, with all of the armor being gone after that. In reality, it wouldn't break through to start hitting hull until the 29th hit, and there is still some contribution from armor (due to the outer cells) for subsequent hits until it finally goes below the 5% minimum value on the 38th hit.

So let's do an example since I know this is probably pretty confusing at first. Say the target ship for whatever reason has a value of 20 armor in each of its cells. Maybe it's a frigate with 300 base armor. It gets hit by shots that do 150 high explosive damage. So the hit strength calculation would be as follows:

Effective armor rating: 9 * 20 (inner cells) + 12 * 1/2 * 20 (outer cells) = 180 + 120 = 300
Hit strength calculation: 2 * 150 / (2 * 150 + 300) = 300 / (300 + 300) = 1/2 or 50%

Since the damage is high explosive, the damage will be doubled when it's taking away armor.

So the total incoming damage will be 75 HE damage, which is then split up as 5 HE damage to each of the 9 inner cells, and 2.5 HE damage to each of the 12 outer cells. Since they are HE, they are doubled against armor, so this removes 10 armor from each of the inner cells and 5 armor from each of the outer cells, so now each of the 9 inner cells has 10 armor and each of the 12 outer cells has 15 armor remaining.

On the next shot, the calculation would be as follows:

Effective armor rating: 9 * 10 (inner cells) + 12 * 1/2 * 15 (outer cells) = 90 + 90 = 180
Hit strength calculation: 2 * 150 / (2 * 150 + 180) = 300 / (300 + 180) = 5/8 or 62.5%

So the total incoming damage will be 93.75, which is then split up as 6.25 HE damage to each of the 9 inner cells, and 3.125 HE damage to each of the 12 outer cells. Thus this removes 12.5 armor from each of the inner cells and 6.25 armor from each of the outer cells. The inner cells only have 10 armor remaining, so this means that 5 HE damage goes toward removing the 10 armor, and the remaining 1.25 HE damage goes to hull damage. Thus, now each of the 9 inner cells has 0 armor remaining, each of the 12 outer cells has 8.75 armor remaining, with a total of 9 * 1.25 = 11.25 damage done to hull.

On the 3rd shot, the hit strength calculation would be as follows:

Effective armor rating: 9 * 0 (inner cells) + 12 * 1/2 * 8.75 (outer cells) = 0 + 52.5 = 52.5
Hit strength calculation: 2 * 150 / (2 * 150 + 52.5) = 300 / (300 + 52.5) = 40/47 or around 85.1%

So the total incoming damage would be around 127.66, which is then split up as around 8.51 HE damage to each of the inner cells and around 4.26 HE damage to each of the outer cells. The inner cells no longer have armor, so that 8.51 HE damage goes straight to hull, while each of the outer cells take around 8.51 damage to their armor, so they have around 0.24 armor left. Thus, this shot does around 102 total damage to armor and around 76.6 total damage to hull.

On the next shot, well, there really isn't much armor left, so now we're at the 5% minimum armor. So:

Effective armor rating: 5% of base armor rating = 15
Hit strength calculation: 2 * 150 / (2 * 150 + 15) = 20/21 or around 95.2%

So the total incoming damage would be around 142.86 (for this and all subsequent shots), which is split up as around 9.52 HE damage to each of the inner cells and around 4.76 HE damage to each of the outer cells. All of the damage for the inner cells go to hull, while the 0.24 armor remaining in each of the outer cells means the hull takes 4.76 - 0.24 * 1/2 = 4.64 damage each. So this comes out to 9 * 9.52 + 12 * 4.64 = 141.42 damage to hull.

For all subsequent hits, each shot does 142.86 damage to hull. Note that this is because the HE bonus vs armor still applies to hit strength. If the shots were energy instead, then the hit strength would instead be 150 / (150 + 15) = 10/11 or around 90.9%, and each shot would instead do 136.36 damage to hull. So in this case, the fact that the damage is HE means around 4.8% more damage to hull than if it were energy.

Anyway. It's a lot of math above. But this should be easy to test out. Take a 300 base armor ship, have something that fires 150 HE shots at it. The floating damage numbers that you should see, as armor/hull (noting that these are cumulative), should be:

150 / 0
315 / 11
417 / 88
420 / 229
420 / 372
420 / 515
420 / 658
420 / 801
420 / 944

And so on, making some allowances for rounding (I'm not sure how the game handles rounding). You can try this with a ship of any base armor where the HE shot is half the ship's base armor and you should see the same result (suitably multiplied for changes to base armor) -- what's important here is the ratio between armor and shot damage.

If the shots were 150 kinetic damage instead, then for the hit strength calculation, they would amount to 75 instead of 300. Their damage against armor would be 75, but their damage against hull would be 150. However, their hit strength vs hull is still 75, due to the residual armor mechanic. So it would end up being something like 150 * 75 / (75 + armor) for their damage vs hull, whereas for HE, it was 150 * 300 / (300 + armor) for damage vs hull.

A while back I made an Excel spreadsheet to do these calculations automatically. I've attached it here. Hopefully I didn't make any mistakes in coding it up. (Note that "Inner Dam" and "Outer Dam" refers to damage as if it were hitting hull, i.e. if it's HE damage you would then have to multiply them by 2 vs armor, etc.) The output is what you should see as the displayed (cumulative) damage for repeated shots to the same location.

If you're coding it up as a matrix (since you're using Matlab), it may be more interesting to investigate things like, what happens if you fire a spread of shots, since not every shot will hit the exact same location. I remember that in 0.91a, with Drover spam, I had a lot of fighters that were relatively weak (broadswords/sparks I think? I forget now), so I as the flagship would bust a hole in the armor for a Radiant, then gradually move down the edge to expand that hole since I had much better anti-armor weaponry than the fighters, so that the fighters could then pummel it since they would be able to hit hull that way. I *believe* that's the most effective way to strip armor (making a current hole bigger, as opposed to making new holes all over the place), especially to take advantage of how inner/outer cells work. It would be interesting to see that quantified.

[attachment deleted by admin]
Logged