Slick Forums

Discuss the Slick 2D Library
It is currently Tue May 21, 2013 5:23 pm

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 ... 21, 22, 23, 24, 25, 26, 27, 28  Next
Author Message
PostPosted: Wed Feb 22, 2012 12:55 am 
Offline

Joined: Wed Feb 01, 2012 2:56 am
Posts: 4
I think I resolved the issue (porting issue) essentially the value for system bit was being pulled incorrectly so I corrected that and it appears to be working. Also do you know when the revisions were made, I started porting about a month ago.

thanks,


Top
 Profile  
 
PostPosted: Thu Feb 23, 2012 12:40 am 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
BlackMarq wrote:
I think I resolved the issue (porting issue) essentially the value for system bit was being pulled incorrectly so I corrected that and it appears to be working. Also do you know when the revisions were made, I started porting about a month ago.

thanks,

You're safe :) longer than that.


Top
 Profile  
 
PostPosted: Sat Feb 25, 2012 4:29 pm 
Offline

Joined: Sat Feb 18, 2012 5:23 am
Posts: 2
appel wrote:
Well, I don't think there's enough traffic for a dedicated forum. I think 1 thread is sufficient, and Google has already decided this is it :)


It's not google, it's because of the link on these two pages:

http://gamadu.com/artemis/
http://entity-systems.wikidot.com/artem ... -framework

Quote:
I did put up a forum, you link to, but as I said, it's pretty dead.


No, I mean it was LITERALLY dead. When I tried to go there it just gave me an error. It seems to be working now. I'll check it out now and update the entity-systems wiki page.


Top
 Profile  
 
PostPosted: Tue Feb 28, 2012 2:51 pm 
Offline
User avatar

Joined: Fri Nov 18, 2011 3:39 pm
Posts: 48
Location: Germany
Hi,

I'm just trying to convert my prototype game to Artemis and I have some questions. Sorry for that! :wink:
I'm looking for opinions rather than solutions. It's a kind of Zelda-esque game, with a TiledMap,
a big bunch of objects (quite like entities) like blocks, bushes, enemies and stuff.

1.) Concerning collision reactions, I have a problem about blocking entities.
In my recent approach I find the new coordinates for each object, check if they collide (no problem on that),
and only move my objects, when they do not collide. In most Artemis examples I've seen so far there is one system for movement, a searate one for collisions and another one for the reaction, mostly something like reduceHealth or removeEntity without any blocking involved.
So I was wondering, what is the best way to block the entities or revert the movement of the collided entities?
Or would my recent approach be best, only to move, when they don't collide. Any cool ideas on that? :roll:

2.) I'm not sure, what should be an entity and what shouldn't. Like I said, I have a bunch of moving objects,
which could do great as entity. But what about the TiledMaps? Should they be entities as well?
Furthermore, I'm rendering different layers of the map at specific times
(i.e. first the ground, then all the objects mentioned above, then the clouds) so when my TiledMap is an Entitiy,
how should I tell the renderSystem, when to render wich layer? I thought about creating an entity for each layer,
but this seems really weird. Again, I'm looking for opinions rather than solutions.

3.) I have an XML coniguration file to tell those objects, what they should do and what not.
For each object type there is an archetype (i.e. stoneBlock has a block config, a render config, no shootable config).
Yep, it's exactly like components, I've read that cowboyprogramming article, when I startet my project.
So, my third question is about triggers, I wanted to add triggers to my archetypes like:
Code:
<component type="playSound" trigger="touchedByPlayer" value="sound1.ogg"/>
<component type="removePowerFromMyself" trigger="touchedByShot" value="valueOfTheShot"/>

Do you think, this would still make sense in an ECS or should there be a better approach?

Sorry for the long text block and my bad english! :mrgreen:


Edit: Okay, forget about part one, I'm going to use a temporary position variable.
When I think about it, it was quite obvious! :x


Top
 Profile  
 
PostPosted: Wed Feb 29, 2012 1:09 am 
Offline
Game Developer
User avatar

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

I'm just trying to convert my prototype game to Artemis and I have some questions. Sorry for that! :wink:
I'm looking for opinions rather than solutions. It's a kind of Zelda-esque game, with a TiledMap,
a big bunch of objects (quite like entities) like blocks, bushes, enemies and stuff.

