I want to design an entity system for my game using just C and a small subset of C++. Many people do this using inheritance, but I stumbled across tagged unions and learned that you can achieve a similar result this way, because virtual functions are slow for games(so I heard from Casey Mouratori and Jon Blow, two game devs from which I draw a lot of inspiration).
struct Unit {
int type;
int hp;
union {
struct {
int kingID;
} soldier_data;
struct {
string name;
} king_data;
};
}
Jon Blow avoids virtual functions using some features from his new language Jai which is not yet released, so the example above is my only idea.
For example I could write only one Update function and use the type to differentiate between entities. This would be a very large function but hey, we avoid virtual functions.
The things is my game contains lets say soldiers and trees. Trees are static and do mostly nothing, so I would write another lighter struct for trees entities, to save some memory, and use a unions to store different types of trees:
struct TreeEntity {
Texture* texture;
union {
struct {
int height;
} pineTree_data;
struct {
string name;
} coconutTree_data;
}
}
The problem I'm facing is what if both soldiers and trees are clickable? If I had used inheritance I would simple have a function Entity* selectEntity(), and check the instance type after, but with my approach I'm a kind of lost.
Is my approach bad? Should I stick to virtual functions or there is a way to handle this?
You ask how to create a generic
Entity* selectEntity()
function which can return either a Unit* or a Tree* (or perhaps other things).You can do it by returning a base-class pointer. Unit and Tree inherit from Entity, and Entity can contain a small enum like:
If you don't want to use inheritance, you can instead just have a common initial subsequence of member variables in every type of Entity, like this:
This is equivalent to the inheritance version in terms of memory layout, and you could return an EntityType* from
selectEntity()
, which will actually point to the first member of a Unit or Tree.