Skip to content

RFC: WebGAL 定制引擎描述文件规范 (WebGAL Engine Manifest) #762

@A-kirami

Description

@A-kirami

RFC: WebGAL 定制引擎描述文件规范

版本 创建日期 修订日期 作者 摘要
2.0 2025-2-5 2025-2-5 Akirami 定义 WebGAL 定制引擎描述文件规范,用于描述和识别 WebGAL 定制引擎。

1. 摘要

本提案旨在为 WebGAL 视觉小说引擎的第三方定制发行版(以下简称"定制引擎")引入一个标准化的描述文件(命名为 webgal-engine.json)。该文件以机器可读的格式(JSON)唯一地定义和描述一个 WebGAL 定制引擎项目,解决当前引擎分发、识别、管理和维护中遇到的关键问题。

2. 动机与背景

WebGAL 的开放性和可扩展性催生了大量优秀的定制引擎(如 MyGO、BandoriCraft 等)。然而,随着生态的发展,以下问题日益凸显:

  1. 识别困难:工具软件(如第三方的 WebGAL 编辑器)无法以编程方式区分官方引擎和定制引擎,以及不同定制引擎之间的差异。
  2. 版本混乱:定制引擎有自己的版本迭代节奏,但缺乏机器可读的版本信息,导致兼容性检查和更新管理异常困难。
  3. 归属不明:优秀的定制引擎由不同的开发者或团队维护,他们的贡献需要被清晰地标识和链接,以给予其应有的荣誉并方便用户寻求支持。
  4. 信息分散:引擎的关键信息(如所基于的 WebGAL 官方引擎版本、README、主页)散落在各处,用户和工具需要手动查找,效率低下。

引入一个标准的描述文件可以一劳永逸地解决上述问题,为工具链开发和生态系统的有序发展奠定基础。

3. 设计目标

  • 机器可读:文件格式必须为 JSON,便于各种工具和脚本解析。
  • 人类可读:字段名称应清晰、直观。
  • 简单易用:开发者只需填写一个文件,即可获得巨大收益。
  • 可扩展性:规范应允许在未来添加新的字段,同时保持向后兼容。
  • 明确性:每个字段的含义和格式都必须有明确的定义,避免歧义。
  • 标准化:参考业界标准(如 npm package.json),保持一致性。

4. 规范详情

4.1. 文件名称与位置

  • 文件名:必须为 webgal-engine.json
  • 文件位置:必须位于定制引擎项目的根目录下。

4.2. 文件格式

  • 文件必须是一个有效的 JSON 文件。
  • 编码必须为 UTF-8

4.3. 字段定义

下表详细描述了 webgal-engine.json 文件中所有可能的字段。

字段名 数据类型 是否必需 描述与示例
name string 引擎的唯一标识名称。应使用短横线命名法(kebab-case),例如 "webgal""mygo-engine"
version string 引擎的版本号。强烈建议遵循语义化版本 2.0.0 规范(主版本号.次版本号.修订号),例如 "4.5.18"
type string 引擎类型。必须是以下值之一:
"official" - WebGAL 官方引擎,由 OpenWebGAL 团队维护
"custom" - 基于 WebGAL 的定制引擎或分支版本,由第三方维护
webgalVersion string 此定制引擎所基于的 WebGAL 官方引擎的版本。必须是一个有效的语义化版本字符串。
注意:对于官方引擎(type: "official"),此值应与 version 字段相同。
description string 引擎的默认描述文本(通常为主要语言),说明其特点、功能等。示例:"界面美观、功能强大、易于开发的全新网页端视觉小说引擎"
descriptions object 其他语言的描述。键为语言代码(如 "en", "ja", "ko"),值为对应语言的描述文本。
示例{"en": "A brand new web Visual Novel engine", "ja": "全く新しいウェブビジュアルノベルエンジン"}
author stringobject 引擎的主要作者/创建者。
字符串格式(推荐):"Name <email> (url)",其中 email 和 url 可选。
示例"Mahiru <Mahiru_@outlook.com>"
对象格式{"name": "Mahiru", "email": "Mahiru_@outlook.com", "url": "https://..."}
参考 npm package.json 的 author 字段。
contributors array 贡献者列表。每个元素可以是字符串或对象,格式同 author 字段。
示例["Person A <a@example.com>", {"name": "Person B", "email": "b@example.com"}]
license string 强烈建议 引擎的许可证标识符(SPDX License Identifier)。例如 "MPL-2.0", "MIT", "GPL-3.0"
注意:WebGAL 官方引擎使用 MPL-2.0 许可证,定制引擎必须遵守相应的许可证要求。
icon string 引擎图标的文件路径,相对于本描述文件所在目录。支持的格式建议为 PNG、WEBP、JPG、SVG 或 ICO,比例为方形。示例:"icons/icon-512.png"
readme string 默认 README 文档的文件路径,相对于本描述文件所在目录。通常为 "README.md"
readmes object 其他语言的 README 文件路径。键为语言代码,值为文件路径(相对路径)。
示例{"en": "README_EN.md", "ja": "README_JP.md"}
urls object 相关链接的集合对象。所有值都必须是完整的 URL 字符串。常用的键包括:
homepage - 项目主页
repository - 源代码仓库
bugs - 问题反馈页面
documentation - 文档站点
changelog - 更新日志
demo - 在线演示
discord / qq - 社区链接
示例{"homepage": "https://...", "repository": "https://...", "bugs": "https://..."}
keywords array 关键词数组,用于搜索和分类。可以包含功能特性、技术栈、主题等。
示例["visual-novel", "galgame", "mygo", "bangdream"]
live2dSupport boolean 是否已包含 Live2D 运行库。
false - 引擎支持 Live2D 但未包含运行库(需手动安装)
true - 已内置 Live2D 运行库,开箱即用
spineSupport boolean 是否已包含 Spine 运行库。
false - 引擎支持 Spine 但未包含运行库(需手动安装)
true - 已内置 Spine 运行库,开箱即用

