Skip to main content

Ski Files

This information is taken from resources for Perfect World. While Perfect World and other Angelica engine games are very similar there may be some differences. This information needs to be confirmed for Ether Saga.

General File Structure

OffsetNameData SizeTyp. ValuesMeaningComments
0x0000moxbiksa[8]CHAR"MOXBIKSA"file type identifierSki BMOX
0x0008ski_typeDWORD8 or 9Type 9 has bone names listed, type 8 doesn't
0x000Cmesh_count[4]DWORD1,0,0,0 or 2,0,0,0number of meshesDefines a vertex_type as well. (index to mesh_count[]); so vertex_type goes (0,1,?,?)
0x001Ctex_countDWORD1 or 2number of textures
0x0020mat_countDWORD1 or 2number of materials
0x0024num_bipsDWORD4 or morenumber of “bones”if ski_type=8, always no bips (but num_bips=4)
0x0028(unknown_2)DWORD0only value 0 spotted currently
0x002C(type_mask)DWORD41 or 43 or ...num.Bones in *.bonSeems to identify the type of Avatar; Human_Female=41, Demon_Female = 43, Human_Male = 35, ...
0x0030zero_60DWORD0,0,0,...just 15 zero DWORDs (or 60 zero BYTEs)
IF ski_type == 9:	{{{				
	Bone Names				
0x006C	Repeat [num_bips]:	{{{			
	bone_len	DWORD	e.g. 12	string len (bone name)	
	bone_name[len]	CHAR	“Bip01 L Foot”	the bone name string	no trailing /0
	}}}	}}}			
					
	Textures				
0x006C + (bones)	Repeat [tex_count]:	{{{			
	tex_len	DWORD	e.g. 16		number of bytes, not chinese letters
	tex_name[len]	CHAR	"中式婚礼女鞋.dds”	Texture file name	(maybe unicode)
		}}}			
	Materials				
	Repeat [mat_count]:	{{{			
	MatHeader	String-z	“MATERIAL: “/0	Header for Mat.Block	10 bytes + trail-/0
	mat_values[16]	FLOAT	1, 1, 1, 1, 1, 1, 1, 1,	(unknown)	could be a matrix ...
			0, 0, 0, 1, 0, 0, 0, 1	(unknown)	... or other float parameters
	scale_param	FLOAT	9.999 or 19,999 or 10.0	a scaling factor?	(a “0” was spotted too)
	is_clothing	BYTE	0x00 or 0x01	if fashion or not?	could be boolean
		}}}			
	Meshes				
	Repeat [mesh_count]:	<<<			
	obj_len	DWORD	e.g. 8	string len (mesh_obj)	
	mesh_obj[len]	CHAR	"萤火虫_0”	name of the model	no trailing /0
	tex_index	LONG_32	0 or 1 or ...?	index to texture	none if -1
	mat_index	LONG_32	0	index to materials	
IF vertex_type == 1:	{{{				vertex_type: (see “mesh_count[]” above)
	extra_data[4]	BYTE		(unknown)	
	}}}				
	vertex_count	DWORD	1235	number of vertices	
	faceverts_count	DWORD	6084	number of faceverts	faceverts_count = 3*face_count, because always triangles
					
	Vertices				
	Repeat [vertex_count]:	{{{			
	vertex_position[3]	FLOAT	(0.05, 1.0, -0.234)	vertex coordinate	-X, -Z, Y
IF vertex_type == 0:	{{{				
	vertex_weight[3]	FLOAT	(0.7, 0.3, 0.0)	bone influence ?	seem 2nd value is always between 1st and 3rd
	bone_index[4]	BYTE	(3, 12, 0, 27)	list of 4 “bones”	the order must be kept; don't sort!
	}}}				
	vertex_normal[3]	FLOAT		vertex normal vector	
	vertex_UV_coord[2]	FLOAT		u/v-coordinate of vertex	U, 1-V
		}}}			
	Faces				
	Repeat [face_count]:	{{{			face_count = faceverts_count / 3
	vertex_index[3]	USHORT_16	(123, 122, 144)	3 indices to vertices	
		}}}			
	(End Meshes)	>>>			
					
	[EOF]