1.) Concerning collision reactions, I have a problem about blocking entities.
In my recent approach I find the new coordinates for each object, check if they collide (no problem on that),
and only move my objects, when they do not collide. In most Artemis examples I've seen so far there is one system for movement, a searate one for collisions and another one for the reaction, mostly something like reduceHealth or removeEntity without any blocking involved.
So I was wondering, what is the best way to block the entities or revert the movement of the collided entities?
Or would my recent approach be best, only to move, when they don't collide. Any cool ideas on that? :roll:

2.) I'm not sure, what should be an entity and what shouldn't. Like I said, I have a bunch of moving objects,
which could do great as entity. But what about the TiledMaps? Should they be entities as well?
Furthermore, I'm rendering different layers of the map at specific times
(i.e. first the ground, then all the objects mentioned above, then the clouds) so when my TiledMap is an Entitiy,
how should I tell the renderSystem, when to render wich layer? I thought about creating an entity for each layer,
but this seems really weird. Again, I'm looking for opinions rather than solutions.

3.) I have an XML coniguration file to tell those objects, what they should do and what not.
For each object type there is an archetype (i.e. stoneBlock has a block config, a render config, no shootable config).
Yep, it's exactly like components, I've read that cowboyprogramming article, when I startet my project.
So, my third question is about triggers, I wanted to add triggers to my archetypes like:
Code:
<component type="playSound" trigger="touchedByPlayer" value="sound1.ogg"/>
<component type="removePowerFromMyself" trigger="touchedByShot" value="valueOfTheShot"/>

Do you think, this would still make sense in an ECS or should there be a better approach?

Sorry for the long text block and my bad english! :mrgreen:


Edit: Okay, forget about part one, I'm going to use a temporary position variable.
When I think about it, it was quite obvious! :x


Hi and hopefully you can do something neat with Artemis.

1) Physics systems often have collision checking. But what you're looking for is pathfinding and some sorts of steering ai. This is a very broad subject in game programming and difficult to master. Blizzard spent a lot of effort on it's movement AI for Starcraft 2. Not something that can be easily answered other than to say that you'll need to spend a lot of time researching this.

2) TiledMap could be an entity, it could be a manager, or it could be a system. It just depends on what you're comfortable with I guess and what fits your game. But for something like a tiled terrain in a top-down game (RTS) you could have the visual representation as just another "spatial" that the rendering system renders. Or you could have a special terrain render system.

3) I think cowboyprogramming article is about component composition, not entity systems, although they are closely related. Components in Evolve Your Hierarchy article are meant to have data and logic, like regular object-oriented objects. Artemis components have no logic, just data.
It depends on the programmer which one is more convenient. I do have a component composition framework called Apollo, but it's still far from being finished: http://gamadu.com/svn/apollo/trunk/src/ It really needs a demo game.. something I need to wrap up soon.

Sorry I can't answer this better. It seems to be that you're brain crunching over how to best design your game. Been there. I recommend that you skip it and start doing something without doing everything you think you need to do. By doing it you'll discover better ways to do it along the way, way better than I can come up with here and now. The strength of Artemis is that it doesn't force a specific design upon you, it's not a template engine, but in some cases that's also its weakness, there's no specific way to do things.


Top
 Profile  
 
PostPosted: Wed Feb 29, 2012 12:24 pm 
Offline
User avatar

Joined: Fri Nov 18, 2011 3:39 pm
Posts: 48
Location: Germany
Hi,

yep, you're right, I've simply been working on a bunch of ideas yesterday and many ideas
become much clearer, when you actually work on them. Funny, I tend to forget this from time to time. :wink:

1.) On that blocking topic, I guess I found a solution that should fit for now.
But I think, further development/research will have to follow soon.
Damned, this always looks sooo easy but when you actually have to do it... :x

2.) I think, I'll convert my framework thingy in various steps, I'll start with my objects for now
an when this works, I can try to change the other aspects afterwards. I still have some problems with
the spatial approach, although I think, I have the right idea about it.

