MSG File Format

MSG files are Fallout and Fallout 2 text message lists. They store numbered strings for dialogue, object names and descriptions, UI labels, combat floats, map names, script errors, and editor-facing vocabulary. The files are plain text, but the engine parser is not line-oriented: it scans for brace-delimited fields and reads entries as repeated {number}{audio}{text} triplets.

Most paths below are relative to master.dat, critter.dat, or an unpacked Fallout data directory. Runtime loading prepends text\<language>\ to the path passed by the caller, so game\misc.msg is normally loaded from text\english\game\misc.msg in English installations.

Format properties

PropertyDescription
File typePlain text. There is no magic number, version field, entry count, or table header.
Entry shapeEvery loaded entry is exactly three brace-delimited fields: {number}{audio}{text}.
IndexingThe numeric message id is the key. File order is not used after loading.
Byte orderNot applicable; MSG files are not binary records.
EncodingUse the game's legacy text encoding for the target language. Treat MSG files as game text assets, not UTF-8 by default, unless the target engine/toolchain explicitly converts them.

Entry syntax

{100}{narrator}{Welcome to the wasteland.}
{101}{}{This line has no audio field.}
{102}{v13_intro}{Line breaks inside a field are ignored by the parser.}
FieldDescription
numberSigned decimal message id. The parser accepts an optional leading + or -, then digits only. Whitespace inside this field makes the file fail to load.
audioOptional speech or sound name. Dialogue code uses it when speech playback is requested and the current dialogue head can play speech.
textThe displayed string. The engine returns this field for normal message lookups.

The audio and text fields may be empty. The number field may not be empty. The parser does not require one entry per physical line; formatting outside brace fields is ignored until the next opening brace.

Because formatting outside fields is skipped, comments can use almost any convention as long as they remain outside braces and do not contain a stray closing brace before the next entry. Common files often place comments or visual separators between entries; those are not part of the loaded data.

Parser behavior

The engine repeatedly reads three fields. A field starts at the next { and ends at the next }. Anything before the next { is skipped, which is why comments and blank lines work when they are outside fields.

BehaviorConsequence
Entries are read as {number}{audio}{text}.A missing second or third field makes the file fail to load.
EOF before a new entry is normal.Trailing whitespace or comments outside fields are safe.
A stray } before the next { is an error.Do not put unbalanced closing braces in comments.
The parser has no escape syntax.A literal } cannot be stored in a field. A literal { inside a field is read as normal text.
Newline characters inside a field are skipped.Wrapped text joins together without an inserted space unless the file already contains one.
Each field uses a fixed 1024-byte buffer.Keep each number, audio, and text field below 1024 stored characters; shorter is safer for old tools.
Numbers are parsed with decimal validation and atoi.Use plain signed decimal ids. Hex values, leading/trailing whitespace, and symbolic names are not accepted by the engine parser.
Message ids are kept sorted in memory.Lookups are by numeric id, not file order.
Duplicate ids replace earlier entries while loading.The last successfully parsed entry for a number is the one that matters.
A missing lookup returns the engine's fallback error string.Some call sites display Error; others log an error and return their own fallback.

A compatible reader can be simple: repeatedly skip characters until {, read bytes until }, repeat two more times, validate the first field as a signed decimal id, and insert or replace that id in a sorted or hashed message table. EOF is successful only when it happens while searching for the next entry, not while reading an unfinished field.

Important locations

PathTypical use
text\<language>\game\misc.msgGeneral game messages loaded during game initialization.
text\<language>\game\map.msgMap and city names.
text\<language>\game\script.msgScript-system messages.
text\<language>\game\proto.msgPrototype editor/type vocabulary such as materials, damage types, calibers, body types, and shared labels.
text\<language>\game\pro_item.msgItem prototype names and descriptions.
text\<language>\game\pro_crit.msgCritter prototype names and descriptions.
text\<language>\game\pro_scen.msgScenery prototype names and descriptions.
text\<language>\game\pro_wall.msgWall prototype names and descriptions.
text\<language>\game\pro_tile.msgTile prototype names and descriptions.
text\<language>\game\pro_misc.msgMisc prototype names and descriptions.
text\<language>\dialog\*.msgScript dialogue files, loaded lazily from the script filename.
text\<language>\game\combatai.msgCombat AI floats referenced by AI.TXT, AIBDYMSG.TXT, and AIGENMSG.TXT.
text\<language>\game\combat.msgGeneral combat messages, including message ids referenced by critical hit tables.
text\<language>\game\item.msgShared item-use messages, book text hooks, explosive messages, and other item-system strings.
text\<language>\game\stat.msg, skill.msg, perk.msg, trait.msgDisplayed names and descriptions for character stats, skills, perks, and traits.
text\<language>\game\pipboy.msgPip-Boy UI labels, holodisk titles, and holodisk body text used with holodisk.txt.
text\<language>\game\quests.msgQuest description lines displayed through quests.txt.
text\<language>\game\worldmap.msgWorldmap UI and encounter text.

Fallout 2 CE falls back to text\english\... when the configured language's message file is missing. The original executables should be treated more conservatively: ship the localized file in the language directory you expect the game to use.

Critical hit messages

Critical hit tables store numeric Message and FailMessage ids. These ids are looked up in combat.msg after the critical effect and any failed defensive stat check have been resolved. If a critical table is edited without matching combat.msg entries, the combat log can show fallback lookup text even though the critical effect still applies mechanically.

PRO dependencies

PRO files do not store object names or descriptions directly. The common PRO header stores a base message_num, and the PID object type selects one of the six pro_*.msg files. The engine resolves message_num + 0 as the object name and message_num + 1 as the description.

PID typeMessage listLookup
0 itemgame\pro_item.msgmessage_num + 0 name, message_num + 1 description.
1 crittergame\pro_crit.msgmessage_num + 0 name, message_num + 1 description.
2 scenerygame\pro_scen.msgmessage_num + 0 name, message_num + 1 description.
3 wallgame\pro_wall.msgmessage_num + 0 name, message_num + 1 description.
4 tilegame\pro_tile.msgmessage_num + 0 name, message_num + 1 description.
5 miscgame\pro_misc.msgmessage_num + 0 name, message_num + 1 description.

Vanilla prototypes usually use base ids that are multiples of 100, but the engine only adds the small name/description offset to whatever base id the PRO file contains. Tools should not infer an object id from the MSG id; read the PRO header and the corresponding list file instead.

Proto editor vocabulary

proto.msg is not the same as the six pro_*.msg name/description files. It supplies shared vocabulary used by the engine and tools: item types, scenery types, materials, damage types, calibers, body types, kill types, and labels such as <None>. PRO data fields often store small integer ids that are displayed through proto.msg or other standard message files such as stat.msg and perk.msg.

MAP dependencies

map.msg is a companion table for map and city names. Fallout 2 CE loads game\map.msg during map initialization and exposes it as a standard message list.

LookupMessage id
Map display name for map index m and elevation e.m * 3 + e + 200
Worldmap city name for city index c.1500 + c

This means map names depend on both maps.txt ordering and map.msg numbering. Reordering maps without updating map.msg can make the UI show the wrong map names even when the MAP files themselves still load.

Script and dialogue use

Compiled scripts call message operations by numeric message-list id and message id. For normal script dialogue, the engine converts the list id to a script index, reads that script's filename from scripts\scripts.lst, strips the extension, and loads dialog\<scriptname>.msg on first use.

For example, a script file named VAULT13.INT expects dialogue text in text\<language>\dialog\VAULT13.msg. The dialogue MSG file is cached after the first lookup. During dialogue speech playback, the audio field is used as the speech name if it is non-empty.

Script valueMeaning
message_str(list, id)Looks up id in the dialogue list selected by list. In normal dialogue use, list is one-based: list 1 maps to the first entry in scripts.lst, list 2 to the second, and so on.
message_str(0, 0)Returns an empty string.
message_str(-1, -1)Returns an empty string.
message_str(-2, -2)Returns message 650 from proto.msg.
Negative message idThe script opcode returns Error without attempting a normal lookup.

Use the script compiler's generated constants or the same list numbering convention as the game scripts. Passing an arbitrary non-special list id to message_str can point at the wrong scripts.lst line or fail to load the expected dialogue file.

Speech audio field

The second MSG field is only meaningful to call sites that ask for speech. Normal string lookups return the text field and ignore the audio field. In game dialogue with speech enabled, message_str can pass the audio field to the lip-sync system.

The dialogue code strips any extension from the audio field, combines it with the talking head art filename, and looks below SOUND\SPEECH\<head>\. The lip-sync loader reads <audio>.LIP, then loads the speech ACM named by the LIP file's internal audio-name field. In normal assets the MSG audio token, LIP filename, internal audio name, and ACM filename all match. Keep the audio token short and extension-free for best compatibility with the original fixed-size buffers. See LIP File Format for the full lookup path.

Message-list repository ids

Fallout 2 CE and sfall-compatible script APIs also expose repository lookups such as message_str_game(listId, messageId). These ids are not the same namespace as normal dialogue message_str list ids.

RangeMeaning
0x0000 to 0x0013Standard game message lists. Examples include combat.msg, combatai.msg, misc.msg, item.msg, map.msg, proto.msg, script.msg, skill.msg, stat.msg, trait.msg, and worldmap.msg. Some standard lists are only initialized while their owning UI/system is active.
0x1000 to 0x1005Prototype message lists for pro_item.msg, pro_crit.msg, pro_scen.msg, pro_wall.msg, pro_tile.msg, and pro_misc.msg in object-type order.
0x2000 to 0x2FFFPersistent extra message lists loaded from sfall's ExtraGameMsgFileList setting.
0x3000 to 0x3FFFTemporary extra message-list ids reserved by the CE repository.

Fallout 2 CE's standard-list enum uses these ids:

IdEnum nameCommon file
0STANDARD_MESSAGE_LIST_COMBATcombat.msg
1STANDARD_MESSAGE_LIST_COMBAT_AIcombatai.msg
2STANDARD_MESSAGE_LIST_SCRNAMEscrname.msg
3STANDARD_MESSAGE_LIST_MISCmisc.msg
4STANDARD_MESSAGE_LIST_CUSTOMcustom.msg
5STANDARD_MESSAGE_LIST_INVENTORYinventry.msg
6STANDARD_MESSAGE_LIST_ITEMitem.msg
7STANDARD_MESSAGE_LIST_LSGAMElsgame.msg
8STANDARD_MESSAGE_LIST_MAPmap.msg
9STANDARD_MESSAGE_LIST_OPTIONSoptions.msg
10STANDARD_MESSAGE_LIST_PERKperk.msg
11STANDARD_MESSAGE_LIST_PIPBOYpipboy.msg
12STANDARD_MESSAGE_LIST_QUESTSquests.msg
13STANDARD_MESSAGE_LIST_PROTOproto.msg
14STANDARD_MESSAGE_LIST_SCRIPTscript.msg
15STANDARD_MESSAGE_LIST_SKILLskill.msg
16STANDARD_MESSAGE_LIST_SKILLDEXskilldex.msg
17STANDARD_MESSAGE_LIST_STATstat.msg
18STANDARD_MESSAGE_LIST_TRAITtrait.msg
19STANDARD_MESSAGE_LIST_WORLDMAPworldmap.msg

These ids are useful for scripting and diagnostics, but they are not a guarantee that a list is currently loaded. Modal UI lists can be unavailable outside the screen that owns them.

Repository idPrototype message list
0x1000pro_item.msg
0x1001pro_crit.msg
0x1002pro_scen.msg
0x1003pro_wall.msg in CE's current registration order.
0x1004pro_tile.msg in CE's current registration order.
0x1005pro_misc.msg

Extra message lists are loaded from the game message directory. In CE, an ExtraGameMsgFileList entry such as mytext:12 loads text\<language>\game\mytext.msg and assigns it repository id 0x2000 + 12. Without explicit ids, the order of entries determines the assigned ids, so stable mods should prefer explicit numbering.

One compatibility wrinkle: Fallout 2 CE's public proto-list enum names tiles before walls, but the actual registration loop follows object type order from the prototype system, where walls are type 3 and tiles are type 4. If a tool exposes raw 0x1003/0x1004 repository ids, verify the target engine's behavior instead of trusting enum names alone.

Filtering and gender words

Dialogue MSG files loaded through the script dialogue path can be filtered after loading. The bad-word filter reads data\badwords.txt, uppercases both the bad-word list and a temporary copy of each line, and replaces matching words in the original text when the language filter preference is enabled.

Fallout 2 CE also supports optional sfall-style gender-specific words. When enabled, text in the form <male^female> is rewritten according to the player character's gender after the dialogue MSG file is loaded.

These filters are applied by the script dialogue loading path. They should not be assumed for every MSG file. Object names, map names, and general UI strings are usually consumed directly from their loaded message lists.

Tool implementation notes

Editing notes

Source references