Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (499)
Games in Android Showcase (118)
games submitted by our members
Games in WIP (567)
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  
  To Component, or not to Component. That is the quest ion.  (Read 1428 times)
0 Members and 1 Guest are viewing this topic.
Offline ClickerMonkey

JGO Coder


Medals: 20


Game Engineer


« Posted 2013-09-20 12:58:48 »

(yeah I had to put a space in question so it would let me post the topic).

There are two projects I've been spending lots of time on recently, an Entity-Component-View-Controller library for games, and a game engine.

My current debate is whether I should refactor my game engine into an entity-component architecture (use my entity library essentially).

Pros:
 - It would greatly simplify my code and my user's code when it comes to: particle systems, sprites, steering behaviors, networking, spatial database, animation, sound, the list goes on.

Cons:
- The overhead of get/set methods for an Entity-Component design is more compared to using interfaces. I'm all about efficiency, and when I think about someone having 100,000 particles on their screen... it will be twice as fast when it's interfaces compared to Entity-Component (I strongly suspect - I should actually do a test).

You may be thinking THIS ISN'T EVEN DEBATABLE FOOL! But just the thought of refactoring it and having it end up being a little bit slower makes me resistant.

Help me JGO, you're my only hope!

Offline princec

JGO Kernel


Medals: 390
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #1 - Posted 2013-09-20 13:21:49 »

Don't do it. Entity systems are best for when you're dealing with 100k+ entities in MMOs. You are undoubtedly not dealing with that.

Cas Smiley

Offline ClickerMonkey

JGO Coder


Medals: 20


Game Engineer


« Reply #2 - Posted 2013-09-20 13:31:51 »

But but but... people could use my engine to make MMOs.

And it makes the code look soooo much nicer.

I am torn.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #3 - Posted 2013-09-20 17:55:33 »

Make MMOs with it?

Very very few people make MMOs, and the very few who do. Are typically large teams who are likely rolling a lot more of their own stuff.  Huh Emo Pointing persecutioncomplex

"Experience is what you get when you did not get what you wanted"
Offline Danny02
« Reply #4 - Posted 2013-09-20 20:13:49 »

I think a component system is a nice idea, but I don't like the Java implementations I saw until now that much.
I'm thinking about how one could do a nicer/better implementation with HLists and because I use scala now if macros could help.

HList would give one a type checked component system. The only problem I have with this is that there are some problem with the type systems which needs to be resolved.
Offline ClickerMonkey

JGO Coder


Medals: 20


Game Engineer


« Reply #5 - Posted 2013-09-20 20:43:07 »

Mine is type safe. The Java version is basically done, I just need to finish documentation and make some examples. Check the bottom of the readme for a code example.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
Component<Vector> POSITION = EntityCore.newComponent( "position", new Vector() );
Component<Vector> VELOCITY = EntityCore.newComponent( "velocity", new Vector() );
Component<String> NAME = EntityCore.newComponent( "name" );

Template EXAMPLE = EntityCore.newTemplate( "example", POSITION, VELOCITY, NAME );

Entity e = new Entity( EXAMPLE );
Vector p = e.get( POSITION );
Vector v = e.get( VELOCITY );
e.set( NAME, "ClickerMonkey" );

Offline Danny02
« Reply #6 - Posted 2013-09-20 22:20:24 »

your entities are not typed in the way as that the type signature does not tell what components the entity has.
Offline ClickerMonkey

JGO Coder


Medals: 20


Game Engineer


« Reply #7 - Posted 2013-09-20 22:31:22 »

Hmm what would be an example of that? Not sure I follow

Offline Jeremy
« Reply #8 - Posted 2013-09-21 04:10:27 »

The primary argument against using OOP inheritance over the Entity Component Model is that with inheritance you usually get very large inhertiance graph. (There are other arguments, i.e performance optimizations that can be done with them etc but I'm assuming you don't have that many entities)

