ID:265678
 
Hey everyone,

Over the past day or so I have been working on a system (blacksmithing). I am trying to find a less space consuming way to go about having random attributes that are skill based but thus far it looks like its going to be a deal buster through and through. I'm not gonna mess around, I am only a hobbyist coder, so I don't have an extensive knowledge of why things work the way they do so much as I should. This is my problem;

I have a system where there is 1000 possible points you can have in this given skill, as you gain, you procure the ability to work with more and more materials (15 total). I want to make it so when producing items with this material the chance of making a higher quality item increases with your skill (7 qualities), and varies with the minimum skill required to make said item.

ie. i would like an iron shortsword (first craftable item) to be much easier to make exceptional than a steel one. at the same time a shortsword of a given metal will take less skill than a long sword of that same metal.

Is there an equation i can use to process sucess in making the item, and quality chance percentages with respect to a lower threshhold limit required?

If someone even attempts at helping me I can throw my jumbled mess of novice coding at their feet. The game is in alpha but i don't like putting out something unfinished, so im trying to get each system out in a polished state before its implemented.


EDIT; If there is no short proc that I can use, the only other alternative is 800 lines of precoded percentages, which i'm not genius but I believe that cuts down significantly on the performance of the game in the long run.
You definitely don't need a bunch of if() statements here. A simple formula should be doable for this. To start with, though, I'd like to ask how you would set this up if you were to show the success chance, and range of quality, as tables. I.e. if you had a grid and each column represented the player's skill level, and each row was a different thing they could make, how would the table look? Seeing the values you would choose would go a long way toward finding a good general-purpose formula.

Lummox JR
In response to Lummox JR
Lummox JR wrote:
You definitely don't need a bunch of if() statements here. A simple formula should be doable for this. To start with, though, I'd like to ask how you would set this up if you were to show the success chance, and range of quality, as tables. I.e. if you had a grid and each column represented the player's skill level, and each row was a different thing they could make, how would the table look? Seeing the values you would choose would go a long way toward finding a good general-purpose formula.

Lummox JR
 Skill | Item  1 | Item  2 | Item  3 |
--------------------------------------
1 teir1 2% - - - - - - - -
2 teir1 4% - - - - - - - -
3 teir1 6% - - - - - - - -
4 teir1 8% - - - - - - - -
5 teir1 10% teir1 2% - - - -
6 teir1 12% teir1 4% - - - -
7 teir1 14% teir1 6% - - - -
8 teir1 16% teir1 8% - - - -
9 teir1 18% teir1 10% - - - -
10 teir1 20% teir1 12% teir1 2%
11 teir2 2% teir1 14% teir1 4%
12 teir2 4% teir1 16% teir1 6%
13 teir2 6% teir1 18% teir1 8%
14 teir2 8% teir1 20% teir1 10%
15 teir2 10% teir2 2% teir1 12%
16 teir2 12% teir2 4% teir1 14%
17 teir2 14% teir2 6% teir1 16%
18 teir2 16% teir2 8% teir1 18%
19 teir2 18% teir2 10% teir1 20%
20 teir2 20% teir2 12% teir2 2%
21 tier3 2% teir2 14% teir2 4%
22 tier3 4% teir2 16% teir2 6%
23 tier3 6% teir2 18% teir2 8%
24 tier3 8% teir2 20% teir2 10%
25 tier3 10% teir3 2% teir2 12%


do you mean something like this? with the item being the weapons, i.e. shortsword, longsword, bastard sword. the teir being the materials the item is made from, i.e. bronze, iron, steel. the skill being the required skill needed for the crafting of said items, blacksmithing or swordsmith

so using the chart above, if you have 15 in the skill. you have 10% chance of success to make a teir two item_1, a 2% cos of making a teir 2 item_2, and a 12% cos for making a tier 1 item_3.

could it also be set up that the % continues to increase by increments for every additional skill point?

or maybe i'm way off and this isn't what Lummox JR meant.
In response to Cuddlebear
thats the question, im kind of at a mind lock here on how to lay out qualities, success rate, etc.


perhaps have each item layed out like this, where each skill is another percent to sucess and after 100% sucess is reached the percent chance to have a higher quality item increases until at... 120+ skill over the minimum your guarunteed always to make quality 7 success?

for each item you just add the minimum skill to the skill for these percentages?

each metal requires more and more skill and the max skill obtainable in this section could be 1500?

i need a bell curve for the quality percentages...
observe
   |    minskill 0 |
-----------------------------------------------
0 | 10% / 50 / 35 / 10 / 5 / 0 / 0 / 0
1 | 11% / 45 / 35 / 12 / 7 / 1 / 0 / 0
...
90 | 100% / 0 / 0 / 0 / 5 / 15 / 20 / 60

| minskill 50 |
-----------------------------------------------
50 | 10% / 50 / 35 / 10 / 5 / 0 / 0 / 0
51 | 11% / 45 / 35 / 12 / 7 / 1 / 0 / 0
...
140 | 100% / 0 / 0 / 0 / 5 / 15 / 20 / 60















legend


| 'minimum skill for item' |
| |
---------------------------------------------------------------------------------
skill| success / (out of sucessfull attempts) quality 1 / 2 / 3 / 4 / 5 / 6 / 7
In response to Perilous Knight
Well, for starters I would suggest actually lowering the range of the skill stat. Any time your stats get into the triple-digit range, your system most likely has a balance issue. I'd stick with the KISS principle and go with lower numbers, not going past, say, 20.

A simple formula could then be used for calculating both quality and success chances. Roll 3d6 for success, then if successful roll 3d6 again for quality.

// chance of 15-18 in 3d6 roll is 20/216, roughly 10%
success = (skill-minskill + roll("3d6") >= 15)

quality = max(1, min(7, round((roll("3d6")+skill-minskill-10) / 3)))

Of course this would be more interesting if there's always a chance of failure. I like to use sigmoids, functions which have an S shape and which never hit 0 or 1.

/*
A very slight chance now exists of creating the item at a lower skill level.
You can code in a hard limit, or else leave it alone and allow for this
chancel. At higher levels, the chance of success approaches 100%
but never reaches it.
*/

success = rand() < (1 - 1 / (1 + 3**(skill-minskill-2)))

/*
For quality, use the same basic function structure, but allow for
varying quality by using Fudge dice. Fudge dice are dice which are
either +, -, or neutral; NdF is equivalent to roll("[N]d3-[2*N]").
This also follows a bell curve.

Here, the Fudge factor is cut in half, but you still roll 4 Fudge
dice instead of 2 for a more even distribution. If you roll all 4
dice as +, it's equivalent to building an item at +2 skill levels'
worth of quality.
*/

quality = 1 - 1 / (1 + 3**(skill-minskill-2 + roll("4d3+-8")*0.5))
// scale this to the 1-7 range
quality = round(quality * 6 + 1, 1)


This version with the sigmoids should scale well. At skill==minskill, it will provide a 10% success chance. For +1, it's 25%. At +2, success jumps to 50%, then 75% at +3. At skill==minskill+4, it's 90%, and there are diminishing returns from there. If this is too quick a jump, you can lower the exponent from 3 to something smaller, and similarly change the -2 to something more negative. The general formula you want (for a 10% starting chance) is:

exponent ** -bias == 9

I chose exponent=3 and bias=-2. At skill==minskill-bias the odds of success are 50%. I think my own numbers fit well because if you stick to a simple low-number stat system, an increase in skill represents a leap forward in knowledge. By using Fudge dice to limit any swing in skill (as applied to quality) from -2 to +2, this means that a very lucky novice can't do more than create a mid-grade item--and a sub-novice would do even worse, being lucky to create a low-quality item.

Lummox JR
In response to Lummox JR
I need a bit to wrap my mind around this, and I may need some advice concerning the implementation but this is wonderful, a large step to smaller more efficient code.
In response to Lummox JR
Lummox, I'd like to ask in more detail about your sigmoid example. I'm testing it out directly "as-is" from the post & it rarely displays a "quality" level other than 1,6 or 7. Which I particularly would really like this to work as it'd help me out a lot but, I don't quite understand the whole sigmoid approach enough to modify it ompletely.
In response to Teh Governator
Teh Governator wrote:
Lummox, I'd like to ask in more detail about your sigmoid example. I'm testing it out directly "as-is" from the post & it rarely displays a "quality" level other than 1,6 or 7. Which I particularly would really like this to work as it'd help me out a lot but, I don't quite understand the whole sigmoid approach enough to modify it ompletely.

A sigmoid is an S-shaped curve. At negative infinity it has a value of 0; at positive infinity it's 1, and at 0 it's 0.5. Because of its S shape, it has a relatively high slope at x=0, but the slope tapers out as x moves toward the extremes. This is the classic sigmoid function:

y = ex / (1 + ex) = 1 - 1 / (1 + ex)

You can adjust the slope of the curve by changing the exponent from e to some other value. If 3 is the exponent, then at x=2, you get a value of 0.9; at x=-2 it's 0.1. And at x=1 and -1 it's 0.75 and 0.25, respectively, so 3 is a convenient exponent for dealing with fractions that are familiar to us.

If you work with a sigmoid, generally you'll want to figure out: 1) At what point should the value be exactly 0.5? Subtract that from your x value. 2) At what other point would you like what other value?

Assuming x0 is the point where you want 0.5 to fall, and a is the exponent, then the function looks like this:

y = 1 - 1 / (1+ax-x0)

And we can solve for the exponent a if we know x and y:

1 / (1+ax-x0) = 1 - y
1 + ax-x0 = 1 / (1-y)
ax-x0 = 1 / (1-y) - 1 = y / (1-y)
a = [y / (1-y)]1/(x-x0)

So, let's say you wanted a value of y=0.5 at x=0, so x0=0. Now say you wanted y=2/3 at x=1.

a = [2/3 / (1/3)]1/(1) = 21 = 2

So your sigmoid in BYOND would be y=1-1/(2**x+1). At x=1 it's 2/3 just like expected, which means at x=-1 it's 1/3; at x=2 it's 0.8, and at x=-2 you get 0.2.

Lummox JR