// // Pure guesswork based on half a dozen preview savegames. // Header { int08 Signature[8]; // "RISNSG01" int32 Version; // 00000002 int32 Reserved; // 00000000 int32 InfoOffset; // Header-based offset into uncompressed Buffer int32 LayerOffset; // Header-based offset into uncompressed Buffer int32 ObjectOffset; // Header-based offset into uncompressed Buffer } // ZLib-compressed Buffer { // @Header.InfoOffset Infos { int32 Version; // 00000002 int16 NameSize; int08 NameData[NameSize]; // Name of the savegame (UTF-16) int08 unknown0[12]; // 00 00 00 00 00 00 00 00 00 00 00 00 int32 reserved; // (alignment) int64 TimeStamp; // (struct FILETIME) int16 WorldSize; int08 WorldData[WorldSize]; // Name of the world (ASCII) Screenshot { int32 Size; // 00010037 Data { int16 HeaderVersion; // 0001 int08 Signature[5]; // "G3IMG" int32 Version; // 00000002 int32 Width; // 00000080 int32 Height; // 00000080 int32 Depth; // 00000000 int32 CubeMap; // 00000000 (bool) int32 Levels; // 00000001 int32 Usage; // 00000000 int32 ColorFormat; // 00000015 int32 Pool; // 00000001 int32 ImageSize; // 00010000 int32 unknown; // 3078C284 int32 Reserved; // 00000000 int08 ImageData[ImageSize]; // (struct RGBQUAD[]) } } Stats { int32 Size; // 0000000C Data { int32 GameTime; // in seconds int32 Flags; // 1 = Minsky? int32 Chapter; // 1..4 } } Objects { int32 Count; for( Count ) { PropertyId { int08 Core[16]; // (struct GUID) int32 Count; } int32 DataSize; // 00000000 } } } // @Header.LayerOffset Layers { Header { int32 unknown; // 00000001 int32 FilesOffset; // Buffer-based offset int32 EmptyOffset; // Buffer-based offset int32 ObjIdOffset; // Buffer-based offset (00000000) } Buffer { // @Buffer.Layers.Header.ObjIdOffset ObjId { int08 unknown; // 01 int32 Count; for( Count ) { PropertyId { int08 Core[16]; // (struct GUID) int32 Count; // 00000000 } } } Datas[File.Count] { int32 BufferSize; int32 ObjectCount; BufferData { for( ObjectCount ) { ObjectId { int08 Core[16]; // (struct GUID) int32 Count; // 00000000 } ParentId { int08 Core[16]; // (struct GUID) int32 Count; // 00000000 } PropertyId { // Template/Class/Type? int08 UnknownId[16]; // (struct GUID) int32 Count; // 00000000 } int08 unknown; // 01 int32 ObjectSize; ObjectData { int16 unknown0; // 00D6 int08 unknown1; if( unknown1 ) { float unknown0[4][4]; // World matrix? (struct D3DMATRIX) float unknown1[4][4]; // Local matrix? (struct D3DMATRIX) float unknown2[3]; float unknown3[3]; float unknown4[3]; float unknown5[3]; float unknown6[3]; float unknown7[3]; float unknown8[8]; } int08 PropertyCount; for( PropertyCount ) { int16 Type; int08 Index; int32 Size; int08 Data[Size]; //TODO: Document property types/data. } } } } } // @Buffer.Layers.Header.EmptyOffset Empty { int32 unknown; // 00000000 } // @Buffer.Layers.Header.FilesOffset Files { int08 Version; // 01 int32 Count; for( Count ) { int16 NameSize; int08 NameData[NameSize]; // "*.lrent" (ASCII) int32 Offset; // Buffer-based offset into Datas } } } } // @Header.ObjectOffset Objects { int32 Count; for( Count ) { PropertyId { int08 Core[16]; // (struct GUID) int32 Count; } int32 DataSize; switch( ObjectId.Core ) { default: { int08 unknownData[DataSize]; // should be empty } case "{5FE3F973-A484-40f1-AAEA-C769A2B544ED}": { // eCWeatherAdmin float CurrentDayTime; for( 21 ) { float unknown1; float unknown2; float unknown3; int16 Name0Size; int08 Name0Data[Name0Size]; int16 Name1Size; int08 Name1Data[Name1Size]; } } case "{D60C1968-46D1-4e7f-9304-A4262C05425E}": { // gCQuestManager int08 unknown0[6]; // 03 00 01 00 00 00 int32 Count; // 00000172 for( Count ) { int16 NameSize; int08 NameData[NameSize]; // (ASCII) int08 unknown1[18]; unknown2 { int08 unknown; // 01 int32 unknownSize; int32 unknownData[unknownSize]; } Infos { int08 Version; // 01 int32 Count; for( Count ) { int16 unknown; // 0001 int16 NameSize; int08 NameData[NameSize]; // "FO_*" (ASCII) int16 TextSize; int08 TextData[TextSize]; // "INFO_*" (ASCII) } } Links { int16 Count; for( Count ) { int16 NameSize; int08 NameData[NameSize]; // NPC name (ASCII) int32 unknown; } } unknown3 { int08 unknown; // 01 int32 unknownSize; int32 unknownData[unknownSize]; } } } case "{2E410075-FEF5-4881-9A9F-69544569B51F}": { // gCTutorialAdmin int08 unknown0[3]; // 01 01 00 int32 Count; // 00000027 for( Count ) { int16 NameSize; int08 NameData[NameSize]; // (ASCII) int08 Value; // 00 | 01 } } case "{C73CC2FB-3743-459c-8F0D-5B23A1869D97}": { // gCSession int08 unknown0[5]; // 04 00 01 00 01 PropertyId { int08 Core[16]; // {C061A561-A862-4092-9D2D-2E55C18627ED} (struct GUID) int32 Count; // 00000000 } int08 unknown2[7]; // 01 00 00 01 00 00 00 int32 unknown3; // 00000000 (???) | 00000002 (???) } case "{9939FCC5-8FC6-4626-B4DD-6546A0B5D95F}": { // gCInfoModule int08 unknown0[2]; // 01 00 Scripts { int32 Count; for( Count ) { int16 NameSize; int08 NameData[NameSize]; // (ASCII) int08 unknown0[2]; // 01 00 int08 unknown1; // 00 | 01 int32 unknown2; // -1 | >= 0 int08 unknown3; // 00 | 01 } } int08 unknown2[54]; // 00 | 01 Globals { int32 Count; for( Count ) { int16 NameSize; int08 NameData[NameSize]; // (ASCII) int32 Value; } } NpcInfo { int08 unknown0; // 00 int32 Count; for( Count ) { int08 unknown0[3]; // 01 00 01 PropertyId { int08 Core[16]; // (struct GUID) int32 Count; } int32 unknown2[2]; int16 NameSize; int08 NameData[NameSize]; // "NPCINFO_*" (ASCII) } } } case "{f2e3af3b-50f7-4462-9bfe-64174d55a90d}": { // gCCameraAdmin uint32 Version; if( Version == 2 ) { float Matrix[4][4]; } } } } } }