Think (This is actually a poor way to inherit things, but its just an example...) GiantSpider inherits Enemy inherits Character inherits PhysicsBody inherits Entity (the problem therei s that Entity has a physics body, it isn't a physics body itself)

However, a lot of people who argue this are ignorant (not all of them.) Before I posted here I saw a couple arguments which clearly did inheritance wrong to argue their point. One article had Car inherit Engine -- which makes no sense at all. I think too many people are blindly using the model with little justification.

If you're careful with inheritance you won't need to use an Entity Component Model unless you are finding your inheritance graphs are growing to an absurd size or you are looking for an incredibly flexible system.

Ther are a lot of arguments for and against the Entity Component Model, I would research them and make the decision yourself.

java typically optimizes getters\setters if they recieve a lot of traffic, so it may not be an issue for you - it is definitely worth a shot if you want to use the model.

JevaEngine, Latest Playthrough (This demo is networked with a centralized server model)

http://www.youtube.com/watch?v=rWA8bajpVXg
Offline Danny02
« Reply #9 - Posted 2013-09-21 07:47:47 »

Hmm what would be an example of that? Not sure I follow
First off all, don't get me wrong your systems seems really nice and it is probably the bust one get hope for with a Java implementation.
I will try to show you in a code sample what I'm thinking about, but know that this is a unfinished thought of mine so there are still things missing.

The following is valid scala code
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
class Position
class Velocity
class Name
class Weapon

type Person = Position :: Velocity :: Name :: HNil

val entity : Person = new Position() :: new Velocity() :: new Name() :: HNil
val extraEntity = new Weapon() :: entity //add some component
val subPerson = entity.tail //only  Velocity :: Name :: HNil now

def printName[T <: HList](en: T)(implicit ev : Person isSuperOf T){
  val name : Name = en.select[Name]
  println(name)
}

printName(entity) //compiles
printName(extraEntity)//compiles
printName(subPerson)//does not compile
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline 65K
« Reply #10 - Posted 2013-09-21 07:54:56 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
Component<Vector> POSITION = EntityCore.newComponent( "position", new Vector() );
Component<Vector> VELOCITY = EntityCore.newComponent( "velocity", new Vector() );
Component<String> NAME = EntityCore.newComponent( "name" );

Template EXAMPLE = EntityCore.newTemplate( "example", POSITION, VELOCITY, NAME );

Entity e = new Entity( EXAMPLE );
Vector p = e.get( POSITION );
Vector v = e.get( VELOCITY );
e.set( NAME, "ClickerMonkey" );

What is the benefit in wrapping core properties like these in components as opposed to place them directly in entity classes ?

Offline ClickerMonkey

JGO Coder


Medals: 20


Game Engineer


« Reply #11 - Posted 2013-09-21 14:10:39 »

Here are the several scenarios to which components would simplify my game engine, and would get ride of tons of interfaces:

 1. You could add a PhysicController to any entity that has position, velocity, acceleration, etc. it could also check "if this entity has angle, and has angular velocity, update it". It would enable many things to be made into controllers that can be shared between entities of different types but similar characteristics.

 2. There are several systems in my game engine that require you to have an object with a specific interface. For example: Networking, Spatial Databases, Steering Behaviors, Particle Systems, etc. This leads to many many methods (getSpatialPosition(), getSteeringPosition(), getPosition()) that often all return the same vector. But sometimes this won't be true. My Particle interface currently has the following methods: location, velocity, acceleration, size, scale, scaleVelocity, scaleAcceleration, angle, angleVelocity, angleAcceleration, color, tile, lifetime, age. So all particle implementations have to have these methods, whether it's a particle type that has an angle or not (to which point angle returns null). I need these methods there because I have several classes which update different parts of a particle over time (like angle by angleVelocity).

 3. My networking library would be greatly simplified. You pass into a NetworkEntity class the components you want sent across the wire (as well as information about how often and the priority of each one). This makes it super simple to network an entity, you don't need to use code that wraps your networkable attributes then pass them to the networking code (if that makes any sense). You just tell it which components, and it handles calling get and set!

I'm still torn, I think of all the simplified code it would take (and a lot less code), and I think of the small amount of overhead it adds.

Offline 65K
« Reply #12 - Posted 2013-09-21 17:40:17 »

Maybe give a more verbose example of the mentioned code simplification.

Offline ClickerMonkey

JGO Coder


Medals: 20


Game Engineer


« Reply #13 - Posted 2013-09-21 19:22:54 »

Ok, here are some examples.

Particle System Simplification

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
public interface Particle extends Entity {
   public void reset( float lifetime );
   public Vec2f location();
   public Vec2f velocity();
   public Vec2f acceleration();
   public Vec2f size();
   public Vec2f scale();
   public Vec2f scaleVelocity();
   public Vec2f scaleAcceleration();
   public Scalarf angle();
   public Scalarf angleVelocity();
   public Scalarf angleAcceleration();
   public Color color();
   public Tile tile();
   public void tile( Tile tile );
   public float lifetime();
   public float age();
}


And here's an example of something I call a ParticleInfluence. It's something that gets called every frame for every particle in the system which has this influence.

1  
2  
3  
4  
5  
6  
7  
8  
public class InfluenceAngle extends InfluencePath<Scalarf> {   
   public InfluenceAngle( Path<Scalarf> path ) {
      super( path );
   }
   protected void onInfluence( Particle p, float elapsed ) {
      path.set( p.angle(), p.age() / p.lifetime() ); // path determines what the angle is depending on a delta [0, 1]
  }
}


As you see this one is for the angle. I ALSO have one for color, acceleration, scale, size, tile, and velocity. Now If I used components, it would look like this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
public class InfluencePath<T> extends ParticleInfluence {
   public Path<T> path;
   public Component<T> component;
   public InfluencePath( Component<T> component, Path<T> path ) {
      ...
   }
   protected void onInfluence( Particle p, float elapsed ) {
      path.set( p.get( component ), p.age() / p.lifetime() );
   }
}


So instead of doing...

1  
2  
3  
4  
ParticleEmitter emitter = new ParticleEmitter();
emitter.addInfluence( new InfluenceAngle( new Tween<Scalarf>( Scalarf.ONE, new Scalarf( 2.0f ) ) );
emitter.addInfluence( new InfluenceScale( new Tween<Vec2f>( Vec2f.ONE, new Vec2f( 1.4f ) ) );
emitter.addInfluence( new InfluenceVelocity( new Tween<Vec2f>( Vec2f.ZERO, new Vec2f( 200f ) ) );


It would be:
1  
2  
3  
4  
ParticleEmitter emitter = new ParticleEmitter();
emitter.addInfluence( new InfluencePath( Particle.ANGLE, new Tween<Scalarf>( Scalarf.ONE, new Scalarf( 2.0f ) ) );
emitter.addInfluence( new InfluencePath( Particle.SCALE, new Tween<Vec2f>( Vec2f.ONE, new Vec2f( 1.4f ) ) );
emitter.addInfluence( new InfluencePath( Particle.VELOCITY, new Tween<Vec2f>( Vec2f.ZERO, new Vec2f( 200f ) ) );


And I could also add:
1  
2  
3  
4  
5  
6  
7  
public class InfluenceAdding<T> extends ParticleInfluence {
   public Component<T> subject;
   public Component<T> addend;
   protected void onInfluence( Particle p, float elapsed ) {
                p.get( subject ).add( p.get( addend ), elapsed );
   }
}


So I can do things like:
1  
2  
3  
emitter.addInfluence( new InfluenceAdding<Vec2f>( Particle.VELOCITY, Particle.ACCELERATION ) );
emitter.addInfluence( new InfluenceAdding<Vec2f>( Particle.POSITION, Particle.VELOCITY ) );
emitter.addInfluence( new InfluenceAdding<Scalarf>( Particle.ANGLE, Particle.ANGULAR_VELOCITY) );


Which stuff like this enables the user to add their own update logic, instead of having this fixed in the ParticleSystem code:
1  
2  
3  
4  
5  
6  
7  
8  
Particle p = ...
if (p.velocity() != null) {
  if (p.acceleration() != null) {
     p.velocity().add( p.acceleration(), elapsed );
  }
  p.position().add( p.velocity(), elapsed);
}
// do the same for angle and size velocity & acceleration


I hope it's clearer now.

Offline 65K
« Reply #14 - Posted 2013-09-22 09:01:56 »

Thanks for the example. It is clearer now.
But, let me be the ignorant potential user of your game engine: I am still not convinced. I see no simplification, but the opposite. Every added abstraction and indirection makes things more complicated first of all.
If it is to avoid bloated interfaces due to many different implementations, then you can as well turn the direction flow: Let particle implementations be the master. Let them look for interesting game attributes and let them modify their own properties. Or turn them into event listeners and notify them about interesting events.

Offline ClickerMonkey

JGO Coder


Medals: 20


Game Engineer


« Reply #15 - Posted 2013-09-22 15:27:49 »

Okay, I think I've been convinced to stay away from using them in my game engine.

For now at least...

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.

Pippogeek (39 views)
2014-09-25 10:13:29

Pippogeek (30 views)
2014-09-25 10:12:22

Pippogeek (19 views)
2014-09-25 10:12:06

Grunnt (45 views)
2014-09-24 08:38:19

radar3301 (27 views)
2014-09-22 17:33:17

BurntPizza (63 views)
2014-09-21 20:42:18

BurntPizza (33 views)
2014-09-21 19:30:30

moogie (41 views)
2014-09-21 18:26:15

UprightPath (50 views)
2014-09-21 14:14:06

BurntPizza (54 views)
2014-09-19 21:14:18
List of Learning Resources
by Longor1996
2014-08-17 04:40:00

List of Learning Resources
by SilverTiger
2014-08-06 13:33:27

Resources for WIP games
by CogWheelz
2014-08-02 10:20:17

Resources for WIP games
by CogWheelz
2014-08-02 10:19:50

List of Learning Resources
by SilverTiger
2014-08-01 10:29:50

List of Learning Resources
by SilverTiger
2014-08-01 10:26:06

List of Learning Resources
by SilverTiger
2014-08-01 05:54:12

HotSpot Options
by dleskov
2014-07-08 19: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!