0
\$\begingroup\$

I'm working on a turn-based tile-based puzzle game, and to create new entities, I use this code:

Field.CreateEntity(10, 5, Factory.Player());

This creates a new Player at [10; 5]. I'm using a factory-like class to create entities via composition.

This is what the CreateEntity method looks like:

public void CreateEntity(int mX, int mY, Entity mEntity)
{
    mEntity.Field = this;
    TileManager.AddEntity(mEntity, true);
    GetTile(mX, mY).AddEntity(mEntity);
    mEntity.Initialize();
    InvokeOnEntityCreated(mEntity);
}

Since many of the components (and also logic) of the entities require to know what the tile they're in is, or what the field they belong to is, I need to have mEntity.Initialize(); to know when the entity knows its own field and tile.

The Initialize(); method contains a call to an event handler, so that I can do stuff like this in the factory class:

 result.OnInitialize += () => result.AddTags(TDLibConstants.GroundWalkableTag, TDLibConstants.TrapdoorTag);
 result.OnInitialize += () => result.AddComponents(new RenderComponent(), new ElementComponent(), new DirectionComponent());

This works so far, but it is not elegant and it's very open to bugs. I'm also using the same idea with components: they have a parameterless constructor, and when you call the AddComponent(mComponent); method in an entity, it is the entity's job to set the component's entity to itself.

The alternative would be having a Field, int, int parameters in the factory class, to do stuff like:

new Entity(Field, 10, 5);

But I also don't like the fact that I have to create new entities like this. I would prefer creating entities via the Field object itself.

How can I make entity/component creation more elegant and less prone to bugs?

\$\endgroup\$
5
  • \$\begingroup\$ Why would you rather create entities via the field object? Is it just personal preference or is there a practical reason for this? I'm afraid I have to tell you this makes little sense for an outsider on your application like me. \$\endgroup\$
    – Koarl
    Commented May 14, 2012 at 11:41
  • \$\begingroup\$ @Koarl I'm using reflection to get entity parameters in my level editor (from the methods in the factory class). If I had to create an entity with x,y,field in the constructor I would have to add these 3 parameters to every single method in the factory class and somehow make them get ignored by the editor. Also, I may be totally wrong, but I find it weird to see a line starting with "new Entity(1, 2, field);" - I think the field is the most important object, and it should manage entity creation/destruction. \$\endgroup\$ Commented May 14, 2012 at 12:05
  • 4
    \$\begingroup\$ If you have unusual requirements due to your level editor, you should mention that in your question because that is pretty important to know when answering. Also, if the design of your level editor is constraining some aspect of your core game, I would say the problem is the design of your level editor. I think you've got your priorities backward; the game is more important than the level editor. \$\endgroup\$
    – jhocking
    Commented May 14, 2012 at 13:20
  • \$\begingroup\$ A level editor is hugely important, and having a good one can impose some special requirements on your engine. The entire purpose of a game engine is to run content; without content, theres no reason to even have a game engine. Never ever sacrifice the quality or effiency of your content generation tools just to simplify a game engine slightly! \$\endgroup\$ Commented May 15, 2012 at 16:55
  • \$\begingroup\$ I agree that a level editor is important, but disagree that you should ever change the game to fit the editor and not the other way around. shrug philosophical difference I guess \$\endgroup\$
    – jhocking
    Commented May 16, 2012 at 11:18

1 Answer 1

2
\$\begingroup\$

If entities must have positions (which is implied, as your CreateEntity() call takes the position as a parameter), why not put the position into the Entity itself, and then pass the x,y coordinates to the Player Factory directly?

\$\endgroup\$
2
  • \$\begingroup\$ I'm not sure I understand, you mean passing the position as a parameter in the Entity's constructor? So that the factory will create a new entity like this? Factory.Player(10, 5) -> return new Entity(10, 5) \$\endgroup\$ Commented May 14, 2012 at 13:18
  • \$\begingroup\$ Yes, exactly that. \$\endgroup\$
    – Kylotan
    Commented May 14, 2012 at 14:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .