Slick Forums

Discuss the Slick 2D Library
It is currently Sun May 26, 2013 3:42 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 ... 15, 16, 17, 18, 19, 20, 21 ... 28  Next
Author Message
 Post subject:
PostPosted: Thu Sep 08, 2011 6:18 am 
Offline

Joined: Sun Aug 21, 2011 9:08 am
Posts: 8
Just a question: why are you comparing bits between components? Is it that much slower than comparing bytes? (I'm worried at going over 64 components on the server side... :/)

_________________
I like programming for fun. Money is good too.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 08, 2011 9:13 am 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
albireox wrote:
Just a question: why are you comparing bits between components? Is it that much slower than comparing bytes? (I'm worried at going over 64 components on the server side... :/)


It only takes a few nanoseconds to do bitwise comparison on two longs.

I may make a new version of Artemis very soon where this 64 limit isn't an issue.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 09, 2011 5:46 pm 
Offline

Joined: Fri Sep 09, 2011 5:08 pm
Posts: 18
Hello appel

I use slick and artemis since few weeks for a little game made with friends.
Artemis and slick are really easy and fast to use but there is one thing that I didn't find on this thread, a way to recycle entities.

I build a shooting game and I am used to send more than 100 bullets by second and it take around ~15% cpu.
I try to optimize different parts of the process to reduce CPU consumption, and allow to display more and more bullets :D
But when I look at VisualVM, I see that the memory consumption grow and GC works very often. So I'm thinking about a way to recycle Bullet entity/component and reuse them for next time. Create lot of bullets and destroy them few seconds later, and repeat this operation again and again don't seems to be a good idea.

I tryed differents methods but I didn't find anything fine in artemis, the only method I find to remove an entity is world.deleteEntity(bullet) but it seems to delete all the component too.
So, I'm looking for a way to remove an entity and his components from the world but without really delete them, storing them in a stack for later utilisation. This could also be used for preloading lots of entities and components during the loading of the stage (and store them in a stack) and not create them during the play


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 09, 2011 8:46 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
Strange, 100 bullets a second is very trivial, so it's not a problem with artemis since I could create and destroy thousands and thousands of entities per second in some of my tests. And for the GC 100 objects are super trivial.

You're clearly doing something wrong in creating your components. Benchmark the bullet creation, like this:

Code:
long start = System.nanoSeconds();
// bullet creation
long end = System.nanoSeconds();
System.out.println("Took " + (end-start) + " nanoseconds to create bullet");


You could paste some of the code here.

Look for anything "new Something" with high suspicion, and never do "new Image" while game is running, or anything slick resource stuff.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 10, 2011 4:04 pm 
Offline

Joined: Fri Sep 09, 2011 5:08 pm
Posts: 18
It's not really 100 bullets. Most of the time it's around 300~400 and in a big room it can grow to 1500. The code is really similar from the tankz exemple and collision system and few other system which could consume CPU are disabled.

After few test, I observed that you're right, the CPU consumption doesn't come from entity creation. I'm surprise but it's come from the rendering.
For exemple, the Explosion Spatial rendering take 4~5% cpu .
Code:
public void render(Graphics g) {
   long start = System.nanoTime();
   color.a = (float)expires.getLifeTime()/(float)initialLifeTime;
   g.setColor(color);
   g.fillOval(transform.getX() - radius, transform.getY() - radius, radius*2, radius*2);
   System.out.println("Took " + (System.nanoTime()-start) + " nanoseconds to render explosion");
}

and the trace
Quote:
Took 113020 nanoseconds to render explosion
Took 142441 nanoseconds to render explosion
Took 114840 nanoseconds to render explosion

I suppose that alpha rendering is the cause of this consumption but I didn't see how to optimize it.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 11, 2011 11:32 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
kef wrote:
It's not really 100 bullets. Most of the time it's around 300~400 and in a big room it can grow to 1500. The code is really similar from the tankz exemple and collision system and few other system which could consume CPU are disabled.

After few test, I observed that you're right, the CPU consumption doesn't come from entity creation. I'm surprise but it's come from the rendering.
For exemple, the Explosion Spatial rendering take 4~5% cpu .
Code:
public void render(Graphics g) {
   long start = System.nanoTime();
   color.a = (float)expires.getLifeTime()/(float)initialLifeTime;
   g.setColor(color);
   g.fillOval(transform.getX() - radius, transform.getY() - radius, radius*2, radius*2);
   System.out.println("Took " + (System.nanoTime()-start) + " nanoseconds to render explosion");
}

and the trace
Quote:
Took 113020 nanoseconds to render explosion
Took 142441 nanoseconds to render explosion
Took 114840 nanoseconds to render explosion

I suppose that alpha rendering is the cause of this consumption but I didn't see how to optimize it.


fillOval is extremely slow.

Instead of that, draw an image.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 15, 2011 4:44 am 
Offline

Joined: Thu Sep 15, 2011 4:09 am
Posts: 4
Hi

I've joined this forum just so that I can post in this thread (!)

Your framework is pretty similar to one I have been developing (or at least conceptualising) for a few years, with incarnations in C++, Python and currently C#. Along the way I have hit a few roadblocks that I have overcome somehow or another - I'd like to discuss my approaches and see if you have any suggestions!

One of the first hurdles was component interaction - I realised that, for example, the CollisionComponent would need to notify the HealthComponent of damage, or modify the PositionComponent to rectify overlap. This all got quite messy with various event handlers and messages being sent around when I realised that the solution was glaringly obvious: to use components simply as data, not processes. I abstracted the processes themselves out into what I now call Systems (familiar? ;)) that could operate over whatever data components they wished.

My first decision with the Systems was to implement a list of Components in which each was interested. For example, the RenderSystem would require a PositionComponent and a SpriteComponent. Whenever a component is added or removed from an entity, the new collection of associated components is passed around to Systems so they may log their interest (variant on the Observer pattern). Having poked around in Artemis, I see that that is pretty much exactly what you're doing. I only wonder why you decided on a bitset implementation? Is the restriction worth the performance gain? Considering you probably won't be creating entities or adding/removing components THAT often.

With the new Systems, I had a few use cases in a game engine to consider, which I'll go through now:

Rendering
Some objects may have a SpriteComponent, while others have a ShapeComponent that merely needs to be drawn using primitive lines, etc. Issues: how does the RenderSystem differentiate between the two, how does the Component list handle this scenario, and how does the System process each case?
Possible solution: Use different RenderSystems for each type of render component. I settled against this, because rendering needs to be done in order of the Z-axis, not in order of render-type.
Proposed solution: Extend the logic of a System's required Component list to include boolean comparisons to allow better description of what the System requires. In this case, the required components would be (RenderComponent && PositionComponent && (SpriteComponent || ShapeComponent)). I implemented this solution as a virtual boolean function that operated over an array of boolean values corresponding to the ComponentList, and am fairly happy with this approach although it is a little complex.
In terms of differentiating between various different components and processing them, I am tempted to use an overloaded dispatch function or just some nested-ifs, ugly as they may be.

Collisions
With first-hand experience in the pain of collision detection and response, I wanted to make sure I nailed this one right off the bat this time. My initial impulse was to use two systems, CollisionDetectSystem and CollisionResponseSystem. The CollisionDetectSystem would pass collision information through a CollisionComponent to the CollisionResponseSystem. The benefits of this approach are the clear separation of logic and the ability to happily insert any other System between the two Collisions. However, the data passed in the CollisionComponent is superficial and not persistent, so I have my doubts as to whether this is truly necessary. One thing I do know is that I'll probably want to subclass the CollisionResponseComponent and use a form of dispatch to handle all collisions.
This doesn't really concern the framework but it was a use case that I needed to consider when hammering out the details.

HUD
The issue of the HUD is a thorny one. I think earlier in this thread someone mentioned a health bar and how to implement it using this kind of framework. The solution that I've come to is still quite vague as I am yet to implement any of it but I like the idea. Key issues in this area: What IS the health bar, and what components does it have? How does it interact with the RenderSystem?
Proposed solution: The health bar is an Entity. In order to track the health of the player, it has a TargetComponent which contains a reference to the player Entity. It must also have a PositionComponent to determine where it lies on the screen. When debating how to handle the two different types of position (world-relative and screen-relative), I stumbled onto an idea that I'm happy with: to allow the PositionComponent to specify which 'world' its co-ordinates lie on. The game world would be one world, and the HUD would be another - then, the window screen simply tracks its movement through each different world. This allows any HUD or menu entity to behave exactly like an ingame entity - something I really want to strive for in my framework.

The only part I'm concerned about is how to render the health bar - should the RenderSystem really have to know how to render this particular piece of information? I'd have to make a special exception for the health bar entity in the RenderSystem's processing code, and that's a slippery slope I'd rather not go down. I am leaning towards giving it a ScriptComponent which would execute every frame and query its target's HealthComponent


I realise this is kind of a wall of text but these are the ideas that have been floating around in my head since 2008 and it's nice to find someone else who has put so much effort into something very similar, and would v much appreciate your feedback/discussion!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 15, 2011 1:27 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
Hi @monkfish, I would like to share how are we (at Gemserk) doing some of the stuff, not so sure if it solves the issues but could be of help as another point of view.

Collisions

We are using Box2D for all the physics interaction and collisions detection. There is a System named PhysicsSystem which registers on its creation a ContactListener to the Box2D world. Each time a collision is detected (begin or end) this listener registers or unregisters that data in each PhysicsComponent of the corresponding two entities in contact. We have created a Contacts class which reflects the Box2D contact data and it is available in the PhysicsComponent. So, if you are in another system and want to, for example, remove health if the Entity is in contact, you can ask for all the contacts of that entity to the PhysicsComponent, and then process each contact depending on the type of the other entity (for different damage calculations).

(note: I put code mainly to make the explanation easier to understand)

One possible problem here is you cant do anything on contacts state change (not being in contact -> being in contact), you only process the "while being in contact" or the "while not being in contact". However, I am using it in various games and it doesn't seem an issue. On the other hand, in theory, if you want to do something on those state changes you could store the current state on a component and on the next update check changes.

We have our way of making some of the other stuff you write about too, but I want to keep this reply smaller as possible, I will probably write another reply later.

_________________
Image


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 15, 2011 4:37 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
Surely is a lot of text.

I decided to use bit fields because it's fast and seemed cool :) But surely it could be replaced with java's BitSet which allows for as many bits as you like without affecting performance by a huge amount. Trivial issue, I plan on doing that in a future version of Artemis. Just accumulating any bit of wisdom before an update.


A lot of your text concerns rendering, and that is a tricky thing indeed. Not only in Artemis, but just generally. Not sure if you're doing 2D or 3D, but since I'm mostly familiar with 2D I'll explain my approach.

You essentially have a RenderSystem. That system picks up any Spatial components and creates a SpatialForm for it. This is already demonstrated in the StarWarrior demo I believe.

The tricky part is the "painters algorithm problem": http://en.wikipedia.org/wiki/Painter%27s_algorithm

Example of this would be a entity in a RTS game like a tank that was composed of the track belts, the tank base, the tower, the barrel, health bar, selection highlighting. We need to ensure all these are rendered in correct order, not only so that the tower is on top of the base, but also that all towers are on top of all bases for all tanks, and all healthbars are rendered after all the tanks to ensure healthbars are above everything.

You cannot solve this problem by rendering entities, you need to break this down into rendering of "spatials", whereas each entity can have multiple spatials.

Your game needs to be rendered in layers, terrain first, tank belts next, then tank base, then barrels, then towers, then healthbars and selection highlighting. Your RenderSystem needs to have buckets, each bucket being the layer and can contain any number of spatials.

Then you can attach one spatial node called TankSpatial to your tank entity, and that TankSpatial node contains children spatials that are TrackBeltsSpatial, TankBaseSpatial, TankTowerAndBarrelSpatial, GenericHealthbarSpatial, GenericSelectionHighlightSpatial. For each of those spatials you assign a layer, and the RenderSystem would put each spatial into the correct bucket according to that layer.

This way you can logically think of and code your entities as a single thing, but the RenderingSystem splits the spatials it up into layers.

I already do this in one of my game and it works great!



Another approach would be to have a special HealthbarRenderingSystem, SelectionHighlightRenderingSystem, and that may be what you need if you can zoom in and out in your game without wanting the healthbars and selection highlight to scale. But for most ingame entities you need layering.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 16, 2011 12:43 am 
Offline

Joined: Thu Sep 15, 2011 4:09 am
Posts: 4
@arielsan - I like the idea of a specialized data structure for collision detection, I used something similar in a previous game - to store how much the object overlaps, and what it is overlapping with. I will poke around in your code a bit more and see if I can't find a way to mesh it with what I'm working with. Thank you for sharing!

@appel - This idea of spatials sounds like exactly what I need. Is this an established concept in game development or a solution you've come up with personally? I guess I'll go hunting through google for some more info - but at the very least you have given me a good idea of how to go about rendering components that have more than one part to them. In previous games I have stored a rendering Z-axis data component that would determine the rendering order, which seemed to work but it was quite inelegant - am intrigued to see how other people have solved the problem.

Thanks both, I will keep track of this thread/Artemis in general, I will probably come knocking on your door again some time!

(p.s. 2D only for me at the moment, figured I'd try to get that much done before moving on to writing the next call of duty :D)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 18, 2011 1:59 am 
Offline

Joined: Sun Aug 21, 2011 9:08 am
Posts: 8
Hi,

It looks really cluttered to put 20 or so variables containing systems and running process on them. In a future release could you perhaps have some sort of systemcategory thing that runs all of the systems in a category? For ordering when these systems are processed, I guess it would be the order they are added to the SystemCategory?

_________________
I like programming for fun. Money is good too.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 18, 2011 6:02 pm 
Offline

Joined: Sun Sep 18, 2011 5:40 pm
Posts: 13
Hi,

First post here, just signed on to ask a question. I've been using libgdx to write some simple Android games, and I want to tackle a more complex project next. After trying to write my own OO class hierarchy, I gave up and decided to try Artemis. I'm still in the early stages of thinking about my components and systems (have to forget all the thinking I did for the OO framework), but so far so good.

I have a question on object pools. As I understand, the garbage collector in Android's dalvik VM is notorious, so "new Anything()" should be avoided to the extent possible. In that context, what's the proper way to handle things like bullets? Looking through the sample game, the EntityFactory creates a missile by calling world.createEntity(), followed by entity.addComponent(new SomeComponent()). I'm assuming createEntity is efficient, as is addComponent, but I'm concerned about the 'new' on the components. What can I do to avoid that?

One option would be to create bigger components that contain more state, but that seems to go against the whole entity/component design approach.

Another idea I had was to create my own pool classes for the component types that I expect to reuse. However, I'm not quite sure how to handle deleting an Entity. Reading through this thread, I understand that the Entity doesn't contain the Components. But they must be referenced somewhere, and I expect that deleting the Entity removes those references. So should I move the Components back into my pool before deleting the Entity? Is there a better way to handle this?

Any advice would be helpful.

Thanks,
Ziggy


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 19, 2011 11:19 am 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
Ziggy wrote:
Hi,

First post here, just signed on to ask a question. I've been using libgdx to write some simple Android games, and I want to tackle a more complex project next. After trying to write my own OO class hierarchy, I gave up and decided to try Artemis. I'm still in the early stages of thinking about my components and systems (have to forget all the thinking I did for the OO framework), but so far so good.

I have a question on object pools. As I understand, the garbage collector in Android's dalvik VM is notorious, so "new Anything()" should be avoided to the extent possible. In that context, what's the proper way to handle things like bullets? Looking through the sample game, the EntityFactory creates a missile by calling world.createEntity(), followed by entity.addComponent(new SomeComponent()). I'm assuming createEntity is efficient, as is addComponent, but I'm concerned about the 'new' on the components. What can I do to avoid that?

One option would be to create bigger components that contain more state, but that seems to go against the whole entity/component design approach.

Another idea I had was to create my own pool classes for the component types that I expect to reuse. However, I'm not quite sure how to handle deleting an Entity. Reading through this thread, I understand that the Entity doesn't contain the Components. But they must be referenced somewhere, and I expect that deleting the Entity removes those references. So should I move the Components back into my pool before deleting the Entity? Is there a better way to handle this?

Any advice would be helpful.

Thanks,
Ziggy


Components need to be new'd, but not Entity. You could pool the components, but that's an bloated overkill. Although, you could use some fly-weight instancing on them, pooling deleted components for later re-use. But, hm, I don't really like it. But if you can't do new, you have to pool. Also, you really want to pool things at an entity level and not component level.

Maybe things will be a little simpler if you made your own entity/component framework. I can't think how artemis can efficiently pool things for you without some mad design.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 19, 2011 1:41 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
Hi @appel, based on the last two posts, is there a way to temporary disable an entity.

Right now, when a bullet hits a target you remove it from the world by calling bullet.destroy(), that internally calls removeComponentsOfEntity() so you cant reuse that entity for another bullet because it has no components any more.

Is there a way to remove the entity from the world but maintain it as it is so I could later add it again and reuse it for the same kind of entity (a bullet for example). In this case I could implement the pool of bullets myself and store it on a component in the weapon entity (or in a weapon component in any entity), so each time a bullet hits something I add it again to my local pool and later instead creating a new entity I add the first one with new values in its components.

That implies:

* a way to add to the world an entity already created (without calling world.createEntity()).
* a way to remove from the world without removing all the entity information
* a way to avoid that removed entity to be reused by world.createEntity()

Another way could be made by storing all that information myself, which information has each entity and instead reusing the Entity instance I create a new entity with world.createEntity() and apply the stored information, but I should be aware in some way when the entity was removed from the world (and before all components/etc were removed from it).

_________________
Image


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 19, 2011 1:47 pm 
Offline
Regular
User avatar

Joined: Tue Apr 07, 2009 12:58 pm
Posts: 232
Location: Uruguay
Answering myself, I believe the second option could be made with a System the ReusableEntityInformationSystem and with a component ReusableComponent so each time an entity is removed from the world, the system stores all the entity information in some place (a map or pool or something) to be used by the next entity which needs it. The problem is you have to tag the reusable information in some way to identify it when you want to reuse it. For example, if I have two types of bullets then I cant reuse information of bullet A when creating a bullet B.

Conclusion, this requires more thinking....

_________________
Image


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 ... 15, 16, 17, 18, 19, 20, 21 ... 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