Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


TheComet

Member Since 02 Oct 2013
Offline Last Active Yesterday, 11:10 AM

Posts I've Made

In Topic: Problem with A*

07 November 2014 - 05:43 AM

for(unsigned int i=0; i < openList.size(); i++)

It's never a good idea to iterate a container AND modify it at the same time. Elements can become invalid.

 

According to the Wikipedia article, you should loop while the openList is not empty:

while(openList.size())  // instead of while(!foundFinish)
{
    // pathfinding stuff here
}

I also don't see you ever remove anything from the openList. You've commented that part of your code out:

//openList.erase(openList.begin());

In Topic: Entity component system: data locality vs. templates

05 November 2014 - 04:52 AM

I'm not sure where this would become handy. Maybe if you make some basic AI system, then you can make some other AI system based on the first one, but overriding certain behaviour? Then you would end up with kind of mix of component and object-oriented design.

 

Basically, yes. Another example from my game would be an input system:

m_World.getSystemManager().addPolymorphicSystem<InputInterface, SDLInput>();

You can dynamically (or statically) switch in and out various input managers (I have another IOSInput class, for instance) without having to change any other code in the process. The other systems will still be able to call getSystem<InputInterface>() without knowing about the implementation change.

 

I don't really agree with this. If you are making a game with OpenGL/Direct3D, the rendering system will want all renderable entities at the same time. You go through the entities and build a list of draw batches from them. then sort the list by render states (shader, texture, VAO) and then render the sorted list. If the render system gets one entity at a time, this is not possible, at least directly. Also, if you have thousands of objects, there will be a lot of methods calls.

 

That's a good point.

 

I think I'll add that functionality to Ontology, thanks for pointing that out.

 

Another approach: Wouldn't it be possible to split the various stages up into systems? I.e.

  • BuildDrawBatchSystem would group the renderable entities together into various groups
  • SortRenderStatesSystem would sort the lists into render states
  • RenderSystem would finally render everything

You could pass the lists around via an entity or just communicate it directly between systems.

 

The downside of course is the function call overhead of processEntity().

 

I wrote Ontology mainly as a learning experience and with a naive approach. In my experience, it's not that hard to do, so maybe you'd want to write a specialised ECS for your render system? That way you can tailor it to your exact needs.


In Topic: Thread-post never made ... almost

04 November 2014 - 04:28 PM

Well excuse me princess, I'm sorry for helping you.


In Topic: Entity component system: data locality vs. templates

04 November 2014 - 03:51 PM

A quick comparison reveals some differences.

 

Ontology does make an effort to store entities in contiguous memory, but it doesn't store components in contiguous memory. I've done a lot of stress tests with ontology and in the grand scheme of things the increased amount of cache misses are irrelevant, but it's worth mentioning. EntityX stores everything in contiguous memory, but at the price of having to look the entity/component up via a unique ID. I'm not entirely sure what's more inefficient - cache misses or having to lookup O(log(n)) every loop for every component.

 

I couldn't find a way to support polymorphic systems in EntityX, where ontology does have a method addPolymorphicSystem(). This is useful for abstracting the exact implementation of a system.

 

Ontology has support for declaring the components a system supports statically, vs EntityX doing it dynamically. There's no real upside/downside to these implementations, it's a matter of taste. Ontology will throw an error if you try to access a component that isn't supported, EntityX will silently ignore it.

 

Ontology has support for creating an execution dependency graph of systems, so you have a lot of control with re-ordering when which system is updated, independent of the order in which you add the systems to the world.

 

Regarding the update method: In the end it really boils down to the same thing. Entityx gives you the list of all entities, and it's up to you - the system implementer - to filter through the entities that you support and process them:

// EntityX' implementation
struct MovementSystem : public System<MovementSystem> {
  void update(entityx::EntityManager &es, entityx::EventManager &events, TimeDelta dt) override {
    Position::Handle position;
    Direction::Handle direction;
    for (Entity entity : es.entities_with_components(position, direction)) {
      position->x += direction->x * dt;
      position->y += direction->y * dt;
    }
  };
};

As you can see, every time you update a system, you need to filter the entities you support with: for (Entity entity : es.entities_with_components(position, direction))

 

I didn't really see any use for having access to entities you cannot support, which is why my implementation pre-processes the entities and every system holds a list of references internally to the entities it supports. My implementation hides all of the filtering and iterating so you can focus on processing the entity.


In Topic: Thread-post never made ... almost

04 November 2014 - 03:20 PM

@Nypyren - Thanks for clearing that up.

 

[EDIT] Why is everyone downvoting my answer? The code I posted solves OPs problem and hints that referencing a pointer (*&) is discouraged with primitive types.


PARTNERS