Modding Wiki

mod.json Format

This is a reference for the standard mod.json format used by several mod loaders. Mod loader developers are recommended to use this format.

The mod.json spec is versioned by SemVer. The current version, which is described here, is 0.1.0.


The metadata for a mod is specified in a mod.json file, located at the root of the mod (either a folder or ZIP in the mod loader’s mods folder). Here is a sample starter file:

{
	"id": "example",
	"name": "Example",
	"authors": ["Your Name Here"],
	"description": "A longer description for your mod",
	"version": "0.1.0",
	"dependencies": {
		"game": ">=2.0.10",
		"spec": "0.1.0"
	},
	"files": {}
}

And here is an example of a mod that uses all of the features:

{
	"id": "test",
	"name": "Basil's Test Mod",
	"authors": ["Basil"],
	"description": "A longer description for your mod",
	"version": "0.1.0",
	"spec": "0.1.0",
	"dependencies": {
		"game": ">=2.0.10",
		"spec": "0.1.0",
		"mods": {
			"andrew-maid-dress": ">=1.0.0",
			"modlib": "2.0.7",
		}
	},
	"files": {
		"assets": [
			"audio/bgm/twisted_clowns.ogg",
			"img/system/wrench.png"
		],
		"imageDeltas": [
			"img/titles1/Book.png.olid"
		],
		"dataDeltas": ["data/Map004.jsond"],
		"plugins": [
			"noMusic.js",
			"plugins/reloader.js",
			"plugins/devtools.js",
			"plugins/menuOption.js",
			"plugins/betterShift.js"
		],
		"languages": ["languages/english.json"],
		"inject": [
			{
				"file": "inject/disableTest.js",
				"at": "tombPostModParse"
			}
		]
	}
}

Keys

id

The id field specifies the unique ID of the mod. Every mod must have a unique ID or you will get an error while launching the game. The ID must be a string of one or more characters. The following characters are valid: lowercase letters from “a” to “z,” numbers from 0 to 9, underscores (_), and dashes (-).

name

The name field specifies the name your mod.

authors

The authors field specifies an array of strings, with each string being the name of one of the authors of the mod.

description

The description field is a longer explanation of what your mod does. Keep it to a sentence or two. If your mod name is sufficiently explanatory, you can set it to an empty string. It is currently required.

version

The version field is a SemVer version string corresponding to the version of your mod.

dependencies

This is where you specify which versions of the game the mod supports, which mod.json spec version the mod loader in use needs to support, and which other mods it requires in order to function.

Some of the values are SemVer ranges. Read the npm documentation on SemVer ranges for more information.

dependencies.game

The game field is a SemVer range that specifies which versions of the game are supported.

If the range is not satisfied, the mod will not load.

Due to the nature of game modding, and because the the game does not follow SemVer in the way the SemVer specification expects, it is recommended to keep game very strict, and to depend only on known versions of the game. Whenever an update to the game is released, you can update this value and release a new version of your mod after checking that it supports it.

Some example SemVer ranges:

  • 2.0.10||2.0.11 - Only supports versions 2.0.10 and 2.0.11.
  • >=2.0.8 <=2.0.11 - Only supports versions from 2.0.8 to 2.0.11 (specifically, versions 2.0.8, 2.0.9, 2.0.10, and 2.0.11).
  • >=2.0.8 <=2.0.11||2.0.4 - Only supports versions from 2.0.8 to 2.0.11 (specifically, versions 2.0.8, 2.0.9, 2.0.10, and 2.0.11), as well as version 2.0.4.
  • 2.0.x - Only supports versions in the range of 2.0.x (anything that starts with 2.0.).
  • 2.0.8 - Only supports version 2.0.8.

dependencies.spec

The spec field is a SemVer version (not a range) that specifies what version of the mod.json spec the mod is written for. Unless you’re targeting an older mod loader that doesn’t support the most recent spec, use the latest spec version.

The point of this field is to allow new features to be introduced to the spec in a backwards-compatible manner. Mod loaders will be able to determine whether they support a mod based on the spec version.

dependencies.mods

The mods field is an optional object that specifies which mods (specified via IDs) and which versions of them are required. In order for the mod to load, all of mods must be installed, with versions that match the version range.

If mods is omitted, then the mod will be treated as if it does not rely on any other mods.

For example:

{
	"settings-lib": "0.2.3",
	"andrew-maid-dress": ">=1.0.0"
}

This would mean that the mod requires another mod with the ID of settings-lib to be installed, and to have the version 0.2.3. Also, a mod with the ID of andrew-maid-dress has to be installed, and the version has to be greater than or equal to 1.0.0.

files

This is where you specify things like asset swaps, patches, plugin injections, and other things.

files.assets

