pyfa-org / Pyfa

Python fitting assistant, cross-platform fitting tool for EVE Online
GNU General Public License v3.0
1.61k stars 409 forks source link

Show length of time an overheated module can run for #445

Open ghost opened 8 years ago

ghost commented 8 years ago

EFT has a nice feature where it shows the amount of seconds a module can run overheated depending on the modules surrounding it, etc. It'd be nice to get this added in to pyfa.

blitzmann commented 8 years ago

Yes, this is a great feature, but one of which would be difficult to add. Kadesh wrote out the equations on the heat mechanics a long time ago on the forums, but the thing that is trippy is that's it's all chance based, and so the amount of time you get out of a module may wildly vary. I am not sure how EFT does it, or if it's even accurate.

If someone could come up with a way to do it reliably and with a good time estimate, we could start thinking about how to best implement it. But until we have a good theory behind it, this will remain on the wishlist

ghost commented 8 years ago

So, I always assumed it was based on the module attributes itself. Something like:

image

So it has 4.32 HP heat damage, has 40HP structure hitpoints, with a cycle time of 4.8s (but -15% since its heated, so 4.08s). So every 4.08 seconds, it takes 4.32 heat damage...which (4.32/4.08) means it takes 1.05 damage every second averaged out. Now (40 HP / 1.05 damage per second) = 38 seconds of running before its burned out.

Obviously it does depend on chance, but its nice to see an approximation at least... EFT basically just guesses. I'm not entirely sure of the spillover rate though to other modules.

Its fine if its not technically feasible. Was just thinking it'd be nice

blitzmann commented 8 years ago

Heat calculations: https://forums.eveonline.com/default.aspx?g=posts&t=32225

It's much more complex than simply assuming that each cycle will inflict damage. To have an accurate heat simulator, you must consider the module neighbors as well. pyfa could easily show the given calculation, which is a worse case scenario, but IMO it's not very helpful.

It's not impossible, but no one really knows how to implement the theory behind it. I could (easily enough) make it display the time, but where does that time come from? That is the big question, as it's based off of chance.

Say you have an overheated module, the cycle time is 10 seconds, the HP is 40, and the heat damage is 20.

Time HP Left Change to damage at end of cycle random(0,100)
0 40 25% 3 (damage)
10 20 50% 43 (damage)
20 0 Dead Dead

This table represents getting very unlucky and getting damaged at each chance. It only last 20 seconds

Time HP Left Change to damage at end of cycle random(0,100)
0 40 25% 75
10 40 50% 51
20 40 75% 89
30 40 100% Damage
40 20 100% Damage
50 0 Dead Dead

This table shows the module getting very lucky and is only damage when the chance to damage reaches 100%. It lasts 50 seconds

This is a large spread, and one of the big things holding a feature such as this back is the fact that we cannot meaningfully convert this data into something useful as far as I'm aware. Unless we simply take the average of our two extremes (in which case it would be 35 seconds, which we would need to round up or down to match the cycle time of 10 seconds). Then we have to consider the other modules on the rack, and it just makes my brain hurt.

If someone is willing to put some time thinking into this and come up with possible solutions I'm all for it and can provide support if need be. Just need a good mechanism for calculating the data. =)

nepphhh commented 8 years ago

I don't know how you'd run the calculations, but as for the display, why not display the average, with the upper and lower bounds in a tooltip?

blitzmann commented 8 years ago

\That could be possible. Also have to consider other modules on the rack - if one burns out in the middle of another's average time, that would increase the time the module survives.

I thought about this a little the other day for some random reason. If (big if) this is ever written and implemented, I imagine it will behave similar to this:

Heat is separated by rack, so right there each rack will have it's own scope. We would probably write a service (or methods on the Fit object) that takes a rack (collection of modules) in the order that they are fitted. It will then do the calculations until all modules are 100% damaged. It then records how long each module lasted, and repeats the process x amount of times (to get good averages, no idea what number we'd use). These values are then averaged.

I have no idea how performance of something like this would be. Depends on how many loops are needed, and depending on how quickly mods would burn out. Due to this, I would need to look up best practices of looping in python as it relates to speed - the less overhead the better. Could look into making it asynchronous like we do with price fetching.

Again, all this is theory and just on paper. Always open to suggestions.

EDIT: Hell, if it turns out performance of these loops and number operations are critical, we always have the numpy library already in pyfa for the graphing stuff. That shits implemented in C and can crunch data faster, maybe it would be useful.

nepphhh commented 8 years ago

I was thinking on this, and I was wondering if perhaps some kind of probability tree-type modeling might be pretty accurate. I was envisioning it as a per-module thing, but what you mentioned about calculating it per-rack makes more sense.

Consider you overheat just one module. The first time it cycles, there's a certain probability that it will take damage, and a certain probability that it won't. This should be pretty easy to calculate. From there, the tree splits into two branches--a damaged branch and an undamaged branch, each with a certain probability associated with it.

Next cycle, each branch then has another split, each with a fraction of the original branch's probability. So on and so forth. Eventually, all branches terminate in dead modules, and you would know what the probability of that exact 'decision path' being followed is, and how long it took to burn out that way. Take a weighted average of the burn-out times with probabilities, and you've got something decent.

Now, do that for the entire rack, with each possibility (this mod damages nobody, this mod damages itself, this mod damages somebody else) its own branch. Cycle times between different mods wouldn't necessarily line up, but that's okay--you'll just split the probability tree for the entire rack whenever any mod's cycle finishes.

No clue how intensive the calculations would be, though I kind of have a hunch that calculation time would increase with at least the factorial of the number of overheated mods. Thank god there's max 8 slots in a rack.

Reasons that this is cool are that: it should be flexible enough to account for not overheating all mods starting at the same time, or even turning OH off and/or back on again. Heck, in theory it could even account for combat refitting, but that probability tree is going to get fucking huge. Also, since it calculates each path's probability exactly, you should be able to produce precise probability graphs of how long each mod could survive. Still, my gut says calculations for this could be awful for an active battleship mid rack.

Don't know if this made any sense. Just some thoughts.