Slick Forums

Discuss the Slick 2D Library
It is currently Thu May 23, 2013 1:55 am

All times are UTC




Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 420 posts ]  Go to page Previous  1 ... 13, 14, 15, 16, 17, 18, 19 ... 28  Next
Author Message
 Post subject:
PostPosted: Wed Jul 13, 2011 1:52 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
arielsan wrote:
@appel What do you say about having a flag on Entity class named modified or shouldRefresh, so whenever you add or remove a component you touch the flag.

Then, on each loop start, you refresh those 'modified' entities. One problem of this approach is you have to iterate between all entities :(

On the other hand, if you don't modify entities once the entity was added to the world, you can iterate between all entities only once.

Don't know for sure the best solution, but having to call e.refresh() doesn't seem natural to me. I understand that if you add/remove a component from an entity, you have to update the corresponding systems.

Maybe adding the entity to refresh collection if entity . add/remove component methods where called. Think that you only call those methods from time to time, not on every update so there should be no performance issue.


Seemingly trivial question, but still difficult to answer.

There's is uniqueId in the entities. If they are a mismatch, then it's not the same entity as before. Until I have a more clever way of dealing with this issue then this might do.

One way is to create a new Entity instance every time a new entity is created, instead of reusing old Entity instances. The overhead is probably miniscule.


The Scripting stuff looks good. There may be a blurred line between data and logic there, because the data component contains reference to something that contains logic. You're really cheating :\

Another way would be to use actual scripts, like Groovy, have the ScriptComponent have only the name of the script file, and then the script system would load it up and compile (if it's not already loaded up and compiled before, because you only load one script file ONCE, and for each entity you execute the script using different context). Then we're talking about pure dynamic stuff, you could even detect if a script has been modified and reload and recompile at runtime, and you'd see the change without even restarting the game!
This is very easy to do actually, I've done a little experiment like this before. Performance wise it's pretty good, not as good as Java though, but good enough for most games. Groovy is your best bet, not only is it popular but it also runs pretty fast. I'd tune the ScriptSystem so it runs at lower frequencies though, like 60 times per second, maybe even 20 times.
The state of the context could be serialized into some sorts of context field in the ScriptComponent, allowing for savegame.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 13, 2011 2:42 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
About the ScriptSystem, I don't believe it is cheating, the data is having or not the Script and which Script, external Lua or Groovy (or other) file or even a Java class, why not? it is code and it is compiled, maybe not easily changed in runtime, but it is clearly different than having a custom method in a custom entity class. I believe data and logic keep being separated. It lets you reuse logic in an easy way also.

In my opinion, it keeps simplicity of how many systems and for that reason it is a bit more scalable. Could be better solutions, I am not saying this is the best, what I am saying is having multiple systems sucks a bit, at least in my experience with some of our games, it didn't feel correct.

Finally, I believe other components engine frameworks like Unity does this, having a ScriptComponent.

About the entity.refresh(), what about marking the entity to be refreshed in the moment you ask world.createEntity(), it will work at least for the case when you are creating entities, for example, now every time I want to create a new entity I have to do the e.refresh():

Code:
Entity e = world.createEntity();
... add some components
e.refresh()


But I know I am creating a new entity, it should be refreshed automatically because as a new entity, it will probably have new stuff.

In case I am modifying the entity in "runtime" (inside some system process) then I am forced to call e.refresh() but in that case is alright.

At least one less e.refresh() to do, and in my case, I am not modifying components in "runtime".

note: with runtime I mean after the entity was created.

What do you say? could work?

_________________
Image


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 13, 2011 2:48 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
True, the World could invoke refresh on inserted/removed entities. Trivial thing really.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 18, 2011 5:49 am 
Offline

Joined: Sun Jun 12, 2011 2:27 pm
Posts: 90
I want to generate a delay of a code within a system as I do?
eg: Quando preciono a tecla para mover, o heroi vai andar 32px em um determinado tempo.

* Example:
Code:
public class MovementSystem extends EntityProcessingSystem
{

...
protected void process(Entity e)
{
  ...
   //Hero must go right
   For (int x=0; x<=31; x++){
      hero.setX(hero.getX()+1);
      Wait_N_Time(TimeValue);
   }

  ...

}

...

}

The animation walked 32 pixels in N time. This is what I would do, can someone help?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 18, 2011 12:54 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
@appel, I had a problem when having more than 16 different component types because the Bag is limited to 16 items by default and EntityManager is holding a Bag<Bag<Component>> to improve the get component by type.

Don't you think 16 is too small limit for different component types? should I be using less component types?

Maybe making that limit number configured through the world or something, and then using new Bag(global_limit) in the EntityManager.

Thanks.

_________________
Image


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 18, 2011 1:31 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
arielsan wrote:
@appel, I had a problem when having more than 16 different component types because the Bag is limited to 16 items by default and EntityManager is holding a Bag<Bag<Component>> to improve the get component by type.

Don't you think 16 is too small limit for different component types? should I be using less component types?

Maybe making that limit number configured through the world or something, and then using new Bag(global_limit) in the EntityManager.

Thanks.


It should auto-expand, right? You get an exception?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 18, 2011 3:01 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
Yes, an array out of bounds exception in Bag class, on EntityManager getComponentMethod I believe, don't have the stacktrace right now.

_________________
Image


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 18, 2011 3:09 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
Code:
Exception in thread "LWJGL Application" java.lang.ArrayIndexOutOfBoundsException: 16
   at com.artemis.utils.Bag.get(Bag.java:141)
   at com.artemis.EntityManager.getComponent(EntityManager.java:117)
   at com.artemis.Entity.getComponent(Entity.java:129)
   at com.artemis.Entity.getComponent(Entity.java:140)
        ....


For more information, an EntityProcessingSystem is asking for a component that no entity has, using e.getComponent(...)

_________________
Image


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 19, 2011 2:43 pm 
Offline

Joined: Fri May 20, 2011 6:08 pm
Posts: 27
On the composite spatial example, I think you are missing the setOwner method on spatial class. Does it set a entityId attribute?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 28, 2011 5:48 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
@appel, remember the ArrayOutOfBoundsException, I have test code to replicate the bug:

Code:
public class ArtemisOutOfBoundsTest {

   private static class Component1 extends Component {}
   private static class Component2 extends Component {}
   private static class Component3 extends Component {}
   private static class Component4 extends Component {}
   private static class Component5 extends Component {}
   private static class Component6 extends Component {}
   private static class Component7 extends Component {}
   private static class Component8 extends Component {}
   private static class Component9 extends Component {}
   private static class Component10 extends Component {}
   private static class Component11 extends Component {}
   private static class Component12 extends Component {}
   private static class Component13 extends Component {}
   private static class Component14 extends Component {}
   private static class Component15 extends Component {}
   private static class Component16 extends Component {}

   private static class ComponentOutOfBounds extends Component {}
   
   @Test
   public void test() {

      World world = new World();

      Entity e = world.createEntity();

      e.addComponent(new Component1());
      e.addComponent(new Component2());
      e.addComponent(new Component3());
      e.addComponent(new Component4());

      e.addComponent(new Component5());
      e.addComponent(new Component6());
      // e.addComponent(new Component7());
      e.addComponent(new Component8());

      e.addComponent(new Component9());
      e.addComponent(new Component10());
      e.addComponent(new Component11());
      e.addComponent(new Component12());
      e.addComponent(new Component13());
      e.addComponent(new Component14());
      e.addComponent(new Component15());
      e.addComponent(new Component16());

      e.refresh();

      e.getComponent(Component1.class);
      e.getComponent(Component2.class);
      e.getComponent(Component3.class);
      e.getComponent(Component4.class);

      e.getComponent(Component5.class);
      e.getComponent(Component6.class);
      e.getComponent(Component7.class);
      e.getComponent(Component8.class);

      e.getComponent(Component9.class);
      e.getComponent(Component10.class);
      e.getComponent(Component11.class);
      e.getComponent(Component12.class);
      e.getComponent(Component13.class);
      e.getComponent(Component14.class);
      e.getComponent(Component15.class);
      e.getComponent(Component16.class);

      e.getComponent(ComponentOutOfBounds.class);
   }
}


And here is the stack trace:

Code:
java.lang.ArrayIndexOutOfBoundsException: 16
   at com.artemis.utils.Bag.get(Bag.java:141)
   at com.artemis.EntityManager.getComponent(EntityManager.java:117)
   at com.artemis.Entity.getComponent(Entity.java:129)
   at com.artemis.Entity.getComponent(Entity.java:140)
   at com.gemserk.commons.artemis.systems.ArtemisOutOfBoundsTest.test(ArtemisOutOfBoundsTest.java:77)


Do you know what could be happening? I believe that componentsByType is only resizing on addComponent and not getComponent() but not sure.

_________________
Image


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2011 3:53 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
I added an array length check before returning the component on getComponent(e, type) to avoid the exception, here is the patch:

Code:
--- a/src/com/artemis/EntityManager.java
+++ b/src/com/artemis/EntityManager.java
@@ -114,7 +114,13 @@ public class EntityManager {
   }
   
   protected Component getComponent(Entity e, ComponentType type) {
-      Bag<Component> bag = componentsByType.get(type.getId());
+      int componentTypeId = type.getId();
+
+      // if asking for a component type never added before, then return null directly
+      if (componentTypeId >= componentsByType.getCapacity())
+         return null;
+      
+      Bag<Component> bag = componentsByType.get(componentTypeId);
      if(bag != null && e.getId() < bag.getCapacity())
         return bag.get(e.getId());
      return null;


Hope you could see it and apply it.

_________________
Image


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2011 4:38 pm 
Offline

Joined: Sun Jan 02, 2011 8:39 pm
Posts: 64
arielsan wrote:
@appel, remember the ArrayOutOfBoundsException, I have test code to replicate the bug:

Code:
public class ArtemisOutOfBoundsTest {

   private static class Component1 extends Component {}
   private static class Component2 extends Component {}
   private static class Component3 extends Component {}
   private static class Component4 extends Component {}
   private static class Component5 extends Component {}
   private static class Component6 extends Component {}
   private static class Component7 extends Component {}
   private static class Component8 extends Component {}
   private static class Component9 extends Component {}
   private static class Component10 extends Component {}
   private static class Component11 extends Component {}
   private static class Component12 extends Component {}
   private static class Component13 extends Component {}
   private static class Component14 extends Component {}
   private static class Component15 extends Component {}
   private static class Component16 extends Component {}

   private static class ComponentOutOfBounds extends Component {}
   
   @Test
   public void test() {

      World world = new World();

      Entity e = world.createEntity();

      e.addComponent(new Component1());
      e.addComponent(new Component2());
      e.addComponent(new Component3());
      e.addComponent(new Component4());

      e.addComponent(new Component5());
      e.addComponent(new Component6());
      // e.addComponent(new Component7()); // WHY?
      e.addComponent(new Component8());

      e.addComponent(new Component9());
      e.addComponent(new Component10());
      e.addComponent(new Component11());
      e.addComponent(new Component12());
      e.addComponent(new Component13());
      e.addComponent(new Component14());
      e.addComponent(new Component15());
      e.addComponent(new Component16());

      e.refresh();

      e.getComponent(Component1.class);
      e.getComponent(Component2.class);
      e.getComponent(Component3.class);
      e.getComponent(Component4.class);

      e.getComponent(Component5.class);
      e.getComponent(Component6.class);
      e.getComponent(Component7.class); // DOESN'T EXIST!
      e.getComponent(Component8.class);

      e.getComponent(Component9.class);
      e.getComponent(Component10.class);
      e.getComponent(Component11.class);
      e.getComponent(Component12.class);
      e.getComponent(Component13.class);
      e.getComponent(Component14.class);
      e.getComponent(Component15.class);
      e.getComponent(Component16.class);

      e.getComponent(ComponentOutOfBounds.class); // DOESN'T EXIST!
   }
}


Do you know what could be happening? I believe that componentsByType is only resizing on addComponent and not getComponent() but not sure.

I see what is happening. You forgot to add the ComponentOutOfBounds.class to the entity and you are trying to retrieve it using e.getComponent. And you commented out the e.addComponent(new Component7()); but you didn't comment out the e.getComponent(Component7.class); ??? Course its going to throw an ArrayOutOfBoundsException. The problem is with your code not Artemis.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2011 9:23 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
The idea is that you can ask for a component missing on the Entity, for example, create two entities, on first entity you add 5 components and on second entity you add another 5 components (different classes), so in some part of your logic, you ask for an entity X to have some component, you don't know if the entity has the component or not. Another example is, imagine you do a custom behavior in some System if the Entity has the InvulnerableComponent, not all entities have that component.

_________________
Image


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2011 9:24 pm 
Offline

Joined: Sat May 23, 2009 8:50 pm
Posts: 24
Location: Uruguay
the thing is that artemis should return null, not throw an ArrayOutOfBoundsException

imagine this, the user is able to press a button to create some entity with a component X at any point in time

on your code on the update loop, you have to check if any entity in some group has X component and do some stuff if they have it, when in your code you do e.getComponent(X.class) it throws an exception, instead of just returning null.

that is the error in the artemis code, you may want to check if some entity has a component, without having added it first.

_________________
Image
Game Dev Blog


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2011 11:02 pm 
Offline

Joined: Sun Jan 02, 2011 8:39 pm
Posts: 64
You are suppose to check for null when you do a e.getComponent unless you are using a system that looks for that entity.

Why would you use e.getComponent anyways? I've ran private tests in my game logic trying to see which is faster and the ComponentMapper, although a pain to use, is faster.

To check if a entity has a component can't you just do

if (e.getComponent(ComponentA.class) == null) ??

I guess you could do a quick fix in your code with a try { getComponent } catch { addComponent }

Have you tried ComponentMapper?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 420 posts ]  Go to page Previous  1 ... 13, 14, 15, 16, 17, 18, 19 ... 28  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 0 guests


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:  
Powered by phpBB® Forum Software © phpBB Group