Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (491)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (556)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Entity System - What do you think?  (Read 2368 times)
0 Members and 1 Guest are viewing this topic.
Offline Gudradain
« Posted 2011-08-29 05:50:16 »

Hello,

Lately, as I was working on a project in group I had 2 principals problems :

1. When you work on the same class at the same times it can be a real waste of time to merge the change later. There is always merge conflict O_O even when you work on different things logic wise.

2. If you do all your logic the OOP way it seems to become nearly impossible to refactor/change your game logic later on. The classes become big with lot of functionalities and when you change something you need to make sure everything still work.

So, to fix those 2 problems, I made some very simple entity system. In fact it only have 2 classes. (Can't really be smaller than that). I would like to have your inputs on that idea. Do you think it could fix some of my problems or do you think it's a waste of time? Here is the code :

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
import java.util.ArrayList;
import java.util.HashMap;

/**
 *
 * The world containing all the entities.
 *
 * The function of this class is simply to store all the entities and give the
 * programmer an easy access to every entities.
 *
 * @author Gudradain
 *
 */

public class World {
   
   private final HashMap<String, ArrayList<Entity>> entityListMap = new HashMap<String, ArrayList<Entity>>();
   
   /**
    * Add an entity to this world.
    *
    * @param entity
    */

   public void addEntity(Entity entity){
      ArrayList<Entity> entityList = entityListMap.get(entity.getID());
      if(entityList == null){
         entityList = new ArrayList<Entity>();
         entityListMap.put(entity.getID(), entityList);
      }
      entityList.add(entity);
     
      for(Entity module : entity.getModuleList()){
         ArrayList<Entity> moduleList = entityListMap.get(entity.getID());
         if(moduleList == null){
            moduleList = new ArrayList<Entity>();
            entityListMap.put(module.getID(), moduleList);
         }
         moduleList.add(module);
      }
   }
   
   /**
    * Remove an entity from this world.
    *
    * @param entity
    */

   public void removeEntity(Entity entity){
      ArrayList<Entity> entityList = entityListMap.get(entity.getID());
      if(entityList != null){
         entityList.remove(entity);
      }
     
      for(Entity module : entity.getModuleList()){
         ArrayList<Entity> moduleList = entityListMap.get(entity.getID());
         if(moduleList != null){
            moduleList.add(module);
         }
      }
   }
   
   /**
    * Get all the entity of this sort in this world.
    *
    * The entities that you will get will probably not be of the type entityID
    * because it will return all the entities having that sort of entities
    * within them.
    *
    * @param entityID
    * @return
    */

   public ArrayList<Entity> getEntityList(String entityID){
      ArrayList<Entity> newEntityList = null;
     
      ArrayList<Entity> entityList = entityListMap.get(entityID);
      if(entityList != null){
         newEntityList = new ArrayList<Entity>();
         for(Entity entity : entityList){
            newEntityList.add(entity);
         }
      }
      return entityList;
   }

}


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
import java.util.ArrayList;

/**
 * An entity exist in a world.
 *
 * An entity has a series of module that implement the different
 * functionalities this entity will have. A module is also an entity.
 *
 * An entity can only have 1 module of each sort. You add module to an entity
 * not to represent the data of this entity but to add functionality to this
 * entity.
 *
 * Example : You have a character in a RPG that has many items. Trying to
 * add each item to the character as an entity would be a bad idea. The good
 * way to do it would be to add an InventoryEntity to the character and then
 * that inventory could hold a reference to every item the player have.
 *
 * ----------------------------------------------------------------------------
 *
 * Why should you use entity in your game?
 *
 * 1. It enables you to work in team! That is probably the biggest advantage.
 * Imagine you have the character with his inventory and that character can
 * also attack enemies. You can easily create a sort of inventory and the code
 * to attack the enemies inside the Character class. Now what if, you and your
 * friend want to work at the same time on the code for the inventory and on
 * the code for attacking enemies. If you put everything in the same class you
 * could get a lot of problem with merging both of your part later on. By
 * splitting the logic in module you can both work on the same entity at the
 * same time.
 *
 * 2. The code can be reuse more easily! Since you split everything in small
 * bit of logic, there is a lot more chance that you could reuse your code in
 * an other part of the project or in an other project.
 *
 * 3. Greatly reduce the size of the classes! Everything is split up in small
 * module so you don't have gigantic class with lot of functionalities.
 *
 * 4. Make refactoring a lot easier! Since you split up everything in small
 * chunk you can't produce code that are interrelated between itself and that
 * are practically impossible to refactor. I'm sure everyone has already done
 * it many times. You create a class with many functionalities and everything
 * in the class is interrelated. Then you want to change/remove/add a
 * functionalities but it is so hard to change that class because everything is
 * interrelated inside it and as soon as you make a small change the rest break
 * up. Well, that's something you want to avoid. Code that can't be change is
 * bad code.
 *
 * 5. Give easy access to everything in the world! Writing the code to store
 * and access thing in your game is probably the most boring one to do. Since
 * every entity has a connection to the world and the world has a connection to
 * every entity in it, it's always easy to get the information you want at any
 * time.
 *
 * @author Gudradain
 *
 */

public class Entity {
   
   private final ArrayList<Entity> entityList = new ArrayList<Entity>();
   
   private final World world;
   
   public Entity(World world){
      this.world = world;
   }
   
   /**
    * The world in which this entity exist
    *
    * @return
    */

   public World getWorld(){
      return world;
   }
   
   /**
    * The unique ID of this sort of entity.
    *
    * @return
    */

   public String getID(){
      return getClass().getName();
   }
   
   /**
    * Add an entity to this one.
    *
    * An entity can only have 1 entity of each sort. If you try to add more
    * than one entity of the same sort it will throw an exception.
    *
    * @param entity
    * @throws Exception
    */

   public void addModule(Entity entity) throws Exception{
      for(Entity e : entityList){
         if(e.getID().equals(entity.getID())){
            throw new Exception("This entity already have an entity of this sort");
         }
      }
      entityList.add(entity);
   }
   
   /**
    * Remove an entity
    *
    * @param entity
    */

   public void removeModule(Entity entity){
      entityList.remove(entity);
   }
   
   /**
    * Get all the entities related to this one
    *
    * @return
    */

   public ArrayList<Entity> getModuleList(){
      ArrayList<Entity> newEntityList = new ArrayList<Entity>();
      for(Entity entity : entityList){
         newEntityList.add(entity);
      }
      return newEntityList;
   }
   
   /**
    * Get the entity of this sort
    *
    * @param entityID
    * @return
    */

   public Entity getModule(String entityID){
      Entity newEntity = null;
      for(Entity entity : entityList){
         if(entity.getID().equals(entityID)){
            newEntity = entity;
            break;
         }
      }
      return newEntity;
   }

}


There is more details about what I would like to achieve in the comments of the Entity class.

I still didn't try the idea yet but if anyone has experience with a similar design how did it work for you?

Offline ra4king

JGO Kernel


Medals: 345
Projects: 3
Exp: 5 years


I'm the King!


« Reply #1 - Posted 2011-08-29 07:57:45 »

Looks really good! There is one potential problem however. The "getID()" method in Entity returns the name of the class. Since you may have multiple entities from the same class and considering the fact that a key in HashMap can only map to 1 value, they will replace each other once they are added to the map.

Offline Z-Man
« Reply #2 - Posted 2011-08-29 12:13:16 »

Looks really good! There is one potential problem however. The "getID()" method in Entity returns the name of the class. Since you may have multiple entities from the same class and considering the fact that a key in HashMap can only map to 1 value, they will replace each other once they are added to the map.
The add method checks to see if there is an ArrayList for that set of ID's if there is it adds to it otherwise it creates a new one. I think...
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Rejechted

Senior Member


Medals: 1
Projects: 1


Just a guy making some indie games :D


« Reply #3 - Posted 2011-08-29 14:58:28 »

I would investigate giving each Entity a UUID when it's created.

http://download.oracle.com/javase/6/docs/api/java/util/UUID.html

1  
2  
static UUID    randomUUID()
          Static factory to retrieve a type 4 (pseudo randomly generated) UUID.


This ensures you'll never have the problem described above.  The downside is you won't be able to give your own ID's like "player" "enemy1" etc. 

Blog for our project (Codenamed Lead Crystal): http://silvergoblet.tumblr.com
Offline ReBirth
« Reply #4 - Posted 2011-08-30 05:19:08 »

I'm kinda confused with the second code. Why add entity to another entity class? it'll make sense if the 2nd code is called EntityContainer or somekind.

Offline Gudradain
« Reply #5 - Posted 2011-08-30 13:21:00 »

I'm kinda confused with the second code. Why add entity to another entity class? it'll make sense if the 2nd code is called EntityContainer or somekind.

For simplicity, only need to create one class. But also, it had flexibility because you can also add module (entity) to the module of your entity.

The world only see the hierarchy as : world -> entities -> modules
But it's in fact : world -> entities -> entities -> entities -> entities -> ...
Online theagentd
« Reply #6 - Posted 2011-08-30 17:03:00 »

I tried to do this for a 2D RPG Maker style game a very long time ago. I abandoned the game, partly because of how hard it was to get these entities working. I had a very similar system of GameObjects having modules, but it didn't make things any easier as all the modules needed access to almost all other modules... I wasn't a very good programmer at that time. xD

Myomyomyo.
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #7 - Posted 2011-08-30 17:07:19 »

If you want a bunch of simple pieces then just make a component-based system. I personally like having everything in one place, it's often easier to figure out issues that way, Well, everything in moderation, I guess.

See my work:
OTC Software
Offline Gudradain
« Reply #8 - Posted 2011-08-30 17:54:40 »

I tried to do this for a 2D RPG Maker style game a very long time ago. I abandoned the game, partly because of how hard it was to get these entities working. I had a very similar system of GameObjects having modules, but it didn't make things any easier as all the modules needed access to almost all other modules... I wasn't a very good programmer at that time. xD

Yup, I tried it too and I miserably failed too Smiley. But I think it was mostly related to my set of minds. I was trying to make general code that could work anywhere, but you should never do it. If you separate everything into module but you don't try to make general code it might work better.

@Eli : Yeah I think I didn't name it right. That is not really an entity system more like a module or component system.
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #9 - Posted 2011-08-30 18:19:00 »

@Eli : Yeah I think I didn't name it right. That is not really an entity system more like a module or component system.
Well you seem about halfway in-between if you ask me. For a component system you usually either make a bunch of Interfaces that define functionality and then you make your class implement however many you need, or you make a bunch of classes that do the functionality on some common object type and you add all those into a list. However, you do it, the general idea is that you effectively say, "My entity can Walk, it can Shoot, it can TakeDamage, it can Die, and it can be Drawn," or something along those lines. Then you add all those various components in, and some sort of priority/ordering system (can it die while it's already shooting? Can it draw?) and you're good to go.

See my work:
OTC Software
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Gudradain
« Reply #10 - Posted 2011-08-30 18:59:54 »

@Eli : Yeah I think I didn't name it right. That is not really an entity system more like a module or component system.
Well you seem about halfway in-between if you ask me. For a component system you usually either make a bunch of Interfaces that define functionality and then you make your class implement however many you need, or you make a bunch of classes that do the functionality on some common object type and you add all those into a list. However, you do it, the general idea is that you effectively say, "My entity can Walk, it can Shoot, it can TakeDamage, it can Die, and it can be Drawn," or something along those lines. Then you add all those various components in, and some sort of priority/ordering system (can it die while it's already shooting? Can it draw?) and you're good to go.

That's something like that but what I will avoid at all cost is including the priority/ordering into the system because you lose half of the control this way.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Nickropheliac (15 views)
2014-08-31 22:59:12

TehJavaDev (23 views)
2014-08-28 18:26:30

CopyableCougar4 (29 views)
2014-08-22 19:31:30

atombrot (41 views)
2014-08-19 09:29:53

Tekkerue (38 views)
2014-08-16 06:45:27

Tekkerue (35 views)
2014-08-16 06:22:17

Tekkerue (25 views)
2014-08-16 06:20:21

Tekkerue (34 views)
2014-08-16 06:12:11

Rayexar (72 views)
2014-08-11 02:49:23

BurntPizza (48 views)
2014-08-09 21:09:32
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!