NEW AND IMPROVED FOR STAT CAP CHANGE:
https://docs.google.com/spreadsheets/d/1_-2F84ac3ggUD8I9fzrHiv_aTk5AA2hsjo7Cr365SCA/edit?usp=sharing
It is not exact yet, plz don't judge me
Training Gains Explained 2.0CalculatorI know most of you aren’t nerds and just want to use my calculator. The Calculator can be found:
HERE Eventually I plan on working with YATA or TornStats to incorporate this into a real website but until then, my calculator will do. Please don’t break it on purpose, be nice.
TL;DR
No.
IntroductionHello all - more than three years ago as a young player I was frustrated that there didn’t seem to be a good unified formula that could be used to predict training gains, and this was causing a lot of speculation as to what was actually better, how good different training methods were, etc. At that time I spent a couple months gathering data at different happy and stat levels, and eventually found a formula that fit pretty well, which is outlined in my
original guide.
Earlier this year, however, Kivou started thinking about how to incorporate my formula into some more in depth math, and I felt inclined to tell him that my formula was close… but far from perfect. This set us on a quest to find the master formula - the REAL formula. We quickly realized this would need a metric crap ton of accurate data to do this, so Kivuo recruited Pyrit to create a script that he would host that would collect volunteer’s trains for analysis.
We then had a ton of raw data, but what to do with it? Luckily we have some bright minds over at the Journal of Torn Science (JTS) Discord - special shout out to Proxima for the huge help he was in this effort, and Pyrit for helping a lot with plotting and analytics that I’m too computer illiterate to do on my own - we spent quite literally weeks bouncing ideas off of each other, and arguing with each other, and shooting holes in each others theories, until finally we came to the conclusion that…. We were never going to find a “nice” formula that perfectly modelled gains. However, we did come VERY close with a messy formula - so close that it pretty much always predicts your actual gains within the margin of randomness.
So, without further ado, the below summarizes what we found, what we know, and what we don’t know.
What this guide isn’tThis guide is NOT to tell you what book is best to be used when, or how to train, or when to stop happy jumping. We may release guides utilizing this formula to answer those questions in the future, but this would become entirely too long if I included all of that. This does give anyone the tools needed to answer those questions for themselves, however… should they choose to do so.
The Latest and Greatest FormulaSo… what is this great, accurate (but still frustratingly messy formula) that I was rambling on about? It is:
dS = (S * ROUND(1 + 0.07 * ROUND(LN(1+H/250),4),4) + 8 * H^1.05 + (1-(H/99999)^2) * A + B + RANDBETWEEN(-C,C)) * (1/200000) * G * E * (1+PERK%A) * (1+PERK%B) * (Etc)
Where:dS = Estimated gain for one train.S = 50,000,000 if above 50m, otherwise the actual stat total being trained.H = Starting HappyG = (1/10) * Gym Dots Result from API (i.e. 7.3 instead of 73)E = Energy per Train from gym from API (i.e. 5,10,25,50)PERK%A, PERK%B etc = each training perk for the stat in question (or training in general). Of the form 0.01 for 1%, etc.A, B and C are unique to each stat, assumed to be the followingStrength: A = 1600, B = 1700, C = 700Speed: A = 1600, B = 2000, C = 1350Dexterity: A = 1800, B = 1500, C = 1000Defense: A = 2100, B = -600, C = 1500Side Notes:RANDBETWEEN(-C,C) should be excluded from any actual calculation, since it cannot be accurately predicted.OK, now WTF does that mean?If you’re like me, you are probably thinking “Vladar, wtf does that big jumble of crap mean?” Excellent question. I will explain this in reverse order, removing all of the modifiers and extraneous confusing stuff until we get down to the base formula. So, that in mind, the first thing that I will discuss is…
Training PerksMost of us have numerous training perks. These can be found in the API or in your home page under “Personal Perks”.
Some examples are those from Private Islands: Property :+ 2% Gym gains
Or from faction steadfast: Faction :+ Increases defense gym gains by 15%
Or from education: Education :+ 1% Defense gym gains
Each perk you have directly multiplies your base gains - they do not add! They are multiplicitive.
To change the stated perks to something useable in a formula, you divide the percentage by 100, and add it to 1. So, +2% gym gains becomes 1 + 2/100 = 1.02.
So as an example, if you would have gained 100 defense with no perks, with the above perks you would gain
100 * 1.02 * 1.15 * 1.01 = 119.65 (or a 19.65% increase) (note 19.65% is NOT the same as 2+15+1 = 18%)
The next thing that modifies the formula is…
Energy Per Train
This is the term “E” in the formula. This is a simple one - if your each train in a gym is 10 energy, the gain is multiplied by 10. If each train takes 25, the gain is multiplied by 25. You can find how much energy a single train is in a given gym on the
Wiki, or in the API.
Some noobs get worried that a 10e gym with 4dots might be worse than a 5e gym with 4 dots… this is the reason why it’s not. Twice the energy spent on a single train = twice the gain. Note this does not hold if you’re talking about multiple trains in a row, because then you have to factor in happy loss, which I will discuss later. This brings us to the concept of...
Gym DotsThis is the term “G” in the formula. It can be obtained via the
Wiki or via the API, however the API expresses gym dots as ranging from 0 to 100, whereas they are more commonly referred to on a scale of 10 (as expressed in the Wiki). For the formula, we used the scale of 10 - so Georges Gym is 7.3 instead of 73 as the API states.
Gym dots are again, a simple concept. Training in a 6.0 gym will give you 1.5 times the gains of a 4.0 gym on a per energy basis, all else held equal.
So that leaves us with just one other term outside the base formula which is….
(1/200000)Why did we include that on the outside of the formula, and what’s the significance of 200,000? Well, ignoring the stat specific factors, when happy goes to 0, the base gain formula becomes…
.dS = S / 200000This trend is really easy to see and to confirm, and jumped out at us immediately. At 200k stats and 0 happy, your base gain (before all the multipliers above) will be 1. At (or above) the stat cap of 50m, your base gains will be 250.
So… rather than distribute this through the formula, we pulled it to the outside. This now brings us to...
The base formulaThe base formula is
dS = (S * ROUND(1 + 0.07 * ROUND(LN(1+H/250),4),4) + 8 * H^1.05 + (1-(H/99999)^2) * A + B + RANDBETWEEN(-C,C))Does that clear things up? No, I didn’t think so. But we can make it look nicer if we first have a discussion about…
RoundingIf you’ve even read this far, you’re probably wondering about the asinine rounding going on here:
ROUND(1 + 0.07 * ROUND(LN(1+H/250),4),4)Why are we double rounding? Are we insane???? No, but Chedburn apparently is. Whether this is relic from the coding, or intentional, we don’t know, but it’s one of the few parts we are 100% confident in. How can we be so confident? Because when we looked at the data, we were able to see that it wasn’t continuous… rather, it went in clumps. Below is a plot of adjusted gains (Y axis) against Happy (X axis), with actual data points as dots, and our formula approximation (unadjusted, more on that later) as the line.
[image: lh3.googleusercontent.com]You can see that once we added rounding in, we were able to have our formula “jump” at all of the right points.
So… for simplicity’s sake, let’s remove the rounding, and look at what remains:
dS = S * (1 + 0.07 * LN(1+H/250)) + 8 * H^1.05 + (1-(H/99999)^2) * A + B + RANDBETWEEN(-C,C)Hmm… not much better. So, let’s have a discussion about
RandomnessThis the term
RANDBETWEEN(-C,C)Like most things in torn, trains also have some degree of randomness built in. In the case of trains, this randomness is not affected by happy or your stats, which means the effect is the same for low happy, low stat gains as it is for people training at the stat cap. Proportionally,, this means it is very noticeable early on, and not really something most people notice later on.
However, of course this couldn’t be too simple, so to make it more complicated, each stat type has its own variance… So that value of C is difference depending on what stat you’re training (approximations below):
Strength: C = 700Speed: C = 1350Dexterity: C = 1000Defense: C = 1500“Not to be rude, but this seems dumb AF Vlad” you are saying right now. And yes, yes it is… but we’re sure that this is the case. Take a look at this color coded graph (Courtesy of Pyrit):
[image: cdn.discordapp.com]So on the Y-axis is the error that the base formula has, unadjusted for stat type. On the X axis is happy, which isn’t really relevant. You’ll notice that there is some scattershot quality to the error - that’s the randomness. However you’ll also notice that this spread is larger for green (speed) than for orange (dex), for example. This is why we know the random piece is different for different stats.
So how much IS this randomness, really? Using Dexterity as an example, it can be ~+/- 1000 to the base equation. However, this is then divided by 200,000, and then multiplied by the amount of energy you’re spending a gym dots. This means for a 50 energy specialty gym, the actual variance might be +/- 2, whereas for the starting gym, it would end up being +/- 0.1. However - keep in mind for someone with 10 in a stat, a difference of 0.1 is quite large percentage wise.
Now, you’ll also notice something else on that plot up there, which is.. Why is the yellow lower than all the rest??? Good question, imaginary person! That brings us to our next part…
Stat Specific Offsets
This is the term
BWhen looking at the data, we kept noticing that defense was oddly, annoyingly lower than all of the other stats. We thought at first that Ched just nerfed defense trains a little, but upon close examination, it became apparent that the centerlines of the error on ALL of the stats were actually slightly different. You can see this on the above plot - the center of the spread for speed, for example, is above the center of that for strength, which is above that for defense. So as it turns out, you need to add a stat specific offset to the base formula. We called this “B”:
Strength: B = 1700Speed: B = 2000Dexterity: B = 1500Defense: B = -600So similar to randomness, these values seem bigger than they really are, but still - in a specialty gym this means trains for speed will be on average 5.2 higher than a specialty train gym for defense. Huh! Note this isn’t ENTIRELY true because of the next discussion point also being stat specific but… it’s very close.
Now then, we’ll move on to…
The Ugly High Happy Adjustment Term AKA the “Proxima Hates It” TermSo, we were sitting pretty after a while, sure that we had nailed down the formula. “Ha - all we need is a bunch of good 99,999 happy data and we can confirm our formula. All is well! We are awesome smart good looking geniuses” the discussion went.
Then… we get the high happy training data, and realized our formula was annoyingly starting to over predict. We were SURE the rounded part of the formula was correct, but the other term not so much… so we started playing with it, and quickly realized that even the most minor change to the base formula resulted in huge swings in error. We pulled our hair out trying to figure this out and… we couldn’t. Something just isn’t right. We don’t know if it’s our base formula, or if there is something else that is stat specific that adjusts for high happy trains.
Examples of un-adjusted error plotted against happy for two difference stats are below (sorry for the y-axis numbers, they are rounded so it looks dumb)
[image: lh3.googleusercontent.com][image: lh4.googleusercontent.com]So you can see that our error is not consistent across the entire happy range… it started to drop towards high happy.. Above, if you look at dexterity, it dropped by about 0.01, whereas if you look at defense, it dropped by about .015. Why would this difference in error be different for the two different stats unless… each stat also had a happy influenced adjustment term.
So, our best correction that we could come up with is…
(1-(H/99999)^2) * AThis term, at 0 happy, just becomes “A”, and at max happy (99999), it becomes 0. This seemed to nicely adjust for what we saw, but was annoying ugly and not clean. It is the part that we are the least confident in.
Now… if you’re still reading (HA!), we’ll explain…
The Base FormulaSo with all that other crap stripped out, the base formula becomes:
dS = S * (1 + 0.07 * LN(1+H/250)) + 8 * H^1.05You’ll notice this has two parts, a logarithmic function (1+0.07*LN(1+H/250)) that is affected directly by your stat total, and a power function portion (8 * H^1.05) which is not affected by speed.
As I explained in the randomness bit, we are VERY confident that the first part is correct. We don’t understand why 0.07, but that seems to be the number. The 250 bit is an adjustment term to your happy, because otherwise the formula would be stupidly small at very low happy, so this makes it so 250 is basically your “base” happy for use in the training formula. This piece of the formula dominates at higher stat levels, as it becomes much larger than the non-stat affected part.
The second part of this, (8 * H^1.05), we are not quite as confident in. Originally we though this term might be linear, but that definitely isn’t the case, and we were unable to find anything that fit better than this relatively clean power term.
This term completely dominates at low stat levels, but as it doesn’t become any bigger with increasing stats, eventually it becomes less and less important. This is why happy jump training is so good at low stats, and becomes less and less so at higher stats. For more of an explanation of the practical implications of this, see my
original guide.
ConclusionWhile we are not 100% confident that this is the complete true form of the equation, we ARE confident that it predicts trains within the bounds of randomness across all stat and happy levels (provided there is no user error!). So while it may not be able to nail it down to the second decimal point, we can come as close as possible to predicting your actual train using the formula.
So - you deserve a damn medal if you made it to the end of this. I am too lazy to proofread and my wife will get annoyed if I spend any longer typing this so, sorry for the mess.
Other Related FindingsHappy LossIn order to accurately determine gains if training more than once, you need to understand how happy loss works. Through this research we determined the loss in happy for a given train is
dH = ROUND((1/10) * ENERGYPERTRAIN * RANDBETWEEN(4,6), 0)In practical terms, this means:
Happy Loss per Train5 Energy Gyms: 2 or 3, Avg. 2.67
10 Energy Gyms: 4, 5, or 6, Avg. 5
25 Energy Gyms: 10, 13, or 15, Avg. 12.67
50 Energy Gyms: 20, 25 or 30, Avg. 25
Multiple TrainsMultiple trains are iterated - there is NO DIFFERENCE between training one at a time 10 times in a row, and training 10 times in a single click. Both of them do the same thing in the background.
However - it is impossible to accurately predict multiple trains, as both your happy and the train itself has randomness in it. All this formula could do is tell you the bounds of possible results (which my calculator spreadsheet does)