Funny thing by the way, until yesterday I always thought a top-down game would be the same
as a platformer an an RTS would be a RealTimeShooter. :oops: Nope, my game is definitely a top-down game

3.) In my first game approach (simple AWT, without Slick at all) I tried to use this pure composition
approach, wich ended in a giant bunch of getters and setters to shove almost everything between
my composition classes, it was quite a mess. Then I had to pause my gaming process for a few months
and when I restartet, I saw my code was quite unreadable. I think I'll stick to Artemis,
I have a good felling about this.


By the way, this really is a great framework, simple yet powerful. :mrgreen:


Top
 Profile  
 
PostPosted: Thu Mar 08, 2012 7:07 pm 
Offline

Joined: Wed Mar 09, 2011 10:40 pm
Posts: 49
I've been brushing dust of my dormant gamecode, poking holes in it and making heavy use of profiler, and I realized that getComponent spends quite a lot of time checking boundaries and so on. To allivate the problem I've been toying with the idea of caching components in each system, trading memory for cpu cycles. What do you think about something like the following (read as proof of concept):

Code:
import com.artemis.Component;
import com.artemis.ComponentType;
import com.artemis.ComponentTypeManager;
import com.artemis.Entity;
import com.artemis.EntityProcessingSystem;

public abstract class CachedComponentsSystem extends EntityProcessingSystem {

    public static final int CAPACITY = 50000;
    private Component[][] sysComps;
    private ComponentType[] sysCompTypes;

    private Component[][] nonSysComps;
    private ComponentType[] nonSysCompTypes;

    public CachedComponentsSystem(Class<? extends Component>... systemComponents) {
        super(systemComponents);
        sysComps = new Component[systemComponents.length][];
        sysCompTypes = new ComponentType[systemComponents.length];
        for (int i = 0, s = systemComponents.length; i < s; i++) {
            sysComps[i] = new Component[CAPACITY];
            sysCompTypes[i] = ComponentTypeManager.getTypeFor(systemComponents[i]);
        }
        nonSysCompTypes = new ComponentType[0];
    }

    @Override
    public void initialize() {}

    /**
     * @param nonSystemComponents Components used by the system not required for an entity to register with the system.
     */
    protected void setNonSystemComponents(Class<? extends Component>... nonSystemComponents) {
        nonSysComps = new Component[nonSystemComponents.length][];
        nonSysCompTypes = new ComponentType[nonSystemComponents.length];
        for (int i = 0, s = nonSystemComponents.length; i < s; i++) {
            nonSysComps[i] = new Component[CAPACITY];
            nonSysCompTypes[i] = ComponentTypeManager.getTypeFor(nonSystemComponents[i]);
        }
    }

    @Override
    protected void added(Entity e) {
        for (int i = 0, s = sysCompTypes.length; i < s; i++) {
            sysComps[i][e.getId()] = e.getComponent(sysCompTypes[i]);
        }

        for (int i = 0, s = nonSysCompTypes.length; i < s; i++) {
            nonSysComps[i][e.getId()] = e.getComponent(nonSysCompTypes[i]);
        }
    }

    @Override
    protected void removed(Entity e) {
        for (int i = 0, s = sysCompTypes.length; i < s; i++) {
            sysComps[i][e.getId()] = null;
        }

        for (int i = 0, s = nonSysCompTypes.length; i < s; i++) {
            nonSysComps[i][e.getId()] = null;
        }
    }

    /**
     * @param compNumber 0-indexed component number as given in constructor
     * @param entityId entity id, typically from entity.getId()
     * @return Non-null component for the given entity, cached in the system
     */
    protected Component getSystemComponent(int compNumber, int entityId) {
        return sysComps[compNumber][entityId];
    }


    /**
     * @param compNumber 0-indexed component number as given in setNonSystemComponents
     * @param entityId entity id, typically from entity.getId()
     * @return Component for the given entiy, may be null
     */
    protected Component getNonSystemComponent(int compNumber, int entityId) {
        return nonSysComps[compNumber][entityId];
    }
}



Example use
Code:
import com.artemis.Entity;
import com.es.components.gamelogic.Lifespan;
import com.es.components.generic.CachedComponentsSystem;
import com.es.state.GameWorld;

