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 Offset Name Data Size Typ. Values Meaning Comments 0x0000 moxbiksa[8] CHAR "MOXBIKSA" file type identifier Ski BMOX 0x0008 ski_type DWORD 8 or 9 Type 9 has bone names listed, type 8 doesn't 0x000C mesh_count[4] DWORD 1,0,0,0 or 2,0,0,0 number of meshes Defines a vertex_type as well. (index to mesh_count[]); so vertex_type goes (0,1,?,?) 0x001C tex_count DWORD 1 or 2 number of textures 0x0020 mat_count DWORD 1 or 2 number of materials 0x0024 num_bips DWORD 4 or more number of “bones” if ski_type=8, always no bips (but num_bips=4) 0x0028 (unknown_2) DWORD 0 only value 0 spotted currently 0x002C (type_mask) DWORD 41 or 43 or ... num.Bones in *.bon Seems to identify the type of Avatar; Human_Female=41, Demon_Female = 43, Human_Male = 35, ... 0x0030 zero_60 DWORD 0,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]