
增长。这就像生活一样事情越积越多也不知道从何收拾。最后导出格式不直观。Steamworks 要求的 JSON 格式与人类阅读习惯不符手动编辑容易出错。毕竟谁愿意去看那些密密麻麻的 JSON 呢这些问题在 HagiCode 项目的实际开发中都被我们遇到了。作为一个面向全球开发的 AI 编码工具我们需要为 Steam 平台维护完整的多语言内容。传统的维护方式已经无法满足需求我们迫切需要一套更高效的解决方案。其实也没什么别的办法只能自己动手了。关于 HagiCode本文分享的方案来自我们在 HagiCode 项目中的实践经验。HagiCode 是一个 AI 编码工具支持多种 AI 提供商和代码编辑器。在开发过程中我们需要为 Steam 平台维护多语言商店内容这促使我们构建了一套结构化的元数据管理系统。本文分享的多语言元数据管理方案正是我们在 HagiCode 开发中实际踩坑、实际优化出来的。如果你觉得这套方案有价值说明我们的工程实力还不错——那么 HagiCode 本身也值得关注一下。毕竟能解决问题就是好工具对吧核心概念语言与字段Steamworks 支持的语言列表相当完整涵盖了主要市场en-US, fr-FR, it-IT, de-DE, es-ES,bg-BG, cs-CZ, da-DK, nl-NL, fi-FI,el-GR, hu-HU, id-ID, ja-JP, ko-KR,nb-NO, pl-PL, pt-BR, pt-PT, ro-RO,ru-RU, zh-CN, es-419, sv-SE, th-TH,zh-TW, tr-TR, uk-UA, vi-VN其中最常用的是en-US英语、zh-CN简体中文、zh-TW繁体中文、ja-JP日语和ko-KR韩语。毕竟这些语言覆盖了主要市场先把这几个搞定了其他的也就不那么可怕了。需要维护的字段主要包括两个about详细描述支持富文本格式short_description简短描述有 300 字符长度限制作用域概念Steam 应用内容可以分为两个作用域Base App主应用内容DLC下载内容每个 DLC 有独立的内容管理这种区分很重要因为 DLC 通常需要独立的商店描述而且一个游戏可能有多个 DLC需要统一管理。就像生活一样有些东西是主要的有些是附加的但都得好好管着不然就会乱成一团。数据模型设计系统定义了清晰的数据模型来支撑多语言内容管理// 支持的 28 种语言代码const STEAMWORKS_SUPPORTED_LOCALES [en-US, fr-FR, it-IT, de-DE, es-ES,bg-BG, cs-CZ, da-DK, nl-NL, fi-FI,el-GR, hu-HU, id-ID, ja-JP, ko-KR,nb-NO, pl-PL, pt-BR, pt-PT, ro-RO,ru-RU, zh-CN, es-419, sv-SE, th-TH,zh-TW, tr-TR, uk-UA, vi-VN];// 支持的字段const STEAMWORKS_SUPPORTED_FIELDS [about, // 详细描述short_description // 简短描述];// 内容作用域type SteamworksScopeKind base | dlc;这个模型设计有几个考虑点怎么说呢其实就是想让事情变得更简单一点使用标准的语言代码格式如zh-CN而不是chinese毕竟标准的东西总是更可靠将字段类型明确列出方便未来扩展谁知道以后会不会需要更多字段呢区分作用域类型支持 Base App 和 DLC 的统一管理把事情分清楚总是好的文件存储结构内容存储在项目目录的.hagiclaw-data/steamworks-metadata/下采用层次化的目录结构.hagiclaw-data/└── steamworks-metadata/└── default-app/├── workspace.json # 工作区配置清单├── base/ # 基础应用内容│ ├── en-US/│ │ ├── about.md│ │ └── short_description.md│ ├── zh-CN/│ │ ├── about.md│ │ └── short_description.md│ └── ...└── dlc/ # DLC 内容└── turbo-engine/├── en-US/│ ├── about.md│ └── short_description.md└── ...这种结构设计有几个优点或者说至少比之前的方式好多了人类可读每个内容都是独立的 Markdown 文件可以直接编辑毕竟人眼还是更喜欢看清楚的东西版本控制友好文本文件便于追踪变更历史和对比差异这样改动过什么一目了然扩展性强添加新语言或新字段只需要创建新文件就像搭积木一样想加什么加什么结构清晰目录结构直观反映了内容的组织方式不会让人觉得混乱workspace.json存储工作区配置包含 DLC 列表和语言配置信息。毕竟有些东西还是得有个清单不然时间久了谁还记得自己放了什么。Markdown 到 BBCode 转换Steam 使用 BBCode 格式的富文本而不是标准的 Markdown。这给内容创作带来了额外的工作量——要么直接写 BBCode要么后期手动转换。HagiCode 的解决方案是让开发者用熟悉的 Markdown 创作系统自动转换为 Steam BBCode。毕竟人总是习惯于自己熟悉的东西何必强迫自己去适应那些奇怪的花括号呢。转换规则// 标题转换# HagiCode → [h1]HagiCode[/h1]## Features → [h2]Features[/h2]// 文本样式**bold text** → [b]bold text[/b]*italic text* → [i]italic text[/i]code → [code]code[/code]// 链接和图片[text](url) → [urlurl]text[/url] → [img src{STEAM_APP_IMAGE}/extras/...][/img]// 列表- item 1- item 2 → [*]item 1[*]item 2(包裹在 [list] 中)语言包装导出时需要用语言标签包裹内容wrapWithSteamLanguage(locale: SteamworksLocaleCode, bbcode: string): string {// 返回 [langenglish]...[/lang] 格式}语言代码需要映射到 Steam 的格式en-US→englishzh-CN→schinesezh-TW→tchineseja-JP→japaneseko-KR→korean这个映射关系其实也不复杂只是需要记住而已。毕竟每个平台都有自己的规矩我们只能适应了。导出格式导出的 JSON 需要符合 Steamworks 的结构要求{itemid: 1158573,languages: {english: {app[content][about]: [h1]HagiCode[/h1]\n[b]About[/b]...,app[content][short_description]: AI coding tool...},schinese: {app[content][about]: [h1]HagiCode[/h1]\n[b]关于[/b]...,app[content][short_description]: AI 编码工具...}}}关键点其实也不多只是需要记住这些格式要求罢了itemid对应 Steam AppIDlanguages下使用 Steam 的语言代码如schinese字段路径使用app[content][fieldName]格式值是转换后的 BBCode 字符串这些规则看起来有点繁琐不过习惯了也就那样。毕竟每个平台都有自己的脾气我们只能适应了。API 服务设计系统提供了完整的 REST API 来支撑多语言内容管理工作流加载工作区GET /api/steamworks/metadata返回工作区配置、所有语言和字段的内容。毕竟总得有个地方把东西都拿出来看看。保存内容POST /api/steamworks/metadata{scopeId: base-app,scopeKind: base,values: {en-US: {about: Markdown content...,short_description: Short text...},zh-CN: {about: Markdown 内容...,short_description: 简短文本...}}}保存时系统会将 Markdown 内容写入对应的.md文件。这样就不会丢失了毕竟记忆总是不可靠的。渲染预览POST /api/steamworks/metadata/preview{locale: zh-CN,field: about,content: # HagiCode\n\n这是关于...}返回 Markdown 渲染结果和 BBCode 转换结果方便预览。预览这个东西就像照镜子总得看看自己长什么样再出门吧。导出 JSONPOST /api/steamworks/metadata/export{scopeId: base-app,scopeKind: base}生成符合 Steamworks 格式的 JSON可直接导入 Steamworks 后台。这一步其实就是把所有东西打包好准备发货了。DLC 管理POST /api/steamworks/metadata/dlc // 创建PUT /api/steamworks/metadata/dlc // 更新DELETE /api/steamworks/metadata/dlc // 删除DLC 管理包括创建、更新和删除 DLC 的元数据配置。毕竟 DLC 也是内容也得好好管着。使用流程1. 访问元数据面板在 HagicLaw 工作区中打开 Steamworks Metadata 面板系统会加载当前工作区的配置和内容。一切准备工作做好了就可以开始了。2. 选择编辑作用域在左侧导航中选择 Base App 或具体的 DLC。每个作用域独立管理其多语言内容。就像整理房间一样先把东西分类然后再一个个收拾。3. 多语言矩阵编辑展开需要编辑的语言直接编辑about和short_description的 Markdown 内容。系统支持实时 Markdown 渲染预览Steam BBCode 转换预览字符计数和长度检查这些预览功能其实挺有用的至少能知道自己写出来的东西长什么样。毕竟谁也不想写了一堆东西最后发现格式全错了。4. 保存内容点击保存按钮内容会自动写入对应的.md文件。文件会被纳入 Git 版本控制便于追踪变更。保存这个动作就像把记忆写下来一样时间久了也不会忘。5. 验证检查系统会自动检查必填字段是否完整short_description是否超过 300 字符Markdown 语法是否正确这些检查能避免一些低级错误毕竟人总是会犯错的有机器帮忙看着点总是好的。6. 导出 JSON选择要导出的作用域Base App 或特定 DLC系统生成包含所有语言的 Steamworks JSON。复制 JSON 粘贴到 Steamworks 后台即可完成导入。这一步完成整个流程也就结束了。一切准备就绪只等发布了。注意事项语言代码映射系统中的en-US对应 Steam 的englishzh-CN对应schinese。这个映射关系在导出时自动处理但手动编辑 JSON 时需要注意。毕竟有些事情机器能帮你做但有些还是得自己记着。BBCode 限制Steam 仅支持 BBCode 的子集复杂的 Markdown 可能无法完美转换。建议在预览中检查转换结果。预览这东西就像照镜子总得看看自己长什么样再出门吧。图片路径图片会被转换为[img src{STEAM_APP_IMAGE}/extras/...]占位符格式。实际图片需要单独上传到 Steam 后台。图片这东西有时候确实比文字更有说服力只是上传起来稍微麻烦一点。字段验证short_description有严格的 300 字符长度限制系统会在导出前验证但建议在编辑时就注意控制长度。毕竟写太多字也没用平台只看前 300 个那就只能精简了。版本控制所有 Markdown 文件都可以纳入 Git 版本控制便于追踪变更历史和协作编辑。建议定期提交变更。版本控制就像时间机器能让你回到过去的某个时刻看看当时写了什么。DLC 管理DLC 的itemId需要与 Steamworks 后台的 DLC AppID 对应。创建 DLC 时要确保 ID 准确。ID 这种东西一旦错了就很难改所以还是小心点好。总结Steamworks 多语言元数据管理的核心挑战在于如何高效维护大量的多语言内容。通过结构化的数据模型、人性化的文件存储和自动化的转换导出流程我们可以将这个繁琐的过程转变为可管理的内容创作工作流。这套方案在 HagiCode 项目的实践中证明是有效的。我们从一个手动维护、容易出错的状态转变为一个结构化、可验证、可协作的工作流程。这不仅提高了效率也减少了人为错误。毕竟工具做好了事情也就简单了。