Mortaldata's Blog

September 21, 2011

Mortal Online Item Value Calculations

Filed under: Uncategorized — mortaldata @ 5:05 am

We’ve moved!

This blog has been moved, please direct your attention to the new website, mortaldata.com.


This is a nice long post, with some terse code sections, but I figure its time people knew what values their items were given.

These calculations, while 100% accurate as of around a year ago, may not still be fully accurate, but will likely provide some insight into how SV generates their numbers. I have not been playing the game, have not had an active account for close to a year now, so many things may have changed that I do not account for here, please keep that in mind.

In general, items have a given ‘rating’ in a statistic. these ‘ratings’ are then translated into real game values by another calculation, one which is constantly being tweeked by SV. From what i have seen, the ‘ratings’ only change very rarely. When boomsticks were nerfed, that was a change in these calculations to generate the new ‘rating’, resulting in people wating ‘pre-nerf’ weaponry. every other change that I have witnessed has been in the game’s usage of these ratings, or in the values that go in to the calculation (hardness/thrustmod/etc) so I assume the calculations themselves are still very accurate.

after deriving these equations, I used these calculations to write a cheezy android application that allowed me to play with the materials and values to get a good idea how to min/max my items. The code for the calculations is included in this post, and its entirely likely you’ll find lillith lyllyth stealing it to make ‘simulators’ sometime soon (also likely he wont reference this as the source of his information, much like the extraction simulator). The android app was given out to maybe 2 people total, so while its possible you can find someone who has a copy, i wouldn’t count on it.

The code references some values that some have difficulty finding, but i’m sure the more resourceful among you will already have references to these values (although, you may want to get a newer version than whats publicly available on the internet, they *do* change).

WEAPONS

weapon damage ratings are generated by adding the damage ratings from the tip and handle together. Furthermore, the handle can be ‘split’ into two values that add together to provide the handle’s totals, the grip and the core. There does not seem to be any ‘magic’ combinations that provide numbers higher than what you would expect by simply adding them together. Stamina use is determined mostly by the weight and handed-ness of the weapon (2h weapons get a 35% stamina break over 1h weapons).

for the longest time, and for all i know it is *still* this way, SV has fucked up the weight calculation for the handle. I have no idea why, but they’ve reversed the weights for core and grip in their calculations such that the core (which for most handles requires the majority of the materials) provides the lesser of the weights to the item. it’s been reported, repeatedly, and apparently noone bothered to check the code at SV. Anyway, the rest of the values are more-or-less self explanatory.

NOTES:
– gripPortion may be termed ‘visFrac’ in other articles.
– although i named them slashingdamage/piercingdamage/bashingdamage, they are really *ratings* and subject to that secondary calculation by SV on the server that changes quite often.

// calculations
float headWeight = (weaponHead.volume * headMat.weight) / 1000;
float coreWeight = (weaponHandle.volume * (1 - weaponHandle.gripPortion) * coreMat.weight) / 1000;
float gripWeight = (weaponHandle.volume * weaponHandle.gripPortion * gripMat.weight) / 1000;

if (mReverseHandleWeightsCheckBox.isChecked()) {
coreWeight = (weaponHandle.volume * weaponHandle.gripPortion * coreMat.weight) / 1000;
gripWeight = (weaponHandle.volume * (1 - weaponHandle.gripPortion) * gripMat.weight) / 1000;
}

float handleWeight = coreWeight + gripWeight;
float weight = headWeight + handleWeight;

mWeightText.setText(Float.toString(weight));

float headMatCritConst = headMat.sharpness / 10 + headMat.critmod;
float coreMatCritConst = coreMat.sharpness / 10 + coreMat.critmod;
float gripMatCritConst = gripMat.sharpness / 10 + gripMat.critmod;

float headWeakspot = headMatCritConst * weaponHead.critMod;
float coreWeakspot = coreMatCritConst * weaponHandle.critMod / 2;
float gripWeakspot = gripMatCritConst * weaponHandle.critMod / 2;

float handleWeakspot = coreWeakspot + gripWeakspot;
float weakspot = handleWeakspot + headWeakspot;

mWeakspotText.setText(Float.toString(weakspot));

float extraStaminaDrain = 5;

if (weaponHead.volume == 0) {
extraStaminaDrain = 0;
}

float staminaDrain = (headWeight * weaponHead.staminaMod + handleWeight) * 8 + extraStaminaDrain;
float staminaDrain2h = staminaDrain * (float).65;

mStaminaDrainText.setText("(1h)" + staminaDrain + " (2h)" + staminaDrain2h);

