Pixel Agents 外部资源目录完全指南:从自定义家具资产包到 manifest 规范与加载原理
人工智能AI Agent开发工具【免费下载链接】pixel-agentsPixel office.项目地址https://gitcode.com/gh_mirrors/pi/pixel-agents点击查看免费下载导读Pixel Agents像素办公室除了内置家具之外还支持从扩展目录之外的任意文件夹加载家具、角色与宠物资源让你可以接入第三方像素艺术资产包或自绘素材。本文以官方文档 docs/external-assets.md 为骨架结合仓库源码完整讲解外部资源目录的添加方式、目录结构约定、manifest.json清单格式含旋转组、状态组、动画组等进阶写法、字段参考表以及底层的资源加载与合并原理读完你既能手工编写资产清单也能理解这些清单是如何被引擎解析并渲染成办公家具的。一、为什么要使用外部资源目录内置家具资产位于 webview-ui/public/assets/furniture覆盖了桌椅、书柜、电脑、绿植等常见办公物品但任何团队都可能有定制需求品牌主题办公区、特殊家具形态、第二套像素画风或者直接购买第三方像素资产包。Pixel Agents 的解决方案不是要求你修改扩展包内的资源而是允许你在扩展之外维护自己的资产目录加载后与内置家具即时合并出现在同一个家具面板furniture palette中。从源码结构看这套机制被设计为内置资源 外部资源双层模型内置资源根assetsRoot由扩展的dist/assets或工作区根目录提供外部目录通过配置中的externalAssetDirectories数组逐一声明。二者在运行时被统一合并后下发到 webview 渲染见 server/src/assetReload.ts 中的loadAllFurniture/loadAllCharacters/loadAllPets以及 adapters/vscode/PixelAgentsViewProvider.ts 中对应的loadAllFurnitureAssets()、loadAllCharacterSprites()、loadAllPetSprites()三个封装方法。二、添加与移除外部资源目录2.1 操作步骤在 Pixel Agents 面板中按以下步骤添加外部目录打开 Pixel Agents 面板点击Settings设置点击Add Asset Directory添加资源目录在系统文件夹选择器中选中一个文件夹自定义资源会立即出现在家具面板中与内置家具合并显示无需重启该目录路径会被持久化保存到~/.pixel-agents/config.json下次启动时自动重新加载。移除目录同样在 Settings 中完成点击目录条目旁边的X即可删除。2.2 底层的消息处理与持久化在 VS Code 适配器源码 PixelAgentsViewProvider.ts 中可以看到完整的处理链路收到 webview 发来的addExternalAssetDirectory消息后扩展调用vscode.window.showOpenDialog仅允许选文件夹获取路径将新路径写入config.externalAssetDirectories若尚未包含随后调用writeConfig(cfg)持久化依次调用reloadAndSendCharacters()、reloadAndSendPets()、reloadAndSendFurniture()热重载三类资源最后向 webview 广播externalAssetDirectoriesUpdated消息同步最新目录列表移除目录removeExternalAssetDirectory消息则是从数组中过滤掉该路径后执行同样的写配置与三路重载流程。配置文件的读取与写入实现在 server/src/configPersistence.ts配置结构PixelAgentsConfig包含vscode、standalone两个适配器命名空间以及顶层数组externalAssetDirectories: string[]见 configPersistence.ts读取时对externalAssetDirectories做了防御性过滤只保留字符串类型的元素损坏或手改导致的非法值会被丢弃configPersistence.ts写入时采用临时文件 rename的原子写入方式避免中途崩溃留下半截 JSONconfigPersistence.ts。配置文件路径由 server/src/constants.ts 中的两个常量决定LAYOUT_FILE_DIR .pixel-agents、CONFIG_FILE_NAME config.json即最终为~/.pixel-agents/config.json。2.3 与独立服务器standalone的共用同一份externalAssetDirectories配置也被独立服务器复用在 server/src/cli.ts 中启动时会readConfig().externalAssetDirectories并传给loadAllCharacters/loadAllPets/loadAllFurniture而 server/src/assetReload.ts 的buildAssetCache也接收externalDirs参数构建完整的内存资源缓存。这保证 VS Code 面板与独立后端对外部资源目录的加载行为完全一致。三、目录结构约定外部资源目录必须遵循如下结构官方文档示例my-assets/ assets/ furniture/ MY_CHAIR/ manifest.json MY_CHAIR.png MY_DESK/ manifest.json MY_DESK_FRONT.png MY_DESK_SIDE.png要点每个家具条目独占一个子文件夹内含一个manifest.json和一张或多张 PNG 精灵图文件夹名称本身没有意义——真正标识物品身份的是 manifest 中的id字段id必须保证在所有已加载资产中全局唯一包含内置资产因为渲染阶段 sprite 以assetId - SpriteData的形式存放在Map中见下文的LoadedAssets结构。从加载器源码 server/src/assetLoader.ts 可以看到扫描逻辑loadFurnitureAssets(workspaceRoot)会拼接workspaceRoot/assets/furniture列出其中的全部子目录逐个读取manifest.json目录缺失或没有子目录时返回null子目录缺少manifest.json或清单解析失败时仅打印警告并跳过不会中断整个加载流程。需要留意的是地板、墙壁、地毯贴图不支持从外部目录加载。在 server/src/assetReload.ts 的buildAssetCache中floorTiles/wallTiles/carpetTiles只从内置资源根加载注释明确说明 bundled-only外部目录只贡献 characters、pets、furniture 三类资源。四、manifest.json 清单格式详解4.1 简单资产单精灵、无旋转最简单的清单只有一个 sprite无方向变体{ id: MY_ITEM, name: My Item, category: decor, type: asset, file: MY_ITEM.png, width: 16, height: 16, footprintW: 1, footprintH: 1, canPlaceOnWalls: false, canPlaceOnSurfaces: false, backgroundTiles: 0 }源码层面的补充细节当type为asset且未指定file时加载器会默认使用{id}.png作为文件名——即file: manifest.file ?? \${manifest.id}.png见 [assetLoader.ts](https://link.gitcode.com/i/a651f167f21395ceaabd0a357b6810cd)。这意味着如果你把图片命名为与id相同可以省略file 字段。4.2 旋转组2-way双方向办公桌这类正面看与侧面看差异很大的家具需要声明两个方向的精灵{ id: MY_DESK, name: My Desk, category: desks, type: group, groupType: rotation, rotationScheme: 2-way, canPlaceOnWalls: false, canPlaceOnSurfaces: false, backgroundTiles: 1, members: [ { type: asset, id: MY_DESK_FRONT, file: MY_DESK_FRONT.png, width: 32, height: 32, footprintW: 2, footprintH: 2, orientation: front }, { type: asset, id: MY_DESK_SIDE, file: MY_DESK_SIDE.png, width: 16, height: 32, footprintW: 1, footprintH: 2, orientation: side } ] }2-way意为引擎会根据放置朝向在front正面与side侧面两个精灵之间切换。注意每个 member 仍有自己的id最终进入渲染管线的其实是这些叶子资产见 4.5 的展平机制。4.3 旋转组3-way-mirror三方向 镜像对椅子这类正面、背面、侧面三视角都需要、但左右对称的家具可以用3-way-mirror方案声明front、back、side三个精灵并给 side 成员加上mirrorSide: true。引擎会在加载时自动水平翻转生成左侧变体你只需提供一张侧视图。{ id: MY_CHAIR, name: My Chair, category: chairs, type: group, groupType: rotation, rotationScheme: 3-way-mirror, canPlaceOnWalls: false, canPlaceOnSurfaces: false, backgroundTiles: 0, members: [ { type: asset, id: MY_CHAIR_FRONT, file: MY_CHAIR_FRONT.png, width: 16, height: 16, footprintW: 1, footprintH: 1, orientation: front }, { type: asset, id: MY_CHAIR_BACK, file: MY_CHAIR_BACK.png, width: 16, height: 16, footprintW: 1, footprintH: 1, orientation: back }, { type: asset, id: MY_CHAIR_SIDE, file: MY_CHAIR_SIDE.png, width: 16, height: 16, footprintW: 1, footprintH: 1, orientation: side, mirrorSide: true } ] }rotationScheme的可选值为2-way、3-way-mirror、4-way。仓库内置的软垫椅就是这一模式的真实样例完整清单见 webview-ui/public/assets/furniture/CUSHIONED_CHAIR/manifest.json。4.4 嵌套组状态组与动画组groupType除了rotation还支持state同一朝向的不同状态与animation连续帧动画且可以任意嵌套。内置电脑桌 webview-ui/public/assets/furniture/PC/manifest.json 是教科书级的综合示例——它同时使用了旋转、状态、动画三层结构外层是rotation3-way-mirror区分正/背/侧视角正面视角下是state组区分on开机与off关机两个状态开机状态内再嵌套animation组用frame: 0/1/2声明三帧循环动画屏幕闪烁效果。PC 清单的正面分支节选如下{ type: group, groupType: state, orientation: front, members: [ { type: group, groupType: animation, state: on, members: [ { type: asset, id: PC_FRONT_ON_1, file: PC_FRONT_ON_1.png, width: 16, height: 32, footprintW: 1, footprintH: 2, frame: 0 }, { type: asset, id: PC_FRONT_ON_2, file: PC_FRONT_ON_2.png, width: 16, height: 32, footprintW: 1, footprintH: 2, frame: 1 }, { type: asset, id: PC_FRONT_ON_3, file: PC_FRONT_ON_3.png, width: 16, height: 32, footprintW: 1, footprintH: 2, frame: 2 } ] }, { type: asset, id: PC_FRONT_OFF, file: PC_FRONT_OFF.png, width: 16, height: 32, footprintW: 1, footprintH: 2, state: off } ] }4.5 清单如何被展平flatten清单是一种树状结构而渲染管线需要的是扁平资产数组。展平逻辑实现在 core/src/assets/manifestUtils.ts 的flattenManifest(node, inherited)中核心规则是属性自上而下继承根清单中的name、category、canPlaceOnWalls、canPlaceOnSurfaces、backgroundTiles会流向所有叶子资产rotation组向子节点传递rotationScheme并以根id作为groupIdstate组向子节点传播orientation与stateanimation组会拼接生成animationGroup标识形如{groupId}_{orientation}_{state}的大写形式同时把state传给子节点叶子资产的orientation/state/frame/mirrorSide若与继承值冲突以叶子自身为准node-level takes priority。最终每个叶子资产成为一条FurnitureAsset记录类型定义见 core/src/assets/types.ts 中的CatalogEntry以及 manifestUtils 中的FurnitureAsset。值得注意的是isDesk是根据继承的category desks自动推导的manifestUtils.ts因此把家具归入desks分类会自动获得桌面相关行为。五、字段参考表5.1 根字段所有清单通用字段类型说明idstring唯一标识符必须在所有已加载资产中全局唯一namestring面板中显示的物品名称categorystring面板分类desks、chairs、electronics、storage、decor、misc、walltypeasset|group单精灵或组旋转 / 状态 / 动画canPlaceOnWallsboolean是否可放置在墙砖上canPlaceOnSurfacesboolean是否可放置在桌面表面上backgroundTilesnumber精灵向下延伸超出其足迹的地板砖数用于高个子精灵如绿植、柜子5.2 仅 asset 有的字段字段类型说明filestring相对物品文件夹的 PNG 文件名widthnumber精灵像素宽度heightnumber精灵像素高度footprintWnumber足迹宽度以砖计1 砖 16pxfootprintHnumber足迹高度以砖计5.3 仅 group 有的字段字段类型说明groupTyperotation|state|animation成员之间的关系类型rotationScheme2-way|3-way-mirror|4-way可用的旋转变体membersarray子资产或嵌套组5.4 成员的朝向取值front、back、side、left、right。六、加载管线与安全机制源码级6.1 从文件夹到 SpriteData完整加载链路如下assetLoader.ts 的loadFurnitureAssets扫描assets/furniture/下的子目录读取每个子目录的manifest.json按type区分单资产与组资产组资产交给flattenManifest展平对每个叶子资产读取 PNG调用pngToSpriteData来自 core/src/assets/pngDecoder.ts把像素解码为引擎可用的string[][]精灵数据以asset.id为键存入spritesMap汇总为LoadedAssets { catalog, sprites }结构定义见 assetLoader.ts再通过sendAssetsToWebview发送furnitureAssetsLoaded消息给 webviewassetLoader.ts。6.2 内置 外部的合并与去重loadAllFurnitureassetReload.ts先加载内置根目录再遍历externalDirs逐个加载外部目录最后用mergeLoadedAssets合并assetLoader.ts。合并时的去重策略是以新目录外部为准剔除内置目录中id相同的老条目——这也是官方文档要求id全局唯一的原因所在。角色与宠物同样遵循内置 外部合并loadAllCharacters/loadAllPets分别调用内置的loadCharacterSprites/loadPetSprites与更灵活的扫描器loadExternalCharacterSprites/loadExternalPetSprites后者允许任意char_N.png编号再用mergeCharacterSprites/mergePetSprites追加assetReload.ts。6.3 路径越界保护加载器对每个 PNG 文件都做了路径安全检查解析后的真实路径必须位于物品子目录之内否则直接跳过并告警assetLoader.ts外部角色与宠物的加载同样带此防护。这意味着 manifest 中声明的file不能通过../等写法逃出资产目录。6.4 单资产 file 缺省如 4.1 所述type: asset的清单可以省略file字段加载器自动回退到${id}.png简化了最简单场景的清单编写。七、使用第三方资产包与可视化编辑工具如果你有一个现成的像素艺术资产包例如 Donarg 出品的 16x16 办公室室内图块集这类常见资源通常需要把图块集tileset按物品逐个切片为独立 PNG为每个物品编写一个manifest.json并放到assets/furniture/ITEM_ID/目录中按第 2 节步骤把整个目录添加为外部资源目录。由于 manifest 格式足够简单这类工作非常适合交给 AI 助手完成——把精灵图或图片列表描述给它让它直接生成符合 4.14.4 规范的清单即可。对于想更直观地维护清单的用户仓库还提供了可视化编辑器scripts/asset-manager.html一个独立的网页工具用于创建与编辑 manifest可避免手工拼写 JSON 出错。内置资产目录 webview-ui/public/assets/furniture 中存放着 20 余个现成范例BIN、BOOKSHELF、CACTUS、CLOCK、COFFEE、DESK、SOFA、WHITEBOARD 等每一个都包含manifest.json与对应 PNG。写作自定义清单时最可靠的做法就是参考这些真实文件的写法——尤其是CUSHIONED_CHAIR3-way-mirror与PC旋转 状态 动画嵌套两份清单它们覆盖了绝大多数进阶场景。八、常见问题与最佳实践资产没出现在面板里先确认目录结构是否为xxx/assets/furniture/ID/manifest.json再检查 manifest 是否 JSON 合法、PNG 文件名是否与file或默认的${id}.png一致。加载器对每个失败目录只打印警告⚠️ No manifest.json in .../Asset file not found不会阻断其余资产。id 冲突怎么办合并逻辑按后加载者胜出处理内置资产会被同 id 的外部资产替换。为避免误覆盖内置家具建议外部资产的id使用独特前缀如MY_。高个子精灵显示被截断使用backgroundTiles声明精灵向下延伸的地板砖数渲染引擎会据此正确处理遮挡关系。不要修改扩展内置资产官方推荐的外部扩展路径是添加外部目录而不是改动 webview-ui/public/assets 中的内置资源外部目录的加载顺序也意味着它天然具备覆盖内置的能力。配置即真相所有已添加目录都记录在~/.pixel-agents/config.json的externalAssetDirectories数组中可直接查看该文件确认当前生效的外部资源列表。结语外部资源目录把 Pixel Agents 从内置家具库扩展为可插拔的像素资产平台一套assets/furniture/ID/manifest.json PNG 的目录约定配合id全局唯一与属性自根向叶继承的展平机制让自定义家具、旋转变体、状态切换与帧动画都能以声明式清单的方式接入而 server/src/assetLoader.ts 与 server/src/assetReload.ts 中的加载、合并、去重与路径防护则保证了外部资源在内置根与独立服务器两种运行面下行为一致、稳定可靠。掌握了清单规范与加载原理之后你既可以手工编写资产包也可以借助 scripts/asset-manager.html 或 AI 助手批量生成为你的像素办公室带来真正属于自己的家具。赞分享人工智能AI Agent开发工具【免费下载链接】pixel-agentsPixel office.项目地址https://gitcode.com/gh_mirrors/pi/pixel-agents点击查看免费下载相关推荐Dolphin 资源包Resource Pack规范 v2 完全指南从 manifest 编写到纹理加载全流程解析Dolphin 资源包Resource Pack规范 v2 完全指南从 manifest 编写到纹理加载全流程解析 Dolphin 是运行于 PC 平台的游戏开发图形学跨平台Momentum-Firmware 资产管线完全指南从图标命名规范到 Dolphin 动画与资源打包Momentum Firmware 资产管线完全指南从图标命名规范到 Dolphin 动画与资源打包 本文以 Momentum Firmware 仓库中的 a嵌入式物联网PixiJS 资源清单Manifest与资源包Bundle加载实战指南PixiJS 资源清单Manifest与资源包Bundle加载实战指南 本文将深入讲解 PixiJS 的 Manifest资源清单 与 Bundle前端图形学上一篇XXPermissions框架详细技术文档下一篇推荐文章探索智能园艺新时代 —— STC89C51驱动的自动浇花控制系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考