Skip to content

Writing the manifest

Status: Implemented. clight check, the loader and the website validate the manifest. Some accepted fields are not acted on yet; they are marked planned below and in clight.mod.json manifest schema (schema 1).

Every mod has a clight.mod.json at the root of its package. The complete field reference, with types and the version-range syntax, is clight.mod.json manifest schema (schema 1). This page is the practical companion: which fields matter for which kind of mod, and the mistakes clight check catches most often.

Minimal manifests

A data mod

{
  "schema": 1,
  "id": "better_loot",
  "version": "1.0.0",
  "name": "Better Loot",
  "license": "MIT",
  "api": 1,
  "side": "server",
  "sync": "server_only",
  "runtime": { "type": "data" }
}

A Lua server plugin

{
  "schema": 1,
  "id": "arena_games",
  "version": "3.0.1",
  "name": "Arena Games",
  "license": "Apache-2.0",
  "api": 1,
  "side": "server",
  "sync": "server_only",
  "runtime": { "type": "lua", "entry": "scripts/main.lua" }
}

A client-only mod in WASM

{
  "schema": 1,
  "id": "mini_map",
  "version": "0.4.0",
  "name": "Mini Map",
  "license": "MIT",
  "api": 1,
  "side": "client",
  "sync": "client_only",
  "runtime": { "type": "wasm", "entry": "bin/mini_map.wasm" }
}

A content mod in C++ (WebAssembly)

{
  "schema": 1,
  "id": "ruby_tools",
  "version": "1.2.0",
  "name": "Ruby Tools",
  "license": "MIT",
  "api": 1,
  "game": ">=26.3 <26.4",
  "side": "both",
  "sync": "required",
  "runtime": { "type": "wasm", "entry": "bin/ruby_tools.wasm" },
  "depends": { "mana_core": "^2.0.0" }
}

The same .wasm runs on every platform, sandboxed.

Choosing side and sync

These two fields decide where your code loads and what multiplayer requires. They are explained in Sides and environments and, for publishing decisions, in Server-required vs client-only mods.

Your mod side sync
Minimap, HUD, zoom, client QoL client client_only
Plugin for vanilla players (chat, ranks, minigames) server server_only
Content mod (new blocks, items) both required (or optional: mod content falls back to vanilla blocks and items)
Server mod with an optional client add-on (extra HUD when installed) both optional
Data-only recipes, loot, enchantments server (or both with assets) server_only

Fields people forget

Field Why it matters
license Required. Users and modpack authors need to know what they may redistribute. Use an SPDX id.
api Required. The CLight API major your mod is written for: 1. The mod loads on every 1.x engine; probe features added in later minor versions with cl.has() / cl_core_has() (ABI stability and API versioning). The older "clight": ">=1.0 <2" range string still loads (with a deprecation warning; 0.x ranges from the v0.1 drafts mean API 1).
game Set it when your logic depends on vanilla behaviour of a specific game version.
permissions Every capability your code uses. Missing ones fail at run time with CL_E_PERMISSION_DENIED; unused ones make users suspicious. The website shows them on the version page.
depends, optional, breaks, load Dependencies and load order (Versioning and dependencies)
api_version Optional (API 1.19). The API versions your mod needs, as a range: ">=1.12" or just "1.12" (the same as >=1.12 <2). Older engines refuse the mod with a clear CLL-2003 message; an upper bound inside the major is ignored with a warning (ABI stability and API versioning).
former_ids / id_aliases Optional (API 1.19). After renaming your mod or its blocks / items / entity types: the old mod ids and "old:id": "new:id" pairs keep dependencies, cl_mod_is_loaded and id lookups working.
limits.memory_mb Raise only with a reason (default 256, 1 to 4096 for WASM and Lua; clight check reports values outside that range). tick_ms and frame_ms are planned.
hot_reload true turns on Lua hot reload outside dev mode
mixins Mixins registered before the entry point (Mixins)
threading, vanilla_clients, provides, services, packs, critical Accepted, planned (not acted on yet)

Display text

name and description are shown on the Mods screen and, for uploads, read by the website. Translating them through lang files is planned. On the website, the project’s own name, summary and description are what players see.

Keeping the manifest in sync with the build

  • version in the manifest is the source of truth. clight build and CMake read it; your code gets it at runtime from cl_mod_version(). Don’t duplicate it elsewhere.
  • clight build fills nothing in automatically; it packs the manifest as it is.
  • The JSON Schema (clight-sdk/schema/clight.mod.schema.json) gives completion and validation in editors: map it to clight.mod.json in your editor’s JSON settings (or add a "$schema" key with the schema’s path to the file; CLight ignores it).