ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Palworld存档无损编辑深度解析:SAV与JSON双向转换完整指南

2026/8/18 12:58:18 拓冰建站 浏览量
Palworld存档无损编辑深度解析:SAV与JSON双向转换完整指南 Palworld存档无损编辑深度解析SAV与JSON双向转换完整指南【免费下载链接】palworld-save-toolsTools for converting Palworld .sav files to JSON and back项目地址: https://gitcode.com/gh_mirrors/pa/palworld-save-tools不少玩家和服务器管理员都遇到过这样的困境想让好友的存档迁移到自己的服务器或者想调整角色的某项数值却发现.sav文件是一堆无法直接打开的二进制数据。用UE4通用工具能读但读出来的全是字段名而不是游戏数据改错一个字节存档就废了。palworld-save-tools 正是为解决这个问题而生的开源存档编辑工具——它把 Palworld 的二进制存档完整解析成人类可读的 JSON改完再转回去承诺SAV 转 JSON 再转回 SAV 后比特级一致。这篇文章会从文件格式的底层机制讲起带你跑通转换、编辑、回写的完整链路并给出批量处理和性能调优的实战方案。先搞懂你的存档到底是什么一层压缩壳套着一个UE结构体在动手之前值得花两分钟理解.sav文件的真实结构。如果你把 Palworld 的存档想象成一个压缩过的保险箱那么打开它需要两步先破译外层密码压缩算法再逐件清点内层财物UE 的 GVAS 数据结构。外层.sav文件头与双重压缩Palworld 存档文件并非原始数据而是经过 zlib 压缩的。文件开头 12 个字节记录了压缩信息前 4 字节是解压后的原始长度接着 4 字节是压缩后长度随后是PlZ魔数标识和 1 字节的存档类型。palsav.py中的decompress_sav_to_gvas函数负责这一层的解析它校验魔数和长度然后根据存档类型做一层或两层 zlib 解压类型0x31是单层压缩0x32是双层压缩最终得到完整的 GVAS 数据。值得注意的是代码里对每一层长度都做了严格校验——如果压缩长度对不上直接抛异常而不是默默接受这种宁可报错也不产出坏数据的态度贯穿了整个项目。内层GVAS 格式与属性树解压出来的数据是 Unreal Engine 的 GVASGame Version Aggregated Save格式由gvas.py负责解析。它的结构是一条属性树头部记录引擎版本、保存游戏版本、自定义版本号等元信息随后是一串递归嵌套的 Property属性。每个属性都有类型标注比如IntProperty、FloatProperty、StructProperty值则按类型编码进字节流。问题在于通用 UE 存档工具只能读懂这些标准属性而 Palworld 的大量游戏数据——公会、角色、物品栏、据点——都塞进了ArrayProperty里的原始字节RawData中。这些字节是游戏自己序列化的通用工具看到的就是天书。破解天书的钥匙paltypes.pyrawdata/这就是 palworld-save-tools 的核心价值。paltypes.py维护了一张解码路径表PALWORLD_CUSTOM_PROPERTIES把每个 RawData 字段映射到rawdata/目录下对应的解析器.worldSaveData.GroupSaveDataMap→group.py解析公会与组织.worldSaveData.CharacterSaveParameterMap.Value.RawData→character.py解析玩家与帕鲁角色.worldSaveData.ItemContainerSaveData→item_container.py解析物品容器.worldSaveData.BaseCampSaveData→base_camp.py解析据点数据.worldSaveData.MapObjectSaveData→map_object.py解析地图对象以character.py的decode_bytes为例它拿到 RawData 字节后用内部构造的只读流重新按属性树规则解析取出object角色完整属性、unknown_bytes未识别字节和group_id所属公会ID并严格检查是否读到了文件末尾——没读完就抛异常。编码方向encode_bytes则是完全逆过程按同样顺序写回字节。类比一下通用工具只能打开保险箱外层告诉你里面有100件物品而这个工具能把每件物品的成色、来历、归属都整理成一张清单改完清单还能原样封回保险箱。从SAV到JSON只需一条命令转换机制与回写验证理解了原理实操就很简单了。工具的核心入口是commands/convert.py它根据文件扩展名自动判断转换方向.sav转 JSON.json转回 SAV。前置条件Python 3.9 或更高版本且不需要安装任何第三方依赖——这是项目刻意的设计哲学后面会展开讲。基础转换SAV → JSON# 将 Level.sav 转换为 Level.sav.json python -m palworld_save_tools.commands.convert Level.savJSON 转回 SAV# 将编辑后的 Level.sav.json 转回 Level.sav python -m palworld_save_tools.commands.convert Level.sav.json转换后的 JSON 结构完全镜像 GVAS 的属性树。比如你要找玩家角色的数据路径是.worldSaveData.CharacterSaveParameterMap.Value其中RawData.object里就是可读的属性字段。找到后直接修改数值保存文件再执行上面的回写命令即可。验证转换无损一行脚本见真章比特级一致这个承诺不是嘴上说说。仓库里提供了专门的验证脚本commands/resave_test.py它把一个.sav完整走一遍SAV → JSON → SAV流程然后解压对比前后两个文件的原始 GVAS 字节是否完全相等。# 验证存档转换是否无损产出 .resave.json 和 .resave.sav python -m palworld_save_tools.commands.resave_test Level.sav # 输出Files are the same!动手改存档前强烈建议先对原始文件跑一次这个验证确认当前游戏版本与工具兼容、转换链路无损。这也是最稳妥的安全网。三个高频实战场景从单文件编辑到批量运维场景一单文件角色数值调整目标修改某个玩家或帕鲁的指定属性后无损回写。转换存档为 JSONpython -m palworld_save_tools.commands.convert Level.sav用现代编辑器VS Code 或 JetBrains IDE打开Level.sav.json。注意文件可能非常大普通记事本打不开。在CharacterSaveParameterMap下按group_id或角色 ID 定位目标修改RawData.object中的数值字段。回写并验证python -m palworld_save_tools.commands.convert Level.sav.json python -m palworld_save_tools.commands.resave_test Level.sav注意事项修改前务必备份原始.sav改动尽量只动目标数值不要删除或重排数组元素否则可能破坏属性树结构。场景二服务器存档批量处理目标批量转换整个目录下的存档用于巡检或迁移。import subprocess from pathlib import Path def batch_convert(sav_dir: Path, out_dir: Path, to_json: bool True): 批量转换目录内所有存档文件 out_dir.mkdir(exist_okTrue) files list(sav_dir.glob(*.sav)) if to_json else list(sav_dir.glob(*.json)) for f in files: out_suffix .json if to_json else .sav out_file out_dir / (f.stem out_suffix) subprocess.run([ python, -m, palworld_save_tools.commands.convert, str(f), --output, str(out_file), --minify-json ], checkTrue) print(f完成 {len(files)} 个文件转换) batch_convert(Path(save_games), Path(json_output))这里用--minify-json压缩输出体积用--output指定输出目录避免默认命名把文件写到原目录。批量回写时把to_json置为False即可。场景三只解析你关心的数据省时省内存目标只想看公会和角色数据跳过据点、地图对象等无关部分。# 只解码公会与角色数据其余保持原始字节 python -m palworld_save_tools.commands.convert Level.sav \ --custom-properties .worldSaveData.GroupSaveDataMap,.worldSaveData.CharacterSaveParameterMap.Value.RawData--custom-properties接收逗号分隔的属性路径对应paltypes.py中的PALWORLD_CUSTOM_PROPERTIES键。默认值是全部解析当存档巨大、内存吃紧时用这个参数裁剪解析范围能显著降低峰值内存。排坑指南与性能优化把踩过的坑提前告诉你高频错误一内存不足Level.sav转成 JSON 后动辄数百 MB解析过程需要同时在内存里持有解压数据、属性树和 JSON 对象。对策有三用--minify-json减少输出体积用--custom-properties裁剪解析范围确保 Python 是 64 位版本。高频错误二报错not a compressed Palworld savepalsav.py里的魔数与长度校验很严格。这个报错通常意味着文件本身损坏、或根本不是 Palworld 存档、或游戏更新后压缩格式变化。先检查文件完整性再确认工具版本是否支持当前游戏版本。项目仍在快速迭代建议跟进最新版本。高频错误三JSON 里出现NaN/Inf部分浮点字段可能携带非有限值标准 JSON 不合法。转换时默认保留这些值方便无损回写但如果下游工具要消费 JSON可以加--convert-nan-to-null把它们变成null——代价是Inf信息会丢失回写无法完全还原。性能优化思路输出默认带缩进方便阅读机器消费时务必--minify-json。可选依赖recordclass能加速属性解析通过pip install palworld-save-tools[performance]安装不想引入依赖也能用FORCE_STDLIB_ONLY1环境变量强制纯标准库路径。超大存档建议分批处理先--custom-properties只导出需要的子结构而不是一次性全量解析。一个重要的设计提醒为什么零依赖项目明确声明正确性优先于性能、无额外依赖。前者保证了 SAV → JSON → SAV 的比特级还原后者意味着你可以在干净的 Python 环境直接运行不必为打包分发、杀毒软件误报操心。理解这两条原则你就理解了它和 uesave 等通用工具的根本差异——通用工具追求能读这个工具追求读得准、写得回。它的价值不止于改存档应用生态与演进方向回到开头那个问题当你真正跑通一次转换 → 修改 → 回写 → 验证的完整闭环你会意识到这个工具的价值并不局限于手工改数值。存档迁移官方已有多款基于它的衍生项目比如把联机存档迁移到专用服务器的工具palworld-host-save-fix、帕鲁可视化编辑 GUIPalEdit、以及通过 RCON 和 SAV 解析管理服务器的面板工具palworld-server-tool。数据洞察JSON 化的存档让数据分析成为可能——统计帕鲁个体值分布、分析物品生成逻辑、研究公会结构这些过去只能靠游戏内观察的内容现在可以程序化处理。容灾恢复把存档定期转成 JSON 存入版本库即使二进制文件损坏也能从 JSON 历史版本重建。项目自身的 Roadmap 也很明确继续补全所有已知数据块的解析rawdata/下模块还在增长以及优化 CPU 与内存占用。前者意味着未来游戏更新后能更快跟进后者意味着超大存档的处理门槛会进一步降低。核心优势一页纸无损转换SAV → JSON → SAV 比特级一致有resave_test.py可验证深度解析覆盖公会、角色、物品容器、据点、地图对象等全部已知数据结构零依赖部署纯 Python 标准库Python 3.9 开箱即用灵活裁剪--custom-properties按需解析兼顾内存与速度生态成熟已被多个第三方存档工具作为底层引擎如果你正在运营 Palworld 服务器或者想深入研究游戏数据现在就克隆仓库跑一次转换实验吧——先用resave_test.py验证无损再放心大胆地改。工具的命令行入口在palworld_save_tools/commands/convert.py想了解某个数据结构的解析细节直接翻开palworld_save_tools/rawdata/对应模块你会惊讶于这些二进制解析代码写得有多规整。【免费下载链接】palworld-save-toolsTools for converting Palworld .sav files to JSON and back项目地址: https://gitcode.com/gh_mirrors/pa/palworld-save-tools创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考