For the past couple of days, I have been stuck in that frustrating mental trap of not being able to think up an elegant way of doing something, so you keep prototyping different ideas, using lots of time, and not coming up with something good while constantly thinking about how this "feels wrong".
In this case, it is introducing tools with durability, instead of just the fully stackable items. This causes a problem since inventory addressing is currently done by item type, throughout the system. This is bad since this doesn't work if you have multiple addressable items with the same item type. To illustrate: Having 2 stone blocks is just a count of 2 addressed by "stone", while having 2 pickaxes with their own durabilities would be 2 distinct things addressed by "pickaxe".
An early approach which I didn't like was was to do some kind of "compound addressing": The high 2 bytes would be the item type and the low 2 bytes would the index into an array of items of that type. This was a mess, though as it meant that the address used to reference something might change if preceding items were removed from the underlying list. It also just felt too much like I was "over-thinking" something from a lower-level than made sense.
My furthest experiment is so far splitting the inventory into stackable and non-stackable item namespaces, where the non-stackable items are addressed by an ID assigned when each of them is added to the inventory. While this design seems to work, it does mean that now the types and APIs used through much of the core system need to be duplicated in order to handle both paths.
However, another idea I want to play with is to see if I can just adapt this ID assignment mechanism in place of the existing type-based addressing, for all cases. This would make it possible to force a "temporal ordering" onto inventory views (so things don't appear to move around when modifying the inventory) but would also mean that I could use the same addressing mechanism throughout the stack.
While this would cause the path splitting to be applied at a lower level based on some other information, that is already required in many cases, anyway (since tool versus item is applied when trying to use or select the item). However, this may just cause additional confusion and special-cases, elsewhere.
More investigation is required,
Jeff.