Accueil > Planet Roguelike, The Chronicles Of Doryen > Hard and soft stacks : more item ramblings

Hard and soft stacks : more item ramblings

Even if I’m only at the first steps of the first chapter of the last doryen prototype (!…), I already need more advanced stuff in the core engine than what I had in the latest versions of TCOD… Funny how things never seem to be complex enough when you code a roguelike….

The basic item

This is always around the item core class. For a basic game like Pyromancer, items contain only the item specific data. Hell, pyro doesn’t even have an inventory. Items are used and destroyed as soon as you walk on them…

class Item {
};
class Weapon : public Item {
.. weapon specific data
};

Hard stacks of items

But as soon as you have an inventory, you have to think about item stacks. If your inventory simply display the items in a list, you can have lots of redundant items. For some complex item classes like weapons, this can be acceptable, but for basic items like ranged weapon ammunition (arrows and bolts), you certainly don’t want to list each one independently…

an arrow

an arrow

an arrow

… (repeat 100 times)

Of course, you want to see all arrows as a single stack of items :

100 arrows

Also, in term of performance and memory, it’s certainly better to have a single Item instance with a count of 100 rather than 100 instances. So you add a count member on the item class.

class Item {
   int count;
};

Then it’s only a matter of merging / splitting items when you pick up or drop one.

Picking up :

if the inventory already contains an item of the same type, increase the count and destroy the item on ground

else move the item from ground to inventory.

Dropping :

if count > 1, decrease the count and create a clone with count = 1 on ground

else move the item from inventory to ground.

But you may not want to merge all types of items. If you wear one rusted knife and you pick up an enchanted knife of diarrhoea (target suffers from diarrhoea for 5 sec on successful hit), you don’t want the magic knife to be merged and stored as a rusted one. So you need a flag on each item type that indicates if it is stackable or not.

class ItemType {
   bool stackable;
};
class Item {
   ItemType *type;
   int count;
};

Now picking/dropping operations only do the merge/split on stackable items.

Ok the count member is useless for non stackable items. You could have two inheriting classes StackableItem and NonStackableItem, but I’m not a big fan of Himalayan class hierarchies…

Soft stacks of items

This is what I was using in TCOD but it’s not sufficient. Imagine you have food depreciation. A piece of meat will give you a lot of health points when it’s fresh, but in your backpack, it losses slowly its quality until it’s really rotten and you’d better not eat it or you’ll be poisoned. Since a piece of meat has an internal timer, you can’t merge it with another one (except if their timer match perfectly). Yet, you still don’t want to see :

a piece of meat

a piece of meat

in your inventory. You want :

2 pieces of meat

and if one of them just get rotten, your inventory now contains :

a piece of meat

a rotten piece of meat

That’s what I call a soft stack. In the program memory, the items behave exactly like non stackable items, but in the inventory screen, they look exactly like the stackable ones. No merge/split operations here.

What if you want to eat the older piece of meat first ? I think a good solution is to be able to unwrap soft stacks.

+ 2 pieces of meat

click on the ‘+’ button :

- 2 pieces of meat

a piece of meat (rotten in 24min)

a piece of meat (rotten in 12 min)

Of course, unwrapping a 100 items soft stack would be bad. But generally, item count is inversely proportional to its “stackability”. Non stackable items are generally big and you wear only a few of them. Soft stackable items are more numerous, but generally no more than 10 per class. If you walk with 50 pieces of meat in your backpack, there’s something wrong in the game’s balance. Hard stackable items are the most numerous, the king of them being the gold coin (even though wearing 2000 gold pieces in one’s backpack is not very realistic…).

Also note that with the possibility to unwrap soft stacks, you could as well discard non stackable items and have everything soft or hard stacked. But that would represent a lot of wrap/unwrap operations while using the inventory, a bit like using windows explorer and it’s probably better to have the major items (weapons, armors, …) directly accessible as non stackable items.

For soft stacks, you just have to replace the stackable boolean by an enumeration :

class ItemType {
  enum { NO_STACK, SOFT_STACK, HARD_STACK } stackMode;
};

Related posts:

  1. Pas encore de commentaire
  1. Pas encore de trackbacks