2013 year end Update

It’s been a couple weeks since the latest patch to Mortal Online which added new armors and material textures (as well as an overhaul to the graphic system to better support large numbers of players). While I understand the need to update the engine to better support the influx of population that could be coming from a steam launch of the game, I was a bit underwhelmed at how little new content was added after 8 months of development (and supposed outsourcing of the animation).

We all hope and dream of the best with each new patch but I don’t think I’m alone in expecting a bit more than 3 new armor sets and some shiny new textures after this long a development cycle. Hopefully the Territory Control patch isn’t too far away and is a bit more interesting than the armor update we just got. I’m hoping most of the dev time was spent on the TC stuff and the armor updates were pushed out just because they needed to add the Christmas event and it happened to be (more or less) ready. Time will tell….

So three new armors added in the patch, Expilator, Direptor, and Tindremic Guard. Everyone’s had time to check them out and few secrets remain, so time for some hard data. Check them out on the Armor Calculator to see how they fare. In general, I expect warriors to move to molarium based Tindremic Guard. Free to play players will have more options with the lighter armors but I don’t expect much of a shake-up as while the direptor and expilator may look cool, they’re not anything too special defense wise.

The annual christmas sacking/looting of a random house was added once again, this time in the Tindrem docks area. Little bags spawn all over the area (underwater, inside buildings, etc) but you can gather them to get some random trinkets. If you’re lucky, you’ll get a fistfull of cuprum coins instead of simply nothing. Really lucky? maybe some silver coins. Win the powerball lottery jackpot lucky? perhaps you’ll get one of the things below, tho i wouldn’t hold your breath.

Mortal Data’s Wiki for Mortal Online is now open!

Yes you read right, we now have a wiki. Its not a regular wiki in the traditional sense; it doesn’t accept submissions. It does, however, convey a lot of information directly to you about various aspects of Mortal Online in a far better way than could be made available here in the blog.

The wiki is far from finished, there’s much work to be done and the multitude of empty links on the main page are testament to that. What is there, however, is a lot of reference information that many players will find handy.

Enjoy your visit to the wiki!

New feature: maps!

Added support for the map of Nave/Myrland in two flavors; one player made the other from StarVault’s chronicles pages.

Toggle the buttons to see possible house spots, keep spots, priests, and towns. This is a helpful resource for newbies and useful information for those looking for possible house spots.

A warning for those on older browsers, if the points on the map don’t display when you press the buttons, you may need to update your browser to view them properly.

New calculators added

Added new calculators in for both the armorcrafting and bowcrafting professions. Weaponcrafting values have been updated as well.

The new graphs allow for the easy comparison of several items at once, simply shift-click or ctrl-click multiple items in the history list. Exact values can be found by clicking on an individual bar in the list. If you find any errors, please let me know.

Mortal Online Skill List Updated

Awakening is released, and it’s time to start getting some reference information posted. I’ve added the skill list similar to how it used to be on the old blog, but since all books can be read to 70 anymore, i’ve removed that data and added a flag for if the skill can be auto-learned or not. Have a look-see:

Mortal Online Skill List

Archived Posts

I’ve added all my old posts from mortaldata.wordpress.com to here. They wont be updated any further and will just exist for archive purposes. I have much better tools and information planned for the future here so there’s no point in keeping the old posts current.

Much of the information I’ve posted previously is outdated by now, tho the general concepts remain. There will be new calculators and other information in the weeks to come, stay tuned…

Mortal Online Item Value Calculations

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));