Skip to content

Instantly share code, notes, and snippets.

@heinezen
Last active December 26, 2017 02:57
Show Gist options
  • Save heinezen/9468c78ec25566630a2bac5dca521b9a to your computer and use it in GitHub Desktop.
Save heinezen/9468c78ec25566630a2bac5dca521b9a to your computer and use it in GitHub Desktop.
Modding format (and general file structure I guess).

Attributes that our modpack format should have:

  • Easy to understand (For modders and for users)
  • Very flexible
  • Powerful, but yet resilient to changes

Fixed vs. non-fixed structure

Non-fixed structure

Wild West approach. Only a the mod header file is mandatory.

+ Modders have a lot of flexibility

+ Having a clean structure is delegated to the creators --> "not our problem"

+ Modders will have the freedom to do whatever they want (which will probably create amazing things)

- could result in a "zoo" of different mod structures

- abandoned mods will be harder to pick up

- conflicts are harder to find (how would the game search for them)

- there will be one guy who'll put 2000 files in the root folder of his mod

- because everything is possible media files, scripts and nyan files have to be explicitly linked --> creates additional pitfall for creators

Fixed Structure

We require a file structure that has fixed standard folders. Files (or objects) in the mod will overlay files from the base pack if they have the same name and relative path.

+ Linkage can be done automatically because nyan, media and scripts have standard folders

+ Modders who are dependent on other mods can be sure that the file structure stays consistent

+ Easier to understand for new modders

+ Easier for conflict solver to check

+ Allows trivial "overlaying" of modded over original files (very efficient for balance mods)

- because of stricter rules we'll have to worry more about feedback

- modders could plan for something that is not reflected in our file structure

--> solution: fixed rules only apply for "standard" folders, modders can still create new folders

- sharing scripts or media files for a nyan object could cause a lot of redundancy

--> solution: See mixed approach

- There is no universal approach to a fixed folder structure; different games could have different requirements

--> solution: Define modpacks with no requirements to other mods as "base packs" (essentially, these base packs are equivalent to a full game like AoE1, AoE2 and SWGB). Mods will only have to follow the file structure of the "base pack" they are modding

(Enhanced) Mixed Structure

We require a structure with fixed standard folders that resembles the folder structure of a base pack. Files (or objects) in the mod will overlay files from the base pack if they have the same name and relative path. Example:

Base Pack Files
|-..
  |-..
  |-units
     |-champion.nyan
     |-knight.nyan
     |-scout.nyan
Mod Files
|-..
  |-units
     |-scout.nyan
     |-donkeyman.nyan
Applying the mod
|-..
  |-..
  |-units
     |-champion.nyan        <Base>
     |-knight.nyan          <Base>
     |-scout.nyan           <Mod>  --> overlays file from base pack
     |-donkeyman.nyan       <Mod>  --> added from mod

+ Very easy to understand: files with the same name will be overlayed, new files are just added

+ Conflict solver can easily spot conflicts between mods: If two mods alter the same file --> conflict

+ Files of the base pack remain untouched --> can be loaded for multiplayer sessions without restarting

Problem 1: Removing objects that are in the base pack

Every once in a while modders will want to remove objects from their mod that are present in the base pack. For example, one might want to replace knights with the donkeymen from previous examples.

Solution: Exclude files

  • Only for mods
  • Exclude files can tell the engine to ignore nyan, media or script files from the base pack
  • Contain a relative path to the file/object that should be ignored when a mod is loaded
  • A mod could have multiple Exclude files throghout the file structure but they have to be registered inside a primary Exclude file in the mod's root folder.
  • Conflict solver has to check Exclude files

Problem 2: What if a .nyan file stores multiple objects?

It could happen that a .nyan file stores multiple objects and patches. If two mods change entirely different objects, this shouldn't produce a conflict.

Solution: Go deeper

  • Instead of replacing files with the same name and path, only Nyan::Objects and Nyan::Patches with the same name are replaced
  • Filenames can stay the same
  • objects and patches that differ from the bas back could be marked with an optional descriptor above their decleration (e.g. @changed, @altered) to increase readability.

+ more possibilities for modders to combine mods

