Imperivm Resurrected

SDK reference

A lookup list of everything a mod can declare. To learn how to do it, see the guides linked in each table.

Paths on this page use \. The game is case-insensitive.

1. Mod structure

A mod is a folder in mods\. Folders starting with . or _ are ignored. Without a mod.json, the game creates a basic one (with autoGenerated).

"Gameplay" = every player must have the same mod (README).

Path in the mod What it does Gameplay
mod.json The mod's manifest. See section 2 No
data\… New files, or files that replace the game's, at the same path Yes
scenarios\, adventures\, conquests\ Maps, adventures and conquests Yes
units\, buildings\, mapobjects\ Replace the game's. .xml and .pass (footprints) count; .rle and the rest don't Only .xml and .pass
visuals\ Effects and projectiles Only .xml
packs\*.bfhp Maps (random, settlements…) Yes
packs\*.pak Packs mounted alongside the game's Depends on their contents
randommap\, randommapsettlements\ Random map shapes and city templates (Random maps, City templates) Yes
patches\<path> Patch of the game file at that path. Only .xml, .ini and .vs. See section 6 Depends on the path it patches
civs\<id>.json Civilizations. Section 3 Yes
specials\*.json Unit specials. Section 4 Yes
options\*.json Game options. Section 5 Yes
events\<Event>.vs Event scripts. Section 7 Yes
loc\<language>.loc.xml, loc\<language>\*.loc.xml Texts added to the game's (Languages) No
local\<language>\<path> File the game sees as currentlang\<path>, only with that language No
local\<language>.pak Language pack (also <language>_something.pak). Only the one for the game's language is mounted Depends on its contents
hidden.txt Game files the mod hides, one path per line; the ones after [language] are only hidden with that language. For old mods that removed files by replacing the game's packs; shrink-mod.js writes it Yes, if it hides gameplay files
rle.mmp.tail Graphics appended to the game's rle.mmp, with the fingerprint of the rle.mmp it extends. shrink-mod.js writes it. Only one active pack can have it No
movies\… Cutscenes (PlayMovie): they are looked up in the active packs first, in load order No
gameres\… Loose interface images (Images) No
Any other path Loose file with the same path as in the game No
  • Forbidden extensions: .exe .dll .asi .bat .cmd .com .scr .ps1 .vbs .js .msi .sys .cpl .lnk .reg .jar .hta .wsf .pif. With one of them, the mod doesn't load.
  • An extension that isn't a known one, and isn't forbidden, is allowed and never executed.
  • If two mods ship the same file, a loose file beats one inside a .pak; between two loose files, or two inside .pak files, the one that comes first in the load order wins. The game works that order out, nobody picks it: first what the mods ask for (a mod goes above the ones it needs in requires and the ones in its loadAfter, and below the ones in its loadBefore); then cosmetic mods go above content (maps, battles, conquest), and content above mods that change gameplay; on a tie, by id. The same mods give the same order on every computer. On each mod's card, the content manager lists the files it shares with other active mods and whose copy of each one is used. If two active mods replace the same gameplay files and neither names the other in requires, loadAfter or loadBefore, it is shown as a problem: use only one, or a compatibility patch (a mod that ships the merged files and has both in its loadAfter). When every file they share is cosmetic (textures, sounds, interface), the player can choose whose files are used; the choice is saved in the profile, only applies to loose files and changes neither the load order nor what counts online. To change a few values of a file that another mod may also change, a patch is better (section 6): patches add up instead of replacing the file.

Test folder <game>\mod\ (no mod needed; it beats all mods):

Path What it does
mod\<path> Replaces the game file at that path (if [Mods] Override=1)
mod\patches\<path>, mod\loc\<language>.loc.xml, mod\events\<Event>.vs, mod\civs\*.json, mod\specials\*.json Same as in a mod. options\ isn't read from here
mod\_cache\ Generated by the game (merged texts, patched files). Don't touch it

2. mod.json

Field Type Default What it does
id text folder name, lowercase with - The mod's identifier
name text, or object per language folder name Name in the content manager
version text empty Version
authors list of texts empty Authors
description text, or object per language empty Description
license text empty License
redistributable boolean false The host may send the mod to someone who doesn't have it
requires list of ids, or {"id", "version"} objects empty Mods it needs. version accepts >=, <=, >, <, =, *, or a number (equal)
incompatibleWith list of ids empty Mods it can't be enabled with
loadAfter list of ids empty Your mod goes above those: its files, patches and texts win
loadBefore list of ids empty Your mod goes below those
category text empty GameBanana category (Publishing)
tags list of texts empty GameBanana tags: players (maps) and language (campaigns, translations, audio)
sources object none url (or page), gamebanana (number) and tags (list, added to the ones above)
language object, list of objects or text none code, name and base (english by default). Plain text = just the code. See Languages
commands object none {"<orders file without extension>": {"name": text or object per language}}. See Keys

A per-language text picks the game's language; if it's missing, English; if that's missing too, the first one.

English aliases the game also reads: name, description, license, redistributable, language (with code, name).

3. civs\<id>.json

Guide: Civilizations.

