Skip to main content
Glama
README.md
# 红警2素材工坊 · RA2 Asset Studio

> 一套面向《红色警戒2 / 尤里的复仇》的素材制作平台:**格式引擎 + Web 编辑器 + MCP 服务**。
> 格式层基于对 SHP Builder、VXLSE III、HVA Builder、VPL Editor、XCC Mixer 等工具的逆向分析(源码 + 真实游戏文件交叉验证)。

## 功能

| 模块 | 能力 | 状态 |
|---|---|---|
| PAL 调色板 | 768B / 6bit RGB 读写、色板编辑、**调色板动画循环预览 + art.ini 导出**、**批量调色(亮度/对比度/饱和/色相/伽马)**、动画色带自动识别、渐变/合并/最近色/比较 API | ✅ |
| SHP 精灵 | RA2/TS 读写、RLE-Zero、帧编辑、PNG 导入导出、**1x–32x 缩放 + 中键平移**、帧操作前自动保存、**8 方向图片合成 SHP**、**光照贴图(AlphaImage)** | ✅ |
| VXL 体素 | 读写、新建、**6 种工具 + 笔刷大小 + 实心矩形 + 撤销/重做 + 快捷键**、调色板点选、**一键导出(VXL+HVA+art.ini)**、保存/另存为、缩放/平移/网格/坐标/光标预览、3D 实时预览、三列/单列 | ✅ |
| HVA 动画(分层体素动画) | 读写、**矩阵逐格编辑**、**曲线拖拽改值**、**帧间补间**、**多段批量锁定/重置/只看**、复制/插入/删除帧、12 分量曲线叠加、保存/另存为;从 VXL 生成配套 HVA | ✅ |
| 图像 IO | PNG/BMP/TGA/PCX 编解码 | ✅ |
| MIX 容器 | 解析索引、提取、**打包新 MIX**(含 LMD 名单);支持嵌套 local.mix 与加密头识别 | ✅ |
| VPL 光照 | 16B头+768B调色板+32×256 重映射表,已完全解出 | ✅ |
| VXL 渲染 | 8 方向软件光栅化 → SHP 帧、法线光照、VPL 接入 | ✅ |
| Web UI | 7 个面板:总览/SHP/VXL/HVA/调色板/MIX/渲染出图 | ✅ |
| MCP | stdio + HTTP,**30 个工具**,AI 创作素材 | ✅ |
| 设置 / i18n | 快捷键自定义(19 项,含冲突检测)+ 中英双语骨架([docs/I18N.md](docs/I18N.md)) | ✅ |
| Electron 桌面版 | 独立窗口 + 中文菜单 + 便携打包(含启动器) | ✅ |

**测试**:98 项(`npm test`),覆盖真实游戏样本 ECM.shp / sqdg_w.shp / xv-24.vxl / xv-24.hva / expandmo*.mix / ra2.mix / voxels.vpl。

## 已知限制

### 能力边界(不是 bug,是设计取舍)

| 项 | 说明 | 变通办法 |
|---|---|---|
| **8 方向是近似** | 骨骼动画的 8 方向用「水平压缩 + 翻转」模拟,不是真的转 45° | 远景小单位够用;特写镜头建议逐方向单独绘制 |
| **骨骼动画适用范围有限** | 适合**步兵**和有部件的特效(旗帜/触手/机械臂);**不适合**载具(用 VXL+HVA 才自然)和爆炸/火焰/烟雾(没有可动的部件) | 载具走 VXL;爆炸走序列帧 |
| **自动拆分对「贴在一起」的部件无效** | 拆分靠连通区域检测。手臂贴着身体、两条腿贴在一起时,会被当成一整块(实测只识别出 1 块) | 手绘时部件之间留 1~2px 的缝;或用「网格模式」手动切 |
| **骨骼动画未用真实角色验证过** | 开发全程用的是合成测试图(色块拼的小人),不是真实 MOD 素材 | 需要你拿真实角色拆好部件后验证效果 |
| **风格取样只能对齐「数值」** | 能对齐颜色/明暗/颗粒感/抖动,**不能对齐笔触与形体**(那需要生成式模型) | 形体差异大时,先换素材再套风格 |
| **TMP 地形只有单块** | 只做单块 60×30 菱形地形,无多地块拼接、无额外图(extra image)、无高度编辑 | 复杂地形请用 FinalAlert 2 / 其它地形工具 |

### 技术限制

| 项 | 说明 |
|---|---|
| **AI 助手看图有偏差** | 多模态模型(deepseek-flash)对像素画**细节**识别有限:色值说不准、精确坐标分不清、部件关系看不出。已用「程序化测量(尺寸/色数/透明度/bbox)+ 引导调工具」补偿,但**复杂图仍可能误判**。<br>**建议**:问精确数字时让它调 `read_shp_info` 这类工具,不要只信它的肉眼描述。 |
| **启动偶发失败** | Electron 加载页面时可能遇到 `ERR_ABORTED (-3)`(后端刚 ready 但 TCP 还没完全稳定的竞态)。已加 3 次自动重试 + 详细错误提示,极端情况仍可能失败——关掉其它工坊窗口再试。 |
| **i18n 只有骨架** | 中英切换的框架有了,但大部分界面文案仍是硬编码中文 |
| **WebP 不支持** | 图片读取器只支持 PNG / BMP / PCX / TGA |