- .. but more work for our poor conflict solver :(

Problem 3: Still not good enough

Now we still face the problem that two mods cannot change the same object. For example, if one mod wants to change the speed of a scout and another one change its abilities, the conflict solver will spout out an error. However these things absolutely don't lead to a conflict.

Solution: Introduce preemptive Nyan::Patches

  • Instead of redefining an object entirely, modders only have to write a patch
  • Patches are immediatly applied to the base pack objects when the mod is loaded (hence "preemptive")
  • Preemptive patches should go into an own file <unit>-patches.nyan that is located in the same relative path as the base pack file
  • Idea: Let modders use both preemptive patches and object redifinition
    • if a mod redefines an object, this indicates that the object should not be changed by other mods (except ones that are listed in the mods header) --> valuable for balance patches which don't want interference
    • if a mod defines a preemptive patch, other preemptive patches can be applied freely unless they produce a conflict

+ allows changes on an attribute level

+ even more combination possibilities

+ still very easy to check for a conflict solver

- modders can block each other by not defining preemptive patches, only objects

--> drama alert

--> solution: allow easy conversion between object redefinitions and preemptive patches

Asset file structure

This is not necessarily related to mods, but rather a template structure for base packs to use. It assumes we use a the mixed file structure mentioned above.

Approach 1: Keep nyan, media files, scripts all in the same folder

Media files and scripts are stored next to a nyan object or in subfolders. This might be the approach that is the easiest to understand ("everything in one place"). It can however, make sharing media files and scripts between different objects difficult.

Approach 2: Keep nyan, media files, scripts seperated

The nyan decleration, graphics, animations, sounds and scripts are all in different subfolders. Because we use standardized folder names, this shouldn't be a problem as the place for media files of every object is known.

Approach 3: Have nyan, media files, scripts seperated but allow references to other places

This is an extension to Approach 2. Nyan objects would allow referencing media files or scripts that are different from the standard path. When no explicit reference is given, the standard path is used. Example:

Standard Path
Donkeyman(Unit):
    hp = 10
    attack = 2   --> no reference is given, therefore the standard media path for Donkeyman is used
                 --> e.g. media/sounds/donkeyman; media/graphcs/donkeyman etc.
Non-Standard Path
Donkeyman(Unit)
    hp = 10
    attack = 2
    creation_sound = 'extra/sound/donkey.opus' --> will use the sound file in path 'extra/sound/donkey.opus'

Example folder structure

assets
  |-data
     |-buildings
     |-civs
     |-techs
     |-units
        |-..
  |-interface
     |-editor
     |-menus
     |-game
  |-localisation
     |-en
     |-..
  |-media
     |-animations
     |-graphics
        |-buildings
        |-terrain
        |-units
     |-music
     |-sounds
  |-missions
     |-campaigns
     |-scenarios
  |-scripts
     |-campaigns
     |-interface
     |-maps
     |-modes
     |-scenarios

data
nyan files and data description for units.

interface
interface files for HUD, menus and launcher. Could also store campaign menus.

localisation
Strings and translations

media
The collection of media files for the game.

missions
Campaigns, scenarios and funmaps go here.

scripts
Triggers, events for scenarios/campaigns as well as random map generation, editor scripts, win condition definition and functionality for interface overlays.

Referencing media for objects

Media files, scripts and strings will be referenced by using an abstraction layer. This means that we won't use paths to reference a media asset, but instead use a pointer. For example, when a mod changes the dying sound for the scout, the mod loader will set the pointer from the original sound in the base pack to the mod's replacement sound. By doing this, the engine doesn't have to worry about the exact placement of files.

Mod Manager

Our mod manager should come in two versions: One "standard" version for the game and a "developer" version for modders.

Standard Mod Manager

  • targeted at the users --> not much complexity needed

  • will check if the mod is signed by us or an equivalent authority

  • If a mod contains a script, the user should be warned when 1) activating the mod in the launcher and 2) right before the mod is loaded

  • if mods are signed, they create no warning

  • users should be able to deactivate the warning, but should be reminded every time the mod is updated that they are playing with fire

  • should detect conflicts between mods, but not suggest changes to a mod --> we'll leave that to devs

  • could optionally check for multiplayer compatibility

  • shows how the base pack is altered in categories (e.g. "media", "data", "script", "scenario")

  • multiplayer communities can ban mods from different categories

Developer Mod Manager

  • for developers to test their mods, zip them and solve conflicts with other mods --> pimped version of the standard mod manager

  • can detect conflicts and optionally suggests solving them

  • converts nyan object redefinitions to preemptive patches and vice versa

  • can create the header file

  • suggests "code compliance" if the modder has chosen a weird file structure

  • displays a diff between the base pack and the mod; optionally shows the diff to other mods as well

  • can launch the game even if conflicts are present

Mod Header File

The header file contains various information about the mod in a human readable file. These fields are suggested:

name
The full name of the mod.

version
Version of the mod.

engine_version
The engine version the mod is targeted at.

converter_version
The version of the converter which created the mod pack. (Only if the mod was converted from Genie Engine format)

description
A description of the mod.

author
The authors of the mod.

url (optional)
Links to the website of the creators.

license
Which license was chosen for the mod.

provides
A list of mods that are integrated into the mod pack.

requires
A list of mods that are required to run this mod

Our header file could also be used to register the mod to the engine: The game could store all of its mods in a folder called mods/. The mod header file is placed into the mods/-folder while its assets are stored inside a subfolder with the same name as the header file. When the game starts, it searches the mods-folder for new mod header files. If it finds one, the mod gets automatically added. By doing it this way, we avoid using manual imports and mod installers will have an easier time registering the mod to the engine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment