插件清单格式(stl-plugin.json)

stl-plugin.json 每个字段的含义,以及启动器如何校验与判断版本兼容

清单放在哪

每个插件一个文件夹,清单 stl-plugin.json 放在文件夹根目录,与主 DLL 并列。安装后的位置是:

代码
Documents\Paradox Interactive\Stellaris\plugins\
  <id>\                     文件夹名 = 插件 id
    stl-plugin.json         清单(必须)
    <你的>.dll              主 DLL(必须);它依赖的其他 DLL 放在旁边
    defaults\               设置文件的默认版本(随包,更新时被替换)
    data\                   插件自己的只读数据(可选)
    config\                 用户的设置(启动器生成;更新时保留)
    logs\                   插件写日志的地方

清单是 UTF-8 编码的 JSON,开头允许带 BOM(启动器解析前会去掉)。

一个真实的清单

stellaris-mcp 仓库的 plugin/stl-plugin.json:

JSON
{
  "schema": 2,
  "id": "stellaris-mcp",
  "name": "Stellaris MCP bridge",
  "version": "0.6.1",
  "description": "Lets AI agents read and play the game over MCP: reads engine state and posts the game's own commands. The MCP server is in mcp-server\\.",
  "dll": "stellaris_bridge.dll",
  "game": { "exe_timestamps": ["0x6ABEAA3F"] },
  "load": { "wait": "window", "delay_ms": 1500 },
  "config": [
    { "file": "stellaris_mcp.ini", "default": "defaults/stellaris_mcp.ini", "title": "Stellaris MCP", "substitute": false }
  ],
  "update": { "github": "Yidhar/stellaris-mcp", "asset": "stellaris-mcp-*.zip" },
  "homepage": "https://github.com/Yidhar/stellaris-mcp"
}

字段

下表按启动器 stl-core 中 Manifest 结构的实际定义整理:

字段必填类型说明
schema应当整数写 2;缺省为 0
id是字符串只能是 ASCII 字母、数字、-、_、.。同时是安装后的文件夹名、播放集里的引用和命令行里的名字。发布后不要改
name是字符串给人看的名字
version应当字符串点分数字版本,如 0.6.1;自动更新靠它比较新旧
description可以字符串一句话说明,显示在插件页
dll是字符串主 DLL 在插件文件夹内的相对路径;不能是绝对路径,不能含 ..
game.exe_timestamps应当字符串数组适配的 stellaris.exe 构建的 PE 时间戳,见下文
load.wait可以字符串"window"(默认):等游戏出现可见窗口;"none":进程一存在就加载
load.delay_ms可以整数满足 wait 后再等多少毫秒,默认 0
config可以数组设置文件列表,见下文
update.github可以字符串GitHub 仓库 owner/repo(也接受 https://github.com/owner/repo),有它才能自动更新
update.asset可以字符串要安装的发布附件名,* 是通配符,默认 *.zip
homepage可以字符串主页;为空时插件页链接 update.github 的仓库
seed_files不要用数组schema 1 遗留:往游戏目录写文件。仍兼容,新插件不得使用

未知字段会被忽略。不要靠这一点在清单里放自己的数据,自己的数据放 data\。

config:设置文件

JSON
"config": [
  { "file": "hello_stellaris.ini", "default": "defaults/hello_stellaris.ini", "title": "Hello", "substitute": true }
]
字段说明
fileconfig\ 里的文件名;**不能有子目录**,不能含 ..
default插件文件夹内的默认文件。config\ 里缺这个文件时,启动器从它复制一份;不写则只在文件存在时列出
title设置编辑器里显示的标题;为空时用文件名
substitute为 true 时,复制默认文件的同时把文本中的 {plugin_dir}、{config_dir} 替换成实际的绝对路径

启动器在安装、更新和每次启动前补齐 config\ 里缺的文件,**已存在的文件绝不覆盖**。config\ 里没在清单中声明的文件也会出现在设置编辑器里(排在声明的文件之后)。

exe_timestamps:版本兼容

插件通常依赖 stellaris.exe 内部的地址,游戏一更新就可能读错内存。exe_timestamps 填的是 exe 的 PE 头时间戳(IMAGE_FILE_HEADER.TimeDateStamp),每个构建都不同。用 stl status 查看当前游戏的值:

代码
> stl status
game        Cygnus v4.5.2 (9776) (…\Stellaris)
exe build   0x6ABEAA3F (2026-10-01 18:45 UTC)

启动时的判断:

情况结果
列出的构建中包含当前构建加载
列出了构建,但不含当前构建跳过,提示 made for the build 0x…, the game is 0x…
没有列出任何构建加载,不检查
dll 指向的文件不存在跳过

注意 时间戳的解析规则:带 0x 前缀按十六进制;不带前缀但含字母也按十六进制;只有数字且不带前缀时按十进制解析。解析失败的条目会被直接丢弃——如果全部写错,结果等同于“没有列出任何构建”,启动器将不做检查。请一律写成 "0x6ABEAA3F" 这样的形式。

不列构建表示“我自己检查或与版本无关”,这时 DLL 必须在运行时自行判断(如特征码找不到就停用),绝不能对未知构建盲目读写内存。手册建议两层都做:清单里列出构建,DLL 里再检查一次,因为手动注入时不会经过启动器的检查。

启动器的校验

清单不满足下列任一条,插件会被列为问题、不会加载:

  • 是合法 JSON,且含 id、name、dll;
  • id 非空,只含允许的字符;
  • dll 非空、是相对路径、不含 ..;
  • config 每项的 file 非空、不含 /、\、..;default(如有)是插件文件夹内的相对路径;
  • seed_files 的路径不越界。

此外,安装时 dll 指向的文件必须存在;从更新包或索引安装时,包里清单的 id 必须与预期相同。

编辑器里可以给 stl-plugin.json 挂上启动器手册附录 B 的 JSON Schema 获得补全,但一切以启动器的实际校验为准。