How to Convert Local Archives to Server Archives in Palworld#
Before Reading#
Please make sure you have some hands-on ability. Based on the assumption that you can start the server, the following text will assume that the reader can use Python3 and the terminal.
Prerequisites#
- Python3
- MuelNova/Palworld-Save-Patcher
- The archive to be converted, referred to as
%SAVE%
in the following text, should look similar to the following:
%SAVE%
├── LevelMeta.sav
├── Level.sav
├── LocalData.sav
├── Players
│ ├── 00000000000000000000000000000001.sav
│ ├── PLAYER_B_GUID.sav
│ └── PLAYER_C_GUID.sav
└── WorldOption.sav
Version Information (Timeliness)#
- Palworld v0.1.2.0
- Server deployment using https://github.com/thijsvanloef/palworld-server-docker
Modification Process#
Extracting Server Archives#
First, make sure your server is fully started and copy the %SAVE%
to the server archives.
The original host logs into the game, and there should be a need to create a new user. At this time, create a new user and perform some operations before exiting.
At this point, there should be a new file in the %SAVE%/Players
folder. This GUID is specific to each STEAM user, and we use 0D000721000000000000000000000001.sav
to represent it.
%SAVE%
├── LevelMeta.sav
├── Level.sav
├── LocalData.sav
├── Players
│ ├── 00000000000000000000000000000001.sav
│ ├── PLAYER_B_GUID.sav
│ ├── 0D000721000000000000000000000001.sav
│ └── PLAYER_C_GUID.sav
└── WorldOption.sav
At this point, 0d000721000000000000000000000001 is the GUID of the original host.
Close the server and make sure you have backed up the %SAVE%
folder.
Running the Script#
git clone https://github.com/MuelNova/Palworld-Save-Patcher.git
cd Palworld-Save-Patcher
python script.py fix-host %SAVE% %GUID%
# Please replace with your own
# python script.py fix-host /home/nova/test_pal 0d000721000000000000000000000000
Restarting the Server#
At this point, the original host should already have something, but the name and guild no longer exist. You need to join a friend's server to fix this. This is also a small flaw (because these contents exist in BYTE and it is not convenient to modify using uesave).
Principle#
People who are not interested in this part can skip it.
Analysis of Archive Files#
Under %applocaldadta%\Pal\Saved\SavedGame\<STEAM_ID>\<WORLD_ID>
LocalData.sav#
Saves the map, unrelated to the user. You can directly copy it to another archive to skip the process of opening the map.
Level.sav#
Key file, saves all resources, their owners, and map events.
Player/xxxxxx.sav#
Player file
.sav Files#
Currently, only the modification method is known, not the principle. You can refer to this gist: Converting PalWorld saves to JSON and back (github.com).
First, for a .sav
file, it is not a standard UE .sav file header, but a file compressed with zlib
(or double compressed).
[0:4]
is the uncompressed size.
[4:8]
is the compressed size.
[8:11]
is a fixed magicNumber "PlZ".
[11]
is a type, which may have the following values: 0x30, 0x31, 0x32
. Among them, 0x30
is not used yet. 0x31
is zlib compressed once, and 0x32
is zlib compressed twice.
[12:]
is the compressed data.
After decompression, it becomes a GVAS file, which can be directly converted to a json file using libraries like trumank/uesave-rs: Rust library to read and write Unreal Engine save files (github.com).
uesave to-json --input <GUID>.sav.gvas --output <GUID>.sav.json