The bag of holding offers a solution to the conflict between "realism" and playability. On the one hand, in real life, you can only hold so many items at once, so at first glance it seems a simulation ought to have such a limit in order to be more realistic. On the other hand, most players justifiably hate having to deal with a carrying limit, because it forces the player to spend a lot of time doing tedious inventory management.
The Bag of Holding is a compromise solution. The concept is borrowed from live role-playing games, where it's usually a magical item that can hold objects of unlimited size and weight, thereby allowing characters to transport impossibly large objects. In text IF, a bag of holding isn't usually magical - it's usually just something like a large backpack, or a trenchcoat with lots of pockets. And it usually isn't meant as a solution to an obvious puzzle; rather, it's meant to invisibly prevent inventory management from becoming a puzzle in the first place, by shuffling objects out of the PC's hands automatically to free up space as needed.
This Bag of Holding implementation works by automatically moving objects from an actor's hands into the bag object, whenever the actor needs space to pick up a new item. Whenever an action has a "roomToHoldObj" precondition, the precondition will automatically look for a BagOfHolding object within the actor's inventory, and then move as many items as necessary from the actor's hands to the bag.
BagOfHolding : object
The purpose of the affinity is to support specialized holders that are designed to hold only specific types of objects, and allow these specialized holders to implicitly gather their specific objects. For example, a key ring might only hold keys, so it would have a high affinity for keys and a zero affinity for everything else. A lunchbox might have a higher affinity for things like sandwiches than for anything else, but might be willing to serve as a general container for other small items as well.
The units of affinity are arbitrary, but the library uses the following values for its own classes:
0 - no affinity at all; the bag cannot hold the object
50 - willing to hold the object, but not of the preferred type
100 - default affinity; willing and able to hold the object, but just as willing to hold most other things
200 - special affinity; this object is of a type that we especially want to hold
We intentionally space these loosely so that games can use intermediate levels if desired.
When we are looking for bags of holding to consolidate an actor's directly-held inventory, note that we always move the object with the highest bag-to-object affinity out of all of the objects under consideration. So, if you want to give a particular kind of bag priority so that the library uses that bag before any other bag, make this routine return a higher affinity for the bag's objects than any other bags do.
By default, we'll return the default affinity of 100. Specialized bags that don't hold all types of objects must override this to return zero for objects they can't hold.