# DesktopPet **Repository Path**: icebabby/desktop-pet ## Basic Information - **Project Name**: DesktopPet - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-30 - **Last Updated**: 2026-10-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AI 桌面宠物_便携版(zhuochong) > 本地推理的 AI 桌面宠物:后端 Python + 本地 Ollama(`qwen2:7b`)驱动对话与状态机,前端 Godot 4.3 渲染 17 个动作的精灵图动画。 > 当前版本:**V17**(阶段二诊断修复收口 + 测试基建:修复 B1~B7 缺陷、N1~N10 规范、E1~E3 错误,U2 日志时间含日期;新增 `tests/` pytest 套件 91 项全绿;启动器与后端版本号 V16→V17。承继 V16 系统日志、V15 精灵图零缓存加载与 V14 动作系统修复)。 > 历史 V4 理想方案(DragonBones / OmniParser / GGUF / Nuitka / Inno Setup)见 `项目文档/桌面宠物开发文档.md`,仅作架构溯源,**与当前实现不符**。 ## 技术栈(实际) | 模块 | 选型 | |---|---| | 前端渲染 | Godot 4.3(`Godot_v4.3-stable_win64.exe --path godot` 直接跑工程源码,随包发布,**不导出** `DesktopPet.exe`) | | 后端推理 | Python 3.11 + Ollama `qwen2:7b`(本地 CPU 推理,经 `http://127.0.0.1:11434/api/chat`) | | 通信 | WebSocket(`ws://localhost:8765`),原生实现 | | 动作表现 | 17 张 1×8 精灵图(spritesheet),状态驱动切换(非骨骼动画) | | 打包 | Godot 编辑器二进制 + 前端工程源码随包(**不含 `.godot/` 导入缓存**)+ PyInstaller 冻结后端 `DesktopPetBackend.exe` → 便携版 zip(V12~V16 结构一致) | ## 目录结构(实际) ``` desktop-pet/ ├── src/ │ ├── backend/main.py # Python 后端主程序(WS 服务 + 状态机 + Ollama 调用) │ └── godot/ # Godot 前端工程 │ ├── project.godot # Godot 工程配置(窗口 380×420 透明无边框) │ ├── pet_controller.gd # 宠物控制器(WS 客户端 + 精灵播放 + 属性面板) │ ├── action_db.json # 17 动作数据库 │ └── sprites/ # 17 张动作 spritesheet(idle_blink/idle_breathing/think/talk/ │ # nod/shake_head/walk/sit/sleep/eat/wave/happy/sad/angry/ │ # surprised/lifted/headpat) ├── requirements.txt # 后端依赖(aiohttp, websockets 为必需;其余为 V4 残留,未使用) ├── README.md ├── CHANGELOG.md ├── LICENSE ├── .gitattributes # `*.bat -text`:防止 core.autocrlf 把启动器改写为 LF(BUG-3 防复发) └── scripts/ └── 启动宠物.bat # 便携版启动器**唯一源文件**(V16;GBK+CRLF,打包时复制进 zip) ``` > 打包路线已定(2026-10-08):**便携版 zip**(编辑器二进制 + 工程源码 + 冻结后端)。原 Inno Setup 模板 `installer.iss` 已废弃(其引用 `launcher.bat` / `DesktopPet.exe` 均不存在),并已于 2026-10-08 随工程根 `备份/` 目录一并删除。 > 说明:`requirements.txt` 中的 `pyautogui / uiautomation / mss / pyperclip` 等 GUI 自动化库为 V4 理想方案残留,**当前 `main.py` 并未 import**,仅 `aiohttp` 与 `websockets` 为运行必需。 ## 快速开始 ### 方式一:源码运行(开发) ```bash # 1. 启动 Ollama(项目文档/启动Ollama.bat,或自行 ollama serve) # 2. 安装依赖 pip install -r requirements.txt # 3. 运行后端 python src/backend/main.py # 4. 前端:用 Godot 4.3 打开 src/godot/project.godot,按 F5 运行 ``` ### 方式二:便携版(用户) 解压便携版 `AI桌面宠物_便携版_V17_{日期}_{SHA256前8位}.zip`(由打包流程生成,交付包不入库),双击 `启动宠物.bat`: - 自动拉起 Ollama(未运行时)→ 启动后端 `DesktopPetBackend.exe` → 用包内 `Godot_v4.3-stable_win64.exe --path godot` 拉起前端主场景; - 对话依赖本机 Ollama 与已拉取的 `qwen2:7b`。 > **便携版注意(V15 修复要点)**:便携包只发布前端**工程源码**,**不含** Godot 导入缓存 `.godot/`,而运行时模式不会自动导入资源。 > 因此前端加载贴图**不得**使用 `load("res://...png")`,必须走 `_load_tex()`(`FileAccess.get_file_as_bytes()` + `Image.load_png_from_buffer()` 直读原始 PNG)。 > V14 及更早版本因违反此约束,解压后会出现「窗口在、气泡在,但宠物角色完全不显示」。 > 启动器遵循 V16 定稿规范:**GBK(cp936) + CRLF + 不含 `^` 转义 + 不切代码页**(LF-only 或 `chcp` 会导致双击无法启动 / 后续逻辑失效,即 BUG-3/6)。 ## 动作系统 - 状态机:`IDLE / CHATTING(THINKING|SPEAKING|WAITING|FINISHING) / COMMAND / INTERACTING / SLEEPING`。 - 动作切换由系统状态变化驱动(V11-R5 已移除随机动作定时器)。 - **V17(阶段二诊断修复收口 + 测试基建)**:修复 B1~B7(多客户端重复执行、日志定位只查 300 条、LLM 失败状态机滞留、ping 刷爆日志、健康检查 URL 推导、属性滞后、配置不广播)、N1~N10 规范、E1~E3 错误,U2 日志时间含日期;`requirements.txt` 瘦身为 aiohttp+websockets;新增 `tests/` pytest 套件 91 项。 - **V16(系统日志 + P0/缺陷收口)**: - 前端「聊天记录」窗口整体替换为「系统日志」窗口:定位区(行为类型过滤 + 关键字搜索)/ 列表区 / 状态区 / 操作区(刷新·导出·打开日志目录·清空·关闭);右键菜单第 4 项改名「系统日志」。 - 修复系统日志窗口 2 个 P0 缺陷:列表区高度塌陷为 0(条目一条看不见,BUG-1)、窗口被 ALWAYS_ON_TOP 的宠物主窗口遮挡(BUG-2,`embed_subwindows=false`)。 - 后端新增 `SysLog`:JSONL 落盘 `system_log.jsonl`,10 类行为、格式 `【时间】【行为】:【内容】`,提供 `tail/export/clear/migrate_from_chat_history`;协议 `log_get/log_clear/log_export/log_update/log_exported`;`log_event()` 统一接入 chat/动作/状态/配置/搭话/连接/启动事件。 - 需求 09 **D2 情感识别**:`user_emotion` 六值域(happy/sad/angry/neutral/miss/love)+ 新增「情感识别」日志类型,按情绪调整后续行为;**D3 属性规则降级**:`_fallback_action()` 取代硬编码 `idle_blink` 兜底(全文件已无 `random.choice`)。 - 便携版启动器 4 个缺陷修复(BUG-3 交付阻断级 LF-only、BUG-4 `2^>nul` 误用、BUG-5 自动拉起 Ollama 阻塞、BUG-6 `chcp` 破坏位置追踪)。 - **V15 修复(便携版阻断缺陷轮)**: - 新增 `_load_tex()`:直接读取 PNG 原始字节构建 `ImageTexture`,完全绕开 Godot 导入管线;原始文件不可读时才退回 `load()`。 - `_load_sheets()` 改用它并输出真实成功计数;`_build_frames()` 增加空纹理防护;`_set_action()` 回退改走 `_default_tex`。 - 实测:干净目录解压启动后 Godot 日志 `精灵图加载: 17/17 张(原始 PNG 直读,便携版零依赖导入缓存)`,宠物角色正常显示。 - **V14 修复(动作修复轮)**: - 整体动作节奏放缓:前端帧间隔 `LOOP_STEP` 0.12→0.26(8 帧循环 0.96s→2.08s),`shake` 抖动 0.05→0.12s。 - 菜单动作如实播放:右键菜单(及任意显式用户指令)触发的动作,后端跳过状态机白名单校验、保持当前状态、如实广播所选动作;前端在 `IDLE` 态下期满后自回待机,非 `IDLE` 态完全由后端驱动,消除「点了动作却播待机 / 被覆盖」。 - 移除自发随机动作:删除每 30s 依心情值自发播 `sad/happy` 的阈值情绪块(及 `_last_mood_ts`)。判定依据:该动作未经用户触发即覆盖用户正在观看的动作,且无法在不干扰用户意图下改好,故按需求「随机动作要么保留验证、要么移除清理」移除并清理干净。 - 前端 3s 回待机计时器增加 `_current_state=="IDLE"` 守卫,杜绝在对话/交互/指令/睡眠态与后端广播互相覆盖。 - 动作菜单与实际动作一致:菜单由 `action_db.json`(17 项,磁盘 17 张精灵图齐全)动态生成,修复后 17 个菜单动作均可真正播放(验证 17/17)。 ## 已知限制 - 前端**不导出** `DesktopPet.exe`:便携版直接以包内 Godot 编辑器二进制跑工程源码;本仓库仅存源码,便携版 zip 由打包流程生成、不入库。 - AI 对话依赖本机 Ollama 与 `qwen2:7b` 模型已拉取。 - 扩展动作 10 个(`nod`/`shake_head`/`walk`/`sit`/`wave`/`happy`/`sad`/`angry`/`surprised`/`headpat`)仍用旧资源,角色尺寸在 512 帧内不一致(切换动作时可见跳变),待按 V13 新标准重做。