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