D3: Openage modding API - Patching

In our last blogpost we talked about abilities, how they are used to define behavior of game entities and had a look at an initial declaration of a Swordsman unit. This time we are going to investigate how we alter the initial declaration at runtime through the use of Patch.

Other articles in the modding API series:

  1. Introduction
  2. Units, Buildings & more
  3. Abilities
  4. Patching (you're here)
  5. Attack
  6. Bonus
  7. Inventory System
  8. Too many villagers!
  9. Transform
  10. Civilizations
  11. Restocking farms

View all articles

Motivation

Most RTS games let players increase the stats of units in one form or another, usually by researching technologies, levelling or giving items to them. Technology heavy games like AoE2 even allow units to upgrade multiple times, e.g. the Miltia unit which can be improved up to four times. One of the easiest methods to accomplish this is by replacing the old unit with an upgraded version that has better stats. For example, the Man-At-Arms upgrade in AoE2 switches all Militia units with Man-At-Arms. While handling upgrades like this is easy, it creates some problems:

  • Units cannot improve individually because the individual stats cannot be carried over to the upgraded replacement unit.
  • The units will be very generic. A replacement unit has to be designed for every possible unit upgrade.
  • Changing ownership of units can create weird bugs because different civilizations could have different upgrade paths for each unit.

We would prefer a more flexible system that is also easy to understand. That's where Patch comes into play. A patch is a special object that defines attribute changes for another nyan object. Here is one simple example of a Patch:

1
2
MoreSpeed<engine.Move>(engine.Patch):
    speed += 0.5

The declaration of a Patch is very similar to the declaration of a normal object with the exception of <engine.Move>. The reference in the angled brackets is the target object of the patch. The line below shows the member that is altered by patching. In this case the current value of speed is increased by 0.5 when the patch is applied. Instead of a relational change, absolute changes are also possible.

1
2
MoreSpeedAbsolute<engine.Move>(engine.Patch):
    speed = 2.0

This alternative patch would set speed to 2.0 when it is applied.

API objects for applying Patches

As stated before, the declaration of a patch does not define in what situation it is applied. However, there are API objects that cover the most common situations, e.g. Tech and Mod.

Tech and Mod

Tech objects represent technologies that have to be researched by a GameEntity with the Research ability. The member upgrades stores a set of patches that are the effects the technology has on the player's units. Patches of Tech are applied as soon as the game entity has finished researching the technology.

Similar to Tech, Mod also holds a set of patches, but they are automatically applied right at the start of a game with no further requirements. This can be utilized by modders to get their intended alteration into the game (e.g. different animations/sounds or balance changes) without touching the original dataset.

Benefits

The great advantage of a Patch is that it only defines what is changed, but when, how often and which unit it will be applied to can be decided elsewhere. The patch MoreSpeed of our example that changes the Move ability could be applied on all units, only selected units, a single unit, a class of units, multiple times, once, every 2 minutes, and so on. Furthermore, it allows us to make more fine-grained upgrades, instead of the sledge hammer approach that the unit replacement method is.

So will every upgrade be defined as patches? The answer is yes. Every single upgrade will be done by a patch or a bundle of patches. This goes so far that in the AoE2 swordsman line (Militia, Man-At-Arms, Longswordsman, Two-Handed Swordsman, Champion), Militia will be the only unit that is initially defined. The other units will be defined as patches that upgrade animations, stats and abilities. This might be unintuitive at first, but gives considerably more options to developers and modders.

Questions?

Now that the basics of abilities and patching are established, we will dive deeper into the topic of abilities and take a look at the Attack abilitiy. See you next time!

Any more questions? Let us know and discuss those ideas by visiting 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

links

stalking