Hello everyone, we are happy to have you here for yet another openage update. For the latter half of the month, we have taken a small break from pathfinding to work on other small internal projects that have been piling up, e.g., some leftover tasks in the renderer. That also means that, unlike last month, this update won't be 100% pathfinding exclusive, so those of you who enjoy more variety have something to look forward to!
Pathfinding in nyan API
Since the pathfinding system in the engine is mostly finished, we have been making efforts to officially use it in the movement systems of the game simulation and build it into our rudimentary map generation. The first major step in this direction is the integration of new pathfinding-related objects into our
nyan modding API. This allows game objects to utilize the pathfinding functionality in several ways.
The new API object
PathType can be used to define grids in the pathfinder. Usually, there exists more than one pathfinding grid per game. For example, AoE2 has two grids, one for land-based units and one for ships. If you are very generous, you could additionally consider that there is a third "air" grid, as the ambient birds flying all over the map have separate pathfinding rules. A unique air grid is also used for flying units in
Star Wars: Galactic Battlegrounds.
PathType objects can be referenced by other API objects to reference a specific grid, e.g., by the
Move ability with its new member
path_type. This tells the engine which grid to search for pathfinding when the ability is used by a game entity. For dynamically influencing the cost of the grid, there is now a
Pathable ability that changes the cost of grid cells for one or multiple grids at its location when it is active. The latter ability may, for example, be used by buildings to make parts of the grid impassable as long as the building exists.
For map generation, the
Terrain API object now allows defining the pathing costs associated with each terrain via the
path_costs member. This member simply assigns a cost value to each grid defined with
PathType. When the map is created, the terrain generator uses these values to initialize the cost fields for the grid in the pathfinder.
Rendering Multi-textured Objects
After adding all the relevant pathfinding types to our API, we are finally able to put all the pieces together and make units move with proper pathfinding. However, there was one minor problem that we wanted to resolve first: While the game state has supported tiling with terrains for a while, the terrain
renderer couldn't display them properly yet. In fact, the renderer would only use the texture of the first tile for texturing a whole 10x10 chunk, so all chunks looked like they only contained a single terrain type. Given that this is rather distracting when we want to test whether pathfinding based on specific terrain costs works, we took a slight detour to extend the renderer first. You can see the result in the screenshot below.
Previously, each terrain chunk in the renderer was handled as a single mesh that would be drawn with one texture in the shader. In the new implementation, the chunk is split up so that all tiles with matching terrain textures get their own mesh. For example, if there are six different terrain textures, then there would be six meshes created for the chunk. All of the meshes are drawn individually, but this is practically unnoticeable as the meshes border each other seamlessly. You may have also noticed the lack of terrain blending, which currently makes the tile edges very distinct.
After we updated the terrain renderer, we also applied similar changes to the world renderer (which draws unit sprites). Here, we added support for rendering animations with multiple layers. In the above screenshot, you can see this in action when you look at the castle, which consists of a
main layer and a
shadow layer.
The main layer is the building sprite, whereas the shadow layer is the semi-transparent grayscale sprite to the left of the building. Previously, the renderer would only draw whatever layer was defined first.
The principle is roughly the same as for the terrain chunks: Every layer gets its own mesh which is drawn individually. Draw order is a bit more important in this context because animations of different units are more likely to overlap each other than tiles in the terrain renderer. Therefore, we added the possibility to insert renderable objects by priority into the rendering pipeline. As a result, all animation parts should now be displayed properly in the game.
What's next?
Now that the terrain renderer actually displays what's happening in the gamestate, we can start working on integrating the pathfinder again. In theory, this is pretty trivial to add, but we'll have to see if we encounter some errors in the implementation.
The next obvious step for the terrain renderer is blending support. This could be much harder as we would have to find a strategy that can handle the blending styles of all the old and new releases (AoE1, Conquerors, and the Definitive Editions all have different approaches). We will probably try to tackle the classic Conquerors blending first and then iterate and adjust gradually for other styles.