Many of the properties of objects in the toolset make reference to 2DAs (two-dimensional arrays). These are read-only arrays containing various data used by scripting and the game engine. Each 2DA is simply an organized collection of strings and numbers. The specific function of each 2DA depends on how it is used by other systems in the game.
Overview - what is a 2DA?
A 2DA contains a set of columns, with each column having a fixed label and a fixed data type. For example, the ABI_Base 2DA has a column that is labeled "namestrref" and has the data type "int". This means that the data stored in this column must be an integer and that the data stored in this column can be retrieved by referring to the label "namestrref". The number and types of columns in a 2DA does not usually ever change. The columns provide the structure of the 2DA that allows it to be referred to and used in a consistent manner. The first column of every 2DA is always labeled "ID" and is always of type "integer". This column is used to uniquely identify the rows in the 2DA.
A 2DA's rows are what contain the data being stored in it. Each row's columns have the same set of labels and data types (as defined at the top of the 2DA) but the data contained within them can be different. Adding new rows to a 2DA is common and easy; you just need to give it a new ID number in the "ID" column and then fill in the rest of the cells with whatever information you need. Once you've given a row an ID number it generally never changes. The game also has a mechanism called "M2DAs" that allow rows to be added to existing 2DAs without having to edit the original file, see below for more detail.
Some 2DAs reference rows in other 2DAs. For example the ABI_Base 2DA has an integer column named "projectile", and each row can have an integer in that column that identifies a row in the PRJ_Base 2DA. These relationships are generally only defined in the scripts that use the 2DAs and are not inherent to the 2DAs themselves so you'll have to keep track of these things yourself.
Excel file formatting
The source files for 2DAs are Microsoft Excel worksheets. This allows a wide variety of sophisticated techniques to be used to generate the values of the 2DA fields, such as macros and formulas. It also makes editing much easier since the columns can be annotated and formatted in helpful ways, and multiple related worksheets can be grouped into one file.
The official campaign source files are in the folder (Program Files)\Dragon Age\tools\Source\2DA, where (Program Files) is the folder in which Dragon Age was installed.
Before they can be used by the toolset or the game, 2DAs must be converted from Excel files into a more efficient form. Processed 2DAs are stored in files with the .GDA extension.
See: compiling 2DAs - for several methods of how to perform this conversion, and where to put 2DAs.
|i stay unused
Data in a 2DA is identified by a row number, with the first row (using ID zero) usually being reserved for internal use (undefined value, etc.) by convention. Each row has an arbitrary number of columns identified by strings. The grey fields in this example table are very specific to the 2DA, the white fields are arbitrary data which the Gameengine identifies for that 2DA.
The ID of a Row is the reference for the Game to access and link to them. As such they are unique across the 2DA, and any M2DA that extends it. The contents of each column is specific to the 2DA given, and arbitrary. When extending a 2DA, new ID's have to be given, and Columns have to be exactly the same.
- Cell A1 will contain "ID". This is checked by the processor and the worksheet will fail if this is not the case.
- Column A starting at line 3 will contain an integer row ID number that is unique to that row across all files (unless creating an M2DA override). Row IDs will be listed from smallest to highest within the same file and do not need to be consecutive.
- A blank row or column will determine the dimension of the spreadsheet in that direction. Everything past that point is ignored by the binarizer.
- Column names are case sensitive. This is because of the CRC32 algorithm used to generate the hash key. Changing the case of a column name after it is in use will break the game. White space before and after a column name will be removed before hashing.
- Row 2 will be a "types" row. Each is a single word: int, string (single chars as well), resource, float or bool. A special type "comment" can be used to exclude a column from export.
- Any column with string data that refers to files should have a type of "resource" and not "string". This is because the "resource" type is used to determine dependencies for the 2DA file.
- 'bool' type may be one of: a zero or non-zero number, Yes or No (case insensitive), or words beginning with T or F (such as True! and False!). NOTE: You cannot use TRUE and FALSE because Excel converts those to a special keyword the binarizer can't parse properly at this time. Note: the scripting language doesn't have a function for retrieving boolean values from a 2DA, and the behavior of Get2DAInt when retrieving a boolean is untested. It is probably safer to just use an integer for scripting purposes.
- If you wish to leave a cell unfilled, the string "****" (four asterisks) can be inserted instead of a value.
- Any worksheets that are not exportable 2DA data will have an underscore prepended to their name - the resource builder will subsequently ignore them.
- Worksheets need to have unique names among all excel files, duplicates will overwrite each other as each worksheet is exported as a file
- You cannot have the workbook open in Excel at the same time as running the binarizer on it.
- Strings have a maximum length of 768 characters. Anything longer will be truncated.
- ExcelProcessor.exe constrains the name length of a worksheet to 27 characters.
Extending the game via M2DAs
An "M2DA" is a "Multiple 2DA" that stacks a number of 2DAs into one larger table. They work much like single 2DA files except they can be patched or expanded later by adding another 2DA. These are useful for any table that lists other resources, such as appearance tables, so that new resources can be added later without having to modify a monolithic table. 2DAs are merged row by row, keyed on the ID column.
This is especially important for third-party modders, since BioWare might release an update to a core table at a later date that would overwrite any changes third parties had made to it. By using an M2DA with a unique name, and by using a range of ID numbers significantly separated from those already in use, you can ensure that your additions won't conflict with other portions of the M2DA.
Every M2DA used by the game is listed in M2DA_base (2DA_base.xls) and is treated as a M2DA, except for those with an ID between 10000 and 10999, which are handled as regular 2DAs. Each M2DA has a label that describes the subject covered by the M2DA and a worksheet prefix that all components of that M2DA must start with, as the name is actually a prefix to the file. The system reads this prefix and then searches through all the 2DAs for the ones starting with this prefix and merges them together as one 2DA. For example: M2DA ID 0 is "ANIM_". The system looks through its list of 2DAs and finds "ANIM_base", "ANIM_combat" and "ANIM_walk". It will read and merge all 3 2DAs into an M2DA called "ANIM_".
Note that M2DA_base is itself an M2DA file and can be extended in the same manner.
- This example 2DA "MonstersCustom" would be merged into the original 2DA "Monsters", if "Monsters" were one of the worksheets listed in the M2DA_base.
Reserved ID Ranges and overriding existing rows
While M2DA files avoid some of the problems associated with ordinary 2DA files, the IDs in each row of the final M2DA must still be unique across all 2DAs associated with it. If you use an existing row ID in your M2DA you can override the existing row with new data. Note that this can be a useful mechanism in some situations, for example allowing you to override existing content without having to edit the original 2DAs directly.
To help ensure compatibility between authors' custom content, you should make sure that the ranges you choose don't conflict with ones already in use: 2DA_ranges_in_use.
To ensure that the M2DA suffix is unique, you might like to register and use a code for your module - see Prefixes in use.
See: compiling 2DAs - for Information on where to place M2DA files to achieve the desired effect.
Bug with M2DA
It should be noted, that currently there is a bug with certain M2DA's, which prevents new ID's above 255 to work in the game. It is unclear which are affected, but most certainly it is ItemVariations.xls related. See Bug report.
2DA XLS files used in Dragon Age
The source files for the 2DAs that came with the installed game can be found under the toolsets directory
Users of Open Office
- Users of Open Office may find that no .gda file is created when they use ExcelProcessor.exe - one workaround is to copy a worksheet from an existing .xls file (such as placeable_types from placeables.xls), process the file, then remove the extraneous .gda file (e.g. placeable_types.gda).
- When editing existing xls files, it also works to leave the format as standard while saving the file. Open Office asks to change the file to its own spreatsheet format when saving a format other then its own, don't change the format and it should work. [Edit- And yet it doesn't seem to.]
When adding strings to a 2DA, you have two options. The simplest is to enter **** for the StringID column. In that case, the name column will be used in the game.
The other approach is to use the toolset's string editor to create a new string. When that happens, you'll get a new StringID. Next enter that number into the StringID column in the 2DA.
The second approach works better when translating your module, at the cost of portability. If someone else wanted to reuse your 2DA, they'd have to generate their own strings, then update the StringID number based on these IDs.
- The current version of the "ExelProcessor"-App is buggy as it can't hanlde INT values above 8388607! Many thanks to elys for figuring that out.
- Also note that the original toolset (v1.0) core-talktable contains wrong ids as well - don't forget to delete it from the "packages\core\override\toolsetexport" directory if you are still using that version.
- Create and export your talktable, delete the core-talktable override.
- Create your M2DA File that you want to refer to your talk-table strings. Never Mind using the real IDs at this stage.
- Use the "Exelprocessor" to create the GDA file.
- Open the GDA-File with the toolset or elys's GDA-Editor App (http://social.bioware.com/project/755/)
- Change the StringIDs to the StringIDs in your talktable.
The previous Version stated: Take that StringID and add 16777216 to the number. this appears to be wrong and is likely a holdover from NWN.
Using a custom 2DA in the toolset
Some 2DA tables are used by the toolset itself - for example, appearances for creatures and rewards for plots.
Once a custom GDA is in the export folder for your module, the next time the toolset is started, it will use your custom table.
|English • русский