Slick Forums

Discuss the Slick 2D Library
It is currently Thu Jun 20, 2013 12:16 am

All times are UTC




Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: Apollo Entity Framework
PostPosted: Wed Aug 01, 2012 10:27 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 620
Location: Iceland
I haven't been doing much game programming lately, but I have been working on this neat entity/component framework for a while and wanted to push it out into the world now that I think it's relatively useful.

What's the similarities between this and Artemis? Not a lot, but Apollo is more of an traditional way of using entities in your games, where you have an Entity object like a jar encapsulating the components, managers and other things. I will create a proper documentation once I get feedback. It's a generic framework, meaning it can be used for 2D or 3D and whatever libraries.

I won't go into much details here, I had previously submitted a thread on Apollo when it was in its infancy, but it has evolved more now.

So, without further delay I have provided Google projects (mercurial) access to both Apollo framework an example game (very simple):

Apollo homepage: http://gamadu.com/apollo/

Apollo Entity Framework
http://code.google.com/p/apollo-entity-framework/

Apollo warrior example game
http://code.google.com/p/apollo-warrior/


You can check both projects out (eclipse) and run without much trouble. Apollo warrior has all the dependencies it needs, and the Apollo framework has no external dependencies.


Please provide feedback.


Some clarification:

Managers: Used as something that has a specially organized collection of entities, or something that provides a special functionality to all entities. E.g. "Managing entities", it's an outside hands manipulating entities or something that keeps track of entities in some special manner, like tagging them, grouping them, etc.

Entities: Just a shell for components really. If you're doing something in entities you're doing it wrong, the Entity class should not really be extended in any way. There's a built in event system as well.

Components: Data and functionality. Not much else to say.

Builders: Encourages you to put entity creation (templating) into these special builders that create new instances of entities along with all their components and events.

Spatials: Anything that is displayed needs to be a spatial. Spatial is a component and is rendered using a provided RenderManager. Node is spatial as well and allows you to attach multiple spatials to an entity, and that is useful beyond belief.


Last edited by appel on Fri Aug 03, 2012 2:24 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Fri Aug 03, 2012 2:01 am 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 620
Location: Iceland
I've added a short introduction page for the framework:

http://gamadu.com/apollo/


Top
 Profile  
 
PostPosted: Mon Aug 06, 2012 8:22 pm 
Offline
Slick Zombie

Joined: Wed Apr 02, 2008 1:32 pm
Posts: 1317
Location: Italy
hi! I've tried a bit Apollo and I'm not sure to understand Builders, I've got the point of "Templating" but using a superclass for all builders is limitating because you cannot pass more parameters. I'm wrong? could not be more useful some sort of Factory pattern on this?

_________________
Blog | Last game Gravity Duck tribute | In progress Gravity Duck tribute


Top
 Profile  
 
PostPosted: Mon Aug 06, 2012 9:35 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 620
Location: Iceland
Gornova81 wrote:
hi! I've tried a bit Apollo and I'm not sure to understand Builders, I've got the point of "Templating" but using a superclass for all builders is limitating because you cannot pass more parameters. I'm wrong? could not be more useful some sort of Factory pattern on this?


I'm open to suggestions on implementation.

I did try something like:
Code:
SpaceshipBuilder builder = world.getEntityBuilder("Spaceship", SpaceshipBuilder.class);
Entity spaceship = builder.createSpaceship(x, y, playerId);

But found it to be inferior in flexibility, simply because it's difficult to make the game data-driven than if you use a generic way of instancing entities.


Top
 Profile  
 
PostPosted: Tue Aug 07, 2012 8:53 am 
Offline
Slick Zombie

Joined: Wed Apr 02, 2008 1:32 pm
Posts: 1317
Location: Italy
But I need to set into world SpaceShipBuilder?

_________________
Blog | Last game Gravity Duck tribute | In progress Gravity Duck tribute


Top
 Profile  
 
PostPosted: Tue Aug 07, 2012 9:40 am 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 620
Location: Iceland
You can create your own method of instancing new entities.

But please share :)


Top
 Profile  
 
PostPosted: Tue Aug 07, 2012 10:14 am 
Offline
Slick Zombie

Joined: Wed Apr 02, 2008 1:32 pm
Posts: 1317
Location: Italy
first a question: why choose Java 7 ? Apollo jar is compiled with it and force me to use Java 7 :(

I have this Builder:

Code:
public class ShipBuilder implements EntityBuilder  {

   @Override
   public Entity buildEntity(World world) {
      Entity e = new Entity(world);
      e.setComponent(new Position());
      e.setComponent(new TextSpatial());
      e.setComponent(new Glyph());
      return null;
   }

}


as you can see, a simple builder, I'm using here:

Code:
      ShipBuilder builder = new ShipBuilder();
      Entity player = builder.buildEntity(world);
      player.getComponent(Position.class).setLocation(1, 1);
      player.getComponent(Glyph.class).setGlyph('@');
      
      world.addEntity(player);


What I have is:
1) I defined a builder class to help me in build an entity
2) then I have to customize it, to set location and glyph (hint: a roguelike)

