Last week we learned about the
GameEntity API object and how it provides a skeleton for the objects present in the game world. This time we are going to enable units to interact with each other by giving them abilities.
Other articles in the modding API series:
- Units, Buildings & more
- Abilities (you're here)
- Inventory System
- Too many villagers!
- Restocking farms
The Ability API object
Ability API object has two main purposes.
First of all, an
Ability is always linked to behavior that is defined by an engine function. By adding an
Ability to a game entity, the engine knows that the unit is allowed to execute this behavior. For example, once the
Move ability is added to a unit, it will automatically be able to move around. The exact behavior of an ability is always decided by the engine, hardcoded into a function.
Ability object stores the attributes that are necessary for the execution of the ability. An example for
Move would be the speed at which a unit moves or for
Build the buildings that can be constructed. Keep in mind that nyan objects only store definition data which is different from the stats of a unit at runtime. For example, the
Live ability only defines the maximum HP, while the current HP value is handled by the engine's runtime simulation system.
Because pretty much everything is an ability, the associated properties can range in complexity. Some abilities are purely passive and don't even define members, e.g.
Passable which just tells the engine to turn the collision of a game entity off. Others define stats for units, like the
Live ability does with
line_of_sight or the
Creatable ability with
The more sophisticated abilities allow units to interact with other entities in the game world, e.g.
Build. Often these complex abilities are also animated and have an execution sound. This is signified by them inheriting from
AnimatedAbility. Abilities usually only store one animation (with rare exceptions), but can define several sounds, one of which is played randomly on execution.
Now (finally) we are going to have a look at how all the definition we talked about are written down in the nyan language.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
In this example we have created a simple unit
Swordsman. Right from the start, we can see that
Swordsman inherits from the
Unit API object (referenced by
engine.Unit). Aside from the values that were required for the members inherited from
GameEntity there are three abilities defined:
SwordsmanDie. As you probably already guessed, they use the API objects
The three abilities are defined as nested objects. Nested objects work just like normal objects with the neat little benefit that we can keep the notation of the units, its abilities and other dependent objects together in one space. For the abilities we do what we always do: We assign values to the members that are required by the API. After filling everything in, we have completed the definition of
Swordsman, a special case of
And that's really the gist of it. Using the API mostly evolves around "filling in the blanks" by assigning values to the required attributes. The above definition can be taken as is, placed as plaintext inside a
.nyan file and will be understood by the engine. Of course, in a real life situation a modder would also have to create animations and sounds to be included. But we hope it was clear that these do not get magically created out of the blue.
We have now seen the initial definition of a unit in nyan, but in real-time strategy games the intial values are often changed by upgrades, techs and other modifiers. How these changes are handled in nyan and why it is awesome will be discussed next week when we talk about Patches.
Until then feel free to ask questions and discuss the blogpost in our subreddit /r/openage!
As always, if you want to reach us directly in the dev chatroom: