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:
- Introduction
- Units, Buildings & more
- Abilities (you're here)
- Patching
- Attack
- Bonus
- Inventory System
- Too many villagers!
- Transform
- Civilizations
- Restocking farms
The Ability API object
Each 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.
Furthermore, an 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.
Complexity
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 hp
and line_of_sight
or the Creatable
ability with creation_time
.
The more sophisticated abilities allow units to interact with other entities in the game world, e.g. Repair
or Build
. Often these complex abilities are also animated and have an execution sound. This is signified by them inheriting from SoundAbility
or AnimatedAbility
. Abilities usually only store one animation (with rare exceptions), but can define several sounds, one of which is played randomly on execution.
nyan example
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: SwordsmanLive
, SwordsmanMove
and SwordsmanDie
. As you probably already guessed, they use the API objects Live
, Move
and Die
.
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 Unit
/GameEntity
.
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.
Questions?
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:
- Matrix:
#sfttech:matrix.org
- IRC:
#sfttech
on libera.chat