4.4. 字段使用说明

4.4.1. 多语言支持

对于 description/descriptionsreadme/readmes

  • 单语言引擎:只需填写单数字段(description, readme
  • 多语言引擎:填写单数字段作为默认值,使用复数字段提供其他语言版本

工具解析逻辑:

// 获取描述
function getDescription(engine, userLang) {
  return engine.descriptions?.[userLang] || engine.description || "No description";
}

// 获取 README
function getReadme(engine, userLang) {
  return engine.readmes?.[userLang] || engine.readme || null;
}

4.4.2. 作者信息格式

authorcontributors 字段支持两种格式:

简写字符串格式(推荐用于手写):

"Name <email> (url)"

其中 <email>(url) 都是可选的。

对象格式(适合程序生成):

{
  "name": "Name",
  "email": "email@example.com",
  "url": "https://example.com"
}

4.4.3. 官方引擎的特殊说明

对于 WebGAL 官方引擎:

  • type 字段必须设为 "official"
  • webgalVersion 字段值应与 version 字段值相同

4.5. 完整示例

4.5.1. 官方 WebGAL 引擎

{
  "name": "webgal",
  "version": "4.5.18",
  "type": "official",
  "webgalVersion": "4.5.18",
  "description": "界面美观、功能强大、易于开发的全新网页端视觉小说引擎",
  "descriptions": {
    "en": "A brand new web Visual Novel engine with a beautiful interface, powerful features, and easy development",
    "ja": "美しいインターフェース、強力な機能、簡単な開発を備えた全く新しいウェブビジュアルノベルエンジン"
  },
  "author": {
    "name": "Mahiru",
    "email": "Mahiru_@outlook.com"
  },
  "license": "MPL-2.0",
  "icon": "icons/icon-512.png",
  "urls": {
    "homepage": "https://openwebgal.com",
    "repository": "https://github.com/OpenWebGAL/WebGAL",
    "bugs": "https://github.com/OpenWebGAL/WebGAL/issues",
    "documentation": "https://docs.openwebgal.com",
    "demo": "https://demo.openwebgal.com",
    "discord": "https://discord.gg/kPrQkJttJy"
  },
}

4.5.2. 定制引擎示例(已安装 Live2D)

{
  "name": "mygo-engine",
  "version": "2.1.0",
  "type": "custom",
  "webgalVersion": "4.5.18",
  "description": "基于 WebGAL 的 MyGO!!!!! 主题定制引擎",
  "author": "MyGO Team <team@example.com>",
  "contributors": [
    "Developer A <a@example.com>",
    "Developer B"
  ],
  "license": "MPL-2.0",
  "icon": "icon.png",
  "readme": "README.md",
  "urls": {
    "homepage": "https://github.com/example/mygo-engine",
    "repository": "https://github.com/example/mygo-engine",
    "bugs": "https://github.com/example/mygo-engine/issues"
  },
  "keywords": [
    "mygo",
    "bangdream"
  ],
  "live2dSupported": true
}

5. 向后兼容性

此规范引入的是一个新增文件,不会破坏任何现有的引擎、游戏或工具。它是一个附加的标准,而非替代性的

  • 它不要求现有引擎必须立即创建此文件。
  • 工具软件在读取此文件时,应具备良好的容错性。如果文件不存在或字段缺失,工具应回退到其原有的处理逻辑,并可以抛出警告提示用户该引擎可能未遵循最新规范。
  • 所有字段(除 nameversiontypewebgalVersion 外)都是可选的,允许渐进式采用。

6. 安全与隐私考虑

此描述文件通常随引擎代码一起公开,不包含敏感信息。作者应避免在 authorcontributors 字段中填写不愿公开的个人信息(如私人电话)。工具在解析该文件时无需特殊权限。

7. JSON Schema

为了便于验证和工具开发,建议提供一个 JSON Schema 文件(webgal-engine.schema.json):

{
  "$schema": "https://json-schema.org/draft-07/schema",
  "$id": "https://openwebgal.com/schemas/webgal-engine.json",
  "title": "WebGAL Engine Descriptor",
  "description": "Descriptor file for WebGAL custom engines",
  "type": "object",
  "required": ["name", "version", "type", "webgalVersion"],
  "properties": {
    "name": {
      "type": "string",
      "pattern": "^[a-z0-9-]+$",
      "description": "Unique engine identifier (kebab-case)"
    },
    "version": {
      "type": "string",
      "pattern": "^\\d+\\.\\d+\\.\\d+",
      "description": "Engine version (semver)"
    },
    "type": {
      "type": "string",
      "enum": ["official", "custom"],
      "description": "Engine type"
    },
    "webgalVersion": {
      "type": "string",
      "pattern": "^\\d+\\.\\d+\\.\\d+",
      "description": "Base WebGAL version"
    },
    "description": {
      "type": "string",
      "description": "Default description"
    },
    "descriptions": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "description": "Localized descriptions"
    },
    "author": {
      "oneOf": [
        {"type": "string"},
        {
          "type": "object",
          "required": ["name"],
          "properties": {
            "name": {"type": "string"},
            "email": {"type": "string", "format": "email"},
            "url": {"type": "string", "format": "uri"}
          }
        }
      ],
      "description": "Main author"
    },
    "contributors": {
      "type": "array",
      "items": {
        "oneOf": [
          {"type": "string"},
          {
            "type": "object",
            "required": ["name"],
            "properties": {
              "name": {"type": "string"},
              "email": {"type": "string", "format": "email"},
              "url": {"type": "string", "format": "uri"}
            }
          }
        ]
      },
      "description": "Contributors list"
    },
    "license": {
      "type": "string",
      "description": "SPDX license identifier"
    },
    "icon": {
      "type": "string",
      "description": "Relative path to icon file"
    },
    "readme": {
      "type": "string",
      "description": "Relative path to default README"
    },
    "readmes": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "description": "Localized README paths"
    },
    "urls": {
      "type": "object",
      "additionalProperties": {
        "type": "string",
        "format": "uri"
      },
      "description": "Related URLs (homepage, repository, bugs, documentation, etc.)"
    },
    "keywords": {
      "type": "array",
      "items": {"type": "string"},
      "description": "Keywords for search and classification"
    },
    "live2dSupported": {
      "type": "boolean",
      "description": "Whether Live2D runtime is included"
    },
    "spineSupported": {
      "type": "boolean",
      "description": "Whether Spine runtime is included"
    }
  }
}