float headMatSConst = (headMat.hardness + headMat.sharpness) / 15;

float headSdmg = weaponHead.cutMod * headMatSConst;
float coreSdmg = 0;
float gripSdmg = 0;

float handleSdmg = coreSdmg + gripSdmg;
float sDmg = headSdmg + handleSdmg;

mSlashingDamageText.setText(Float.toString(sDmg));

float headMatBConst = headMat.hardness / 20 + (float)0.65;
float coreMatBConst = coreMat.hardness / 20 + (float)0.65;
//float gripMatBConst = gripMat.hardness / 20 + (float)0.65;

float headBdmg = (headWeight * 6 + weaponHead.bluntMod) * headMatBConst;
float coreBdmg = handleWeight * 2 * coreMatBConst;
float gripBdmg = 0;

float handleBdmg = coreBdmg + gripBdmg;
float bDmg = headBdmg + handleBdmg;

mBashingDamageText.setText(Float.toString(bDmg));

float headMatPConst = headMat.sharpness / 12 + (float)0.2;
float coreMatPConst = coreMat.sharpness / 12 + (float)0.2;

float headPdmg = headMatPConst * weaponHead.thrustMod;
float corePdmg = coreMatPConst * weaponHandle.thrustMod;
float gripPdmg = 0;

float handlePdmg = corePdmg + gripPdmg;
float pDmg = headPdmg + handlePdmg;

mPiercingDamageText.setText(Float.toString(pDmg));

ARMOR

Like weapons, armor has separate values for piercing/slashing/bashing (defenses in this case). The armor values are pretty straightforward, without any real surprises, except that the ‘durability’ of a given material contributes quite a significant amount to the actual defense ratings, which is a bit counter-intuitive since, in my mind, thats the contributing factor to the durability on the item, how long it lasts, not how much it protects for. leave it to mats to come up with this shit.

IMO, the armor ratings, while they may be mostly realistic, do not necessarily make for good game values. The way the calculations are done make it very difficult to provide specific protections in armors. In general, if you have high protection vs one type of damage, you also have high protection vs the other two. While there are ways to maximize a given specific protection, armors do not vary in protection types nearly as much as weapons vary in damage types. I would like to see ways of customizing armor to provide far greater protection vs a given type of damage, albeit at the cost of the other two types of protection.

An issue thats plagued armor crafting since the beginning is that the slider for ‘density’ is typically either 0% or 100%. the number returned by the slider is always taken literally as the visMat or nvisMat value, capped at either end. so, for instance, if the nvisMat has a min/max of 1.0/2.0, the slider doesnt range between 1.0 to 2.0 as any sane person might expect, rather it returns the absolute value of the position of the slider which is 0-100, taken *LITERALLY*, and if the slider is not between 1-2 % on the bar, you get the value capped at either 1 or 2.

NOTES:
– baseDensity/supportDensity are values from 1-100 representing the location of the slider when creating the item (SV currently only really supports 0% and 100%. you can get in-between values but its rather difficult, as noted above).
– vismat is the base, nvismat is the support

float baseVariance = armorStyle.baseMax - armorStyle.baseMin;
float supportVariance = armorStyle.supportMax - armorStyle.supportMin;

float baseQuantity = baseDensity * baseVariance / 100 + armorStyle.baseMin;
float supportQuantity = supportDensity * supportVariance / 100 + armorStyle.supportMin;

float baseBashingDefenseCoefficient = (baseMat.damping * 5 + baseMat.hardness)/20 + baseMat.durability/36;
float supportBashingDefenseCoefficient = (supportMat.damping * 5 + supportMat.hardness)/20 + supportMat.durability/36;

float baseSlashingDefenseCoefficient = baseMat.hardness/8 + baseMat.durability/30;
float supportSlashingDefenseCoefficient = supportMat.hardness/8 + supportMat.durability/30;

float basePiercingDefenseCoefficient = baseMat.hardness/10 + baseMat.durability/20;
float supportPiercingDefenseCoefficient = supportMat.hardness/10 + supportMat.durability/20;

float bashingDefense = armorStyle.defenseStatic + armorStyle.defenseMultiplier * (baseBashingDefenseCoefficient * baseQuantity + supportBashingDefenseCoefficient * supportQuantity);
float slashingDefense = armorStyle.defenseStatic + armorStyle.defenseMultiplier * (baseSlashingDefenseCoefficient * baseQuantity + supportSlashingDefenseCoefficient * supportQuantity);
float piercingDefense = armorStyle.defenseStatic + armorStyle.defenseMultiplier * (basePiercingDefenseCoefficient * baseQuantity + supportPiercingDefenseCoefficient * supportQuantity);

