Coming soon toSteam
Modding docsAPI 1

mod.json

Every mod has a mod.json at its root. The game reads it before anything else, and a mistake in it is reported with the line number in Mods, in the script editor's Problems and by theonaris-mod validate. Misspelled keys are reported with a suggestion ("did you mean permissions?").

mod.json
{
  "format": 1,
  "id": "yourname.thruster-pack",
  "name": "Thruster Pack",
  "version": "1.2.0",
  "description": "Three new thrusters and a tuning window.",
  "authors": ["Your Name"],
  "license": "MIT",
  "homepage": "https://example.com/thruster-pack",
  "icon": "icon.png",
  "tags": ["blocks", "building"],

  "game": ">=0.1.0",
  "api": 1,
  "side": "both",
  "network": "required",

  "entry": { "server": "scripts/server.lua", "client": "scripts/client.lua" },
  "dependencies": { "someone.shared-lib": "^2.0.0" },
  "permissions": ["building", "building.edit", "ui", "net"],
  "settings": [
    { "key": "strength", "type": "number", "label": "Strength", "default": 1, "min": 0.1, "max": 5, "step": 0.1 }
  ],
  "content": { "blocks": ["content/blocks/*.json"] }
}

Identity

FieldRequiredDescription
formatyesAlways 1.
idyesUnique forever. Lower-case yourname.modname: letters, digits, - and _, at least one dot, 3–64 characters. Changing it makes a different mod. Do not start yours with theonaris., which the game uses for its own modules and examples.
nameyesShown to players. Up to 64 characters.
versionyesSemantic version: 1.4.2, 2.0.0-beta.1.
descriptionnoUp to 4000 characters.
authorsnoUp to 16 names.
licensenoFor example MIT or CC-BY-4.0.
homepagenoAn https:// address shown in Mods.
iconnoA .png inside the mod, up to 1 MB, shown beside the mod in Mods. Square pictures look best.
tagsnoUp to 16 lower-case words, such as blocks, ui or map.

Compatibility

FieldDefaultDescription
gameanyThe game versions the mod works with, as a version range. A mod outside its range does not start and says why.
api(required)The API version the mod was written for. Currently 1.
sidebothWhere the mod has code: both, client or server. A client-only mod never runs on a dedicated server.
networkrequiredHow it behaves in multiplayer. See below.

network values:

Version ranges

Ranges use the npm style:

RangeMeans
*any version
1.2.3exactly 1.2.3
^1.2.31.2.3 up to, not including, 2.0.0 (for 0.x, the minor number is the breaking one)
~1.2.31.2.3 up to, not including, 1.3.0
>=1.0.0 <2.0.0all conditions must hold
1.x, 1.2.xwildcards
^1.0.0 || ^2.0.0either range

Pre-release versions only match a range that itself names a pre-release, so ^1.0.0 never picks up 2.0.0-beta.

Code

"entry": { "shared": "scripts/common.lua", "client": "scripts/client.lua", "server": "scripts/server.lua" }

shared runs on both sides first, then client or server. All three are optional: a mod made only of content needs no scripts. Scripts load other scripts with require; see Scripting.

Relationships

FieldExampleDescription
dependencies{ "a.lib": "^1.0.0" }Must be installed, enabled and in range. Starts first. If it fails, this mod does not start.
optionalDependencies{ "b.extras": "*" }Used if present and in range. Starts first when present.
conflicts{ "c.old": "<2.0.0" }This mod refuses to start alongside these.
loadAfter["d.mod"]Start after these if they are running, without requiring them.
loadBefore["e.mod"]Start before these if they are running.

Another mod's exports are only reachable through mods.get when it is listed in dependencies or optionalDependencies.

Permissions

"permissions": ["ui", "world", "http:api.example.com"]

Up to 64 entries. Each is a permission name from the permissions reference, some with an argument after a colon. Unknown permissions are reported, and calls that need them are refused. Medium and high risk permissions are shown to the player before the mod runs. See Security and permissions.

Settings

Settings are values the game keeps for your mod, always within what you declare here. Scripts read them with mod.settings.get(key) and change them with mod.settings.set(key, value).

"settings": [
  { "key": "enabled",  "type": "bool",    "label": "Enabled", "default": true },
  { "key": "speed",    "type": "number",  "label": "Speed", "default": 2.5, "min": 0, "max": 10, "step": 0.5 },
  { "key": "count",    "type": "integer", "label": "Count", "default": 3, "min": 1, "max": 20 },
  { "key": "greeting", "type": "string",  "label": "Greeting", "default": "Hello" },
  { "key": "mode",     "type": "choice",  "label": "Mode", "default": "calm",
    "options": [ { "value": "calm", "label": "Calm" }, { "value": "wild", "label": "Wild" } ] },
  { "key": "hotkey",   "type": "key",     "label": "Open window", "default": "F7" },
  { "key": "tint",     "type": "color",   "label": "Tint", "default": "#40c0ff" },
  { "key": "rounds",   "type": "integer", "label": "Rounds", "default": 5, "scope": "server" }
]
FieldDescription
keyAn identifier (letters, digits, _), up to 48 characters, unique in the mod.
typebool, number, integer, string, choice, key (a key name) or color ("#rrggbb", or "#rrggbbaa" with alpha).
label, descriptionA name and an explanation for the setting, in words players understand.
defaultMust suit the type and range.
min, max, stepFor number and integer.
optionsFor choice: { "value", "label" } entries.
scopeuser (default) is each player's own preference. server is chosen by the host and sent to every player.

Up to 64 settings. See Settings and storage.

Content

"content": { "blocks": ["content/blocks/*.json"], "maps": ["content/maps/*.json"] }

Keys are content types (see Content types). Values are lists of file patterns: * matches within a folder and ** across folders. Each matched .json file holds one definition, or an array of them. Paths inside a definition are relative to that JSON file. Start a path with / to begin at the mod root.

Files a mod may contain

The game only reads file types it understands. Anything executable is refused outright, and a package containing one is rejected.

KindExtensionsLimit (installed)Limit (downloaded from a server)
Scripts.lua2 MB each2 MB each
Data.json16 MB16 MB
Text.txt .md .csv2 MB2 MB
Pictures.png .jpg .jpeg32 MB, 8192 px per sidesame
Audio.wav .ogg .mp3256 MB64 MB
Video.mp4 .webm512 MB128 MB
Models.glb .gltf .obj .fbx (+ .bin .mtl)256 MB64 MB
Interfaces.uxml (layout) / .uss (style)1 MB1 MB
Refused.dll .exe .so .dylib .bat .cmd .ps1 .sh .vbs .js .jar .msi .scr .com .cs——

A whole mod may have up to 4096 files and 1 GB (2048 files and 256 MB when downloaded). README, LICENSE, CHANGELOG, AUTHORS and NOTICE without an extension are allowed. Files and folders whose names start with . (like .luarc.json) are ignored and never packed. File names must be portable: no .., no drive letters, no reserved Windows names, and no two paths that differ only in letter case.