Skill lvl400/getting gold when buy items

 Posts: 1
 Joined: Sun Apr 05, 2020 11:34 am
Skill lvl400/getting gold when buy items
I did enchant my items with enhanse mercantile. My Skill went over 100 and at some point the shopkeepers offered me "  gold" when i wanted to buy an item. They actually gave me the gold so if it is 20 gold i get the item and 20 gold.
The turningpoint lies between skill lvl of 241 and 256. I could boost my mercantile skill up to 406
(with a base skill of 31), for that i used up every slot for equipement.
I use mods but none of them mess with the skill system. In classic, it was possible to raise skills above 100 to an absurd amount too but i can't remember if the effect with " gold" was there too.
(my mod list: https://prnt.sc/rtf11k)
best regards
Aleks
ps: here is a photo of a baby bat https://prnt.sc/rtf36q
 pango
 Posts: 2607
 Joined: Wed Jul 18, 2018 6:14 pm
 Location: France
 Contact:
Re: Skill lvl400/getting gold when buy items
Welcome to the forums WolframPolizei
And I'm pretty sure the formulas were reverse engineered from assembly, from the look of it:
https://github.com/Interkarma/daggerfal ... r.cs#L1904
(some range tests could have been missed, though)
If you look past the integer operations, it is actually quite simple: everything relies on the use of a function f so that f(100) = 2 * f(0), that's used over and over as a factor in selling and buying prices. Its parameter is an ability or a skill, and when that ability or skill is supposed to drive prices down, then f(100  x) is used instead.
If we refactorize the code according to that analysis, this gives:
As we can see, f is (again if you don't look too closely at integer operations) a simple linear function, basically f(x) = 128 * (1 + x/100).
The trouble comes from the use of 100  x as parameter, because when x becomes greater than 200, f(100x) becomes zero, then negative, and hell breaks loose.
One way to deal with that would be to cap that function, so that it stops decreasing with some negative value of its parameter. It would give no incentive for reaching insane skill levels, so I'm sure some players will disagree with that approach
I think an implementation that would better extend past 0..100 values would be an exponential; If prices double (or are halved) as you go from skill 0 to 100, it should be doubled again (or halved again) as skill go from 100 to 200, etc.
This does not match perfectly with the classic linear function over 0..100 (worse can being around x = 53, where it's about 8% lower), so we could use classic formula for 0..100 range and new formula to extend it outside this range:
At least that's something to try, and see how it feels in game...
I remember reading about DagSkills breaking mercantile in classic in a similar way. I don't know if that was ever fixed, maybe Ferital knows better.WolframPolizei wrote: ↑Sun Apr 05, 2020 12:24 pm I use mods but none of them mess with the skill system. In classic, it was possible to raise skills above 100 to an absurd amount too but i can't remember if the effect with " gold" was there too.
And I'm pretty sure the formulas were reverse engineered from assembly, from the look of it:
https://github.com/Interkarma/daggerfal ... r.cs#L1904
(some range tests could have been missed, though)
If you look past the integer operations, it is actually quite simple: everything relies on the use of a function f so that f(100) = 2 * f(0), that's used over and over as a factor in selling and buying prices. Its parameter is an ability or a skill, and when that ability or skill is supposed to drive prices down, then f(100  x) is used instead.
If we refactorize the code according to that analysis, this gives:
Code: Select all
private static int MercantileF(int level)
{
return (level << 8) / 200 + 128;
}
...
if (selling)
{
delta_mercantile = MercantileF(100  merchant_mercantile_level) * MercantileF(player.Skills.GetLiveSkillValue(DFCareer.Skills.Mercantile)) >> 8;
delta_personality = MercantileF(100  merchant_personality_level) * MercantileF(player.Stats.LivePersonality) >> 8;
amount = ((((179 * delta_mercantile) >> 8) + ((51 * delta_personality) >> 8)) * cost) >> 8;
}
else // buying
{
delta_mercantile = MercantileF(merchant_mercantile_level) * MercantileF(100  player.Skills.GetLiveSkillValue(DFCareer.Skills.Mercantile)) >> 8;
delta_personality = MercantileF(merchant_personality_level) * MercantileF(100  player.Stats.LivePersonality) >> 8 << 6;
amount = ((((192 * delta_mercantile) >> 8) + (delta_personality >> 8)) * cost) >> 8;
}
The trouble comes from the use of 100  x as parameter, because when x becomes greater than 200, f(100x) becomes zero, then negative, and hell breaks loose.
One way to deal with that would be to cap that function, so that it stops decreasing with some negative value of its parameter. It would give no incentive for reaching insane skill levels, so I'm sure some players will disagree with that approach
I think an implementation that would better extend past 0..100 values would be an exponential; If prices double (or are halved) as you go from skill 0 to 100, it should be doubled again (or halved again) as skill go from 100 to 200, etc.
Code: Select all
private static int MercantileF(int level)
{
return (int) (128 * Mathf.Exp(Mathf.Log(2f) / 100f * level));
}
Code: Select all
private static int MercantileF(int level)
{
if (level >= 0 && level <= 100)
// classic formula
return (level << 8) / 200 + 128;
else
// exponential extension of above
return (int) (128 * Mathf.Exp(Mathf.Log(2f) / 100f * level));
}
When a measure becomes a target, it ceases to be a good measure.
 Charles Goodhart
 Charles Goodhart