HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavaModerate

Inventory - how to handle items?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
handleinventoryitemshow

Problem

I've been designing a game server, where a player has inventory, bank, and other features with items.

There are some definitions of what item can be in my game:

  • Item is either stackable or not stackable.



  • If item is stackable, item's amount can be up to 100 per stack.



So since each item can have an amount if it's stackable, my regular idea was having two arrays, int[] itemIds and int[] amount, where itemIds holds the IDs of the items, and amount holds the amount for item in that index.

I must keep the indexes the same, because when the client selects an item, it sends over the slot id he clicked on.

But then I thought, I could just do an Item object, with the tools in that class for that item, and have a private property isStackable and amount.

But then my mate said the following thing:


If you want to change some value of an Item object, you'll need to
call a new construct and then get the old value then add the new value
and then pass it to the construct. with primitives you can do that
instant, which gives also performance positives

But then I thought of an idea, have a class named ItemStorage which will contain two arrays, items and amount like I described above:

public class ItemStorage {

    private int[] items;
    private int[] amount;

    public void setItems(int[] a, int[] b) {
        this.items = a;
        this.amount = b;
    }

    public int[] getItems() {
        return this.items;
    }

    public int[] getAmount() {
        return this.amount;
    }

}


I have a class called Inventory, it's my domain object for handling the inventory, it extends the interface Storage.

public interface Storage {
    public T getStorage();
}


Now, since it implements it, the class must have the method getStorage() which will return ItemStorage, so to modify items, you do inventory.getStorage().getItems()[0] = 50;

But I am not sure about it, I am sure that List or Item[] will be much friendly, but I a

Solution

About your existing code

There's only two things I have to complain about in your current ItemStorage.

-
public void setItems(int[] a, int[] b) See those parameter names? a and b. They represent completely different things, they should have been named itemIds and amount.

-
Item(id)s in one array, and amount in another. What if each item would have enchantments? (which, for the sake of simplicity, also is an int for now) Would you add private int[] enchantments? Then what if you would add damage for items? Or other properties? It's a bad bad idea to store it like this. It's not all about performance, it's also about extensibility.

But then I thought, I could just do an Item object, with the tools in that class for that item, and have a private property isStackable and amount.

Yes, yes, YES!!

If you want to change some value of an Item object, you'll need to call a new construct and then get the old value then add the new value and then pass it to the construct. with primitives you can do that instant, which gives also performance positives

No, no, NO!!

If by "construct" you mean constructor, then no - use a setSomeValue(int newValue) method instead. If by "construct" you mean a set method like setSomeValue(int newValue), then sure, if you want to change some value you'd have to do item.setSomeValue(item.getSomeValue() + 3); but that's fine. This won't affect performance much. Java even use a Just in Time compiler to boost the performance of such calls.

If you want to you could even add a method like this to your Item class:

public void changeSomeValue(int change) {
    this.someValue += change;
}


This is especially useful for values you change often without caring much about the actual value at the moment, such as changing a player's HP. (I personally often call methods such as player.heal(4) or player.damage(6))
Designing an Inventory and Items

I think you should look at how the API of Bukkit (the Minecraft server) has been made. Bukkit have a class for ItemStack and also an interface for Inventory. You can probably find a lot of inspiration from Bukkit, although you probably won't even need half of it.

Here are some example classes that I think you could use:

public class ItemStorage {
    private Item[] items;
    private SomeObject owner; // Player, Chest, whatever... if you need it.
}

public enum ItemType {
    WEAPON(1, 1), SHIELD(2, 1), MONKEY(3, 4), MUG(4, 42), FISH(5, 64);
    // You never know what you might need in your game

    private final int id;
    private final int maxStackSize;
    private ItemType(int id, int maxStackSize) {
        this.id = id;
        this.maxStackSize = maxStackSize;
    }
}

public class Item {
    private ItemType type;
    private int amount;
}


If you want to somehow dynamically add items, then an enum won't work well for you, use an int in that case. Although I think an enum is good enough for now.

Code Snippets

public void changeSomeValue(int change) {
    this.someValue += change;
}
public class ItemStorage {
    private Item[] items;
    private SomeObject owner; // Player, Chest, whatever... if you need it.
}

public enum ItemType {
    WEAPON(1, 1), SHIELD(2, 1), MONKEY(3, 4), MUG(4, 42), FISH(5, 64);
    // You never know what you might need in your game

    private final int id;
    private final int maxStackSize;
    private ItemType(int id, int maxStackSize) {
        this.id = id;
        this.maxStackSize = maxStackSize;
    }
}

public class Item {
    private ItemType type;
    private int amount;
}

Context

StackExchange Code Review Q#55555, answer score: 17

Revisions (0)

No revisions yet.