public class LifespanSystem extends CachedComponentsSystem {

    public LifespanSystem() {
        super(Lifespan.class);
    }

    @Override
    protected void process(Entity entity) {
            Lifespan lifespan = (Lifespan) getSystemComponent(0, entity.getId());
            lifespan.lifespan -= world.getDelta();
            if (!lifespan.isAlive()) {
                ((GameWorld) world).expireEntity(entity);
            }
    }

}


Now, I realize that having to manually manage component-number based on method parameter order and the need to cast kinda smells, but this change has almost doubled the throughput for simple systems like the one shown above.


Top
 Profile  
 
PostPosted: Thu Mar 08, 2012 8:36 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
Mmmm.... smelllly :)

I'd rather look at ways of refactoring under-the-hood in Artemis so it doesn't do those bound checks. One of the challenges in writing this framework is making it easy to use and understand, without having to do book-keeping yourself. Your system doesn't do that, and it also introduces extra memory usage, and while it does improve performance, it does it without really affecting framerate of any game, because once you start rendering some sprites that performance gain is so tiny it doesn't matter, hence making the complexity cost not worth it.

It's easy to get lost in profiling away imaginary performance bottlenecks. Add some moving sprites, and you'll notice that what you're trying to enhance is actually less than 0.1% of the CPU usage.


Top
 Profile  
 
PostPosted: Thu Mar 08, 2012 9:12 pm 
Offline

Joined: Wed Mar 09, 2011 10:40 pm
Posts: 49
Edit: Let me preface this by saying this - Artemis works. Case and point:
Zoomed in, most entities offscreen
Image
Zoomed out, most entities on screen.
Image

IT HIT ME THAT INSTRUMENTATION PROFILING PROBABLY SKEWS MY RESULT BECAUSE OF OVERHEAD; take this with a pinch of salt:

I have tried, and as it stands, this change has quite the impact when entity count starts exceeding 5k. getComponent was responsible for about 50% of each system CPU tax. In situations where alot of stuff has to be updated off screen, this gave me a nice boost. The fact that implementing systems dont have to manage mappers themselves, also reduces verbosity. Also, moving over to Android, I'm looking under every stone for marginal preformance boosts.

Example:
Image

LifespanSystem1 uses the above approach, LifespanSystem uses EntityProcessSystem with Mappers, otherwise the logic and load is identical. About 15k entities.
But yeah, I realize that this is messy from a framework perspective, and I hear you on the topic of micro optimization.

Unrelated question: Another point I'm trying to make work is object pools for entities and components. My main concern is how I would go about returning stuff to a pool after deleteEntity has run. The motivation here is avoiding object creation in the main loop, but the distributed nature of entities makes a solid solution elusive. I'm using an entity assembler to create entities. What I would like, is to be able to create a pool of entities with accompanying components, and pull and return entities from this pool.


Top
 Profile  
 
PostPosted: Thu Mar 08, 2012 11:37 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
Pretty cool. I'll look at this more carefully. Thanks.


Top
 Profile  
 
PostPosted: Thu Mar 08, 2012 11:50 pm 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
Uberrated wrote:
Edit: Let me preface this by saying this - Artemis works. Case and point:
Unrelated question: Another point I'm trying to make work is object pools for entities and components. My main concern is how I would go about returning stuff to a pool after deleteEntity has run. The motivation here is avoiding object creation in the main loop, but the distributed nature of entities makes a solid solution elusive. I'm using an entity assembler to create entities. What I would like, is to be able to create a pool of entities with accompanying components, and pull and return entities from this pool.


That's a problem currently, it's not possible to pool "Entity" because Artemis already internally pools them. You cannot create an Entity without it being created internally in the framework.

However, it's not "committed" to the systems unless you call Entity.refresh, so maybe you could pool them without actually making them run. But pooling is really more of an OO nature. If Artemis entities were comprised of data coming from database tables it wouldn't make sense to pool them.

I'd rather look at pooling inside your systems.


Top
 Profile  
 
PostPosted: Fri Mar 09, 2012 6:03 pm 
Offline