The assets field allows you to both override existing files and add new files, referred to as asset swapping. It consists of an array of strings, corresponding to the file location relative to the www/ folder. You must supply the new files at the same relative path in the mod directory.

For example, if you wanted to replace the file at audio/bgm/twisted_clowns.ogg (the main menu music) with a different audio file, set up the following structure in your mod folder:

<your mod folder>/
└── audio/
    └── bgm/
        └── twisted_clowns.ogg <- This would be the new audio file

And―omitting the metadata tags―your mod.json would look like this:

{
	"files": {
		"assets": [
			"audio/bgm/twisted_clowns.ogg"
		]
	}
}

If you want to change a portion of an image instead of replacing the entire file, you should use image deltas instead.

files.imageDeltas

Image deltas―also known as image patches―are specified with the imageDeltas key. They allow you to patch parts of images without having to include the original image.

They work like asset swaps, except that you provide image patch files instead of images and add .olid to both the end of the file path in the imageDeltas array and the patch file itself.

Patches use the OneLoaderImageDelta format. You can generate and apply them with Rph’s web tools. To make a patch, all you have to do is supply the original, unmodified file, as well as the modified file, and it will automatically generate a patch to only change the modified pixels.

For example, if you wanted to modify img/parallaxes/ground3.png (the very first room of the game), you would make a copy of the decrypted file and edit the copy in an image editor (make sure to save it as a lossless PNG). Then, go to Rph’s patch generator, input both the original and modified images, and generate a patch. Your folder structure would look like this:

<your mod folder>/
└── img/
    └── parallaxes/
        └── ground3.png.olid <- This would be the patch file

And again, omitting the metadata tags, your mod.json would look like this:

{
	"files": {
		"imageDeltas": [
			"img/parallaxes/ground3.png.olid"
		]
	}
}

files.dataDeltas

You can also apply patches to the .json files in the data/ folder2. These may be referred to as JSON deltas/patches or data deltas/patches. Like imageDeltas, dataDeltas is an array of strings that correspond to paths to JSON files relative to www/. The difference here is that instead of ending in .json, the the files end in .jsond.

Patches are stored in the JSON-Patch format.

files.plugins

plugins specifies an array of strings that points to JavaScript files relative to the mod folder. Any files specified in plugins will be injected as RPG Maker plugins. The files don’t have to have a specific path or name.

For example, Tomb includes a “core” mod called Gravestone that draws the text in the bottom corner of the game. You can check out the source code for that plugin here.

files.languages

The languages field specifies a list of .json files that will be merged with the parsed data of the translations loaded by the game. They can either replace existing text or add new text. They follow the same format as the languages/english/dialogue.loc files, but only the following top-level keys are taken into account: sysLabel, sysMenus, labelLUT, and linesLUT.

The language they affect is determined by the file name; they can be located in any folder. For example, patches/langs/english.json would modify the language with an ID of english. The ID must match with the name of whichever folder the translation is targeting. For example, if you had an unofficial Japanese translation in the www/languages/japanese folder in the game, you would target the ID japanese with japanese.json in your mod.

For example, if you wanted to add the line yourmodid_conflict9 (accessible through (lines)[yourmodid_conflict9] in the Show Text command) to the English localization, you would make a file called english.json, and put the following in it:

{
	"linesLUT": {
		"yourmodid_conflict9": [
			"\"Why do they call it oven when you",
			"of in the cold food of out hot eat the food?\""
		]
	}
}

Then, in mod.json:

{
	"files": {
		"languages": [
			"languages/english.json"
		]
	}
}

files.inject

The inject field specifies hooks, code that is run (injected) at certain parts of the mod loader’s loading process. Hooks can be used to modify the behavior of the mod loader. As different mod loaders can vastly differ in their architecture, the specific hook names they use will vary. For example, a mod could be used to inject a library into $tomb.lib.

The inject field is an array of objects, with each object being in the following format:

{
	"file": "<path to .js file>", // The path to the injected file relative to your mod folder
	"at": "<injection point>" // The injection point, see below
}

This is a list of all of the injection points that Tomb currently supports.

Hook (at)Description
tombPostModParseRun after all of the mod.json files are parsed.
tombPostModProcessRun after all mods are actually processed (i.e. file conflict checking, preparing Tomb’s state, etc).
tombPostPluginInjectRun after the custom RPG Maker plugins the mods provide are injected.

If you plan on using hooks, you should look through the Tomb codebase to understand when they’re run and what you can do at that point.

If you’re making your own mod loader, prefix hook names with the name of your mod loader in lower camel case.


Changelog

0.1.0

”Initial” versioned version of the spec.

  • Introduced the dependencies key.

Footnotes

  1. As of writing, when the game tries to load an asset, it checks to see if the data is encrypted. If it doesn’t appear to be encrypted, it loads the file as-is.

  2. Or rather, any JSON file that is fetched via network requests.