跳到正文

制作模组

用一个 JSON 文件加入新单位、建筑和升级等级:格式说明、如何在游戏里测试,以及如何发布到模组仓库。

《钢铁浪潮》支持模组。一个模组可以加入单位、建筑和升级等级——写在一个 JSON 文件里,若你画了图,精灵图放在旁边——游戏在“设置 → 模组”里列出它们,旁边就是发布所有人模组的官方仓库。模组不能改动规则、界面或游戏自带的单位:它只做加法,而它加的一切都会随它一起关闭。这正是模组能放心安装、存档能放心读取的原因。

完整参考就在本页,由游戏校验模组时用的同一份表格生成。如果你更愿意把活交给编程智能体,页面底部的说明会告诉它需要知道的一切。

模组是什么

一个文件夹:

my-mod/
  mod.json          清单:模组的身份、它的定义,以及定义所用的精灵图
  sprites/*.png     可选的图像
  README.md         可选

mod.json 先给模组命名,再列出它的定义(每个是一个单位、一座建筑或一个升级等级),如果模组自带图像,再列出精灵图。定义可以带的每个字段都是游戏自身单位定义的字段,所以你能在这个百科页面上读到的任何数值,模组都能设定。

五分钟做出第一个模组

最简单的路径是 extends:从一个原版定义出发,只覆盖你想改的。下面就是一个完整可用的模组——后期用的重型野牛:

{
  "format": "steel-tide-mod",
  "v": 1,
  "id": "bison-ii",
  "name": [
    "Bison II",
    "野牛 II"
  ],
  "version": "1.0.0",
  "author": "you",
  "description": [
    "A heavier Bison for the late game.",
    "后期用的重型野牛。"
  ],
  "defs": [
    {
      "id": "bison2",
      "extends": "mbt",
      "name": [
        "Bison II",
        "野牛 II"
      ],
      "desc": [
        "Thicker plate, a bigger gun, and a bigger bill.",
        "更厚的装甲、更大的炮,也更贵。"
      ],
      "tier": 3,
      "cost": 520,
      "hp": 1100,
      "speed": 52,
      "requires": [
        "radar"
      ],
      "weapons": [
        {
          "id": "cannon",
          "cls": "cannon",
          "dmg": 90,
          "reload": 2,
          "range": 5,
          "splash": 12,
          "turret": true,
          "muzzleOffset": 23
        }
      ],
      "aiWeight": 2
    }
  ]
}
  1. 把它保存为 mod.json,放进一个名为 bison-ii 的文件夹。
  2. 在游戏里打开“设置 → 模组”,点打开文件夹…(或者把文件夹压缩后点上传文件…)。游戏会告诉你加载了什么——或者列出哪里有问题,每一条都带着它在 mod.json 里的路径。
  3. 开一局遭遇战。野牛 II 会从二级战车工厂开始出现在生产列表里,因为野牛就在那里生产;它用野牛的图像;而且 AI 也会造它,因为定义带了 aiWeight

extends 会复制一切——图像、武器、造价、生产位置——你写出的每个字段都替换掉复制的值。不写 weapons 就保留基础单位的武器;写自己的列表就整个替换。

测试

  • 打开文件夹…就是编辑循环。在 Chrome 和 Edge 里游戏会记住这个文件夹,改完 mod.json 后在该模组那一行点重新读取即可生效。其他浏览器里重新选一次文件夹。
  • **上传文件…**接受文件夹的压缩包,或者 .steel-tide-mod 文件(内嵌了精灵图的清单——转换器输出的就是这种)。
  • **从网址添加…**和 ?mod= 接受通过网络提供的模组:npx serve --cors my-mod,然后打开 https://play.steelti.de/?mod=http://localhost:3000/——每次启动都会重新获取,刷新页面就能看到修改。
  • “开发者工具 → 展示台”(开发者模式:连点版本号五次)会把每个单位和建筑,包括你的,摆在同一张地图上,不用建造就能看图像、看开火。
  • 控制台(反引号键)里 give <id> 可以给出任何定义。

模组适用于遭遇战和战役。联机对战始终不含模组——服务器的单位表是原版的。存档会记住制作时启用的模组,缺了它们就无法读取。

更进一步

一个自带图像、带防御建筑、并为发电厂线加上第四级的模组:

{
  "format": "steel-tide-mod",
  "v": 1,
  "id": "ironworks",
  "name": [
    "Ironworks",
    "铁工厂"
  ],
  "version": "1.0.0",
  "author": "you",
  "description": [
    "A hover tank, a bunker and a fusion plant.",
    "一辆悬浮坦克、一座碉堡和一座聚变电站。"
  ],
  "license": "CC-BY-4.0",
  "defs": [
    {
      "id": "ironworks-hover",
      "name": [
        "Skimmer Hover Tank",
        "掠行悬浮坦克"
      ],
      "desc": [
        "Fast, thin-skinned, rockets.",
        "快、皮薄、打火箭。"
      ],
      "kind": "unit",
      "domain": "ground",
      "tier": 2,
      "cost": 260,
      "hp": 320,
      "armor": "light",
      "speed": 110,
      "turnRate": 5,
      "radius": 9,
      "trail": "tire",
      "weapons": [
        {
          "id": "pods",
          "cls": "rocket",
          "dmg": 16,
          "reload": 2.2,
          "range": 4.5,
          "burst": 4,
          "burstDelay": 0.1,
          "splash": 10,
          "spread": 14
        }
      ],
      "producedBy": [
        "factory2",
        "factory3"
      ],
      "aiWeight": 1
    },
    {
      "id": "ironworks-bunker",
      "name": [
        "Bunker",
        "碉堡"
      ],
      "desc": [
        "A gun pit that takes a beating.",
        "扛打的火力点。"
      ],
      "kind": "building",
      "cost": 380,
      "hp": 1600,
      "fw": 2,
      "fh": 2,
      "power": -3,
      "vision": 8,
      "weapons": [
        {
          "id": "gun",
          "cls": "autocannon",
          "dmg": 22,
          "reload": 0.5,
          "range": 5,
          "turret": false,
          "targets": [
            "ground",
            "ship"
          ]
        }
      ]
    },
    {
      "id": "ironworks-fusion",
      "name": [
        "Fusion Plant",
        "聚变电站"
      ],
      "desc": [
        "The plant line's fourth level.",
        "发电厂线的第四级。"
      ],
      "extends": "power3",
      "upgradeOf": "power3",
      "cost": 2200,
      "hp": 2600,
      "power": 500,
      "upgradeCost": 1100,
      "upgradeTime": 60,
      "requires": [
        "radar",
        "reactor"
      ]
    }
  ],
  "sprites": [
    {
      "key": "u.ironworks-hover",
      "file": "sprites/u.ironworks-hover.png",
      "frames": 1,
      "rotated": true,
      "fw": 24,
      "fh": 26
    },
    {
      "key": "u.ironworks-bunker",
      "file": "sprites/u.ironworks-bunker.png",
      "frames": 1
    }
  ]
}

计量单位

一格是 32 个世界像素。speed 和弹药 speed 是世界像素/秒;rangeminRangevisionsonarstealthdetectrepairRangeinterceptRange 以格计;radiussplashspreadmuzzleOffset 以世界像素计;所有时间都是秒。作为参照,野牛主战坦克 的造价 280、生命 620、速度 60、半径 10,主炮每 1.8 秒 60 伤害、射程 4.6;侦察车 造价 60、生命 150、速度 120;战车工厂 占地 3×3、生命 1500、耗电 8。

在哪里生产

  • 单位会加入 producedBy 中各建筑的生产列表。不写的话,加入其移动域的生产线,从它的等级起:二级地面单位出现在二级和三级战车工厂,一级舰船出现在每座造船厂。用了 extends,就在基础单位的生产处生产。
  • 建筑builtBy 中的单位建造——不写就是工程车。带 produces 列表的建筑就是工厂;单位在 producedBy 里写了一座普通建筑,也会把它变成工厂。
  • 升级等级是带 upgradeOf 的建筑:被指名的建筑获得一个升级按钮,花 upgradeCost、用 upgradeTime 秒变成这个定义,而这个定义永远不能直接放置。一座建筑只有一个下一级,所以 upgradeOf 可以指向原版某条线末端的建筑(power3factory3extractor3gatlingcannonturret2samsiteinterceptor2radarrepairtowerreactornukesilo),或者本模组的另一个定义。
  • requires 列出建造前必须存在的建筑,就像 T3 需要雷达站一样。

图像

定义用 sprite(主体)和 turretSprite(旋转部件)里的图集键来绘制。三种填法:

  1. **什么都不给。**没有精灵图的定义会画成阵营色的简单占位图,大小按定义——图还没画好,模组就能玩。
  2. 借用。"sprite": "u.mbt", "turretSprite": "tur.mbt" 用野牛的图像;extends 继承基础单位的图像。
  3. **自己画。**每张精灵图一个 sprites 条目:一张 PNG(WebP 和 JPEG 也行),frames 帧动画从左到右横向排列,等距、无缝隙。主体的键是 u.<id>,炮塔的键是 tur.<id>,模组不能占用原版的键。

车体、炮塔以及一切会转向的东西都是一张朝上的图"rotated": true——游戏会烘焙 24 个朝向。fw/fh 是这张图在游戏内的世界像素尺寸(坦克车体约 24×24;按 2–4 倍画,加载器会重采样)。pivotX/pivotY 把旋转枢轴放到炮塔座圈上。

建筑是不旋转的帧序列,以略带南向倾斜的俯视角绘制:占地是帧底部 fw×32 × fh×32 像素的区域,上面多出的部分会遮住后方地形。宽、高和锚点会按定义的占地自动确定。

阵营色是品红:用 #FF66FF、#FF00FF 和 #990099 涂阵营色部件,其他地方不要用品红;游戏会按玩家重新着色。生成的图片在加载时会被清理——去背景、对齐帧、冻结静态像素——所以透明背景最好,但不是必须。

AI

AI 对手会按 aiWeight 生产模组单位,量表和原版一致(野牛是 3,侦察车 1),前提是 requires 已满足。不写就永远不造。建筑和升级等级只有你自己会用。

参考

表格之外的字段会被忽略并给出提示;超出范围的数字是错误。

mod.json

字段类型必填默认含义
formatstring必填固定为 "steel-tide-mod"
vinteger 1–1必填格式版本,1
idid必填模组 id:小写字母、数字和 `-`,也是它在仓库中的文件夹名
nametext必填模组列表中显示的名称
versionstring必填如 `1.0.0`;仓库版本更新时游戏会提示更新
authorstring作者
descriptiontext一两句话的介绍
homepagestring主页链接
licensestringCC-BY-4.0模组许可证(SPDX 标识)
minGamestring所需的最低游戏版本
defsdef[]必填单位、建筑与升级等级
spritessheet[]各定义使用的精灵图(见下)
files{ path: dataURL }仅单文件形式:按路径内嵌的图片(data URL)

namedescription 以及定义的 name/desc 都是文本:一个字符串(两种语言共用)、["English", "中文"],或 { "en": "…", "zh": "…" }

定义(defs[]

字段类型必填默认含义
idid必填在所有模组和原版中唯一;通用名字前加上模组 id 前缀
nametext必填HUD 中显示的名称
desctext""提示中的描述
extendsid要复制的原版定义 id(或本模组中前面的定义),再逐字段覆盖;继承其图像和生产位置
kindunit | building必填单位或建筑(除非 `extends` 已说明,否则必填)
domainground | ship | air仅单位ground移动域;潜艇是带 `underwater` 的 `ship`
tierinteger 1–31出现的工厂等级与徽标
costnumber 0–99999必填金属造价
buildTimenumber 0–3600cost ÷ 14满电力下的建造秒数
popinteger 0–501 for a unit, 0 for a building占用人口
hpnumber 1–1000000必填生命值
armorlight | medium | heavy | ship | sub | air | structureby domain武器倍率所针对的装甲类型
speednumber 0–1000仅单位60世界像素/秒(一格 32)
turnRatenumber 0–50仅单位3.5弧度/秒
visionnumber 0–648视野(格)
radiusnumber 1–2009, or the footprint碰撞半径(世界像素)
weaponsweapon[][]武器列表(见下);空列表即无武装
fwinteger 1–8仅建筑2占地宽度(格)
fhinteger 1–8仅建筑2占地高度(格)
producedByid[]仅单位the line for its domain, from its tier up加入哪些建筑的生产列表(原版或本模组的)
producesid[]仅建筑工厂:可生产的单位
builtByid[]仅建筑["engineer"]可建造它的工程单位
buildsid[]仅单位工程单位:可建造的建筑
buildRatenumber 0–10000仅单位工程单位:每秒建造量
powernumber -10000–100000正为发电,负为耗电
metalRatenumber 0–1000仅建筑每秒金属(采矿场)
needsDepositboolean仅建筑必须建在矿点上
repairRangenumber 0–64仅建筑维修光环范围(格)
repairRatenumber 0–10000仅建筑每目标每秒维修量
repairTargetsinteger 1–50仅建筑同时维修的目标数
upgradeOfid仅建筑作为哪座建筑的下一等级;那座建筑获得升级按钮
upgradeCostnumber 0–99999仅建筑cost − the source's cost配合 `upgradeOf`:升级价格
upgradeTimenumber 0–3600仅建筑buildTime配合 `upgradeOf`:升级秒数
requiresid[]建造前必须存在的建筑 id
nukeCapacityinteger 0–10发射器:可储存的弹头数
nukeCostnumber 0–99999发射器:每枚弹头的金属
nukeTimenumber 0–3600发射器:每枚弹头的秒数
interceptRangenumber 0–64拦截:范围(格)
interceptMaginteger 1–200拦截:备弹数
interceptReloadnumber 0.05–600拦截:每发补充秒数
interceptMuzzleOffsetnumber 0–200拦截:发射器长度(世界像素)
transportCapinteger 1–50仅单位运输载具:载重
landsForCargoboolean仅单位装卸时降落的运输机
cargoWeightnumber 0–50仅单位pop占用的载重
underwaterboolean仅单位潜艇:仅声呐可见
sonarnumber 0–64仅单位声呐范围(格)
stealthnumber 0–64仅单位仅在敌方此距离内可见
detectnumber 0–64仅建筑在此范围内揭示隐形
hoversboolean仅单位悬停而非盘旋的飞行器
altitudenumber 0–64仅单位12飞行器的绘制高度(像素)
fireOnMoveboolean仅单位移动时持续开火
trailtread | tire | wake仅单位by domain留下的痕迹
spritestringthis mod's u.<id> sheet, else the base's art主体图像键:本模组的精灵图,或借用原版的键
turretSpritestringthis mod's tur.<id> sheet, else the base's (when its art is kept)旋转部件的图像键(若有)
aliasesstring[]控制台 `give` 接受的别名
aiWeightnumber 0–10仅单位0AI 生产它的倾向——野牛是 3,侦察车 1;0 为从不

没有 extends 时的默认值:单位是 domain: "ground"tier: 1pop: 1speed: 60turnRate: 3.5vision: 8radius: 9,装甲按移动域(地面 medium、舰船 ship、空中 air),陆地留履带痕、海上留尾迹;建筑是 fw: 2, fh: 2armor: "structure"power: 0pop: 0buildTime 默认为造价 ÷ 14 秒。

武器(defs[].weapons[]

字段类型必填默认含义
idstringw1, w2…武器名
clsmg | autocannon | cannon | at | he | rocket | navgun | ashm | torpedo | aa必填设计用途——决定装甲倍率表中的行
dmgnumber 0–100000必填每次命中伤害
reloadnumber 0.05–600必填两次射击/齐射间隔秒数
rangenumber 0.5–64必填射程(格)
minRangenumber 0–64最小射程(格)
projectilebullet | shell | missile | rocket | bomb | torpedo | flakby class弹药样式
speednumber 1–5000by projectile弹速(世界像素/秒)
targets(ground | ship | sub | air)[]by class可攻击目标:ground、ship、sub、air
mult{ armour: number }按装甲类型覆盖倍率
splashnumber 0–500溅射半径(世界像素)
burstinteger 1–32每次齐射发数
burstDelaynumber 0–5齐射内各发间隔秒数
homingboolean弹药追踪目标
interceptableboolean可被拦截
arcboolean抛物线弹道(火炮)
turretbooleantrue when the def has a turretSprite由旋转部件发射
muzzleOffsetnumber 0–200枢轴到炮口距离(世界像素)
spreadnumber 0–200最大射程处的散布(世界像素)
friendlyFireboolean溅射也会伤及己方
soundmg | autocannon | cannon | missile | flak | arty | rocket | torpedo | bombby class开火音效

伤害 = dmg × 装甲倍率表中该武器类型对目标装甲的格子,mult 可覆盖单个格子。克制体系解释了各类型;倍率表如下:

武器轻甲中甲重甲建筑舰船潜艇飞行器
侦察车
×1.50×0.80×0.40×0.35
野狼轻型坦克
×1.50×1×0.50×0.50×0.70
野牛主战坦克
×0.60×1.30×1×0.80×0.90
猛犸重型坦克
×0.60×1.30×1.10×1×0.90
蝰蛇反坦克车
×0.40×1.10×1.80×0.70×1
防空炮车
×1
猎鹰防空导弹车
×1
雷霆榴弹炮
×1.20×1×0.75×1.60×1
风暴火箭炮
×1.20×1×0.75×1.60×1
火蜥蜴温压炮车
×1.20×1×0.60×1.60×1
炮艇
×1.50×1×0.50×0.50×0.80
导弹艇
×1.60
神盾护卫舰
×1×1×0.75×0.75×1×1
虎鲸驱逐舰
×1×1.10×0.80×0.80×1×1.90
梭鱼潜艇
×1.30×1.20
君王战列舰
×1.20×1×1×1.60×1.20
海妖巡航导弹潜艇
×1.20×1×0.75×1.60
猎隼战斗机
×1
眼镜蛇武装直升机
×0.60×1.10×1.80×0.80×1
霹雳攻击机
×1.40×1.40×0.90×0.70×0.90
信天翁反舰攻击机
×1.70
秃鹫轰炸机
×1.20×1.20×1×1.60×1.10
幽灵炮艇机
×1.20×1.20×1.10×1×1
幽魂隐形轰炸机
×1×0.90×0.60×1.60×1
鸬鹚反潜直升机
×0.90×1.80
机枪塔
×1.50×0.80×0.40×0.30×0.60×0.70
加特林炮塔
×1.50×0.90×0.50×0.30×0.70×0.80
加农炮塔
×0.60×1.30×1.10×0.60×1
要塞重炮
×0.60×1.30×1.20×0.60×1.10
防空炮塔
×1
防空导弹阵地
×1

精灵图(sprites[]

字段类型必填默认含义
keystring必填主体用 `u.<id>`,旋转部件用 `tur.<id>`;不可与原版键重名
filestring必填图片路径,相对 mod.json(PNG、WebP 或 JPEG)
framesinteger 1–641动画帧数,横向排列
fwnumber 4–512the footprint (a building) or the image游戏内帧宽(世界像素)
fhnumber 4–512游戏内帧高(世界像素)
rotatedboolean一张朝上的图;游戏烘焙 24 个朝向(车体、炮塔)
pivotXnumber 0–10.5旋转枢轴(帧宽比例)
pivotYnumber 0–10.5旋转枢轴(帧高比例)
anchorYnumber 0–512顶部到占地中心的像素(高建筑)
mount[x, y]主体:炮塔安装位置 `[fx, fy]`
fpsnumber 0–60动画速度
teamsbooleantrue按阵营重着色品红部分
ssinteger 1–4超采样倍率;留空由游戏决定
fitFootprintboolean缩放内容以填满帧
animRegion[x0, y0, x1, y1]动画所在区域 `[x0, y0, x1, y1]`(比例);其余部分冻结
stabilizebooleantrue对齐漂移的帧
freezeStaticboolean冻结几乎不变的像素
stripBgboolean强制开启/关闭背景去除
bgMinLumanumber 0–255仍视为背景的最亮颜色
artifactCleanupboolean清理背景去除后的杂点

发布

模组仓库是公开的 rivertwilight/steel-tide-mods:每个模组是 mods/<id>/ 下的一个文件夹,游戏和本站列出其中的全部内容。

  1. Fork 仓库,把你的文件夹加为 mods/<id>/——文件夹名就是模组的 id
  2. 运行 node tools/check.mjs mods/<id>。它会打印游戏会报的每一个错误,并把文件夹和已发布的所有模组对照检查:id 是全局的,所以通用的词要加上模组 id 前缀(用 ironworks-bunker,不用 bunker)。
  3. 提交 Pull Request。CI 会跑同样的检查;合并后索引重建,模组就出现在游戏的仓库列表和模组页面上。
  4. 每次改动都提升 version。游戏会向装了该模组的人提示更新。

模组按清单里写的许可证发布(不写则为 CC-BY-4.0)。只发布你有权使用的图像。

转换 Rusted Warfare 模组

转换器接受一个 Rusted Warfare 自定义单位模组——.rwmod、压缩包或单位文件夹——输出一个钢铁浪潮模组:.ini 变成定义,图片变成精灵图,绿色阵营色变成品红。造价、生命、速度和射程会按比例缩放,使 RW 的坦克接近野牛的水平(也可以选择逐单位忠实换算)。它在浏览器里运行,不上传任何东西。转换后请检查清单:特效、动画、护盾和能量在这里没有对应物。

给编程智能体

模组仓库自带一个技能(skill)——完整格式、如何测试模组、如何发布,按 Claude Code、Cursor、Codex 等智能体读取的形式写好。用 skills 安装:

npx skills add rivertwilight/steel-tide-mods --skill steel-tide-mods-guideline

然后让你的智能体做一个模组。在仓库的克隆里工作时,智能体会读到同样内容的 AGENTS.md;能读网址的工具也可以取 steelti.de/mods/AGENTS.md 的纯文本。