2019-05-09, 04:34 PM

One day I felt my math skills are itching. I've spent another ten hours designing APS cannon and this itch become even stronger. So I've taken formulas from FTD wiki page for APS cannons, crushed them by the power of math from 18th century and dumped results to jupyter/sympy notebook. You can check ftd_spreadsheet repository on github.

Part 1. Calculus

All of this can be found at Deriving formulas for DPS

Parameters:

Shell velocity:

Note:

(N-Np-Nr) is length of shell without any casings. Maybe I should replace it by single value, but not today.

Do these enormous lines help us anyhow? Not yet. We need to go further and differentiate it!

Derrivative of DPS with respect to the variable D:

That is more useful. If we do not use rail charge at all, then the second part of this function is zero, and the function itself is strictly positive. That means if you increase diameter, DPS increases as well. So given you already have chosen autoloader size, you should pick largest diameter possible for this autoloader.

But things become complicated if you make railgun: your DPS decreases if you increase diameter. Let's check derrivative for damage:

dDamage/dD is still positive for all values of D. Damage will still grow, but reloading time increases even faster, so you get negative return.

Part 2. Shell optimization

Showcase for shell optimizer

We have python, we have some formulas implemented. So we can try to find some shell designs.

My optimizer works this way:

1. Iterate all over shell module variants, given size limit. This iterator generate sequences like ['apcap', 'bsabot', 'solid', 'gunpowder', 'gunpowder', 'gunpowder']. It can generate A LOT of combinations and chew your CPU.

2. Calculate damage/velocity/... values for every shell design. It takes maximum diameter fitting autoloader size.

3. Record best N designs for optimizer setup

Opmitization setup:

Each call to FTD.calcBeshShells generates 4 best results for given arguments. I drop them in a single list and generate a pretty table:

Let's study our results:

1. The first 8 lines correspond to setup with 8 modules at max. But optimizer gives us only two shells with length of 7, and the rest are shorter. It means that there is no need to make simple shells any longer.

2. Shells for autoloader with size=2 are stronger.

3. Optimizer prefers railgun shells when we pump quite solid rail charge.

3. Railgun variants for autoloader with size=1 are stronger. I guess that is because lower diameter and mentioned problems with picking proper diameter for rails.

The problems so far (TODO):

1. I still can not calculate accurate values for base bleeder module. My calculator underestimates shell velocity, and all other values (damage, AP) are underestimated as well.

2. I haven't implemented a way to tell optimizer: "I certainly need a fuse and distruptor module in every proposed shell design".

3. DPS values for railguns is nowhere optimal, due to the way optimizer picks diameter. I'll fix it later.

Part 3. How to use it

1. Study some Python

2. Install jupyter notebook

3. git clone https://github.com/dkargin/ftd_spreadsheets

4. Consider yourself a modern scientist!

5. Profit

PS: Phew. It takes so much time to write science articles.

Part 1. Calculus

All of this can be found at Deriving formulas for DPS

Parameters:

- Shell diameter D

- Number of modules in a shell, N. Note: we consider all modules have the same length, equal to diameter. Generally, it is not true for fuses.

- Number of propellant modules, Np

- Number of rail modules, Nr

- Rail charge Q.

Shell velocity:

Note:

(N-Np-Nr) is length of shell without any casings. Maybe I should replace it by single value, but not today.

Do these enormous lines help us anyhow? Not yet. We need to go further and differentiate it!

Derrivative of DPS with respect to the variable D:

That is more useful. If we do not use rail charge at all, then the second part of this function is zero, and the function itself is strictly positive. That means if you increase diameter, DPS increases as well. So given you already have chosen autoloader size, you should pick largest diameter possible for this autoloader.

But things become complicated if you make railgun: your DPS decreases if you increase diameter. Let's check derrivative for damage:

dDamage/dD is still positive for all values of D. Damage will still grow, but reloading time increases even faster, so you get negative return.

Part 2. Shell optimization

Showcase for shell optimizer

We have python, we have some formulas implemented. So we can try to find some shell designs.

My optimizer works this way:

1. Iterate all over shell module variants, given size limit. This iterator generate sequences like ['apcap', 'bsabot', 'solid', 'gunpowder', 'gunpowder', 'gunpowder']. It can generate A LOT of combinations and chew your CPU.

2. Calculate damage/velocity/... values for every shell design. It takes maximum diameter fitting autoloader size.

3. Record best N designs for optimizer setup

Opmitization setup:

Code:

`# Limit number of modules to be used`

maxShellModules = 8

# First parameter is the size of autoloader

results += FTD.calcBestShells(1, maxShellModules, batch, dict(loaders=1, clipsPerLoader=1, velCharge=0), filterResult)

results += FTD.calcBestShells(2, maxShellModules, batch, dict(loaders=1, clipsPerLoader=1, velCharge=0), filterResult)

maxShellModules = 20

# We add rail charge here.

results += FTD.calcBestShells(1, maxShellModules, batch, dict(loaders=1, clipsPerLoader=1, velCharge=10000), filterResult)

results += FTD.calcBestShells(2, maxShellModules, batch, dict(loaders=1, clipsPerLoader=1, velCharge=10000), filterResult)

Each call to FTD.calcBeshShells generates 4 best results for given arguments. I drop them in a single list and generate a pretty table:

Let's study our results:

1. The first 8 lines correspond to setup with 8 modules at max. But optimizer gives us only two shells with length of 7, and the rest are shorter. It means that there is no need to make simple shells any longer.

2. Shells for autoloader with size=2 are stronger.

3. Optimizer prefers railgun shells when we pump quite solid rail charge.

3. Railgun variants for autoloader with size=1 are stronger. I guess that is because lower diameter and mentioned problems with picking proper diameter for rails.

The problems so far (TODO):

1. I still can not calculate accurate values for base bleeder module. My calculator underestimates shell velocity, and all other values (damage, AP) are underestimated as well.

2. I haven't implemented a way to tell optimizer: "I certainly need a fuse and distruptor module in every proposed shell design".

3. DPS values for railguns is nowhere optimal, due to the way optimizer picks diameter. I'll fix it later.

Part 3. How to use it

1. Study some Python

2. Install jupyter notebook

3. git clone https://github.com/dkargin/ftd_spreadsheets

4. Consider yourself a modern scientist!

5. Profit

PS: Phew. It takes so much time to write science articles.