{"name":"Stringtable.csv","title":"Stringtable.csv","type":"topic","url":"https://community.bistudio.com/wiki/Stringtable.csv","revid":373437,"updated":"2025-05-08T11:27:12Z","aliases":["CSV File Format - Stringtables","Stringtable.csv File Format","csv File Format - Stringtables"],"markdown":"### Purpose\n\nStringtables are used to make internationalization easier for the game. They are used in addons, missions, and scripts.\n\nAny strings that are used in the game can be kept separate from the code, and can therefore easily be edited and expanded into different languages.\n\nInstead of using message strings directly in the code you are using a variable. This variable will then contain the actual string, read from stringtable.csv, with the language that's being read depending on the game settings.\n\n### CSV Format\n\nThe **Stringtable.csv** file is an ASCII text file, and can be edited with any text editor.\nOne *could* theoretically use a spreadsheet program (like Excel) to edit the file, but that would be serious overkill.\n'*DO NOT* use a word processor (like MS-Word, or Write) to edit this file though, as it will corrupt it, unless you are very knowledgeable and careful.\n\n> [!NOTE]\n> CSV stands for Comma-Separated Values. Using e.g Microsoft Excel to edit this file *may* corrupt the file, as some language settings will use a semicolon `;` instead of a comma `,`.\n\n- Operation Flashpoint uses [ANSI](https://en.wikipedia.org/wiki/ANSI) encoding, the codepage is defined by the font used.\n  - Operation Flashpoint cannot accept UTF encoding. You need to convert back to ANSI (e.g remove the 3 byte UTF \"BOM\" (byte order mark) tag at beginning of file when converting back the the real game).\n- Armed Assault accepts ANSI, [Unicode](https://en.wikipedia.org/wiki/Unicode) and [UTF-8](https://en.wikipedia.org/wiki/UTF-8) encoding (Unicode will be converted to UTF-8 on load)\n- Arma 2 and Arma 3 both accept CSV but use Stringtable.xml in preference. For whatever reason, Bohemia Interactive have destroyed the default language. It is no longer possible to simply state\n\n```\nSTR_ANYTHING,Some Name\n```\n\nand have all languages accept it. You will get a 'blank' if a specific language (e.g 'german') is not endlessly repeated as well.\n\n### Function\n\nCSV files are used as string lookup tables.\n\nAlthough the engine uses other files with the extension CSV, the file for missions, addons, and campaigns is 'stringtable.csv' and **must** be located in the primary folder of the mission/addon/campaign.\n\nIn point of fact, the naming convention inside a csv is such that the first three letters of any variable (more later) **must** begin with `STR`, and referenced in mission.sqm, description.ext or anywhere else as `$STRsomething`.\n\nThe characters `STR` tell the engine to look in 'stringtable.csv' as opposed to use the literal string value.\n\n### Format\n\n#### Language Columns\n\nThe basic idea is that every language is assigned one column. (e.g. English has one column, French has another.) The order of the columns doesn't matter. (i.e. whether English comes first, or French, or Czech, is irrelevant). However, when game language doesn't match any of the languages listed in stringtable, the first column is selected by default. Therefore it is recommended to use English there.\n\nThe very first line of any csv must contain a statement like this:\n\n```\nLANGUAGE,  Polish, Hungarian, Turkish\n```\n\nWith this line you define the order in which the language columns are arranged. You can have as many or as few as you like.\n\nBelow this line the CSV file contains one line for each string definition; starting with the string *name*, and followed by the translations for the different languages:\n\n```\nLanguage,  English,Turkish,French\nSTR_BROKEN,Broken, Bozuk,  Merde\nSTR_GOOD,  Good,   İyi,\nSTR_BAD,   Bad,    Kotu,   Merde, Encore\nSTR_FIXED, Fixed,  Sabit,  \"Merde, Encore\"\nSTR_ONE,   One,    ,    Une\n```\n\n#### Blank Strings\n\nNote some interesting and highly flexible aspects of the above syntax.\n\nThere is **no** French equivalent for `STR_GOOD`, nor is there a Turkish equivalent for `STR_ONE`. The engine will default to the 2nd column. It happens to be 'English', but need not be.\n\n**ArmA:** In ArmA this is different. If your country column exists, it will use that string, even if it is blank and not default to the 2nd column. So do not include languages in the LANGUAGE row which you are not utilising yet.\n\n#### Default Language Column\n\nThe second column (the first 'string') is the default. Because of that, it is important that *all* of the 2nd columns are filled.\n\nThe second column does not *have* to be English - it can be any language the author is most comfortable with, and for which he will be able to supply *all* the required definitions.\nIn that case though, he will have to adjust the \"LANGUAGE, ...\" column definition at the top of the file.\n\n**ArmA:** In ArmA, if your language column is missing, then it will default to the game distributor's language column, if it exists.\nSo if you own the German version of the game and a German column exists in any column and your chosen language is not in any column, then German will be used, even if German is not in the 2nd column.\n\n#### Commas and Quotes\n\nTo separate strings from one another, commas are used. String do not have to be enclosed with quotation marks.\nIn the case that commas are needed in the string definition itself, then that string would have to be enclosed by quotes (e.g. \"Merde, Encore\" you *would* need quotes).\n\n#### Leading/Trailing Spaces\n\nWhen defining a string, the text used by the engine is from the *first non space character* after a comma, until the *last non space character* before the next comma (or end of line).\nThis would be familiar to many programmers as the Trim() function.\n\nThus\n\n```\n,this is a text,\n,      this is a text       ,\n```\n\nwould both return *\"this is a text\"*.\n\nThis feature is helpful if you want to keep columns aligned (tabbed), to keep better track of the columns.\n\n### Usage\n\nDefinition in stringtable.csv:\n\n```\nLANGUAGE,    English,          German\nSTR_MOVETO,  Move to the,      Gehen sie zum\nSTR_STATION, railroad station, Bahnhof\nSTR_AIRPORT, airport,          Flughafen\n```\n\n#### Scripts\n\nActivations and conditions too.\n\nArma\n\n```sqf\n_text = localize \"STR_MOVETO\" + \" \" + localize \"STR_AIRPORT\";\n```\n\nOperation Flashpoint\n\n```\n_text = $STR_MOVETO + \" \" + $STR_AIRPORT\n```\n\n#### description.ext\n\n```cpp\n \"$STR_AIRPORT\"\n```\n\n#### mission.sqm\n\nMarkers, texting effects, mission name, etc:\n\n> [!IMPORTANT]\n> If adding string table entry through the mission editor, the proper syntax is automatically added to the mission.sqm.\n> If you are converting a mission from OFP to ArmA, you may need re-add the string table to avoid the `\"scalar bool array string 0xe0ffffef\"` error.\n\nOperation Flashpoint\n\n```\n@STR_AIRPORT\n```\n\nArma\n\n```\n\"@STR_AIRPORT\"\n```\n\n### Comments\n\n- Arma: Arma doesn't appear to accept any (type of) comment string. Every line appears to be a string entry to Arma, with obvious consequences when converting from a properly documented (commented) Operation Flashpoint csv\n\nAny syntax the engine cannot understand is interpreted as a comment.\n\nBy convention the double-forward slash (//) at the beginning of the line is used:\n\n```\nLANGUAGE,     English,          German\n// actions\nSTR_MOVETO,   Move to the,      Gehen sie zum\nSTR_DESTROY,  Destroy the,      Zerstören sie den\n// locations\nSTR_STATION,  railroad station, Bahnhof\nSTR_AIRPORT,  airport,          Flughafen\n```\n\nHowever, in practice anything that *doesn't* start with STR can only be a comment.\n\nArma 2: To insert a string refering to a stringtable.csv or stringtable.xml, don't use the \"\" in the editor.\nFor example: you have `STR_myString`.\nTo add it in the description field of the selected unit, just add it like `@STR_myString`, the \"\" will be added, self-acting by the editor, in mission.sqm.\n\n### The selected language\n\n`flashpoint.cfg` in the root directory of your operation flashpoint folder defines the language to be used for your installation:\n\n```cpp\nLanguage=\"English\";\n```\n\nThis can be changed to any language that has valid entries in the stringtable.csv's. For more information on this subject read Language Selection.\n\n### Replacing original game texts\n\nIt is possible to replace every message of the original game by editing the global stringtable.csv file (in \\res\\bin\\stringtable.csv).\n(Some messages, like addon names some GUI texts, briefing chapters (Plan, Notes, Gear, Group), etc. *cannot* be changed via the stringtable.csv though).\n\nFor example, you can create custom radio names for your squads.\n\nCreate your group and give them a normal radio name with the following command in the init line of the commander.\n\n```sqf\nthis setGroupId [\"Alpha\", \"GroupColor0\"];\n```\n\nNow, add in your Stringtable.csv:\n\n```\nSTR_CFG_GRPNAMES_ALPHA, \"Your group name\",\nSTR_CFG_GRPCOL_BLACK, \"Your color name\",\n```\n\nWhere *Your group name* is the custom name you'd like your squad radio messages to have, *Your color name* is color of the squad (GroupColor0 is Black, for more details see setGroupId).\n\n### Different sounds under different languages\n\nYou can use *stringtable.csv* not only for texts but sounds and other Description.ext classes. See example:\n\nstringtable.csv\n\n```\nLANGUAGE,\"English\",\"Polish\"\n\nSTR_R1,\"ENGLISH\",\"POLSKI\"\nSTR_R2,\"US AND A SOLDIER HERE.\",\"TUTAJ POLSKI ŻOŁNIERZ.\"\n\nSTR_RadioMsg1,\"ENG\\R1.WAV\",\"POL\\R1.WAV\"\nSTR_RadioMsg2,\"ENG\\R2.WAV\",\"POL\\R2.WAV\"\n```\n\nOf course all sounds we have in *Sound* directory. Moreover they are in two different folders: *POL* and *ENG*. It makes *Sound* more clean. You can use prefixes like: *eng_* or *pol_* insted.\n\nDescription.ext (CfgRadio class only)\n\n```cpp\nclass CfgRadio\n{\n    sounds[] = {};\n\n    class R1\n    {\n        name = \"Radio #01\";\n        sound[] = { \"$STR_RadioMsg1\", db + 10, 1.0 };\n        title = \"$STR_R1\";\n    };\n    class R2\n    {\n        name = \"Radio #02\";\n        sound[] = { \"$STR_RadioMsg2\", db + 10, 1.0 };\n        title = \"$STR_R2\";\n    };\n};\n```\n\nHow does it work? During loading, Description.ext exactly, all string values preceded with *$* (dollar) are changed on right entires from *stringtable.csv*.\nSo when a player run game under English language, they will have English texts and sounds. The same think with Polish and other specified languages.\n\nThis solution you can use for CfgIdentities class to create personages with translated names or even native faces.\n\n**Notes:**\nThere are instances where the radio name will revert to the default after a reload of the mission.\n\n```cpp\nclass CfgSounds\n{\n    sounds[] = { 07av1 /* etc */ };\n    class 07av1\n    {\n        name = \"\";\n        sound[] = {\"07av01.ogg\", db, 1.0};\n        titles[] = { 0, \"$STRCAMP_07av01\" };\n    };\n\n    // (...)\n\n    class AnotherClassName\n    {\n        name = \"\";\n        sound[] = { \"Another.ogg\", db, 1.0 };\n        titles[] =\n        {\n            { 0, \"$STR_SomeCsvString\" },    // one piece of voice text\n            { 6, \"$STR_AnotherCsvString\" }    // then another\n        };\n    };\n};\n```","sections":[{"heading":"Purpose","level":3,"markdown":"Stringtables are used to make internationalization easier for the game. They are used in addons, missions, and scripts.\n\nAny strings that are used in the game can be kept separate from the code, and can therefore easily be edited and expanded into different languages.\n\nInstead of using message strings directly in the code you are using a variable. This variable will then contain the actual string, read from stringtable.csv, with the language that's being read depending on the game settings."},{"heading":"CSV Format","level":3,"markdown":"The **Stringtable.csv** file is an ASCII text file, and can be edited with any text editor.\nOne *could* theoretically use a spreadsheet program (like Excel) to edit the file, but that would be serious overkill.\n'*DO NOT* use a word processor (like MS-Word, or Write) to edit this file though, as it will corrupt it, unless you are very knowledgeable and careful.\n\n> [!NOTE]\n> CSV stands for Comma-Separated Values. Using e.g Microsoft Excel to edit this file *may* corrupt the file, as some language settings will use a semicolon `;` instead of a comma `,`.\n\n- Operation Flashpoint uses [ANSI](https://en.wikipedia.org/wiki/ANSI) encoding, the codepage is defined by the font used.\n  - Operation Flashpoint cannot accept UTF encoding. You need to convert back to ANSI (e.g remove the 3 byte UTF \"BOM\" (byte order mark) tag at beginning of file when converting back the the real game).\n- Armed Assault accepts ANSI, [Unicode](https://en.wikipedia.org/wiki/Unicode) and [UTF-8](https://en.wikipedia.org/wiki/UTF-8) encoding (Unicode will be converted to UTF-8 on load)\n- Arma 2 and Arma 3 both accept CSV but use Stringtable.xml in preference. For whatever reason, Bohemia Interactive have destroyed the default language. It is no longer possible to simply state\n\n```\nSTR_ANYTHING,Some Name\n```\n\nand have all languages accept it. You will get a 'blank' if a specific language (e.g 'german') is not endlessly repeated as well."},{"heading":"Function","level":3,"markdown":"CSV files are used as string lookup tables.\n\nAlthough the engine uses other files with the extension CSV, the file for missions, addons, and campaigns is 'stringtable.csv' and **must** be located in the primary folder of the mission/addon/campaign.\n\nIn point of fact, the naming convention inside a csv is such that the first three letters of any variable (more later) **must** begin with `STR`, and referenced in mission.sqm, description.ext or anywhere else as `$STRsomething`.\n\nThe characters `STR` tell the engine to look in 'stringtable.csv' as opposed to use the literal string value."},{"heading":"Format","level":3,"markdown":""},{"heading":"Language Columns","level":4,"markdown":"The basic idea is that every language is assigned one column. (e.g. English has one column, French has another.) The order of the columns doesn't matter. (i.e. whether English comes first, or French, or Czech, is irrelevant). However, when game language doesn't match any of the languages listed in stringtable, the first column is selected by default. Therefore it is recommended to use English there.\n\nThe very first line of any csv must contain a statement like this:\n\n```\nLANGUAGE,  Polish, Hungarian, Turkish\n```\n\nWith this line you define the order in which the language columns are arranged. You can have as many or as few as you like.\n\nBelow this line the CSV file contains one line for each string definition; starting with the string *name*, and followed by the translations for the different languages:\n\n```\nLanguage,  English,Turkish,French\nSTR_BROKEN,Broken, Bozuk,  Merde\nSTR_GOOD,  Good,   İyi,\nSTR_BAD,   Bad,    Kotu,   Merde, Encore\nSTR_FIXED, Fixed,  Sabit,  \"Merde, Encore\"\nSTR_ONE,   One,    ,    Une\n```"},{"heading":"Blank Strings","level":4,"markdown":"Note some interesting and highly flexible aspects of the above syntax.\n\nThere is **no** French equivalent for `STR_GOOD`, nor is there a Turkish equivalent for `STR_ONE`. The engine will default to the 2nd column. It happens to be 'English', but need not be.\n\n**ArmA:** In ArmA this is different. If your country column exists, it will use that string, even if it is blank and not default to the 2nd column. So do not include languages in the LANGUAGE row which you are not utilising yet."},{"heading":"Default Language Column","level":4,"markdown":"The second column (the first 'string') is the default. Because of that, it is important that *all* of the 2nd columns are filled.\n\nThe second column does not *have* to be English - it can be any language the author is most comfortable with, and for which he will be able to supply *all* the required definitions.\nIn that case though, he will have to adjust the \"LANGUAGE, ...\" column definition at the top of the file.\n\n**ArmA:** In ArmA, if your language column is missing, then it will default to the game distributor's language column, if it exists.\nSo if you own the German version of the game and a German column exists in any column and your chosen language is not in any column, then German will be used, even if German is not in the 2nd column."},{"heading":"Commas and Quotes","level":4,"markdown":"To separate strings from one another, commas are used. String do not have to be enclosed with quotation marks.\nIn the case that commas are needed in the string definition itself, then that string would have to be enclosed by quotes (e.g. \"Merde, Encore\" you *would* need quotes)."},{"heading":"Leading/Trailing Spaces","level":4,"markdown":"When defining a string, the text used by the engine is from the *first non space character* after a comma, until the *last non space character* before the next comma (or end of line).\nThis would be familiar to many programmers as the Trim() function.\n\nThus\n\n```\n,this is a text,\n,      this is a text       ,\n```\n\nwould both return *\"this is a text\"*.\n\nThis feature is helpful if you want to keep columns aligned (tabbed), to keep better track of the columns."},{"heading":"Usage","level":3,"markdown":"Definition in stringtable.csv:\n\n```\nLANGUAGE,    English,          German\nSTR_MOVETO,  Move to the,      Gehen sie zum\nSTR_STATION, railroad station, Bahnhof\nSTR_AIRPORT, airport,          Flughafen\n```"},{"heading":"Scripts","level":4,"markdown":"Activations and conditions too.\n\nArma\n\n```sqf\n_text = localize \"STR_MOVETO\" + \" \" + localize \"STR_AIRPORT\";\n```\n\nOperation Flashpoint\n\n```\n_text = $STR_MOVETO + \" \" + $STR_AIRPORT\n```"},{"heading":"description.ext","level":4,"markdown":"```cpp\n \"$STR_AIRPORT\"\n```"},{"heading":"mission.sqm","level":4,"markdown":"Markers, texting effects, mission name, etc:\n\n> [!IMPORTANT]\n> If adding string table entry through the mission editor, the proper syntax is automatically added to the mission.sqm.\n> If you are converting a mission from OFP to ArmA, you may need re-add the string table to avoid the `\"scalar bool array string 0xe0ffffef\"` error.\n\nOperation Flashpoint\n\n```\n@STR_AIRPORT\n```\n\nArma\n\n```\n\"@STR_AIRPORT\"\n```"},{"heading":"Comments","level":3,"markdown":"- Arma: Arma doesn't appear to accept any (type of) comment string. Every line appears to be a string entry to Arma, with obvious consequences when converting from a properly documented (commented) Operation Flashpoint csv\n\nAny syntax the engine cannot understand is interpreted as a comment.\n\nBy convention the double-forward slash (//) at the beginning of the line is used:\n\n```\nLANGUAGE,     English,          German\n// actions\nSTR_MOVETO,   Move to the,      Gehen sie zum\nSTR_DESTROY,  Destroy the,      Zerstören sie den\n// locations\nSTR_STATION,  railroad station, Bahnhof\nSTR_AIRPORT,  airport,          Flughafen\n```\n\nHowever, in practice anything that *doesn't* start with STR can only be a comment.\n\nArma 2: To insert a string refering to a stringtable.csv or stringtable.xml, don't use the \"\" in the editor.\nFor example: you have `STR_myString`.\nTo add it in the description field of the selected unit, just add it like `@STR_myString`, the \"\" will be added, self-acting by the editor, in mission.sqm."},{"heading":"The selected language","level":3,"markdown":"`flashpoint.cfg` in the root directory of your operation flashpoint folder defines the language to be used for your installation:\n\n```cpp\nLanguage=\"English\";\n```\n\nThis can be changed to any language that has valid entries in the stringtable.csv's. For more information on this subject read Language Selection."},{"heading":"Replacing original game texts","level":3,"markdown":"It is possible to replace every message of the original game by editing the global stringtable.csv file (in \\res\\bin\\stringtable.csv).\n(Some messages, like addon names some GUI texts, briefing chapters (Plan, Notes, Gear, Group), etc. *cannot* be changed via the stringtable.csv though).\n\nFor example, you can create custom radio names for your squads.\n\nCreate your group and give them a normal radio name with the following command in the init line of the commander.\n\n```sqf\nthis setGroupId [\"Alpha\", \"GroupColor0\"];\n```\n\nNow, add in your Stringtable.csv:\n\n```\nSTR_CFG_GRPNAMES_ALPHA, \"Your group name\",\nSTR_CFG_GRPCOL_BLACK, \"Your color name\",\n```\n\nWhere *Your group name* is the custom name you'd like your squad radio messages to have, *Your color name* is color of the squad (GroupColor0 is Black, for more details see setGroupId)."},{"heading":"Different sounds under different languages","level":3,"markdown":"You can use *stringtable.csv* not only for texts but sounds and other Description.ext classes. See example:\n\nstringtable.csv\n\n```\nLANGUAGE,\"English\",\"Polish\"\n\nSTR_R1,\"ENGLISH\",\"POLSKI\"\nSTR_R2,\"US AND A SOLDIER HERE.\",\"TUTAJ POLSKI ŻOŁNIERZ.\"\n\nSTR_RadioMsg1,\"ENG\\R1.WAV\",\"POL\\R1.WAV\"\nSTR_RadioMsg2,\"ENG\\R2.WAV\",\"POL\\R2.WAV\"\n```\n\nOf course all sounds we have in *Sound* directory. Moreover they are in two different folders: *POL* and *ENG*. It makes *Sound* more clean. You can use prefixes like: *eng_* or *pol_* insted.\n\nDescription.ext (CfgRadio class only)\n\n```cpp\nclass CfgRadio\n{\n    sounds[] = {};\n\n    class R1\n    {\n        name = \"Radio #01\";\n        sound[] = { \"$STR_RadioMsg1\", db + 10, 1.0 };\n        title = \"$STR_R1\";\n    };\n    class R2\n    {\n        name = \"Radio #02\";\n        sound[] = { \"$STR_RadioMsg2\", db + 10, 1.0 };\n        title = \"$STR_R2\";\n    };\n};\n```\n\nHow does it work? During loading, Description.ext exactly, all string values preceded with *$* (dollar) are changed on right entires from *stringtable.csv*.\nSo when a player run game under English language, they will have English texts and sounds. The same think with Polish and other specified languages.\n\nThis solution you can use for CfgIdentities class to create personages with translated names or even native faces.\n\n**Notes:**\nThere are instances where the radio name will revert to the default after a reload of the mission.\n\n```cpp\nclass CfgSounds\n{\n    sounds[] = { 07av1 /* etc */ };\n    class 07av1\n    {\n        name = \"\";\n        sound[] = {\"07av01.ogg\", db, 1.0};\n        titles[] = { 0, \"$STRCAMP_07av01\" };\n    };\n\n    // (...)\n\n    class AnotherClassName\n    {\n        name = \"\";\n        sound[] = { \"Another.ogg\", db, 1.0 };\n        titles[] =\n        {\n            { 0, \"$STR_SomeCsvString\" },    // one piece of voice text\n            { 6, \"$STR_AnotherCsvString\" }    // then another\n        };\n    };\n};\n```"}],"categories":["ArmA: Armed Assault: Editing","ArmA: Armed Assault: File Formats","Operation Flashpoint: Editing","Real Virtuality File Formats"],"groups":["Tools and File Formats"]}