8. 采用策略与未来展望

  1. 社区讨论:将此 RFC 在社区(如 GitHub Discussions、QQ 群、论坛等)中公布,收集反馈并进行修改。
  2. 文档化:在 WebGAL 官方文档中创建新章节,详细描述此规范。
  3. 官方实施:为 WebGAL 官方引擎创建标准的 webgal-engine.json 文件,作为参考实现。
  4. 工具开发:鼓励社区开发者基于此规范开发工具,例如:
    • 引擎包管理器:自动安装、更新引擎。
    • 引擎展示网站:自动爬取和索引所有公开的、包含此描述文件的引擎。
    • 编辑器集成:WebGAL Terre 等编辑器可以读取此文件,识别引擎类型和版本。
    • 兼容性检查工具:检查游戏与引擎的兼容性。
  5. 示范应用:为几个流行的定制引擎(如 MyGO)创建此描述文件,作为最佳实践示例。

9. 参考资料

10. 变更记录

v2.0 (2025-2-5)

  • authors 改为 author + contributors,参考 npm 标准
  • 添加 type 字段用于区分引擎类型(official / custom
  • 添加 descriptionsreadmes 字段以支持多语言
  • 添加 live2dSupportedspineSupported 字段
  • homepagerepository 等链接字段统一到 urls 对象中,参考 pyproject.toml
  • 添加 JSON Schema 定义
  • 完善字段说明和示例

v1.0 (2025-8-25)

  • 初始版本

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions