- Add cell/tile map APIs: /api/state/cell, /api/state/cells, /api/state/cells/slice, /api/state/gas - Add entity registry APIs: /api/registry/buildings, /api/registry/elements, /api/registry/techs - Add plants, rooms, mop, harvest endpoints - Rich semantic metadata: element state/category, building category/power, duplicant chore/cell - AI-friendly coordinate system with (x,y) + cell index in all responses - Build AI_KNOWLEDGE_BASE.md with building IDs, element IDs, tech trees, game mechanics - Rewrite SKILL.md with data model explanation, coordinate guide, operation patterns - Update Python tools: explore, cell, cells, slice, gas, registry subcommands - Update MOD_DEV_GUIDE.md with AI data design principles
10 KiB
10 KiB
ONI Agent Mod 开发指南
概述
本文档规定了一个与外部 Agent(AI 助手)对接的《缺氧》(Oxygen Not Included) Mod 应遵循的接口规范、约束条件和最佳实践。遵循此规范开发的 Mod 可与 oni-agent 工具链无缝协作。
1. 通信协议
1.1 传输层
- 协议: HTTP 1.1
- 地址:
127.0.0.1(仅本地回环,禁止暴露到外部网络) - 端口: 由配置文件指定(默认
23876) - 编码: 所有请求和响应均为 UTF-8
1.2 数据格式
- 所有请求和响应使用
application/json - 响应必须包含有效的 JSON
- 错误响应必须包含
error字段
// 成功响应
{ "result": "ok", ... }
// 错误响应
{ "error": "error_message" }
1.3 请求超时
- 服务端应在 5 秒内响应
- 长时间操作应排队后立即返回
{ "result": "queued" }
2. API 端点规范
2.1 健康检查
GET /health
用于 Agent 探测 Mod 是否存活。必须始终可达,不依赖游戏状态。
响应:
{ "status": "ok", "service": "mod_name" }
2.2 状态查询端点
所有状态查询为 GET 请求,路径前缀 /api/state/。
| 端点 | 返回内容 | 必需 | 新增字段 |
|---|---|---|---|
/api/state/game |
周期、复制人、世界尺寸 | 是 | gridWidth, gridHeight |
/api/state/resources |
资源列表(含分类/物态) | 是 | id, state, category |
/api/state/duplicants |
复制人详情 | 是 | x, y, cell, currentChore |
/api/state/buildings |
建筑列表 | 推荐 | cell, category, powerWatt |
/api/state/research |
科技树(含解锁列表) | 推荐 | requiredTechs, unlockedBuildings |
/api/state/geysers |
喷泉详情 | 可选 | cell, isActive, isDormant |
/api/state/alert |
当前警报 | 推荐 | clickable |
/api/state/critters |
小动物详情 | 可选 | cell, calories |
/api/state/plants |
植物列表 | 可选 | isGrown, progress, isWilting |
/api/state/rooms |
房间列表 | 可选 | 类型/格数/建筑/生物/植物 |
2.3 地图/格子数据端点
这是 AI 理解游戏世界最重要的端点。格子级数据让 AI 知道每个具体位置的状态。
| 端点 | 说明 | 参数 |
|---|---|---|
GET /api/state/cell |
单格详情 | ?x=&y= |
GET /api/state/cells |
矩形区域(批量) | ?x=&y=&width=&height= |
GET /api/state/cells/slice |
行或列扫描 | ?axis=x&index=&start=&end= |
GET /api/state/gas |
气体分布分析 | ?x=&y=&radius= |
GET /api/state/cell?x=10&y=5
{
"x": 10, "y": 5, "cell": 4523,
"element": "Oxygen",
"elementId": "Oxygen",
"elementState": "gas",
"massKg": 1.8,
"temperatureC": 23.5,
"isSolid": false, "isLiquid": false, "isGas": true,
"hasBuilding": true, "buildingName": "GasPump",
"hasDuplicant": false, "duplicantName": null,
"isVacuum": false, "isVisible": true
}
GET /api/state/cells?x=0&y=0&width=5&height=5
{
"region": { "x": 0, "y": 0, "width": 5, "height": 5 },
"cells": [ /* array of cell objects */ ]
}
2.4 实体注册表端点 (AI 参考)
用于 AI 在运行时查询游戏实体的元数据。所有为 GET 请求。
| 端点 | 返回内容 |
|---|---|
/api/registry/buildings |
全部建筑定义(尺寸/功耗/发热/材料) |
/api/registry/elements |
全部元素定义(比热容/导热/熔沸点) |
/api/registry/techs |
全部科技定义(前置/解锁建筑) |
GET /api/registry/buildings
[
{
"id": "Electrolyzer",
"name": "Electrolyzer",
"category": "Oxygen",
"width": 2, "height": 2,
"powerCost": 120,
"heatGeneration": 1.25,
"constructionMass": ["IronOre", "IronOre"]
}
]
2.5 操作端点
所有操作为 POST 请求,路径前缀 /api/action/。
| 端点 | 作用 | 必需 |
|---|---|---|
/api/action/dig |
挖掘指定区域 | 是 |
/api/action/build |
建造建筑 | 是 |
/api/action/deconstruct |
拆除建筑 | 推荐 |
/api/action/prioritize |
设置优先级 | 可选 |
/api/action/research |
选择研究方向 | 推荐 |
/api/action/schedule |
修改复制人日程 | 可选 |
/api/action/wardrobe |
修改复制人装备 | 可选 |
/api/action/mop |
清理液体 | 推荐 |
/api/action/harvest |
收获植物 | 推荐 |
/api/action/cancel |
取消操作 | 可选 |
GET /api/state/game
{
"cycle": 42,
"duplicantCount": 6,
"worldName": "Terra",
"worldSize": 256
}
GET /api/state/duplicants
[
{
"name": "Dup1",
"stress": 12.5,
"calories": 850000,
"stamina": 98.2,
"oxygen": 85.0,
"diseases": 0,
"skillLevels": 3
}
]
GET /api/state/resources
[
{ "name": "Oxygen", "tag": "Oxygen", "amount": 12345.6, "unit": "kg" }
]
GET /api/state/buildings
[
{
"name": "Manual Generator",
"id": "ManualGenerator",
"x": 10,
"y": 5,
"isOperational": true
}
]
2.3 操作端点
所有操作为 POST 请求,路径前缀 /api/action/。
| 端点 | 作用 | 必需 |
|---|---|---|
/api/action/dig |
挖掘指定区域 | 是 |
/api/action/build |
建造建筑 | 是 |
/api/action/deconstruct |
拆除建筑 | 推荐 |
/api/action/prioritize |
设置优先级 | 可选 |
/api/action/research |
选择研究方向 | 推荐 |
/api/action/schedule |
修改复制人日程 | 可选 |
/api/action/wardrobe |
修改复制人装备 | 可选 |
POST /api/action/dig
请求体:
{ "x": 10, "y": 5, "width": 8, "height": 6 }
响应:
{ "result": "dig_queued", "x": 10, "y": 5, "width": 8, "height": 6 }
POST /api/action/build
请求体:
{ "buildingId": "Electrolyzer", "x": 10, "y": 5, "rotation": null }
响应:
{ "result": "build_queued", "buildingId": "Electrolyzer", "x": 10, "y": 5 }
3. Mod 约束
3.1 安全性
- 仅绑定本地回环地址
127.0.0.1,不得监听0.0.0.0 - 不得实现认证/授权——回环地址默认安全
- 不得执行文件 I/O(读取 Mod 自带配置除外)
- 输入校验——所有用户输入必须校验类型和范围
3.2 性能
- 状态查询必须是只读操作,不得持有锁
- 资源列表等大数据量接口应考虑分页(未来扩展)
- 建造/挖掘等操作应返回
queued后异步执行 - HTTP 服务器应在单独线程运行,不得阻塞游戏主线程
3.3 兼容性
- 使用
KMod.UserMod2基类 - 使用
Harmony进行补丁(如果使用) - 引用
UnityEngine和Assembly-CSharp程序集 - 最小支持游戏版本应在
mod_info.yaml中声明(当前推荐612000)
3.4 错误处理
// Mod 内部错误的通用格式
{ "error": "error_type", "details": "human readable message" }
// 常见错误类型
{ "error": "not_found" } // 404 端点不存在
{ "error": "invalid_request" } // 请求体解析失败
{ "error": "not_implemented" } // 功能尚未实现
{ "error": "unknown_building", "buildingId": "..." } // 建筑 ID 不识别
{ "error": "unknown_tech", "techId": "..." } // 科技 ID 不识别
4. 配置文件规范
Agent 侧通过 config.json 定位 Mod:
{
"modHost": "127.0.0.1",
"modPort": 23876,
"timeout": 10
}
modHost: 始终为127.0.0.1modPort: 应与 Mod 中监听的端口一致timeout: HTTP 请求超时秒数
5. AI-Friendly 数据设计原则
5.1 数据可读性
所有暴露的数据应满足 AI 可直接理解的三个条件:
- 命名语义化 — 使用自然语言字段名(如
temperatureC而非tempK) - 数据类型合理 — 使用数字而非枚举字符串(温度用
float而非string) - 上下文完整 — 每个实体包含足够的位置和状态信息(坐标、类别、是否可运行)
5.2 坐标系统
- 统一使用
(x, y)整数坐标,对应游戏网格 - 原点在左下角:
(0, 0) - 建筑使用其左下角锚点坐标
- 返回数据中同时提供
cell索引(Grid 内部使用)和(x, y)坐标
5.3 实体分类
每个实体(建筑、元素、科技)必须包含分类标签:
- 建筑:
category(Base/Oxygen/Power/Food/...) - 元素:
state(solid/liquid/gas)+category(metal/water/fuel/...) - 资源: 带
state和category帮助 AI 推理用途
5.4 AI 推理辅助
/api/registry/*端点提供完整的实体元数据查询GET /api/state/gas提供区域气体分布统计(AI 无法逐格遍历)/api/state/rooms提供房间判定结果(AI 无法自行判断房间类型)
5.5 操作设计
操作设计遵循以下原则:
- 幂等性 — 同个操作重复执行不产生副作用
- 非阻塞 — 操作立即返回
queued,异步执行 - 确定性 — 使用绝对坐标
(x, y),不支持"在某个建筑旁边"这类模糊表述 - 输入校验 — 拒绝未知的
buildingId或越界坐标
6. 扩展建议
5.1 添加新端点
- 在
ProcessRequest中添加路由匹配 - 实现对应的处理方法
- 更新本指南和
SKILL.md
5.2 蓝图系统
预置的建造方案(蓝图)应满足:
- 坐标相对于原点,便于偏移
- 包含预先挖掘区域
- 建筑顺序隐含依赖关系
5.3 事件推送(未来)
考虑支持 WebSocket 或 SSE,用于游戏事件实时推送(如警报触发)。
6. 开发检查清单
- Mod 继承
UserMod2,在OnLoad中启动 HTTP 服务 - 在
OnUnload中停止 HTTP 服务 - 实现全部必需端点(health, game, resources, duplicants, dig, build)
- 错误响应包含
error字段 - 端口号与
config.json一致 - 仅绑定
127.0.0.1 - 使用
System.Text.Json而不是Newtonsoft.Json(减少依赖) mod_info.yaml声明了正确的游戏版本