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 versions2.0.10
and2.0.11
.>=2.0.8 <=2.0.11
- Only supports versions from2.0.8
to2.0.11
(specifically, versions2.0.8
,2.0.9
,2.0.10
, and2.0.11
).>=2.0.8 <=2.0.11||2.0.4
- Only supports versions from2.0.8
to2.0.11
(specifically, versions2.0.8
,2.0.9
,2.0.10
, and2.0.11
), as well as version2.0.4
.2.0.x
- Only supports versions in the range of2.0.x
(anything that starts with2.0.
).2.0.8
- Only supports version2.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 |
---|---|
tombPostModParse | Run after all of the mod.json files are parsed. |
tombPostModProcess | Run after all mods are actually processed (i.e. file conflict checking, preparing Tomb’s state, etc). |
tombPostPluginInject | Run 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.