Like you said, I can use my own factory to do that:

Code:
public class ShipFactory {

   public static Entity buildPlayer(World world, int x, int y, char glyph){
      Entity e = new Entity(world);
      e.setComponent(new Position(x,y));
      e.setComponent(new TextSpatial());
      e.setComponent(new Glyph(glyph));
      return e;
   }
}


and use it like that:

Code:
      World world = new World();
      Entity player = ShipFactory.buildPlayer(world, 1, 1, '@');
      world.addEntity(player);


that seems more "clean" to me (IMHO), what do you think?

Idea: if, using an annotation, we can mark class as @Builder and metod as @BuilderMethod, you can use this annotation at runtime to store a "map" of builders and use them around? Too complicated.. maybe I just need to forgot builders and use my factory ?

_________________
Blog | Last game Gravity Duck tribute | In progress Gravity Duck tribute


Top
 Profile  
 
PostPosted: Tue Aug 07, 2012 11:00 am 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 620
Location: Iceland
I'll look at making it java 6 compatible. I wasn't really thinking much about this.

There are several goals I'm trying to achieve in Apollo:
- First goal of EntityBuilder is to allow you to load resources in the initialize of your game, and you can do so in the constructor of each EntityBuilder, load resources and share among entities.
- Second goal of EntityBuilder is providing for a generic way of instancing new entities for e.g. data-driving purposes, like: world.createEntity("Something") is better than SomethingFactory.create(...) simply because you can more easily create new entities by some string value than hardcoded static class name. This goal is debatable as you can easily create entities any way you like so you could implement a way around this problem.
- Third goal is that people can easily understand how it works and "plugs" into the framework, too complex methods don't sound too easy to do even if they shorten code and seem cleaner in the end.

I'm not quite sure about using annotations so heavily.

But I like how clean it is to instantiate new entities using a factory like yours. If you can explain how to solve first goal then I'm open to change.


Top
 Profile  
 
PostPosted: Tue Aug 07, 2012 12:33 pm 
Offline
Slick Zombie

Joined: Wed Apr 02, 2008 1:32 pm
Posts: 1317
Location: Italy
My best attempt for now is using annotation:

Code:
// define a builder/factory method for an entity
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BuilderMethod {

}


You mark with annotation only methods, so you can do a class like you want ( in my example I assume a constructor with World as parameter):

Code:
   @BuilderMethod
   public Entity buildPlayer(Integer x, Integer y, Character glyph){
      Entity e = new Entity(world);
      e.setComponent(new Position(x,y));
      e.setComponent(new TextSpatial());
      e.setComponent(new Glyph(glyph));
      return e;
   }


and here set it into world (could be possible load it at runtime?

Code:
world.setEntityBuilder("player", new ShipBuilder());


Then when you use it you must specify arguments, using varargs (if you have defined @BuilderMethod so). Another idea could be add another annotation and mark class as @Builder (or EntityBuilder) and don't set it, just let Apollo discover it and set it. With a property as name, like @EntityBuilder(name="player"), you can avoid setting it? Could be possible?

Code:
world.createEntity("player",1,1,'@');


here my parser code to invoke method:

Code:
class TestAnnotationParser {
   @SuppressWarnings("rawtypes")
   public void parse(Class clazz, Object...objects) throws Exception {
      Method[] methods = clazz.getMethods();
      for (Method method : methods) {
         if (method.isAnnotationPresent(BuilderMethod.class)) {
            BuilderMethod test = method.getAnnotation(BuilderMethod.class);
            if (test!=null){
               System.out.println("good...");
               method.invoke(clazz.newInstance(),objects);
            }
         }
      }
   }

}

public class Demo {
   public static void main(String[] args) throws Exception {
      TestAnnotationParser parser = new TestAnnotationParser();
      parser.parse(ShipFactory.class,1,1,' ');
   }
}


Where in apollo code do you handle annotations?

Quote:
I'm not quite sure about using annotations so heavily.


I've tried also Artemis yesterday and Apollo with annotations seems to be more easy to understand (IMHO), for now :D

_________________
Blog | Last game Gravity Duck tribute | In progress Gravity Duck tribute


Top
 Profile  
 
PostPosted: Tue Aug 07, 2012 1:47 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 620
Location: Iceland
That seems like a lot of magic :)

Several things I dislike. Using varargs is questionable, not only performance-wise but also in readability. You have no way of knowing what arguments each entity type supports when writing in your IDE. Also varargs even for primitives? Doesn't compute to me. Too much magic makes things opaque, right amount of magic makes things clean and simple.

Annotation handling:
http://code.google.com/p/apollo-entity- ... 2Fannotate

I prefer your idea of:
Code:
SpaceshipFactory.create(world,x,y,rotation)

Only problem is.. it's not really something that you do in the framework, you can do this "as is".

Another way is to provide a context when creating entities with builders. Like:
Code:
world.create("Spaceship", new SpaceshipContext(x,y,rotation));

Only problem is, it would allow for any type of context to be passed.

But you could simply do:
Code:
world.create(new SpaceshipContext(x,y,rotation));

But this is really just an encapsulation of
Code:
SpaceshipFactory.create(world,x,y,rotation)


Top
 Profile  
 
PostPosted: Tue Aug 07, 2012 2:26 pm 
Offline
Slick Zombie

Joined: Wed Apr 02, 2008 1:32 pm
Posts: 1317
Location: Italy
Well, about varargs.. you are right! But if you use wisely could help your work IMHO :D
If arguments will be of only one type (String), not "generic", I think could be a good solution. I'll think about that.

Maybe I'm just facing problem from the wrong side. The problem is not factory, is Apollo's builders. My proposals is to keep it into Apollo, but adding into homepage a tip about a "Factory approach" to build entities to simplify your work.

_________________
Blog | Last game Gravity Duck tribute | In progress Gravity Duck tribute


Top
 Profile  
 
PostPosted: Tue Aug 07, 2012 4:52 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 620
Location: Iceland
Gornova81 wrote:
Well, about varargs.. you are right! But if you use wisely could help your work IMHO :D
If arguments will be of only one type (String), not "generic", I think could be a good solution. I'll think about that.

Maybe I'm just facing problem from the wrong side. The problem is not factory, is Apollo's builders. My proposals is to keep it into Apollo, but adding into homepage a tip about a "Factory approach" to build entities to simplify your work.

Well, the entity builders are perfectly fine as they are, but they are maybe not as convenient when it comes to initializing the entity as you point out.

The problem with Factory is, what if you have a entity that can shoot many different types of bullets? Wood bullets, lead bullets, silver bullets.

Instead of doing just:
Code:
world.createEntity(bulletTypeName);

you end up doing something like:
Code:
if(bulletTypeName.equalsIgnoreCase("WoodBullet")) {
  BulletFactory.createWoodBullet(...);
}


Top
 Profile  
 
PostPosted: Thu Aug 09, 2012 11:45 am 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 620
Location: Iceland
My intention for Apollo is to provide for a performant entity framework that is cross-graphics-library and ideal for indie games. The goal is to enable the game maker to quickly get started making the actual game.

But Apollo is just an "entity" framework currently, but it is possible to add common packages such as:
- Collision detection and handling
- Pathfinding
- AI behavior trees
- etc.

So far I've not wanted to add these, not as part of the core framework, because it introduces assumptions of what the framework is targeted for, e.g. 2D or 3D, or excludes possibility of using other solutions for those problems.
It's also difficult to make it so generic that it's re-usable for every possible game, especially 2D and 3D, but still possible. But my primary concern is that it doesn't encourage the developer to make his own implementations tailored for his own game, making him try to mold his own game into the frameworks "box".

I know many value having modules like those available in the framewok, but it might make the framework less generic and cross-usable. But I realize that most of those likely to use Apollo might use it for 2D based games and want those ready-to-use solutions. Slick already includes a-star pathfinding solution even if it's a graphics library.

So, my question is:
Should Apollo be more than just an entity framework?
Should Apollo be targeted for generic 2D games?
Should Apollo include those common packages we all have to implement anyway?


Your thoughts?


Top
 Profile  
 
PostPosted: Thu Aug 09, 2012 12:38 pm 
Offline
Slick Zombie

Joined: Wed Apr 02, 2008 1:32 pm
Posts: 1317
Location: Italy
Tip: I've found this project for finding a classes with a given interface :D

Quote:
But Apollo is just an "entity" framework currently, but it is possible to add common packages such as:
- Collision detection and handling
- Pathfinding
- AI behavior trees
- etc.

So far I've not wanted to add these, not as part of the core framework, because it introduces assumptions of what the framework is targeted for, e.g. 2D or 3D, or excludes possibility of using other solutions for those problems.


Just build a library, like "Apollo Commons" and provide a set of components and builder, with examples to build some basic games. For example: a top-down 2d shooter with Fizzy? , a 2d platform (slick based), a 3d shooter (jmonkey) as proof of concept how to use different spatial to render in 3d same top-down 2d shooter.

In my experience build a generic framework is hard and require a lot of time. Start from a simple game, then share components and iterate!

Quote:
So, my question is:
1) Should Apollo be more than just an entity framework?
2) Should Apollo be targeted for generic 2D games?
3) Should Apollo include those common packages we all have to implement anyway?


1) not apollo, somethink build on top of it, yes
2) not only, with different spatials and rendering systems, 3d could be possible (with simple games, of course! not like Crysis-stuff)
3) as separated library, yes.

For example, some components/systems (I don't know if is okay to call them so):
1) positionComponent: x,y,z coordinate (3d only? or 2d and 3d ?)
2) velocityComponent, mixed with position => TransformComponent?
3) a way to control input from player in a simple way: topDownController, PlatformController and so on
4) an example how to handle a decent gui (not apollo-related problem, but users will ask you anyway :D)
5) Fizzy/Jbox/Phys2d system example
6) behaviour tree
7) pathfinding => for 2d slick pathfinding works well.. in tiled based games, but in not-tile worlds?

Target:
1) build a simple 2d top down game

_________________
Blog | Last game Gravity Duck tribute | In progress Gravity Duck tribute


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group