Stacking system: Comparison

Item stacking seems to be a common thing people want to do; and as far as I can see there's three main ways to do it. I thought it might be interesting to compare the pros/cons of each method. Are there any methods I'm missing, or other advantages?

  1. One object, count attribute
    The most obvious solution, maybe the first one you'd think of.

    • ADVANTAGE: Simple data structure; easy to understand.
    • ADVANTAGE: Small number of objects; lower memory use; maybe quicker.
    • ADVANTAGE: Simple attribute to check how many the player has got.
    • DISADVANTAGE: Code ends up in lots of places. There are a lot of things that don't work properly unless you add extra code to deal with them (Including inventory limits, and any script/library that interacts with the player's inventory at all, such as shops), meaning the code quickly ends up being more complex than other methods.
  2. Object as a container
    If you're carrying one object and pick up another, they go inside each other.

    • ADVANTAGE: Can be implemented as a single script, so all the code is in one place.
    • ADVANTAGE: Works effortlessly with inventory limits, and with any shop system etc. that understands the concept of containers.
    • ADVANTAGE: A bit of careful alias changing can let the player input "get 3 bananas" without needing to modify the commands at all.
    • ADVANTAGE: Objects can have unique features and still stack. You could have a bunch of different flowers that stack together, but can be separated in some cases.
    • DISADVANTAGE: Different ways of implementing this, which seems to give a choice between being inefficient or inelegant.
    • DISADVANTAGE: Has more objects in play than method 1, so can be slower.
  3. Separate objects, override FormatObjectList and/or updateList functions
    You don't necessarily need to treat the objects as a stack internally. You could just change the functions that format a list of objects for displaying to the user, such that it only shows each item once.

    • ADVANTAGE: Works with all other systems/scripts/libraries, because it doesn't change the internal representation of the objects at all.
    • ADVANTAGE: Quick, simple.
    • DISADVANTAGE: Player can only interact with one object at a time, unless you add extra code elsewhere (in which case you're almost maintaining two stacking systems at once)

Having implemented all three, I have to say 2 is my favourite so far.
Are there any I'm missing?

Me: Uses standard container code.

Ugh… I had method 2 working just how I wanted it before, and I can't replicate it. I can only get it to work properly with the new GetScope().

Back to a crazy hybrid method:

foreach (c, AllCommands()) {
  if (HasString(c, "scope") and not GetBoolean(c, "supportsStackedObjects")) {
    c.realScript = c.script
    c.script => {
      stackedargs = getStackOptions(game.pov.currentcommandresolvedobjects)
      if (ListCount(stackedargs) = 0) {
        do (this, "realScript", game.pov.currentcommandresolvedelements)
      else {
        foreach (stackmembers, stackedargs) {
          args = DictionaryCombine (game.pov.currentcommandresolvedelements, stackmembers)
          do (this, "realScript", args)

My current script is a weird one. My changedparent script looks for all items of the same type in the same location. If it finds any, it loops over them (in object order) changing their aliases to "Bunch of bananas (6)", "5 bananas", "4 bananas", "3 bananas", "2 bananas", and "banana." All objects except the first have their listalias changed to "[STACK=o,n]", where o is the name of the first object in the stack, and n is the quantity assigned to this particular object. I'm playing around with the javascript updateList function so that these extra objects appear with display: none in the sidebar; but when you select the first one, a drop-down-list to select a number appears next to the verb buttons.

Next task is making this work the same in the case of FormatObjectList; which shouldn't be difficult because the JS already has a list of all the reachable objects for the sidebar; so I should be able to make the popup verb list when you click on an object have a number selector at the side.

Putting the hidden objects in a container seems sensible, but ends up being more trouble than it's worth because they need to be in scope. For now they're transparent containers, relying on FormatObjectList and updateList to prevent them actually displaying. But that ends up being unnecessary work; I might as well have them all in the same place if they're hidden anyway.

Log in to post a reply.