I developed the mathematics of BNumbers some ten years ago. The problem that BNumbers address is the tendency for algorithms to push values beyond acceptable boundaries. If Love[Mary, Tom] is 0.75 (she loves him a lot), what happens if a series of algorithms push it over 1.00? We can’t have Mary loving Tom more than is humanly possible.
BNumbers are a simple system whose operations never exceed the bounds ±1. BNumbers can only be operated on by functions that cannot push them over the boundaries. In truth, the BNumber system is something of a fake: it merely maps the entire number line (from -∞ to +∞) onto the number line from -1 to +1. Thus, you can add small increments to Love[Mary, Tom] forever and, since the sum will never reach +∞, the resulting value will never reach +1.00.
After developing the BNumber system, I kept running into problems with its use, and I eventually developed an operator that solved all my problems: Blend. You can find an explanation of how it works here. Here’s a diagram illustrating how Blend(from, to, howFar) works:
While writing all this up for a lecture, I realized that the Blend function provides everything that BNumbers provide. So long as both from and to fall within the range ±1, the value of Blend will also stay within that range.
Moreover, Blend is endlessly useful: by using the three input values in different ways, you can accomplish all sorts of algorithmic effects. Here are some examples:
Approach to boundary
This is the most common application of Blend. Tom does something that causes Mary to feel greater affection for him. Use Blend(currentAffection, +1.00, nicenessOfTom’sAction).
Variable to Value
Use this when you want to place an upper limit on the magnitude of the response to the event. For example, suppose that Tom gives flowers to Mary. He should not be able to win her hand by merely giving her lots of flowers. For this task, use Blend(currentAffection, maximumUtilityOfFlowers, valueOfTheseFlowers).
Approach to Zero
Suppose that you want to diminish a value without making it negative. For example, Tom ignores Mary, and over time her Affection for him diminishes. She will not come to hate Tom if enough time passes; instead, her Affection for him will erode to zero. Use Blend(currentAffection, 0, timeElapsed).
Sometimes an actor’s response to an event requires a combination of several ActorTraits. Combining two traits like this is easy with Blend. Use Blend(firstTrait, SecondTrait, mixingRatio). Here, mixingRatio represents the degree to which firstTrait is favored over secondTrait. A value of 0.5 mixes them evenly; a value of 0.9 will add 90% of firstValue to 10% of secondValue.
There are even wilder applications of Blend. I have nested Blend inside itself; I have even developed a four-parameter version of Blend that brings additional variability to the function. The moral of this story is: