@Adinimys, no problems, the discussion of various methods is a worthy topic.
I'm not experienced with using classic OOP for game dev so I can't say a lot about this.
First of all, you should read Programming in Lua which is free online and a good read.
I have no idea how to inherit from C++ classes in Lua (not sure if it's even possible). I suggest you to inherit from base classes in C++ and then override some functions from the base class so that they call other functions in Lua.
For example, suppose you have
class Monster
Now you have some classes like
class Vampire : public Monster
and
class Troll : public Monster
You can then define their interact() functions like this:
void Vampire::interact(...) {
// call vampire.interact function in Lua
}
void Troll::interact(...) {
// call troll.interact function in Lua
}
So, you can have vampire and troll table which define interaction functions in Lua (and some other stuff, like collision responce function, for example. Or some vamrire and troll stats (moving speed, health, etc.).
But you see, the inheritance is not really needed anymore
You can have pointers to interact and collision response functions in a Monster class by setting vampire.interact to one Monster and troll.interact to another. So, this makes the inheritance tree easier. But if you really need inheritance in this case, use the method I've proposed later. You will still gain a lot from Lua.
If you have some more questions, create another thread or feel free to write me,
[email protected] Progress updateFinally I've figured out the way to store components continuosly in memory. It may not give the significant speed up (but I'll post the results of testing!) but it will be very helpful for the future. (And for other games I'll work on using the same engine).
I'm still working on this, but
I will post the source code soon (probably this month) so people can use it for their own games. I would also love for people to propose some ideas about how I can make this system better.
Note that I won't post the source code of my engine. It's a completely separate prototype project with some tests but it would show most of the stuff I'll integrate into the game later.
The main principle is what someone later proposed in this thread.
I have this class:
class IComponentList {
...
};
and this class:
template <typename T>
class ComponentList : public IComponentList {
...
private:
std::vector<T> components;
}
and then this map:
std::map<std::type_index, IComponentList*> componentLists
where key is std::type_index is std::type_index(typeid(T)) where T is a type of the component a corresponding value (a component list) holds.
I can currently get the list I need like this:
auto& list = ComponentManager::getInstance().getComponentList<SomeComponentType>();
The entity class interface remains the same, though. I still have:
class Entity {
...
std::vector<Component*> components;
}
But now the entity points to components inside the component lists.
This is harder to implement than it looks, because:
1) Changing the position of a component in a component array invalidates the pointer in Entity so I have to change it manually
2) If I insert some new components in some vector L and the size of the vector is more than it's capacity, it will reallocate which means that every component pointer (of component type which L holds) in every entity becomes invalid.
This is not a big problem, though!
The first problem is easily solvable. The second is a bit harder, though.
I can fix it by reserving enough memory for each component vector so it won't reallocate again when the game is running (vectors would need to change it's sizes during level load but this is not critical, changing some pointers is not that hard during that.)
How can I know how much components of each type there will be? Easy. I have a list of every entity on the level in a level file which means that I can count how much of each component time I would need.
What about entities which could previously create entities when the game was running (like bows which created arrow entities). I won't do this anymore! Allocating memory on when the game is running is bad anyway.
So, each entity can explicitly show that it can create new entities and each component list would get additional size to allocate.
For example, you won't see more than 1-2 arrows flying from the same bow on the screen. This means that I can reuse the same arrow entity over and over again. I will create arrow entity for each bow entity when the level loads and there's no need to create entities during gameplay anymore.
So, those limitations lead to some great improvements of other things! There are more aspects which I'll cover later.
P.S. Anyone knows any good articles about C++ templates? Especially about header dependency aspect of it. I want to make templates the way that they won't cause more recompilation then necessary (this is very easy to make if you're not careful).