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
versionin the manifest is the source of truth.clight buildand CMake read it; your code gets it at runtime fromcl_mod_version(). Don’t duplicate it elsewhere.clight buildfills 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 toclight.mod.jsonin your editor’s JSON settings (or add a"$schema"key with the schema’s path to the file; CLight ignores it).