---

## 快速开始

```powershell
# 安装依赖(只需一次)
cmd /c "npm install"

# 编译
cmd /c "npx tsc -p tsconfig.json"

# 启动 Web 界面(自动打开浏览器)
node dist/src/cli.js web
# 或双击 start.cmd
```

浏览器访问 `http://127.0.0.1:7799`。

### 桌面版(Electron)

```powershell
# 双击 start-desktop.cmd,或:
npm run desktop
```

桌面版自带本地服务(随机空闲端口),独立窗口、中文菜单,功能与 Web 版完全一致。

> 注意:本机若设置了环境变量 `ELECTRON_RUN_AS_NODE=1`(部分开发工具会设置),直接双击 `electron.exe` 会以纯 Node 模式运行而失败。源码目录用 `start-desktop.cmd` / `npm run desktop`(已自动清除该变量)。

**界面缩放**:顶栏 `− 100% +` 或快捷键 `Ctrl +` / `Ctrl -` / `Ctrl 0`(80%–160%,自动记忆)。桌面版使用真正的页面缩放(布局会正确重排、内容不会被裁掉),Web 版退回 CSS zoom;切片/画布内缩放独立,互不干扰。

**VXL + HVA 配套规则(做 3D 单位素材)**:游戏里的 3D 单位需要 单位.vxl + 同名 单位.hva 两个文件一起放(游戏目录或打进 MIX)。HVA 定义每个 section 的位移/旋转,1 帧单位矩阵 = 静态模型。工坊里做完 VXL 后点 **「导出 HVA」**,会在同目录生成同名 .hva(section 名取自 VXL,1 帧单位矩阵),直接和 VXL 一起放游戏目录即可。

**术语对照(HVA)**:HVA = Hierarchical Voxel Animation,中文可叫「**分层体素动画**」;实际用法是「**部件动画 / 分段动画**」——把模型拆成若干段(section,比如车体、炮塔、炮管),每段在每一帧有一个 3×4 变换矩阵(位移+旋转)。文件大小公式:24 + 段数×16 + 帧数×段数×48 字节(1 段 1 帧 = 88 字节,实测游戏内最大约 11 KB)。

**渲染出图说明**:导出的 `.shp`(8 方向帧)可直接作为游戏素材使用;`.hva` 是模型动画数据,渲染时已烘进帧里,**不需要**随 SHP 输出。导出成功后会显示**绝对路径**,点「打开输出文件夹」由 Electron 直接打开目录;还可「导出 PNG 序列」在游戏外预览。

**新建文件规则**:文件名可省略扩展名(自动补 `.shp` / `.vxl`);输出目录不存在会自动创建;包含 `< > : " | ? *` 等非法字符会被拒绝。

**测试样本生成(开源 / 新机器)**:仓库不含游戏原始素材(版权原因,`.gitignore` 已排除 `test/fixtures/`)。clone 后先跑:

```powershell
node scripts/make-fixtures.js --game "你的游戏目录"
```

脚本会:① 复制游戏根目录的独立 `.vxl` / `.hva`;② 从 `ra2.mix` 内嵌的 `local.mix` 按文件头识别提取 VXL/HVA(已存在的文件不覆盖);③ 报告每个样本的来源与大小。之后 `node scripts/run-tests.js` 即可运行测试。

**受损火焰位置自动估算**:生成 art.ini 时可选「自动估算受损火焰位置」,工具按 VXL 包围盒做 2:1 等轴测投影,输出 4 组 `DamageFireOffset0~3` 建议值(建筑 HP<50% 起火动画的屏幕偏移,需按美术效果微调)。

**单位配置生成(art.ini)**:渲染出图页 →「生成 art.ini」→ 填单位 ID / 是否有炮塔 / TurretOffset / PrimaryFireFLH / 图标,右侧会显示生成的配置段并可一键复制。详细规则见 [docs/ART-INI.md](docs/ART-INI.md)。

**调色板动画与批量调色**:调色板页新增两块面板(顶部有锚点条直达)——

- **调色板动画**:指定起始索引 / 长度 / 速度(ms) / 方向(正向·反向·往返)→ 色带循环预览(暖色描边标出参与循环的区间),可「自动识别」从当前色盘推断动画色带,并把参数导出成 art.ini 段(真实键 `Palette=` / `AnimPalette=` / `Rate=`,动画参数写成可回读的 `; @palette-animation` 注释元数据)。
- **批量调色**:亮度 / 对比度 / 饱和度 / 色相 / 伽马一次性作用到整盘,可限定索引区间、跳过索引 0(透明色),支持撤销;结果不自动落盘,确认后点「保存 PAL」。

> ⚠ 原版 RA2/YR **没有调色板循环(palette cycling)的 INI 参数**:`Palette=` / `AnimPalette=` 只决定用哪张色表;水面/火焰的「动」来自 SHP 多帧或 TMP 多帧瓦片。动画参数是本工具的创作元数据,要真正「流动」请按它导出多帧 SHP(每帧旋转一次索引)并配 `Rate` / `LoopStart` / `LoopEnd` / `PingPong`。完整分析(Palette Studio 的模板格式、Gradient 语义、数据模型、API 与取舍)见 [docs/PALETTE-STUDIO.md](docs/PALETTE-STUDIO.md)。

**打包便携版**(含运行时,复制到任何机器双击即用):

```powershell
node scripts/pack-desktop.js
# 产物: release/RA2-Asset-Studio/
#   启动桌面版.cmd      ← 双击启动(已清除环境变量,推荐)
#   红警2素材工坊.lnk   ← 桌面快捷方式
#   electron.exe        ← 运行时(干净环境可直接双击)
```

便携版约 360MB(含 Electron 运行时),内置测试样本,无需安装 Node.js。

## MCP 接入(让 AI 帮你创作素材)

### stdio 通道(推荐,接入 DSH / Claude Desktop / Cursor)

在客户端配置里添加:

```jsonc
{
  "mcpServers": {
    "ra2-asset-studio": {
      "command": "node",
      "args": ["D:/lijia/Red Alert 2游戏素材制作工具/dist/src/cli.js", "mcp"]
    }
  }
}
```

### HTTP 通道

```powershell
node dist/src/cli.js mcp --http --port 7800
# 端点: http://127.0.0.1:7800/mcp
```

MCP 工具覆盖:浏览素材、读取 SHP/VXL/HVA/PAL 信息、渲染预览、SHP 像素编辑、PNG→SHP、VXL→8方向SHP、MIX 解包等。

## 目录结构

```
src/formats/     格式编解码(pal/shp/vxl/hva/image/mix/vpl)
src/engine/      渲染与组合(render/sprite/shp-io)
src/server/      HTTP 服务(REST API)
src/mcp/         MCP 服务(stdio/HTTP)
src/cli.ts       命令行入口
web/             Web UI(原生 JS + Canvas)
test/            测试(node:test)+ fixtures 真实样本
docs/            格式规格(FORMATS.md)、API 契约(API.md)、逆向报告
reference/       逆向参考资料(解压的参考源码,不参与构建)
```

## 真实样本

`test/fixtures/` 内有从本机游戏目录复制的真实素材:
- `ECM.shp`(42×20 1帧)、`sqdg_w.shp`(198×198 30帧)
- `xv-24.vxl`(180×103×66 4节)、`xv-24tur.vxl`
- `xv-24.hva`、`xv-24tur.hva`
- `unittem.pal`

### 标定资料(下一轮迭代用)

`test/output/ref-units/` 内含从 `ra2.mix → local.mix` 提取的真实单位:
- `gtnk`(灰熊)、`mtnk`(幻影)、`htnk`(天启)的 `.vxl` / `.hva`
- `MEASUREMENTS.md`:每节的尺寸 / voxelSize / det / tailer.unknown / HVA 矩阵 / 8 方向渲染包围盒

实测要点(供 `pxPerUnit` 与方向 0 朝向标定):
- 真实单位 `det = 1/12`,而 `voxelSize ≈ 0.99`(**两者不相等**,`xv-24` 是特例:det=0.8333、voxelSize=0.98)
- `MaxBounds ≠ -MinBounds`(模型原点不在包围盒中心)
- `tailer.unknown` 按 **section** 决定法线表:htnk=2(36 条 TS 法线),gtnk/mtnk=4(245 条 RA2 法线)——真实单位里两种并存

## 技术栈

- Node.js 24 + TypeScript 7(编译到 dist/,CommonJS)
- 原生 HTTP / Canvas,无前端框架
- 纯软件渲染器(体素光栅化),无 GPU 依赖
- 全部格式读写自主实现,不依赖第三方库

## 格式知识来源

以下开源工具的源码帮了大忙:

| 工具 | 作者 / 许可 | 用途 |
|---|---|---|
| **OS SHP Builder** | Boll / MPL | SHP、TMP 格式 |
| **VXLSE III** | 社区开源 | VXL 格式 |
| **HVA Builder** | 社区开源 | HVA 格式 |
| **vcf VoxelViewer** | 社区开源 | 体素渲染 |
| **VPL Editor** | 社区开源 | 光照格式 |
| **XCC 工具箱** | Olaf van der Spek | MIX 格式 |

具体出处见 [docs/FORMATS.md](docs/FORMATS.md)。

## 制作人与许可证

制作人:**GuangYun** · 许可证:MIT(见 [LICENSE](LICENSE))

开源计划与 GitHub 上传步骤见 [docs/OPEN-SOURCE-ROADMAP.md](docs/OPEN-SOURCE-ROADMAP.md)。

MIT(本项目自写代码);参考工具的源码/素材版权归各自作者所有,仅用于格式研究。