• Advertisement
Sign in to follow this  

Data Driven Item component system?

Recommended Posts

I am trying to figure out a good component design for my item classes since otherwise it probably ends up in a hierarchy disaster. I will just be just using this to define my items in a data driven way. My items do not have a position or interact with the map, they are either on a character or on a tile in the map and that is where they are stored. So I created a blank interface and a couple implementations, nothing is set in stone but I think my concept is pretty solid and I'm looking for feedback from people with more experience on the topic since it would not be the first time I burry myself into something I cannot climb out of :).

public interface ItemComponent {

}
public class WeaponComponent implements ItemComponent{
    int damage;
    int range;
    float attackSpeed;
    String damageType;
}
public class ArmorComponent implements ItemComponent {
    int defense;
    String armorType;
    String bodyPart;
}

Easy enough, like most component systems they only add data the system in my case are the characters using the items, I could add functionality but that will probably complicate things once more components are added. When the character uses any item with the corresponding component I have access to the data, and that is all I currently need. A shield that could also be used as a weapon should be easy to model in. To know and find a specific type of item I implemented a Map that maps a String to a ItemComponent.

public class Item {
    private String name;
    private int weight;

    private Map<String, ItemComponent> itemComponents = new HashMap<>();

    public Item() {
    }

    public void addComponent(ItemComponent component) {
        itemComponents.put(component.getClass().toString(), component);
    }
}

A basic item that is used for crafting only would not have any components. For easy lookup I added a couple methods.

public boolean hasComponent(Class c) {
    return itemComponents.containsKey(c.toString());
}

public boolean isWeapon() {
    return hasComponent(WeaponComponent.class);
}

public boolean isArmor() {
    return hasComponent(ArmorComponent.class);
}

To instantiate items I will import all JSON data in a Factory pattern and clone the items. Since crafting is a thing I will add another Map to this that maps the items name to the recipe.

public Item clone() {
    return new Item(name, weight, itemComponents);
}
public class ItemPrototype {
    private Item item;
    private Recipe recipe;

    public Item cloneItem(){
        return item.clone();
    }

    public Item createItem(List<Item> ingredients) {
        // Todo: Check ingredients.
        // Todo: Remove ingredients.
        return cloneItem();
    }
}
public class ItemFactory {
    private static Map<String, ItemPrototype> itemPrototypes = new HashMap<>();

    static {
        // Todo: Import items from JSON
    }

    public static Item createItem(String name, List<Item> ingredients) {
        // TODO: Error handling
        return itemPrototypes.get(name).createItem(ingredients);
    }

    public static Item createItem(String name) {
        // TODO: Error handling
        return itemPrototypes.get(name).cloneItem();
    }
}

Here is how an item would look inside a JSON file. A simple rock would truncate everything except for it's name and weight unless it I decide it can be used as a weapon too.

"Rifle" : {
  "item" : {
    "name" : "Rifle",
    "weight" : 3500,
    "itemComponents" : {
      "WeaponComponent" : {
        "damage" : 18,
        "range" : 20,
        "attackSpeed" : 10.0,
        "damageType" : "Piercing"
      }
    }
  },
  "recipe" : {
    "ingredients" : {
      "Wood" : 1,
      "lense" : 1,
      "Steel Plate" : 4
    }
  }
}

I love to hear what more experienced people have to say about this. There are not much examples to look at on internet except for a couple that go all the way down to engine level where basically everything is a entity. If I have success with this structure I definitely write a article about it.

Share this post


Link to post
Share on other sites
Advertisement

Hello!

It looks good to me. My own minimal ECS is very similar. Just a few small notes:

- You can directly use your Component object's type as the key for the HashMap, there is no need to go the detour over stringifying it. Just use a HashMap<Class, ItemComponent>.

- Why store name and weight as direct members of the Item class? Put them in components, too, and you'll have a completely "pure" and generic ECS.

- You could think about whether you need the Item class at all. In my implementation, an entity is just an integer (actually a "Long") ID, so the whole data structure of the ECS is a HashMap<Long, HashMap<Class, AbstractComponent>>. All code to manage entities, which is in your implementation partly located in Item and partly in ItemFactory, lies in a single "EntityManager" class.

Share this post


Link to post
Share on other sites

Another thing:

Also don't put methods like isWeapon() or isArmor() into your Item class. This goes towards the "god class" anti-pattern which is exactly what you want to avoid by using a component system. An item/entity should not make any fixed assumptions about what it is (or might be). Any actual "use case"- or "semantics"-related code belongs into separate classes/functions (the "systems" in ECS terminology). As already mentioned, best get rid of the Item class completely - in a good ECS design, it has no purpose. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By EddieK
      Hi, so I have this game which I'm working on and I have implemented A* pathfinding algorithm, but the problem is that the game framerate drops significantly if there are more than 50-100 enemies which need to find path to player.
      I did some code analyzing and noticed that the part which takes longest to process is part where it searches for node with the lowest F score. Is there anyway I could speed the process up?
      Here's the code I'm using:
      public ArrayList<Node> getPath(Node start, Node end){ closedSet.clear(); openSet.clear(); openSet.add(start); cameFrom.clear(); start.gScore = 0; start.fScore = heuristicCostEstimate(start, end); while(openSet.size() > 0){ Node currentNode = lowestFScoreNode(openSet);//openSet.findLowestFScoreNode(); if(currentNode.equals(end)){ return reconstructPath(cameFrom, currentNode); } openSet.remove(currentNode); closedSet.add(currentNode); Node [] neighbours = getNeighbours(currentNode); for(int i = 0; i < neighboursCount; i++){ if(closedSet.contains(neighbours[i])) continue; openSet.add(neighbours[i]); float tentativeGScore = currentNode.gScore + heuristicCostEstimate(start, neighbours[i]); if(tentativeGScore >= neighbours[i].gScore) continue; cameFrom.put(neighbours[i], currentNode); neighbours[i].gScore = tentativeGScore; neighbours[i].fScore = neighbours[i].gScore + heuristicCostEstimate(neighbours[i], end); } } return null; } The lowestFScore node function just returns result of Collections.min() 
      Thanks in advance.
    • By EddieK
      Hi I am having this problem where I am drawing 4000 squares on screen, using VBO's and IBO's but the framerate on my Huawei P9 is only 24 FPS. Considering it has 8-core CPU and a pretty powerful GPU, I don't think it is not capable of drawing 4000 textured squares at 60FPS.
      I checked the DMMS and found out that most of the time spent was by the put() method of the FloatBuffer, but the strange thing is that if I'm drawing these squares outside of the view frustum, the FPS increases. And I'm not using frustum culling. 
      If you have any ideas what could be causing this, please share them with me. Thank you in advance.
    • By Honneamise
      Hello,
      im looking for some feedback about my latest experiment .
      You can find it here :
      http://www.honny.net/hexnet
      But please before to do that take some minutes to read what follow.
       
      In all my previous projects i have always used C language ( C not C++ ), yes i am a very old person.
      Some time ago I felt the need to “evolve” in some way, I cant say why exactly.
      To be honest in C i have always been able to find a way to solve a problem by myself or a library for a specific task.
      Of consequence all this stuff about OOP and Classes was really new to me.
      To test this experience i have used Processing.
      From what i have understood this was the fastest ( and easiest ) way to setup this kind of project.
      Well, if you are reading this you have already understood that this is not really a "complete game",
      just a minimalist minesweeper-like similar to the "mini hack" sub-games that you can find in major titles.
      Keep in mind that the main goal was to make some experience with basic stuff like :
      setup a project
      learning OOP and Classes
      basic drawing and images loading
      handling user input
      etc...
       
      UPDATE 11/02/2018 : updated new game version and added some screenshots !!!
      UPDATE 03/02/2018 : now it exist AT LEAST a path to complete the game :-)
       
    • By Ruzicar
      Hi folks,
      During a recent leave of absence for family reasons, I needed something to take my mind off my troubles.  So I decided to learn Android development and create a game I've always wanted to play.  "Borbudo" is available on the Google Play Store at:
      https://play.google.com/store/apps/details?id=com.borbudo.free
      Very briefly, Borbudo is inspired by the old 80s games Time Bandits and Gauntlet, and in the future I hope to include lots of puzzles and quests in the spirit of Dungeon Master.  Right now I confess that the game needs some re-work to create a unifying theme, but I think the alpha version available now is pretty solid.  My game also features the music of Eric Matyas.
      I'd very much appreciate any comments (or even Patreon pledges).
      With many thanks,
      Rob Lehrbass
    • By Time4Tea
      This is linked to another question that I asked here a couple of days ago:
      I'm looking at making a client-server game with a game server programmed in Java. The game will be a 2D turn-based game (like a board game), with a maximum of around 50-100 games going on at any one time. So, the performance requirements are not very high. The reason I would like to use Java for the server are because I already have some familiarity with it and I would like the server to not be tied to one particular platform. I would also like to design it so that the client interface to the server is as generic as possible, so that the same server could be used with multiple different clients. For example, there might be a web-based client, or someone else might design a stand-alone 3D client application later on, using the same server.
      So, I am looking for some advice on where to start with this, as I have very little experience with coding servers.
      I was planning to use web sockets for the client-server connection, which apparently uses Java EE (Enterprise Edition), which seems to require the use of the GlassFish server. However, I have been advised that a fully-fledged application server, like GlassFish, may be overkill for a game server. So, here are my questions:
      Should I use something like GlassFish? Does it makes sense for the type of game server I am describing? If not, then what sort of networking protocol/library would experienced Java game designers recommend? Are there any existing, general-purpose Java game servers that exist, which I might be able to use as a starting point? (Or even free software/open-source client-server games?) Or, should I look at coding my own game server from scratch? In which case, again, what sort of connection type/library would be recommended? Does anyone know of any suitable introductory tutorials that deal with how to make this sort of game server in Java? I guess my priority is probably minimizing the learning curve and the amount of time/effort involved, over performance. How much effort is this sort of undertaking going to require?
      Thanks in advance! :-)
  • Advertisement