Crafting with multiple inputs
Consider a game with a crafting system. Imagine that crafting an object requires several inputs.
- Crafter skill level
- Input A
- Input B
- Input C
The qualities of these inputs may be variable.
- The crafter's skill level varies as the crafter gains experience.
- Metals: how well refined it is
- Food product: age and suitability
- ... etc ...
Imagine that any input can have a quality rating from 0 to 100%. The quality of the inputs can affect the quality of the resulting product. To implement this, we must create a function to determine the output quality. Let us call our inputs [A,B,C,D], each ranging from 0-1, and create some example functions.
- Multiplication: q = A * B * C * D
- Summation: q = (A + B + C + D)/n where n is the number of inputs
- Sum of squares: q = (A^2 + B^2 + C^2 + D^2)/n
- sqrt(Sum of squares)
The multiplication function emphasizes differences from 1.0, the netural position. The addition of flawed components will create greater flaws in the result.
The summation function minimizes the effect of flawed components on the end result. The addition of perfect components will even out the result toward 1.
The sum-of-squares function will produce results somewhere in the middle of these two extremes. Taking its square root will push the quality value toward 1.
The choice of function is up to the game designer. It will help to throw several functions and examples into a spreadsheet and see what ranges of results you feel are appropriate for your game.
Crafting with weighted inputs
How about weighting the inputs so that some will matter more than the others? You will need to rewrite your algorithm.
Rules for weighting:
- Inputs with a larger weight will have more influence on the result than inputs with a smaller weight.
- If all weights are equal, the result should be the same as the unweighted algorithm.
- If one weight approaches infinity while the others hold still, the result should be as if all other weights are zero.
Let us call the inputs [A,B,C,D] and their weights [Z,X,Y,W].
It may help to calculate how much any weight differs from the mean average weight of all objects in the set. For input weights of [5, 1, 4, 2.8], this produces [1.5625, 0.3125, 1.25, 0.875].
- f(Z) = Z/(Z+Y+X+W) * n where n is the number of weights
It may also help to adjust the values of the weights relative to the largest weight. For the same inputs, this produces [1, 0.2, 0.8, 0.56].
- g(Z) = Z / max(Z, Y, X, W)
The multiplication function (q = A * B * C * D) emphasizes the input's difference from 1.0 and compounds these differences as more inputs are added. We can create a helper function m(input, weight) to adjust this difference relative to the weight. For weights [5, 1, 4, 2.8] and all inputs 0.9, this produces [0.9, 0.98, 0.92, 0.944].
- m(A,Z) = 1 - (1-A)*g(Z)
An analogue to the multiplication function becomes:
- q = m(A,Z) * m(B,Y) * m(C,X) * m(D,W)
The summation function is easily modified by multiplying each input by its weight, then dividing by the sum of weights.
- q = AZ + BY + CX + DZ / (Z+Y+X+W)
The sum of squares function can be modified similarly to the summation function.
- q = (A^2*Z + B^2*Y + C^2*X + D^2*W) / (Z + Y + X + W)
Here is some bonus math that I was working on the other day. Imagine that you have three different crafting functions Z,X,Y that take inputs A, B, and C.
- Z = A + 2B
- Y = 0.5A + 2B + C
- X = B + 3C
Now imagine that you have volumes of A, B, and C in storage; let's say 40A, 80B, 20C. How does one maximize production? This is a solved linear algebra problem so you should go looking for the appropriate method in your language's math libraries.
In Python, you lay out the functions like this:
a = [ [1.0, 0.5, 0.0], [2.0, 2.0, 0.0], [0.0, 1.0, 3.0] ] r = [40,80,20] print scipy.optimize.linprog(c=(-1,-1,-1), A_ub=a, b_ub=r )
optimize.linprog() is used because linalg.solve() will give you negative numbers.
What if you want to weight the functions so that one is more valuable than another? I'm still working on it.