EXLT
and it's version following that. Each sequential line after the 'header' is a path, relative to the exd/
category, and its immutable ID. The immutable ID is optional and in cases where not relevant (eg. quest dialogue files) it's value is -1
.Achievement
exd/achievement.exh
Action
exd/action.exh
content/DeepDungeon2Achievement
exd/content/deepdungeon2achievement.exh
content/DeepDungeon2Gacha
exd/content/deepdungeon2gacha.exh
BitConverter.IsLittleEndian
will return whether or not a conversion needs to take place. See the Lumina source code for this file for a working example.EXHF
. If it's not, the file is probably not the file you're trying to read.DataOffset
isn't relevant to this file at all, but is required when loading certain data from Excel Data files such as strings. It points to the end of the fixed size data of a row. For example, a row can be made of a bunch of integral types which have a known length at compile time, however a string length is variable. This offset allows you to then seek to the end of the row and access any additional data that may be on the end. If this is weird, don't worry, because it'll make sense later.ColumnCount
is how many columns exist within the file and is the first thing you'll read after the header. In other words, you'll need to read sizeof( ColumnDefinition ) * ColumnCount
immediately after the header.Offset
is relative to the row offset, which you don't have until you read the offset table from a data file.Type
is the type of data stored. Most don't have any special handling outside of String
and PackedBoolX
but we'll cover that later.PageCount
is the number of 'pages' an excel data sheet is split into. Many sheets only have a single page and every row will exist in a single page, however larger sheets such as Quest
or Item
have many pages. This information is another structure and immediately follows the column definition data.startId
is the row id where a page starts. You'll need this to build file paths for data files.rowCount
is how many parent rows a sheet contains. As a quick example before we cover it more in depth later is that given a row id, you can calculate which page a row is on with row >= startId && row < startId + rowCount - 1
.Default
requires no extra processing and you can just iterate over the offset list inside a data file. SubRows
makes each row contain it's own rows. As a better example, it's like having a compound key on a database table. Instead of one column being the identifier for a row, you have two instead.None
), the following format applies:exd/item_0_en.exd
exd/item_10000_ja.exd
exd/mount_0_fr.exd
exd/quest_65536_de.exd
magic
should always be EXDF
.indexSize
is how large the row offset index is, in terms of total size. To convert that to a number of entries, you'd do indexSize / sizeof( ExcelDataOffset )
.ExcelDataHeader
, the root row offsets are stored. The reason it's called the 'root row offset' is because on variant 2 sheets (or sheets with subrows), this offset won't point to data that can be read following the column data.rowId
is the absolute row id, so a simple way to map these in whatever you're doing is to convert the list of data offsets in this file to a key value map, where the key is the rowId
and the value is the offset
. Then you can directly index rowId
s on any given data page.offset
is the absolute offset to where the data is located in the file. It can be used as is. dataSize
is the entire size of the row, including any data for subrows (if they exist). You can use this field to copy out the exact amount of data for a row (or subrows) to then later parse if you choose not to do it in place.rowCount
is always 1 on variant 1 sheets and you can ignore that field entirely if you choose to. However, on variant 2 sheets, the rowCount
is how many subrows belong to a row.rowOffset
is the offset from the offset list.rowOffset + 6
is the skipping the size of the row header. You could just store the offset once you read the row header and use that.header.dataOffset
points to the end of the raw data of the row, or is basically the 'fixed' size of a row, not including strings. This lets you seek to the end of a row and immediately go to the next subrow.uint32
where there string column is. You can then obtain the offset of the string by doing the following:rowOffset
is the offset of the first column of a row, the dataOffset
from the header and the uint32
that you read out from the column.