Imperivm Resurrected

Custom unit specials

The game ships with 36 fixed unit specials (Parry, Penetration, Deflection…). They can't be extended, but a mod can declare new ones, and you program their effect with scripts.

Ready-to-copy example: examples/specialty-example, "Golpe crítico": 25% of hastatus hits deal triple damage.

How it works

Each unit carries a 64-bit mask, one bit per special. Bits 0 to 35 are the game's 36. Bits 36 to 63 are yours and are saved with the game. A mod special takes one bit.

There are three steps.

1. Declare it. A specials\<id>.json file in your mod:

{
  "id": "Critical",
  "bit": 36,
  "name": {"spanish": "Golpe crítico", "english": "Critical hit", "italian": "Colpo critico"},
  "description": {"spanish": "Uno de cada cuatro golpes hace el triple de daño.", "english": "One hit in four does triple damage.", "italian": "Un colpo su quattro fa il triplo del danno."}
}
Field What it is
id The name: letters, numbers and _, starting with a letter, up to 24 characters. You write it in unit_specials and it's the script constant (Critical). It can't be the name of one of the game's 36 (Triple strike…). Also avoid ids that, lowercased and with _ for spaces, match game constants (triple_strike, keen_sight, life_steal…): the validator doesn't check this and the constant would clash with the game's.
bit A number from 36 to 63. Don't change it once published: saved games remember it. Two mods can't use the same one.
name Its name in each language, or a single string.
description It's read, but not shown anywhere yet. Describe it in the unit's help text.
icon (Optional) It's read, but not used.

2. Assign it to classes. With the usual unit_specials attribute. The game ignores names it doesn't know and the mod sets the bit. Better done with a patch, so you don't replace the class file:

<patch>
  <set select="/class/properties[@unit_specials='Deflection']" unit_specials="Deflection, Critical"/>
</patch>

Inheritance works as in the game. If a class sets unit_specials, its list replaces the parent's; if it doesn't, it inherits the parent's whole list. When adding one to a class that already has some, repeat the ones it had (Deflection, Critical). In the game names are case-sensitive; your mod's aren't.

3. Program the effect. The game only stores the bit. You write what it does in a script:

Function What it does
Mod_HasSpecial(Unit unidad, int bit) : bool Does the unit have this special? Works for any bit from 0 to 63, including the game's. Takes a Unit; with an Obj, use objeto.AsUnit() (if it isn't a unit, returns false).
Mod_SetSpecial(Unit unidad, int bit, bool puesta) Sets or clears the special on that unit, for example on level-up. It's saved with the game.

The bit is the constant named after the id: Mod_HasSpecial(attacker.AsUnit(), Critical).

The natural place for the effect is the OnAttackResolved event, which can change each hit's damage (events\OnAttackResolved.vs). Any other script works too: a <behavior> that checks units periodically, OnObjectKill, OnObjectDie…

// void, Obj attacker, Obj victim, int damage
if (!attacker.IsValid) return;
if (!Mod_HasSpecial(attacker.AsUnit(), Critical)) return;
if (rand(100) >= 25) return;
Mod_SetAttackDamage(damage * 3);

Multiplayer

specials\, events\ and civs\ count as gameplay: all players need the same mod.

Errors

They show up in Logs\imperivm\imperivm-mod.log (lines tagged specials) and on the mod's card in the manager: an invalid id, a missing or duplicate bit, a name that belongs to a game special.

Warning: if you add an unknown [Section] to UNIT_SPECIALS.INI (with a patch, to give a special an icon and text), the game may crash. Don't. Mod specials don't use that file.

What's missing

  • The unit info bar at the top, where the game shows up to three of a unit's specials with their icon, doesn't show mod specials.
  • The recruit button's stats text should list them below the game's, without the "Specials" title: a unit with only mod specials would show them with no title.
  • Custom icons: not shown.
  • You can't add to the table of the game's 36 or create new native hero abilities. Active ones are made with commands and scripts.