xxP File Structure

I'm sure PSO2 will get a US version some time this century. Meanwhile there is a patch and this is the forum where you can discuss it and get help with issues.

xxP File Structure

Postby Chikinface » Mon Mar 28, 2016 1:59 pm

xxP files are PSO2 character creation files. They can be made from data read from a CML but otherwise they don't resemble a CML all that closely. It's actually a pretty simple file format that's just run through Blowfish encryption.

It has a 16 byte header.
First is an int, usually 6. Then it's another int for filesize (excluding the header) and then a 32bit checksum followed by 0s.

Following the header is a large chunk of signed ints; essentially all of the ints present in the CML file only without the tags or element IDs. Specifically all the data from the DOC, FIGR, COLR and SLCT tags. However unlike the CML format (and because there are no tags or IDs), the order of each element is fixed. So it is always FIGR[1,2,3..] then COLR[1,2,3..] then SLCT[1,2,3..] whereas I've seen CML files go FIGR[20,1,2] SLCT, SLCT, SLCT, SLCT, COLR...

Like the CML format, it isn't 100% understood. There are still some odd quirks I've seen the format do that I don't yet understand (such as a set of colour sliders that duplicates itself for some reason)

File Names

The filename is related to the character's sex and race.

The first letter is f or m, for female or male.

The second letter is h, n, c or d, for human, newman, cast and dewman respectively.

Replace the xx with these two letters and you get the complete filename (example, fdp for a female dewman).

Note that the file contains race and sex data, so just editing the filename won't be enough to make a race change.

Data Structure

This section details the locations of each part of the character, mapped from the cml in part. As such it may not be 100% accurate, but judging by the consistency of Parser results it seems to be.

Offsets are inclusive of the header.

Note that CML tags are included for labelling convenience, they're not present in the file.

Code: Select all
DOC (ints)
10 - Race               
14 - Sex               
18 - Unknown            

FIGR (3 ints each)
1C - Main Body             
28 - Arm               
34 - Leg               
40 - Bust               
4C - Unknown            
58 - Face Shape            
64 - Eye Shape            
70 - Nose Height         
7C - Nose Shape            
88 - Mouth               
94 - Ears               
A0 - Neck               
AC - Waist               
B8  - Main Body2            
C4 - Arm2               
D0 - Leg2               
DC - Bust2               
E4 - Unknown            
E8 - Neck2               
F4 - Waist2   

Note: Main Body2, Arm2 etc appear to be for having multiple proportions. This may be for allowing characters to have one set of proportion for cast parts and another for outfits.            
COLR (3 ints each)
170  - Unknown   - Changed to a copy of 184 on changing body part
178 - Costume Color         
184 - Main Color            
190 - Sub1               
19C - Skin/Sub2            
1A8 - Left Eye/Sub3         
1B4 - Right Eye/Eyes         
1C0 - Hair               
1C8 - Unknown            

SLCT (1 int each)
244 - costume/body      
248 - bodypaint               
24C - sticker             
250 - Right Eye            
254 - eyebrow            
258 - eyelash            
25C - facetype            
260 - unknown            
264 - Makeup1            
268 - hairstyle            
26C - acc1                
270 - acc2                
274 - acc3                
278 - Makeup2            
27C - Leg Part            
280 - Arm Part            
284* - acc4                
288 - Basewear            
28C - Innerwear            
290 - bodypaint2

It's still missing a value for the 2nd hair colour because I have yet to actually see what this data looks like. I don't have any dual haircolour files to test this with.

Accessory Values

Unlike the CML files, xxP files contain a section near the end that holds accessory position data (for transform, rotation and scale). Like the rest of the data, it's slider data rather than actual transforms, but unlike the rest of the data it is not stored as a series of ints.

It's stored as a series of signed Nybbles (so it runs from -8 to 7). Play with one of the sliders, you'll see it moves in these fixed steps. The way it's stored is kind of all over the place. This is still being studied and honestly I'm not really sure of a good way to represent it. Here's an attempt anyway:

Code: Select all
accessory adjustment:   2C4 - 2D5 (One Nybble per slider)
nybble in decimal offset relative to 2C4

Format nXy where n = accessory number, X is either P, R or S for position, rotation and scale, y is axis.

Still under construction.

1Px - 3
1Py - 0
1Pz - 1
1Rx - 15
1Ry - 12
1Rz - 13
1Sx - 27
1Sy - 24
1Sz - 25
2Px - 7
2Py - 4
2Pz - 5
2Rx - 19
2Ry - 16
2Rz - 17
2Sx - 29
2Sy - 26
2Sz - 27
3Px - 10
3Py - 18
3Pz - 14
3Rx -
3Ry -
3Rz -
3Sx -
3Sy -
3Sz -
4Px - 
4Py - 
4Pz - 
4Rx -
4Ry -
4Rz -
4Sx -
4Sy -
4Sz -

End of file

At the end of the file is about 0x16 bytes of unknown stuff! Typically it's two numbers but it always seems to be 2 (short) and 1 (short) followed by nothing but 0s.
User avatar
Posts: 329
Joined: Thu Feb 16, 2012 12:18 am

Return to PSO2 Patch

Who is online

Users browsing this forum: No registered users and 1 guest