Joined: Wed Mar 09, 2011 10:40 pm
Posts: 49
I'm going to toy with pooling components only, and get back to you with how that works. My entity assembler is pretty much all OO, so hopefully I can make it work.


Top
 Profile  
 
PostPosted: Wed Mar 14, 2012 10:49 pm 
Offline

Joined: Wed Mar 09, 2011 10:40 pm
Posts: 49
I did it. Its not the most pretty of implementations, but... but... its glorious! :lol:

The problem:
When creating lots and lots of entities, a very heavy burden is placed on world.loopStart(). Registering a refreshed entity with all systems takes its toll. Time spent removing references to components linked to deleted entires piles up, and if you account for the cost of creating new components for new entities, things starts adding up.

Suggested solution:
A way to indicate that a given Entity is member of some pool. This pool is specific for a certain entity template; we can be certain that entities belonging to the pool share the same components. When a pooled entity is deleted (not all entities has to be pooled, highly dynamic entities will not benefit from this, they require constant calls to .refresh() anyway), the entity connection to components are not nulled out and the entity is not returned to the available entities inside EntityManager. Instead, the entity is returned to the pool, and marked as "suspended". Suspended entities are still registered in systems, but the processEntites method does not pass suspended entities to the process method. Now, when a template is called upon to create entires, it pulls new entires from the pool (which unsuspends the entity), and uses getComponent(type) to reset the component fields. No need for refresh(), component creation or component deletion.

Of course, this will not work for all cases, but it is extremely useful for projectile entities, particles or other types of entity which share the same set of components with relatively short lifespans and high creation rate. This also becomes more and more useful for every new system added, as refresh() and reference removal time increases with systems in the gameworld.

Too involved, or something to consider? I know for me, this has been the final piece that was missing from the puzzle.


Top
 Profile  
 
PostPosted: Thu Apr 19, 2012 5:01 pm 
Offline

Joined: Thu Apr 19, 2012 3:54 pm
Posts: 10
Anyone still on this thread?

I started my first larger scale game (well, the idea is large anyway), programming my own gameloop etc. from Bucky's tutorials from thenewboston. I started coding the rest in a strict OO hierarchy tree format... That did not last long. I've spent the last week looking for a better framework/code structure I could try and program myself when I stumbled upon Slick2D, then the Entity System concept (Which I'm still trying to wrap my head around!), then Artemis. I am downloading Artemis now, and I'd like to thank you for all the work you've done for us in the community!

Now, I have some questions:

(Btw, my Java knowledge seems a little lower than the average user here, I would appreciate it if you could answer my questions without using more advanced terms. Thanks!)

Like I said, I'm very new to the Entity concept, but I understand the basics of it. Now what I need clarification on is mainly that "spatial"... thing.

1. What does spatial mean?

2. What are ComponentMappers? Can they be compared to something like an ArrayList?

3. I think I understand the "concept" of Artemis, but I don't understand how to implement it. In StarWarrior, I understand most of the code, but don't quite understand the Components/Systems/Entities interaction with eachother. Do you by any chance have a more simple example? Or a flowchart or something so that I can get a better understanding of this?

Either way, I will be using this framework in my game. I think I might make something more simple before I try to transfer my game code over. It would still be great if you could answer the questions I have :D


Top
 Profile  
 
PostPosted: Sat Apr 21, 2012 3:21 am 
Offline
Game Developer
User avatar

Joined: Tue Nov 21, 2006 4:46 am
Posts: 619
Location: Iceland
1. Spatial is just a part of the rendering system that I created for the StarWarrior demo. It's the visual representation of an entity. You can implement your rendering system any way you like.

2. ComponentMapper are just for convenience really, they are little helpers to retrieve associated component of a certain type for an entity.

3. Components are data, like position, velocity, etc. Systems process (operate on the data) only components, e.g. to move a entity. An Entity can have one or many components. The interaction is simple, systems do all the logic and interaction. Components have no logic and Entities certainly not. So, all the logic and interaction is inside the systems.


I'm not sure I can recommend this for you if you haven't done any programming with entity/components. Perhaps you're better off doing something more standard.


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 ... 21, 22, 23, 24, 25, 26, 27, 28  Next

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