A real-time strategy game where you design airships and then fight with them. The aim is to have pretty chaotic explodey fights and interesting ship design choices.

Post news Report RSS Modding Preview: The Imperial Cannon

Airships v8 will introduce a new, easier modding system. Here's how to make a giant cannon.

Posted by on

About a year ago I did a series of blog posts on how to mod a giant cannon into Airships by editing the source code. Now, as a preview for the modding features in dev 8, here’s the same thing as a proper mod.

This new modding approach has major advantages: you don’t have to know Java, you don’t need a Java development setup, the mod will stay compatible when the game updates, and fewer things can go wrong overall.

So in this post I’m going to give you a tour of the structure of the mod. You can download the whole thing from here. Of course you’ll have to wait for dev 8 to come out to actually use it.

The mod consists of a directory containing some files and folders:

info.json is the "header" of the mod, containing basic information. It's the presence of an info.json file that makes Airships see the directory as a mod. The file contains the mod's ID, which should be an unique string, as well as its name and description in whatever languages it supports. This one supports English, French and German like the base game, but it's not a requirement for all languages to be present! (Also, you can use mods to add entire new translations to the game, more on that later.)

{
    "id": "imperial_cannon",
    "name": {
        "en": "Imperial Cannon",
        "de": "Kaiserliche Kanone",
        "fr": "Canon Impériale"
    },
    "description": {
        "en": "A powerful but impractically large bronze cannon.\n\nby David Stark",
        "de": "Eine mächtige aber unpraktisch grosse Bronze-Kanone.\n\nvon David Stark",
        "fr": "Une arme massif. Un seul coup peut détruire la plupart des modules.\n\npar David Stark"
    }
}

logo.png is a 300x300 px title image that gets shown in the mod browser.


The images sub-directory contains the spritesheets for the mod. All game graphics are organized into 1024x1024 px spritesheets. The main spritesheet, impcannon.png, consists of the module graphic for the cannon, the barrel, and the giant cannon ball. (Yes, the cannon has a “hood ornament”.)

In addition, there is also impcannon_bump.png, which is the normal map for impcannon.png.

Finally, there’s impcannon_frags.png, which is a fragment map, indicating what regions the module should break apart into when destroyed.

These images are referenced in sheets.json in the SpritesheetBundle sub-directory. Each data type has its own sub-directory containing one or multiple JSON files with entries. You’ll be able to see all the data types and JSON files by looking into Airships’ data directory. sheets.json is pretty simple and just ties together the three images as a spritesheet bundle that can then be referenced from elsewhere. (Note that the .png suffix is implicit.)

[
    {
        "name": "impcannon",
        "bump": "impcannon_bump",
        "fragments": "impcannon_frags"
    }
]

Now we get to the meat of the matter: IMPERIAL_CANNON.json in ModuleType. (Module types are named in uppercase for historical/backwards-compatibility reasons.) I won’t go over each field in detail, but you can consult the old blog post for an explanation of pretty much all of them.

    [
        {
            "name": "IMPERIAL_CANNON",
            "categories": ["WEAPONS"],
            "isWeapon": true,
            "w": 5,
            "h": 3,
            "appearance": {
                "src": "impcannon",
                "x": 0,
                "y": 0,
                "w": 5,
                "h": 3
            },
            "hp": 500,
            "fireHP": 220,
            "moveDelay": 600,
            "weight": 400,
            "cost": 500,
            "crew": 4,
            "recommendedCrew": 5,
            "recommendedGuards": 1,
            "frontOnly": true,
            "isGun": true,
            "isCannon": true,
            "reload": 10000,
            "clip": 1,
            "inaccuracy": 0.0023,
            "blastDmg": 0,
            "penDmg": 400,
            "fireArc": { "direction": "forwards", "degrees": 45 },
            "muzzleCenterX": 3.8,
            "muzzleCenterY": 1.5,
            "muzzleLength": 2.5,
            "optimumRange": 400,
            "fireSound": "hv_cannon",
            "fireSoundCount": 3,
            "explodeHP": 150,
            "explodeDmg": 300,
            "weaponAppearance": {
                "shot": { "src": "impcannon", "x": 97, "y": 1, "w": 13, "h": 13 },
                "barrel": { "src": "impcannon", "x": 9, "y": 55, "w": 80, "h": 34 },
                "barrelX": 20,
                "barrelY": 7,
                "recoil": 15
            },
            "canOccupy": [
                { "x": 0, "y": 2 },
                { "x": 1, "y": 2 },
                { "x": 2, "y": 2 },
                { "x": 3, "y": 2 },
                { "x": 4, "y": 2 },
                { "x": 0, "y": 0 },
                { "x": 0, "y": 1 }
            ],
            "upDoors": [ 0 ],
            "leftDoors": [ 2 ]
        }
    ]

Finally, the strings directory contains all the translation keys for the mod in English, German and French:

en.properties:

mod_IMPERIAL_CANNON=Imperial Cannon
mod_desc_IMPERIAL_CANNON=A preposterously large weapon. A single hit will destroy most smaller modules.

de.properties:

mod_IMPERIAL_CANNON=Kaiserliche Kanone
mod_desc_IMPERIAL_CANNON=Eine absurd grosse Waffe. Ein einzelner Treffer zerstört die meisten kleineren Module.

fr.properties:

mod_IMPERIAL_CANNON=Canon Impériale
mod_desc_IMPERIAL_CANNON=Une arme massif. Un seul coup peut détruire la plupart des modules.

Finally, there’s the generated directory, which contains a whole lot of images automatically derived from the three in images: the spritesheet with various lighting effects baked in, damaged versions, a blueprint version, and the individual fragments of the module. All of this gets created by the mod tooling inside Airships, by simply pressing the “Process Spritesheets” button. So there’s no need to go into that folder - just hit “Process Spritesheets” whenever you change anything graphical about your mod during development, and stuff will work.

And that’s it! One slightly long JSON file for defining the module itself, some pictures and some really simple additional files to glue things together and provide text, and you have a new module available in-game.

Airships: Conquer the Skies is available on Steam and itch.io. You should vote for it on IndieDB!

Post comment Comments
Galacticruler
Galacticruler - - 1,053 comments

But what about large multi part mods?

Reply Good karma Bad karma+1 vote
explorer13
explorer13 - - 238 comments

Probably much of the same but with more .json files/a longer entry in the existing one to define where to use the other sprites. Though how to mod other things besides components I have no idea. Perhaps a way exists to override existing variables so that you can change otherwise hard-coded values? (though that would, of course, make it incompatible with other mods)

Reply Good karma Bad karma+1 vote
Zarkonnen Author
Zarkonnen - - 77 comments

Exactly, you can add however much stuff you want by just putting in new JSON files. I'm making as many values as possible non-hard-coded, but there'll be limits - you can't create whole new game mechanics or GUI elements.

Reply Good karma+1 vote
Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: