About the project
Note: The information here borrows from https://wiki.oatmealdome.me/BCSV, which is where I originally posted my findings. I have since moved the data here with some updated clarifications
BCSV, also known as Binary CSV, is a file format used on the Nintendo Switch which stores data normally stored in a table or spreadsheet in a compact binary file. All information was gathered from reverse engineering the BCSV files found in Animal Crossing: New Horizons
Overview
All data is in little-endian. BCSV files contain 3 main parts:
- 1: A header which sets data such as the number of row blocks, their size, the number of columns, etc
- 2: A list of all column name hashes and their offset inside each row block
- 3: Row blocks
Header
The header sets the BCSV files metadata such as column and row count
Offset | Size | Description |
---|---|---|
0x00 | 0x4 | Row block count |
0x04 | 0x4 | Row block size |
0x08 | 0x2 | Column block count |
0x0A | 0x2 | Always 0x0101 |
0x0C | 0x4 | VSCB Magic |
0x10 | 0x2 | Always 0x1027 |
0x12 | 0xA | Padding |
Column Blocks
Following the header is a list of coulmn blocks. These blocks contain the CRC32 hash of the real column name followed by the relative offset in each row block that that columns data is
Offset | Size | Description |
---|---|---|
0x00 | 0x4 | Identifier |
0x04 | 0x4 | Offset relative to start of each row block |
The `Identifier` is the CRC32 of "column-name data-type", for example `UniqueID u16`. In the case of AC:NH these are entirely in-lined and the game has no knowledge of the pre-hashed strings, so knowing what the columns original names are requires calculating them yourself
The data type for each column is only known at compile time and therefore there is no way to 100% know what each data type is. It is possible roughly determine the type by checking the data size, though (IE, data with a size of 2 could be an int16)
Row Blocks
Following the list of coulmn blocks is a list of row blocks. These blocks contain the actual data from each column in the given row using the relative offset found before. These blocks always begin with the blocks relative offset from the start of the file
Offset | Size | Description |
---|---|---|
0x00 | 0x4 | Offset relative to file start |
0x04 | Row data |