My sword and sorcery game, using the working name action-rogue up to this point, is now called Altar’s Gold. An ancient altar, which according to stories is filled with treasure, is hidden deep within a dungeon below the ruins of a fortress.
In the previous post I described how I switched to a more elaborate ECS (entity component system). Already a bit before that, I decided to abandon the idea of the player sprite containing a sword and a shield. To have the option of using different weapons, such as those found in the dungeon, the graphics of the player and the weapons needed to be separated. This fits with the new ECS approach: the player is an entity, but swords and shields are also entities. The player entity is made up of components that make it possible for them to move around the dungeon using keyboard input, while a sword entity cannot walk but instead has components that allow it to be picked up and wielded by other entities such as the player.
Therefore I remade the player walking animation, this time without sword and shield. Of course this will require displaying weapons in the correct location and orientation during walking, attacking, etc. On the one hand this make everything much more complex that I had perhaps planned originally. On the other hand, once it works it will allow for a richer game.
While working on my action roguelike, which up to this moment was using an ‘Entity’ type, I ran into the point that in App Game Kit, it is not possible to store a reference to one type instance in another type instance. For example, while it is possible to have a property ‘sword’ of type Entity, this will then be the actual instance of the sword, and not a pointer to a sword stored elsewhere.
This was a bit of a setback. (Though I can appreciate that in the AGK language, pointers have not been added, to keep things simple. On the plus side, passing an instance by reference into a function is supported.) One alternative way of pointing to another entity would be the use of indexes. For example, a property ‘sword’ would hold the integer index into the array of all entities. This did not seem like an appealing solution. However, this did make me think of how in an entity component system (ECS), entities are represented by integer ids.
While I was already creating a kind of ECS, up to this point I was using an Entity type, containing components as properties. In more elaborate entity component systems, an entity is represented only by an integer id. Components are stored in arrays (or other suitable containers), and the integer id is used to find the set of components that make up the entity. In such a system, it is also much more natural to refer to another entity by simply mentioning its id.
So I started rewriting my code so far, to use this new approach. There now is an array for each component type. Since AGK does not support the null value for missing instances, each array holds a component instance for every entity, but the component itself has an ‘active’ property so it can be disabled by default. The integer id of the entity is also the index into the component arrays.