Field Type Default Required What it does
id text file name No Letters, numbers and _; starts with a letter; up to 24. Stored in lowercase. In scripts it's the constant as you write it, with a capital first letter (Dacia, RomeImperial)
index integer 10-99 — Yes The civilization's number
base text Gaul No Game civilization it inherits from: Gaul, RepublicanRome, Carthage, Iberia, ImperialRome, Britain, Egypt, Germany (also Rome, Roman, Briton)
name text, or object per language the id, capitalized No Name in the lobby
letter one letter the base's No Prefix for classes and orders
template text empty No Prefix of your city and village templates
internalName text the base's No Name the game uses to look for interface files. Also valid in race= if it's not the base's
folder text the base's No Name in the selection texts
random boolean true No Included in the random civilization draw
biome text (a game civilization) the base No Terrain, trees and objects of the random map
ai boolean false No The AI plays with your classes and orders (otherwise with the base's). In the draw, an AI only gets civilizations that have it
ownAi boolean false No With ai: the mod ships all the AI scripts
alias object none No classes and commands: name in the base → name in your civilization (each value a text)
variant boolean false No Variant of the base: uses its classes, GetPlayerRace returns the base and Mod_PlayerCiv the chosen one. With it, ai is true unless set
replacesBase boolean false No The base doesn't show in the lobby: this civilization takes its place and its share of the random draw
  • race="<id>" in a class's <properties> uses the civilization by its id or its internalName.
  • Repeated id or index: the one from the mod that comes first wins; the others are ignored with a warning.
  • English aliases: index, name, letter, template, internalName, folder, random, biome, ai, ownAi.

4. specials\*.json

Guide: Unit specials.

Field Type Default Required What it does
id text — Yes Letters, numbers and _; starts with a letter; up to 24. Can't be a game unit special. It's the script constant (Critical) and the name in unit_specials
bit integer 36-63 — Yes Mask bit. Don't change it once published
name text, or object per language the id No Name
description text, or object per language empty No Read; not shown
icon text empty No Read; not used
  • Repeated id or bit: the one from the mod that comes first wins.
  • In unit_specials, names are comma-separated; mod ones are case-insensitive. The game ignores the ones it doesn't know.
  • English aliases: name, description, icon.

5. options\<id>.json

Guide: Game options.

Field Type Default What it does
id text file name Letters, numbers, _ and -; up to 32. Stored in lowercase. It's what Mod_GetOption and Mod_GetOptionValue use
name text, or object per language the id Text in the lobby
description text, or object per language empty The row's help text
values list of 2 to 16 none (= toggle) Each value: a text, or {"id", "nombre"}. The first is 0
default boolean, number or text false / 0 Toggle: true/false. List: the value's number (from 0) or its id. An id that doesn't exist gives 0
  • A values with fewer than 2 or more than 16 items ignores the whole option.
  • Bits: toggle 1; list of 2 values 1; of 3-4, 2; of 5-8, 3; of 9-16, 4. They're taken in alphabetical order of id.
  • With a repeated id, the one from the mod that comes first wins.
  • English aliases: name, description, values, default.

6. Patches

Guide: Patches. A patch goes in patches\<path of the game file>. Only .xml, .ini and .vs. Order: from the last mod in the load order to the first, so the first one has the last word; mod\patches last.

XML

The patch's first tag is the root (usually called <patch>); its children are the operations, applied in order. Operation, tag and attribute names are case-insensitive.

Operation Attributes Content What it does
<set> select, optional, unset, and any other attribute None Changes or adds those attributes on the selected elements. unset removes attributes (separated by spaces or commas)
<add> select, optional, position Elements or comments Adds them. position: end (default), start, before, after
<remove> select, optional None Removes the selected elements
<replace> select, optional Elements or comments Replaces the selected elements with the content
  • select is required. You can't use <set> to set an attribute called select, optional or unset.
  • optional: 1, yes, si, sí or true avoid the error if the selector finds nothing.
  • <add> and <replace> without content give an error.
  • A selector with no results, or an unknown operation, is skipped with an error; the rest go on. If the patch isn't well-formed, no operation is applied.
  • The patched file keeps comments and quotes; attributes are collapsed onto one line.

Selector

Element Syntax
Child / descendant step /nombre, //nombre
Any name *
With attribute equal [@a='v'] or [@a="v"] (case-insensitive; understands &amp; &lt; &gt; &quot; &apos;)
With attribute [@a]
The nth [n], from 1: the nth of those matching name and conditions, within each parent

You can chain conditions ([@a='v'][2]). Nothing else exists (and, contains, text(), ..). Always start with / or //.

INI

Each line of the patch, under a [Seccion] (required before any line):

Line What it does
Clave = valor Changes the first line with that key in the section, or adds it at the end of the section. It's written as Clave = valor
-Clave Removes all lines with that key from the section, or that exact line. Error if there are none
+Linea Adds a standalone line if it isn't there already
[Seccion] Switches section. If it doesn't exist in the file, it's created at the end
;… or #… Comment. Only valid on a whole line

Keys and sections are case-insensitive. A comment at the end of a patch line isn't stripped.

.vs scripts

Directives start with @ in the first column; the code below each one is what gets inserted.

Directive Where it inserts
@top After the first line if it's a // comment (the signature); otherwise at the start
@bottom At the end of the script
@before TEXTO Before the first line containing TEXTO
@after TEXTO After that line
@replace TEXTO In place of that line. With no code below, it deletes the line
@end Closes the block; anything after it up to the next directive is ignored
  • TEXTO is a literal piece of a line (case-sensitive). The first line containing it is used, and directives apply in order: they see what the earlier ones inserted.
  • Error (and the directive is skipped): unknown directive, @before/@after/@replace without TEXTO, a directive without code (except @replace), TEXTO not found.

7. Script events

Guide: Scripts. File: events\<Event>.vs. Runs on every PC; with several mods, all of them run.

Event When Signature (first line)
OnGameStart When a game starts, after the victory scripts start. Can use Sleep // void
OnObjectDie An object dies, before its death is processed (the first time) // void, Obj victim
OnObjectKill A blow kills an object // void, Obj killer, Obj victim
OnSettlementCaptured A settlement changes owner while the game is running. Players 1-16; 0 = no owner // void, Obj building, int oldPlayer, int newPlayer
OnAttackResolved A blow that deals damage, before it's applied // void, Obj attacker, Obj victim, int damage
OnPlayerDefeated A player (1-8) is declared defeated, once per player // void, int player
  • Except for OnGameStart, they run immediately and can't wait.
  • An event that fires inside itself is cut off at 4 levels.
  • If the script fails at run time, the log records it up to 5 times per script.
  • Only these event names are read. You choose the parameter names.

8. Mod_* functions

Guide: Scripts. The current API is 6; it's part of the multiplayer check.

Function API
Mod_Log(str text) 1
Mod_LogInt(str text, int value) 1
Mod_IsActive(str id) : bool 1
Mod_ApiVersion() : int 1
Mod_SetInt(str name, int value) 2
Mod_GetInt(str name) : int 2
Mod_AddInt(str name, int delta) : int 2
Mod_HasKey(str name) : bool 2
Mod_AttackDamage() : int 3
Mod_SetAttackDamage(int damage) 3
Mod_HasSpecial(Unit unit, int bit) : bool 4
Mod_SetSpecial(Unit unit, int bit, bool on) 4
Mod_TrueRace(Obj obj) : int 5
Mod_GetOption(str id) : bool 6
Mod_GetOptionValue(str id) : int 6

Script constants: each mod civilization's id with a capital first letter (value = its index) and each mod unit special's id (value = its bit).

9. imperivm-mod.ini

It's in the game folder. It's read at startup.

Section Key Value Default What it does
[Debug] LogFiles 0 or 1 0 The log records every file the game opens and marks the ones that don't exist (VFS: opens … -> does not exist)
[Debug] Dump comma-separated paths, or * empty Copies each file to mod-dump\<path> exactly as the game reads it (patches and mod texts already applied), the first time it opens it. Exact name, no wildcards except * (all)
[Debug] DumpAtStartup comma-separated paths empty Copies those files to mod-dump\ at startup, without waiting for the game to open them
[Mods] Override 0 or 1 1 Enables <game>\mod\<path> as a file replacement
[Mods] Profile profile name, Original or No profile Original Profile the game starts with (No profile is "My content" in the manager). The content manager changes it; a change applies on restart

10. Limits

What Limit Source
Game option bits 8 across all options of all mods Code
Values in an option list 2 to 16 Code
Option id up to 32; letters, numbers, _, - Code
Civilization and unit special id up to 24; letters, numbers, _; starts with a letter Code
Civilization index 10 to 99 Code
Civilization letter 1 character Code
Unit special bit 36 to 63 Code
bit in Mod_HasSpecial and Mod_SetSpecial 0 to 63 (out of range: false / does nothing) Code
Mod variable name up to 64 characters Code
Mod variables up to 1,024; 32-bit integers Code
Mod_Log and Mod_LogInt 2,000 lines per session Code
Mod_SetAttackDamage a negative value is clamped to 0 Code
Event script errors in the log 5 per script Code
Nested events 4 levels Code
Patch errors per mod the first 50 are kept Code
Dump up to 1,023 characters; DumpAtStartup, 2,047 Code
<behavior> per class 8 Scripts
Images, layers and states in an .ent.xml 32, 32 and 8 Graphics
<anim> idx and frames per animation 1 to 28; up to 64 (2 are sentinels: 62 rows) Graphics
Sprite directions 8 soldiers, 12 heroes and animals, 4 ships Graphics
Sprite colors 256; with player color, 192 Graphics
Button / portrait 153 x 51 / 65 x 76 Images
Formation BonusDamage, BonusArmor, BonusRange, BonusLevel -1000 to 1000 Formations
Random map type name 2 to 31 characters Random maps
--players, --small, --distortion of create-random-map.js 2 to 8, 0 to 8, 0 to 0.5 create-random-map.js
--width of create-template.js 0 to 4 City templates

The guides explain how to do each thing; this is the complete list. Back to the README.