内容
# AI 精灵 & 游戏资产工具
<img width="1398" height="503" alt="image" src="https://github.com/user-attachments/assets/0d7e2faa-9d93-44f1-bb3f-2f8db24863a7" />
一个本地优先的角色动画工作台,可以根据文本提示(和可选的参考图像)生成可重复使用的动画片段和版本化的引擎准备包。
Azure GPT 图像、Gemini 或独立运行的 loopback ComfyUI 服务器可以完成生成工作;
一个确定性的 Python 管道处理修复、调色板、精灵表格打包、帧 ZIP、包校验和和 Godot 资源。
横向卷轴游戏还为 Gemini 提供确定性的八阶段姿势指南,
因此帧会改变肢体几何形状,而不是仅仅重新设置相同的姿势。
在 [Apache-2.0](LICENSE) 下许可。参见 [CONTRIBUTING.md](CONTRIBUTING.md)、
[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) 和 [SECURITY.md](SECURITY.md),在贡献或报告漏洞之前。
## 布局
```
backend/ FastAPI + 确定性图像管道(Python 3.11+)
frontend/ React + Vite + TypeScript 薄客户端
projects/ 每个项目的输出文件夹(git-ignored)
```
## 后端设置
```bash
cd backend
uv sync --locked --extra dev
cp .env.example .env # 然后填写以下值
uv run python ../scripts/doctor.py
uv run pytest -q
uv run uvicorn app.main:app --reload
```
### 环境 / 认证
该项目通过 **Vertex AI(Google Agent Platform)** 使用服务账户 JSON 密钥认证到 Gemini —— 而不是 `GEMINI_API_KEY`。在 `.env` 中设置:
| 变量 | 含义 |
|---|---|
| `SPRITE_ENV_FILE` | 可选的绝对 dotenv 路径。如果省略,则后端无论进程 CWD 如何,都使用 `backend/.env`。所选 dotenv 文件内的相对路径从该文件目录解析。 |
| `GOOGLE_APPLICATION_CREDENTIALS` | 服务账户 JSON 密钥文件路径(显式加载;如果未设置,则回退到 `gcloud` ADC) |
| `GOOGLE_CLOUD_PROJECT` | GCP 项目 ID |
| `GOOGLE_CLOUD_REGION` | Vertex 区域(默认 `global`) |
| `GEMINI_MODEL_GENERATE` | 阶段 1 模型(默认 `gemini-3.1-flash-image`) |
| `GEMINI_MODEL_EDIT` | 阶段 2 模型(默认 `gemini-3.1-flash-image`) |
| `GEMINI_MODEL_TEXT` | 可选的提示预览模型(默认 `gemini-3.5-flash`) |
| `GEMINI_TIMEOUT_SECONDS` | 每次尝试 Gemini 请求超时(默认 `120`) |
| `GEMINI_MAX_RETRIES` | 可重试 Gemini 失败的最大尝试次数(默认 `5`) |
| `GEMINI_BACKOFF_SECONDS` | 非配额失败的初始重试延迟;后续延迟加倍(默认 `1`) |
| `GEMINI_QUOTA_BACKOFF_SECONDS` | `429 RESOURCE_EXHAUSTED` 之前的最小延迟,然后自动重试(默认 `15`) |
| `AZURE_OPENAI_ENDPOINT` | 可选的 Azure OpenAI 资源或 `/openai/v1` 端点 |
| `AZURE_OPENAI_API_KEY` | Azure API 密钥;本地密钥,永远不要提交 |
| `AZURE_OPENAI_DEPLOYMENT` | Azure 部署名称,例如 `gpt-image-2-2` |
| `AZURE_IMAGE_QUALITY` | `low`、`medium`、`high` 或 `auto`(默认 `low`) |
| `AZURE_IMAGE_TIMEOUT_SECONDS` | 每次尝试 Azure 请求超时(默认 `180`) |
| `AZURE_IMAGE_MAX_RETRIES` | 可重试失败的最大 Azure 尝试次数(默认 `2`) |
| `AZURE_IMAGE_MAX_CONCURRENCY` | 最大并发 Azure 帧编辑(默认 `3`) |
| `PROJECTS_DIR` | 输出目录(默认 `./projects`)。相对值从所选 dotenv 文件的目录解析,而不是进程 CWD。 |
| `ACTION_PACKS_DIR` | 严格数据 JSON 操作包的即时目录。可选。相对值从所选 dotenv 文件解析。 |
| `COMFYUI_URL` | 可选的显式 loopback URL 和端口,例如 `http://127.0.0.1:8188`。 |
| `COMFYUI_WORKFLOW_DESCRIPTOR` | 受信任的操作员拥有的描述符,位于 API 格式的工作流 JSON 文件旁边。 |
| `MAX_UPLOAD_BYTES` | HTTP 参考图像上传限制(默认 `10485760`);由 MCP 能力报告,尽管直接 MCP 生成不接受图像上传。 |
> 服务账户密钥必须保持本地 —— 它是 git-ignored (`project-*.json`),并且永远不能被推送。
> **区域说明:** Gemini 3.x 图像模型(`gemini-3.1-flash-image`,`gemini-3-pro-image`)从 **`global`** 端点提供服务,而不是像 `us-central1` 这样的区域端点 —— 区域端点返回 404 "模型未在区域中找到"。
> **首次运行:** `rembg` 在首次使用时下载其 ~170 MB 的背景去除模型,因此首次生成/动画调用很慢。`onnxruntime` 推理后端是一个声明的依赖项(通过 `pip install -e ".[dev]"` 安装)。
## 前端设置
```bash
cd frontend
npm ci
npm run dev # 开发服务器在 http://localhost:5173
npm run build
```
## 测试
- **管道**(`backend/tests/`):针对已提交的固定件的纯单元测试 —— 快速、免费、确定性。
- **Gemini 客户端**:针对模拟的 SDK 进行测试;CI 中没有实际的 API 调用。
- **前端**(`frontend/`):`npm test` —— Vitest 涵盖 API 请求塑形、项目浏览器恢复/删除行为、Zustand 水合、`FrameStrip` 再生/策划动作以及 `AnimationPlayer` 环路计时数学。
- **实时烟雾测试**:进行实际的 Gemini 调用,**仅限手动**(不属于 `pytest`)。在配置 `.env` 后,从后端 venv 运行它:
```bash
cd backend
# Windows: .venv\Scripts\activate macOS/Linux: source .venv/bin/activate
python ../scripts/smoke_generate.py "a knight with a sword"
```
它生成一个基本精灵,将其编辑成一个行走帧,运行管道,并将结果写入 `scripts/smoke_out/`(git-ignored)以供检查。使用此方法确认实时模型 ID 和 SDK 签名在任何依赖项提升后仍然匹配。
- **实时模型验证矩阵**:按区域探测配置的提示、生成和编辑模型;记录可用性、延迟、可选的安全阻止行为以及原始/处理的工件,以进行评分的手动质量审查。它是付费的、按需的、超出 CI 的,并写入一个可丢弃的 git-ignored 目录。有关支持的模型/区域表和验收标准,请参见 [`docs/live-model-validation.md`](docs/live-model-validation.md)。
```powershell
cd backend
.venv\Scripts\python.exe ..\scripts\validate_live_models.py --repeats 3 --include-block-probe
```
## 使用应用
在后端(`uvicorn`)和前端(`npm run dev`)都运行时,打开 http://localhost:5173。保存的项目浏览器首先加载本地项目;打开一个健康的项目以恢复其提示、精灵、动画帧和导出工作流。然后通过角色工作空间进行:
1. **生成** —— 描述精灵,选择像素/高分辨率和游戏相机,然后选择允许的方向。提示增强是可选的:请求可见的预览,编辑它,并在生成之前显式接受。选择自动、Azure 或 Gemini;自动优先使用 Azure,然后使用 Gemini,然后使用配置的 ComfyUI。Hyperagent 显示为实验性,但在其代理介导的图像路径验证之前保持禁用。您还可以附加参考。
2. **动画** —— 从操作包或自定义动作创建或替换命名剪辑,然后预览循环范围和每帧持续时间。横向卷轴允许左右;顶向下/2.5D 项目允许所有八个方向。
3. **修复** —— 从保留的源重新渲染,共享调色板,翻转,微调,启用/禁用,重置或重新生成而不累积变换。
4. **导出** —— 下载工作表,大图,单个帧 ZIP 或确定性的角色包。Godot 配置文件包括 Godot 4.7 `SpriteFrames` 和场景文件。
参见 [包和 Godot 文档](docs/character-bundles.md)、
[操作包和配方](docs/actions-and-recipes.md),以及
[ComfyUI 安全边界](docs/comfyui.md)。
## 本地 MCP 服务器
后端安装 `sprite-mcp`,一个由与 FastAPI 相同的同步 `SpriteService`、`ProviderRegistry` 和项目存储支持的本地 stdio MCP 服务器。启动仅存储安全:初始化、能力发现、项目读取和资源读取不需要云凭证。创意工具如果其所需的提供者未配置,则会失败并出现安全工具错误。
在 MCP 客户端中使用控制台脚本注册它:
```json
{
"mcpServers": {
"sprite-game": {
"command": "/absolute/path/to/backend/.venv/bin/sprite-mcp",
"env": {
"SPRITE_ENV_FILE": "/absolute/path/to/backend/.env",
"PROJECTS_DIR": "/absolute/path/to/projects"
}
}
}
}
```
`SPRITE_ENV_FILE` 必须是绝对的。`PROJECTS_DIR` 在 MCP 客户端配置中也应该是绝对的,这样即使客户端从外部工作目录启动服务器,行为也是明确的。
### 直接 MCP 合同
确切的直接工具清单如下:
| 工具 | 提供者/计费影响 | 本地覆盖影响 |
|---|---|---|
| `get_capabilities` | 无 | 无 |
| `list_projects` | 无 | 无 |
| `get_project` | 无 | 无 |
| `enhance_prompt` | Gemini 文本调用;可能产生提供者计费 | 无 |
| `generate_sprite` | 通过 `auto`、`azure` 或 `gemini` 进行一次图像生成调用;可能产生提供者计费 | 创建新项目;不会覆盖现有项目 |
| `animate` | 通过项目中存储的提供者进行多次图像编辑调用;可能产生提供者计费 | 替换先前的动画帧和动画元数据 |
| `regenerate_frame` | 通过项目中存储的提供者进行一次图像编辑调用;可能产生提供者计费 | 替换选定的帧 |
| `export_sheet` | 无提供者调用或提供者计费 | 替换匹配的本地精灵表格和大图输出 |
| `set_render_settings` | 无 | 重新渲染保留的源 |
| `set_frame_adjustment` | 无 | 更新一个精选的帧 |
| `update_clip` / `delete_clip` | 无 | 更新或删除剪辑拥有的状态/资产 |
| `export_character_bundle` | 无 | 替换确定性的包 ZIP |
| `validate_recipe` / `get_project_recipe` | 无 | 只读;无覆盖 |
`auto` 在配置了 Azure 时优先使用 Azure,否则使用 Gemini,但仅在初始生成期间。解析的混凝土提供者被持久化。`animate` 和 `regenerate_frame` 始终使用存储的提供者,如果提供者不再配置,则返回错误;它们从不静默切换提供者。
`get_capabilities` 报告应用程序版本 `0.1.0`、提供者可用性、操作预设、相机/方向组合以及所有提示、上传、解码图像、导出、工作表和帧错误限制。FastMCP 1.28.1 不为应用程序版本公开 FastMCP 构造函数参数,因此应用程序版本在此处报告,而不是在 MCP 初始化服务器版本字段中。
项目输出是 MCP 特有的 DTO。它们包括修订、混凝土提供者、操作结果、帧状态/错误、绝对本地路径和 `sprite://` 资源 URI,但从不公开持久化/浏览器仅限的 `Frame.url` 字段。服务器发布两个只读资源模板:
```text
sprite://projects/{project_id}/manifest
sprite://projects/{project_id}/assets/{filename}
```
两者都通过规范的 `PROJECTS_DIR` 存储解析,并拒绝不安全的 ID、文件名、符号链接逃逸和遍历。服务器不接受任意文件系统路径或参考图像路径。
FastMCP 1.28.1 从 `Annotated`/Pydantic 约束中生成有用的输入模式,但其公共工具装饰器不提供严格额外的选项。因此,未知的顶级工具参数被 SDK 的生成参数模型忽略。此限制由合同测试涵盖;服务器不会修补私有 SDK 内部。
### 能力边界
上述工具由本地 MCP 服务器直接导出。其他操作可能存在于框架中立的运行时内部;从 `tools/list` 中不存在仅意味着操作不是直接的 MCP 工具。
Hyperagent 仍然是一种实验性的远程代理能力。它在提供者能力元数据中显示为不可用。其身份验证的、代理介导的图像路径仍需要单独验证;不要从直接服务器的工具清单中推断远程代理能力。
从存储库根目录运行无凭证协议烟雾测试:
```powershell
backend\.venv\Scripts\python.exe scripts\smoke_mcp.py
```
烟雾脚本从临时外部 CWD 启动已安装的 `sprite-mcp` 控制台入口点,使用绝对的临时 `SPRITE_ENV_FILE` 和 `PROJECTS_DIR` 值,删除云凭证,初始化 stdio,断言确切的工具清单,调用 `get_capabilities`,并仅打印其父进程成功行。
### 代理技能
可在 [`skills/sprite-game-gen/`](skills/sprite-game-gen/) 找到一个可移植的 Agent Skills 兼容指南。将该完整目录安装在代理主机的技能路径中,并连接 `sprite-mcp` 服务器。该技能教导代理发现实时能力,区分计费和破坏性操作,保留部分动画结果,验证项目修订,并安全使用 `sprite://` 资源。其设置参考包括客户端中立的 stdio 配置示例。
## 版本和发布
包、项目清单、包、操作包、配方和批次状态版本独立演化。参见 [版本合约](docs/version-contracts.md)、
[发布流程](docs/release-process.md) 和 [CHANGELOG.md](CHANGELOG.md)。