18 hours ago18 hr <removed by moderator>Hi everyone!I’m sharing the resources extracted from the .hdr / .pak archives of City Racing <removed by moderator> and Python script for extraction. This post describes the archive structure, the extracted file types, and the extraction method.Source archivesThe game stores its resources in four archive pairs. Each .hdr contains the file index, while the corresponding .pak contains the actual file data:Objects.hdr / Objects.pak — 284 object descriptions and configuration files.SD.hdr / SD.pak — 119 audio files.Textures.hdr / Textures.pak — 336 texture files.World.hdr / World.pak — 822 mesh and miscellaneous data files.Contents of the attached ZIPThere are 1,561 extracted game files, plus an extraction manifest:647 .msh files — custom binary meshes, including vehicles, characters, buildings, roads, sidewalks, and other scene geometry. These are game-specific files, not a standard interchange format.284 .obj files — XOR-obfuscated text descriptions and configuration files. These are not Wavefront OBJ models. Once decoded, they contain resource paths, object properties, vehicle parameters, effect settings, and placement information.267 .jpg files — JPEG textures.69 .dds files — DDS textures using DXT1, DXT3, DXT5, or uncompressed 32-bit formats. The collection also includes a cubemap and a volume texture.119 .wav files — RIFF/WAVE audio resources.175 .dat files — miscellaneous game data, including terrain heights, route/map data, rendering-technique definitions, and font data. The extension covers several different structures, not one universal format.EXTRACTION_MANIFEST.json — archive metadata and the path, size, and SHA-256 hash of each extracted resource.The directory structure is preserved under the source archive name: The directory structure is preserved under the source archive name:Objects/Data/...SD/Data/...Textures/Data/...World/Data/...EXTRACTION_MANIFEST.jsonHow the files were extractedI used a custom Python extraction script to read the original archive indexes.Read the entry count from the final four bytes of each .hdr.Parse each entry’s filename, file size, and offset.Decode the filename bytes using XOR 0x80. The terminating zero byte, size, offset, and entry count are stored unencoded; the integers are little-endian.Seek to the recorded offset in the matching .pak and copy exactly the recorded number of bytes.Recreate the indexed directory paths and calculate SHA-256 hashes for the extracted files.For these four archives, the entries cover the corresponding .pak files completely, without gaps or overlaps. No additional archive-level decompression was needed: extraction consists of locating and copying the indexed byte ranges. Individual payloads such as JPEG or DXT textures still use their own compression.Important notesThe attached files are raw extracted resources, not converted assets. In particular, the .obj descriptions still need bytewise XOR 0x80 decoding before they can be read as text. The binary .msh files require a format-specific reader.The original archives were not modified, and the extracted payloads were checked against their recorded sizes and hashes. Some .dat structures and mesh fields still need further investigation.Hopefully this is useful for anyone researching the game’s resource formats, textures, models, audio, or configuration files.extract_game_archives.py
Create an account or sign in to comment