Talk:GMA
GMA File Documention
I've been looking around for documentation related to the GMA format and found this GitHub page which has this code which reads GMA files. Below I will document how GMAs are read, which I can confirm does work with my implementation in C#. If any information below is wrong or you have thoughts, please amend the details or comment.
The file starts out with a header, describing information about the GMA itself:
struct GMAHeader
{
int Signature; // File's Signature, always 'GMAD' (0x47 0x4D 0x41 0x44)
byte Version; // GMAD Version, only '3' has been seen
ulong AuthorSteamID; // The ID of the Steam user who authored the GMA
ulong TimeStamp; // TimeStamp in Unix Time of when the GMA was authored
byte padding; // Padding byte, always 0x00
string AddonName; // Null-terminated string of the name of the addon
string JSON; // Null-terminated string of the JSON data, indicating the addon type, tags, etc.
uint AddonVersion; // The addon's version, starts at '1' (0x01)
};
Immediately trailing the header, a list of file entries begin, detailing information about each file but not storing the file data in this section:
struct GMAFileEntry
{
string FilePath; // Null-terminated string of the filepath of the file. Example: "folder1/voice1.wav"
ulong FileLength; // Length of the file's data
uint CRC32; // Checksum of the file's data
};
Each GMA File Entry has a uint before it with a number, counting the current file. The first 4 bytes at the end of the GMAFileEntry block will always be '0', indicating the end of the block. The GMA File Entry block can be read like this:
BinaryReader reader = new BinaryReader(MemoryStreamWithGMAData);
while(reader.ReadInt32() != 0)
{
ReadGMAFileEntry();
}
Following the GMA File Entry Block, the rest of the file is data from the files packed into the GMA. They exist in the same order as the GMA File Entry and can be read by reading the amount of bytes based on the file's length.

byte[] FileData = reader.ReadBytes((int)GMAFileEntry.FileLength);