mBashingDefenseText.setText(Float.toString(bashingDefense));
mSlashingDefenseText.setText(Float.toString(slashingDefense));
mPiercingDefenseText.setText(Float.toString(piercingDefense));

float setWeight = armorStyle.weight + baseQuantity * baseMat.weight + supportQuantity * supportMat.weight;

mSetWeightText.setText(Float.toString(setWeight));

float leftShoulderWeight = setWeight * armorStyle.leftShoulderPercent;
float rightShoulderWeight = setWeight * armorStyle.rightShoulderPercent;
float leftArmWeight = setWeight * armorStyle.leftArmPercent;
float rightArmWeight = setWeight * armorStyle.rightArmPercent;
float leftHandWeight = setWeight * armorStyle.leftHandPercent;
float rightHandWeight = setWeight * armorStyle.rightHandPercent;
float headWeight = setWeight * armorStyle.headPercent;
float torsoWeight = setWeight * armorStyle.torsoPercent;
float legsWeight = setWeight * armorStyle.legsPercent;
float bootsWeight = setWeight * armorStyle.bootsPercent;

BOWS

Bows only have two real important values, the suggested strength, and the range rating. the damage on bows seems to vary linearly with the range rating (so the distance you can shoot is indicative of the damage you can do, as you might expect).

It use to be such that if you were below the suggested strength of a bow, the game would tell you as much, and the bow would be neigh unusable for you. SV later removed that hard requirement and smoothed the curve out for bows of suggested strength above your strength. There used to be people claiming ‘magic’ recipes for bows, but of all the ones i’ve tested, nothing has landed outside the curve i would expect by these calculations.

NOTES:
– I call it a ‘strength requirement’ here, but its really more of a ‘suggested’ strength value.
– compositePercent is the state of the slider, from 0-100

float backPercent = (float)(.65 - .6 * compositePercent / 100);
// calculations
if (mSelfBowCheckBox.isChecked()) {
backPercent = 1;
}

float bowStrength = bowSize.strength + bowType.strength;
float bowRange = bowSize.range;

float strengthRequirement = (float) (bowStrength * ((1-backPercent) * bellyMat.tensileStrength + backPercent * .25 * backMat.tensileStrength * (backMat.tensileStrength + 3)));
float range = (float)(bowRange * (backPercent * backMat.tensileStrength + (1-backPercent)*.25*bellyMat.tensileStrength*(bellyMat.tensileStrength + 2)) + bowSize.rangePlus);

mStrengthRequirementText.setText(Float.toString(strengthRequirement));
mRangeText.setText(Float.toString(range));

Advertisements

5 Comments »

  1. It’s “Lyllyth”, not “Lillith”… =p
    If you’d like to be credited for what parts I did take from this site, I’ll give it.

    Comment by Lyllyth — September 21, 2011 @ 5:58 pm | Reply

    • I would say that, in general, its a good idea to cite your sources.

      Comment by mortaldata — September 21, 2011 @ 7:31 pm | Reply

  2. Hey there,

    first of all, thanks a lot for shedding some light on the obscure MO crafting system.

    While I get most of the material data from mortalwiki to reconstruct your formulas, there are still some values I can’t really make up at the moment.
    You mentioned that weaponHead.cutMod, weaponHead.bluntMod and weaponHead.thrustMod are determined and changed serverside by SV.
    (Even though the values you released in an earlier post are deprecated, like you say, they give a good hint on distribution)

    Is this also the case with:
    bowSize.strength
    bowSize.range
    bowSize.rangePlus
    bowType.strength

    ?

    If not, would you mind to share the source or these values itself to actually make use of the formulas (Or the original values you used, so that one has a starting point when trying to estimate them)
    Thanks in advance.

    Comment by Nihil4nth — September 21, 2011 @ 7:20 pm | Reply

    • thrustmod/bluntmod/cutmod are all values that apply to the weapon tips/handles, and if you’re creative enough, i’m sure you can find these values on the internet.

      the same goes for the bowery values, you asked about, as well as any of the armor values except maybe the individual piece percentages (tho those are easily calculated).

      Comment by mortaldata — September 21, 2011 @ 9:36 pm | Reply

  3. Anyone has the armorStyle.defenseMultiplier of the armors?

    Comment by Lingh — May 31, 2012 @ 4:23 pm | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: