[2000-07-04]

Baldur's Gate: File Format Hacking Project

 

Site news

2000-07-03 This page is now officially dead. The project has changed its name to the Infinity Engine File Format Hacking Project and is now lead by Jed Wing. This page will remain here for historical reasons only. I repeat, the information on this page is to be considered extremely outdated. For current information go to the new homepage.
2000-06-03 This page is now extremely outdated. Jed Wing is about to take over as maintainer. For the latest on BG-hacking check out Infinity Explorer. 2000-01-12 Small additions.
1999-09-10 First pass of table optimization. Contact info changed. New tools linked.
1999-09-02 Petr updated the page in the sections AREA (huge update), BAM and ITM.

[ file formats ] [ in-depth discussions ] [ credits & contact info ] [ tools / downloads ] [ tables ]

 

Introduction

If you are looking for the Baldur's Gate Mapping Effort - BAGME - you have the wrong address. That page has moved here. This page will instead focus on what gamehacking ought to really be about, namely hexeditors, calculators and lot's and lot's of notes with hexadecimal offsets :-)

I (Eddy L O Jansson, I'm authoring this page) and my friend Robert Risberg will here try to disclose everything we know about the inner workings of Baldur's Gate. Since 1999-05-10 we have also been joined by Petr Zahradnik who's been injecting many fresh ideas into this project, and who deserves equal credit.

Note that we will often sound as if we are stating a fact when we're actually just stating what we currently hold for true. This is just a convention so that we can keep the technical parts of this paper reasonably brief and to the point without lotīs of "we believe", "as far as we know", et cetera. You will also see me go back and forth between the we and I form as I move from something we know/don't know to my personal opinions which are to be held separate from those of the other participants of this project..

It has been our intention from the very start to hack the internals of BG. We talked about it even before the game was out. Personally though, I didn't want to start hacking until after I'd completed the game as looking through the datafiles will ruin the overall experience. Now (1999-04-04), I'm done and can proceed to hack.

Naturally, I took the time to look at the current state of BG-hacking, only to find lot's of executables and no real useful information. I think it's sad that this community seem to be so focused on thinking "proprietary" (there are some notable exceptions; see the credits section), when sharing information would be much more efficient and fun. To counter this we will take the other path; less executables and more information. All we would ask in return is that - if you use this information to build a tool - that you please greet us somewhere in the documentation and/or in the program itself.

Another exception is the fact that we are not doing this in order to cheat - which should be obvious if you study which structures we've worked on so far - we do this because it's a challenge, because it's fun and because we really enjoy games, game development and reverse-engineering. If you simply want to cheat, please go somewhere else, and please don't bother us with questions about cheating. Thank you.

 

General

Baldur's Gate is scripted internally using the language Lua, developed by TeCGraf at the Pontifical Catholic University of Rio de Janeiro in Brazil. Some knowledge of this language will be useful for the serious hacker. You can read the reference-manual online, it will take you a couple of hours if you read it all, much less if you just browse the highlights; datatypes, how to adress tables, the preprocessor, comments. I am not sure if the scripting available to players is also based on Lua, but it seems probable.

When we adress individual bits, we count with bit 1 being the least significant bit at the far right, with increasing value as we move from right to left.

There's much research yet to be done.

 

File Formats

BG use a number of different files, and each can contain may different resources. We will go thru them and disclose what we know so far.

Index (see also TblResourceType)
AREA TAREAHeader,   TAREANpcEntry, TAREAInfoEntry,   TAREAExitEntry, TAREAContainerEntry, TAREAItemEntry, TAREASoundEntry, TAREADoorEntry, TAREAAnimEntry
BAM TBAMHeader, TBAMFrameHeader, TBAMAnimHeader, TBAMAnimArray
BIFF TBIFHeader, TBIFCatalogEntry, TBIFMMEntry
CHR TCHRHeader
CRE TCREHeader, TCREAffectionEntry, TCREItemEntry, TCRESpellEntry, TCREMemorizedInfo
DLG TDLGHeader, TDLGSourceEntry, TDLGNPCEntry, TDLGSayEntry
GAME TGAMHeader, TGAMActionEntry, TGAMNPCEntry
ITM TITMHeader, TITMWeaponEntry, TITMEffectEntry
KEY TKEYHeader, TKEYResFileEntry, TKEYResourceEntry
MOS TMOSHeader
SAV TSAVHeader, TSAVResourceEntry
STOR TSTORHeader, TSTORItemEntry
TLK TTLKHeader, TTLKEntry
WAVC TWAVCHeader
WED TWEDHeader
WMAP TWMapHeader

 

    BIFFV1

    One of the primary file formats are that of BIFFV1 (extension .bif). These files are resource-files of the type that became      popular with the .WAD files of Doom et al, in other words, the act as a container for other (much smaller) resources. It is obvious that the bif-files of BG are to remain static and that they will not be affected by patches. For one thing, they mostly remain on your CD :-), but I was thinking more on their structure; having the catalog at the top of the file, something which is a really bad idea if you want to add entries. Instead there's an override directory which when a resource is sought will get searched first, only if the resource is not found there the game will reach for the bif-file.

    One common BIFF is the AREAxxxx.BIF. These files contain the basic information about an area, three smaller BMP images of which is probably used for the sound-system (very smooth but crude approximation of the area layout), one is used as a map over where you can walk (looks hand drawn) and the last one.. well, we don't know. You will also find a couple of other chunks, and at the very end, all the graphics for the map as seen by the player (we've got some info on the format of that, stay tuned).

What BIFF stands for? If it is an acronym, it could stand for Baldurīs Gate Interchangable File Format

This is what we know about these files.

TBIFHeader (0x14 bytes)
8 Marker 'BIFFV1'<space><space>
4 Catalog entries Count of TBIFCatalogEntries.
4 MM entries Count of 0x03EB resources in file, see TBIFMMEntry.
4 Catalog offset Absolute file offset to start of TBIFCatalog entries.

 

TBIFCatalogEntry (0x10 bytes)
2 Resource index
2 unknown
4 Resource offset Abolute file offset to start of this resource.
4 Resource size The size in bytes of the resource.
4 Resource type See TblResourceType for some known resource types.

    The following structure is unique to BIF's containing ARxxxx resources. The starting offset of this list must be calculated using the formula 0x14+(TBIFHeader.CatEntries*0x10). Not yet fully researched. See also MOS.

TBIFMMEntry (0x14 bytes)
2 unknown 00 40
2 unknown 20 00
4 ResPtr Absolute offset of start of resource.
4 ResSize Resource size in blocks of 0x400 (TPalette) + 0x1000 bytes (Graphics)
2 unknown 00 14
2 unknown 00 00
4 ResType EB 03 00 00

[ back to index ]

    TLK V1

    Resource containing dialogue, descriptions and names of objects; items, NPC, etc. Various items and functions will then reference these strings using the zero-based index of the TTLKEntry.

TTLKHeader
8 Marker 'TLK V1'<space><space>
2 unknown <0><0>
4 CatEntries
4 BaseOffset Absolute offset to start of data.

 

TTLKEntry
2 ResType 03 00 (02 00 = inactive?)
8? ResID example: 'YESLK01',0 (ASCIIZ), often null.
4 unkPad Always zero in dialog.tlk
4 unknown Possibly bitmap
4 ResOffset Relative to TTLKHeader.BaseOffset
2 ResSize

[ back to index ]

    KEY V1

    An index over where a resource file (.bif) can be found, and what particular resources it contains. Only 2+4+4 bits remain unaccounted for.

TKEYHeader
8 Marker 'KEY V1'<space><space>
4 ResFileEntries
4 ResEntries
4 ResFileOffset points to list of TKeyResFileEntry
4 ResOffset points to list of TKeyResourceEntry

 

TKEYResFileEntry
4 FileSize
4 FilenameOffs Absolute pointer to ASCIIZ
2 FilenameLen Length in bytes of filename (including terminating zero)
2 ResLocation Which CD this file is on. bit 8 thru 2 codes for CD7 thru 1 respectively.
The two lowest bits (2 and 1) are always '01'. Their meaning is unknown. They do not seem to affect access or caching in any way, but they are acted upon.
The bitmap does not seem to extend beyond bit 8 (cd 7).

 

TKEYResourceEntry
8 Identifier ASCII[Z]
2 ResType Ref: TblResourceType
2 ResIdx Bits 1-12: BIFF catalog entry of this resource in the .bif file indexed ResFileIdx below.
Bits 13-16: unknown.
2 ResFileIdx Bits 1-4: codes for something unknown.
Bits 5-16: codes the file this resource is found in (indeces the TKEYResFileEntry table)

[ back to index ]

    SAV V1.0

    Holds the state of the world. Consists of a short header followed by one or more TSAVResourceEntries. Typically found in a 'baldur.sav' file, located in the path of a save-game. We believe this one contains local data, that is, information in one of these chunks are only accessed when you actually enter the area in question.

TSAVHeader
8 Marker 'SAV V1.0'

    Each of the entries of this file stores the state of one area or store. One of the things stored here is what parts of the area you have uncovered.

TSAVResourceEntry
4 ResIDLen
x ResID ASCIIZ
4 ResDataSize Uncompressed size of resource data.
4 ResDataCmprSize Compressed size.
x ResData Compressed data. (LZ77+Huffman (deflate), see RFC-1951)

[ back to index ]

    GAME V1.1

    Another resource found in save-games, this one is found in the file 'baldur.gam'. We believe this one stores global data, that is, data that must be available to the engine at all times. Your party is saved out in this file, and it also contains a list of all major actions you've taken throughout the game.

TGAMHeader
0x0000 8 Marker 'GAME V1.1'
0x0008 4 GameTime (Hours*300)+0x0834 (don't ask :-)
[...]
0x0018 4 Gold Party gold. Characters don't have money in BG.
0x001C 4
0x0020 4 PartyPtr
0x0024 4 PartyCnt
0x0028 8
0x0030 4 TblNPCPtr Absolute offset of a table of TGAMNPCEntries.
0x0034 4 TblNPCCnt
0x0038 4 TblActionPtr Absolute offset of a table of TGAMActionEntries.
0x003C 4 TblActionCnt

 

TGAMNPCEntry (0x160 bytes)
0x0000 2
0x0002 2 Position Character position, as per portrait. 0xFFFF for characters no longer in your party.
0x0004 4 NPCDataPtr
0x0008 4 NPCDataLen

    These global variables below are set using code like SetGlobal(ActionID,"GLOBAL",value) or SetGlobalTimer(ActionID,"GLOBAL",EIGHT_DAYS).

TGAMActionEntry (0x54 bytes)
0x0000 28 ID ASCIIZ
0x0028 4 Value Used to signal the current state of this action/quest.

[ back to index ]

    CHR V1.0

    Character resource. Found as a small header preceeding the CRE V1.0 resource of exported characters. Believed to be fixed size; 0x64 (100) bytes.

TCHRHeader (0x64 bytes)
0x0000 8 Marker 'CHR V1.0'
0x0008 20 Name ASCIIZ. Name of the exported character.
0x0028 4 CREOffset Absolute file offset of CRE resource.
0x002C 4 CRESize Size of CRE resource

 

    CRE V1.0

    Creature resource. Holds information about stats, inventory and everything else that is your character. Variable in size depending on the spells and inventory of the creature. This will probably result in this resource being split in five or more different TCRE-types (note: this is a low-priority structure for us).

TCREHeader
0x0000 8 Marker 'CRE V1.0'
0x0008 4 Name Creature Name (TLK resource)
0x000C 4 Name2 Another TLK resource
0x0010 4
0x0014 4
0x0018 4 Experience
0x001C 4
0x0020 4
0x0024 2 CurrHP Current amount of hitpoints
0x0026 2 MaxHP Maximum amount of hitpoints
0x0028 4 DollGfx Bit 1-4 = race
Bit 5-8 = sex
Bit 9-12 = class
Bit 13-16 = unknown
0x002C 1 unknown 0x1E, 0x1C, 0x1B.. (decreasing thru party?)
0x002D 1 ColorMinor
0x002E 1 ColorMajor
0x002F 1 ColorSkin
0x0030 2 unknown Invalid values will crash game.
0x0032 1 ColorHair
0x0033 1
0x0034 8 ImageS Small portrait image (ASCIIZ)
0x003C 8 ImageL Large portrait image (ASCIIZ)
0x0044 2
0x0046 2
0x0048 2 AC Armour Class
0x0052 1 THAC0 To Hit Armour Class Zero
0x0053 1 NoAttack Number of Attacks
0x0054 1 SavPPD Saving Throw: Paralyzis/Poison/Death
0x0055 1 SavRSW Saving Throw: Rod/Staff/Wand
0x0056 1 SavPP Saving Throw: Petrify/Polymorph
0x0057 1 SavBreath Saving Throw: Breath Weapon
0x0058 1 SavSpells Saving Throw: Spells
0x0059 4
0x005D 1 ResMagic Magic resistance
[...]
0x0067 1 ThiOpen Open locks
0x0068 1 ThiStealth Stealth
0x0069 1 ThiTraps Detect traps
0x006A 1 ThiPockets Pick pockets
0x006B 1
0x006C 1
0x006D 1
0x006E 1 ProLS Weapon proficiency: Large swords
0x006F 1 ProSS Weapon proficiency: Small swords
0x0070 1 ProBow Weapon proficiency: Bows
0x0071 1 ProSpear Weapon proficiency: Spears
0x0072 1 ProBlunt Weapon proficiency: Blunt weapons
0x0073 1 ProSpike Weapon proficiency: Spiked weapons
0x0074 1 ProAxe Weapon proficiency: Axes
0x0075 1 ProMiss Weapon proficiency: Missile weapons
[...]
0x00a4 4*100 TlkResArray 100 different talk resources, amongst other things the biography for the character. 0xFFFFFFFF (-1L) for unused entries.
[...]
0x0234 1 Class1lvl Character level for main class.
0x0235 1 Class2lvl Character level for second class (multi/dual classed characters).
0x0236 1 Class3lvl Character level for third class (multi/dual classed characters).
0x0237 1 unknown
0x0238 2 AbStr Strength (First byte is base, the other byte is the /xx bonus.)
0x023A 1 AbInt Intelligence
0x023B 1 AbWis Wisdom
0x023C 1 AbDex Dexterity
0x023D 1 AbCon Constitution
0x023E 1 AbCha Charisma
[...]
0x0246 2 MageType 0x4000 for plain mage (0x40, 80, 100, 200, 400, 800, 1000, 2000)
[...]
0x0272 1 Race 01=Human, 02=Elf, 03=Half-Elf, 04=Dwarf, 05=Halfling 06=Gnome
0x0275 1 Sex 01=male, 02=female, 03=other, 04=neither, 05=both
[...]
0x027B 1 Alignment Alignment. Good=1/Neutral=2/Evil=3 + Law=10/Neutral=20/Chaotic=30
[...]
0x02A0 4 Spell1Ptr Known spells (TCRESpellEntry)
0x02A4 4 Spell1Count
0x02A8 4 MemorizedInfoPtr (TCREMemorizedInfo)
0x02AC 4 MemorizedInfoCount
0x02B0 4 Spell2Ptr Spells set to memorize (TCRESpellEntry)
0x02B4 4 Spell2Count
0x02B8 4 ItemLocationPtr Size: 0x28*2=0x50. Each word represents one slot. Value indicates position in the item-list (0xFFFF = empty)
0x02BC 4 ItemsPtr Item-list (TCREItemEntry)
0x02C0 4 ItemsCount
0x02C4 4 AffectionsPtr (TCREAffectionEntry)
0x02C8 4 AffectionsCount

 

TCREItemEntry (0x14)
0x00 8 Identifier 'Dagg06',0,0
0x08 2
0x0A 2 Count Number of items/wand charges
0x0C 4
0x10 2 Identified 1 = Item identified
0x12 2

 

TCRESpellEntry (0x0C)
0x00 8 Identifier 'SPPR210',0 - SP:Always SP; PR: PR-Priest WI-Wizard IN-Innate; 2: Level; 10: ID
0x08 2 Level Spell level - 1 ?
0x0A 2 Type Known: 0=Priest, 1=Mage, 2=Innate. Memorized: ?

 

TCREMemorizedInfo (0x0F)
0x00 2 SpellLevel spell level - 1 ?
0x02 2 CanMemorize1
0x04 2 CanMemorize2
0x06 2 SpellType 0 = Priest; 1 = Wizard; 2 = Innate
0x08 2
0x0A 2
0x0C 2 NumMemorized
0x0E 2

 

TCREAffectionEntry (0x30)
0x00 0x30

[ back to index ]

    ITM V1

    Items. Used for anything you can carry.

TITMHeader (0x70)
0x0000 8 Marker 'ITM V1'<space><space>
0x0008 4 DescPTR1 Index of TLK- one line description - UnIdentified
0x000C 4 DescPTR2 Index of TLK- one line description - Identified

0x0010

8

DestroyedID ASCII[8] - 'MISC56',0,0

0x0018

2

ItemAttributes bit 4 = item cursed

0x001A

2

0x001C

2

ItemType tblItemType

0x001E

4

Usability tblItemUsability
0x0022 2 WeaponID ASCII (spaces if n/a). Ref: TblWeaponID

[...]

0x0034 4 price Depends on CHA Reputation etc. This is the base value.
0x0038 2 MaxInStack
0x003a 8 BAMIDinv BAM ID for when item is in inventory.

0x0042

2

LoreToIdentify
0x0044 8 BAMIDgro BAM ID for when item is on the ground.
0x004c 4 weight
0x0050 4 DescPTR3 Index of TLK-resource, general description (pre-identify)
0x0054 4 DescPTR4 Index of TLK-resource, complete description.
0x0058 8 BAMIDc BAM ID for when the item is worn/carried(?)

0x0060

4

0x0064 2 WeaponEntryPtr1 Relative offset to list of TITMWeaponEntries.
0x0068 2 WeaponEntryCnt1 Count?
0x006a 2 EffectTablePtr Points to Effect-Array (TITMEffectEntry)
0x006c

2

FirstGlobalEffect

0x006e

2

GlobalEffectCount

    Only valid for weapons? No. Describes item abilites (if any). Detected ability types: Weapon,Spell,Missile,Launcher,and 0-'InGuiAbillity - Learn Spell etc.' . This may be valid only for Baldur's Gate and not for TOTSC, because of the new resource  type EFF :-)

TITMWeaponEntry (0x38)
0x0000 1 AbilityType 0-InGuiAbility,1-Weapon,2-Missile,3-Spell,4-Launcher
0x0001 1 UseOnlyIdentified 01 - must be identifed before use

0x0002

2

0x0004 8 IWeaponID ASCIIZ. Example: 'IBLUN04',0 - image of ability (may be scroll etc ...)
0x000C 2 unknown
0x000E 2 range Attack range (1-sword,2-staff,... in feets)

0x000A

2

THAC0
0x000C

2

SpeedFactor

0x000E

2

Bonus
0x0010

2

DiceValue
0x0012 2 DiceCount
0x0014 2
0x0016 2 DamageType 01=piercing, 02=crushing, 03=slashing, 04=missile(piercing), 05=stun
0x0018 2 EffectCount
0x001A 2 FirstEffect Index in Effect-Array (TITMHeader.EffectTablePtr) (TITMEffectEntry)

[...]

 

    TITMEffectEntry is probably variable record, which depends on Effect.

TITMEffectEntry
0x0000 2 Effect see tblEffectType
0x0002 1 Param1 usualy mode

0x0003

1

Param1a submode ?

0x0004

2

Param2 usualy value

0x0006

12

0x0012

2

Probability usualy 100%

0x0014

8

File ASCII[8]  'squirp',0,0

0x001C

8

0x0024

4

Throws ?

0x0028

4

DiceSides ?

0x002C

4

[ back to index ]

    AREA V1.0

    An important resource. Defines the contents of an area; the location of exits (doors), signs, triggers, and other things that interact with your character in one way or another.

TAREAHeader (0x11C)
0x0000 8 Marker 'AREAV1.0'
0x0008 8 Identifier 'AR5600' - DataLink. 4ex: area 5601 shares data with area 5600 etc.
[...] zero
0x0018 8 ExitN ASCII[8]. ex: 'AR2800',0,0
0x0020 4 03 00 00 00
0x0024 8 ExitW ASCII[8]
0x002C 4 03 00 00 00
0x0030 8 ExitS ASCII[8]
0x0038 4 03 00 00 00
0x003C 8 ExitE ASCII[8]
0x0044 4 03 00 00 00
[...]
0x0054 4 NPCPtr Characters / monsters (TAREANpcEntry)

0x0058

2

NPCount
0x005A 2 InfoCount  01 00

0x005C

4

InfoPtr (TAREAInfoEntry) Infos,Triggers,Doors,Traps etc.
0x0060 4 UnknowPtr
0x0064 4 ^-count ?
0x0068 4 ExitPtr (TAREAExitEntry) Entry/Exit points.
0x006C 4 ExitCount
0x0070 4 ContainerPtr Container-list (TAREAContainerEntry) Crates,Chests etc.
0x0074 2 ContainerCount
0x0076 2 ItemCount
0x0078 4 ItemsPtr Item-list (TAREAItemEntry)
0x007C 4 UnknownPtr -> coordinates array ?
0x0080 2 ^- Count ?

0x0082

2

SoundCount
0x0084 4 SoundsPtr Things that make sound (TAREASoundEntry)

0x0088

4

Unknown Ptr

[...]

zero

0x0094

8

AreaID ASCII[8] - 'AR5601',0,0

[...]

zero

0x00A0

4

UnknownPtr -> 0000 FFFF 13000 ....

0x00A4

4

DoorCount

0x00A8

4

DoorPtr (TAREADoorEntry)

0x00AC

4

AnimCount

0x00B0

4

AnimPtr Animated thinks (TAREAAnimEntry)

0x00B4

4

0

0x00B8

4

UnknownPtr -> chaos :-) - coordinates array ?

0x00BC

4

UnknownPtr -> 0000 0000 FFFF ...

[...]

zero

 

TAREANpcEntry (0x110)
0x00 30? Name 'Bentley Mirrorshade'
[...]

0x20

2

Xcoord

0x22

2

Ycoord

0x24

2

Xcoord - again

0x26

2

Ycoord - again

[...]

0x80

8

CreFile ASCII[8] - name of the .CRE resource.

[...]

 

TAREAInfoEntry (0xC4)
0x00 30? Identifier ASCIIZ 'Info2616',0,chaos.
[...]
0x20 2 Active Boolean flag. (01 00 for active and zeroes for inactive).

0x22

2

X

0x24

2

Y

0x26

2

X2

0x28

2

Y2
[...]

0x36

8

ExitArea ASCII[8] 'AR2602' (Doors only)

0x3E

8

Exit ASCII[8] 'Exit2600' (Doors only)

[...]

0x64 4 DialogPtr Index of the TLK V1 entry to print. (signs only)
[...]  

 

TAREAExitEntry (0x64)
0x00 30? Identifier 'Exit2605'
[...]

0x20

2

X

0x22

2

Y

0x24

2

Z

[...]

 

TAREAContainerEntry (0xC0)
0x00 30? Identifier 'Container 4'...
[...]

0x24

2

ContainerType ? (sack,chest,wardrobe,ground,table,shelf,altar,book,barel,crate...)

0x26

2

OpenDificulty if not locked - 100

0x28

2

Locked 01 00 - locked

[...]

0x38 2 XCoord
0x3A 2 YCoord
[...]
0x40 4 StartItem zero-based index to the Item-list (TAreaHeader.ItemsPtr)

0x44

4

ItemCount

[...]

 

TAREAItemEntry (0x14) (=TCREItemEntry?)
0x00 8 Identifier 'Dagg06',0,0
0x08 2
0x0A 2 Count Number of items/wand charges
0x0C 4
0x10 2 Identified 1 = Item identified
0x12 2

 

TAREASoundEntry (0xD4)
0x00 30? Name 'Fountain 5'

[...]

0x20 2 Xcoord
0x22 2 Ycoord
0x24 2
[...]
0x2E 2 ? 32 - volume ???

0x30

8

SoundFile ASCII[8] - 'AMB-E10A'

[...]

 

TAREADoorEntry (0xC0)
0x00 8 Identifier 'Door2608'
[...]

0x1F

8

Identifier2 'DOOR2608'

[...]

 

TAREAAnimEntry (0x48)
0x00 8 Identifier 'FISH3S'
[...]

0x28

8

Identifier2 'FISH3S'

[...]

[ back to index ]

    DLG V1.0

    This resource controlls the flow of dialogue.

TDLGHeader (0x30 bytes)
0x0000 8 Marker 'DLG V1.0'
0x0008 4 SayEntryCount
0x000C 4 SayEntryPtr Points to a list of TDLGSayEntries.
0x0010 4 NPCEntryCount
0x0014 4 NPCEntryPtr Points to a list of TDLGNPCEntries.
0x0018 4 SourceEntry1Ptr Points to a list of TDLGSourceEntries.
0x001C 4 SourceEntry1Count
0x0020 4 SourceEntry2Ptr Points to a list of TDLGSourceEntries.
0x0024 4 SourceEntry2Count
0x0028 4 SourceEntry3Ptr Points to a list of TDLGSourceEntries.
0x002C 4 SourceEntry3Count

 

TDLGSourceEntry (0x08 bytes)
4 SourceOffset Absolute offset of start of source-code block.
4 SourceLen Length of sourceblock.

 

TDLGNPCEntry (0x20 bytes)
4 unknown Boolean flag?
4 unknown TLK V1 index?
4 unknown zero?
4 unknown flag? Often -1.
4 unknown flag? Often -1.
8 Identifier 'gnoll5',0,0
4 unknown

 

TDLGSayEntry (0x10 bytes)
4 DialogPtr Index of the TLK V1 entry to print.
4 unknown
4 unknown
4 unknown

[ back to index ]

      BAM V1

    This format is used for storing multiple animations, which could share the same frames and same palette. Even though this is a format for animations, some files contain only one frame, or a set of static images.  

TBAMHeader (0x18 bytes)
0x0000 8 Marker 'BAM V1'<space><space>
0x0008 2 FrameCnt Number of shared frames
0x000A 2 AnimCnt Number of animations
0x000C 4 FrameHeaderPtr Pointer to the first of the TBAMFrameHeaders
0x0010 4 PalettePtr Not a palette in the standard VGA meaning, the palette is 32-bit RGBA
0x0014 4 AnimArrayPtr Pointer to the TBAMAnimArray

    After the header comes FrameCnt of TBAMFrameHeaders as specified below.

TBAMFrameHeader (0x0c bytes)
0x0000 2 Width
0x0002 2 Height
0x0004 2 Xpos
0x0006 2 Ypos
0x0008 4 GraphicsPtr Pointer to graphic data

    The Xpos/Ypos are coordinates of top left hand corner of the frame, relative to the reference point (usually that cross between foots). That means that both Xpos and Ypos should be negative. Width and height is given only for each frame, this means you must calculate the maximum width/height of the animation.

    After those frame headers comes AnimCnt of TBAMAnimHeaders:

TBAMAnimHeader (0x04 bytes)
0x0000 2 Frames Number of frames in this animation
0x0002 2 Start Index to the TBAMAnimArray

    After those animations headers comes one TPalette (standard 0x400 bytes). Then comes TBAMAnimArray

TBAMAnimArray (variable size)
0x0000 2 FrameID
0x0002 2 FrameID
etc.

    TBAMAnimationArray contains a lots of FrameID's. Exactly Sum(TBAMAnimHeader.Frames). To play animation simply
display frames from TBAMAnimArray[Start] to TBAMAnimArray[Start+Frames]. (maybe :-)

    And then finally comes the graphics data itself, which uses a special kind of run length transparency encoding where the byte 0x00 is special and codes for the byte after it meaning either a) the number of transparent pixels to emit or b) if the following byte is zero also, emit the entries for palette[0].

[ back to index ]

    WAVCV1.0

    Compressed sound resource..

TWAVCHeader (0x1C bytes)
0x0000 8 Marker 'WAVCV1.0'
0x0008 4 ResDataOrgSize
0x000C 4 ResDataCmprSize
0x0010 4 ResDataOffset
0x0014 2
0x0016 2
0x0018 4
0x001c x ResData Proprietary lossy compression? Could be MPEG1 (layer 2/4?).

[ back to index ]

    STORV1.0

    Stores and what they sell. Called up using code like: StartStore("tav0114",LastTalkedToBy())

TSTORHeader (0x9C bytes)
0x0000 8 Marker 'STORV1.0'
0x0008 4 StoType Type of resource. Valid values are 0 (Store), 1 (Tavern), 2 (Inn), and 3 (Temple)
0x000C 4 StoreNamePtr TLK resource of store/inn name.
0x0010 4 StoAttrs Bitmask determening the stores attributes:
0 = Sells items.
1 = Buys items.
2 = Identifies items.
3 = Stealing allowed.
4 = unknown - set for temples.
5 = unknown - set for temples.
6 = Bar/Drinking allowed.
7 = not used.
0x0014 4 SellPriceWeight Sell price in percentage of real item cost.
0x0018 4 BuyPriceWeight Buy price in percentage of real item cost.
0x001C 4 unk
0x0020 4 unk
0x002C 4 TblBuyItem Table of IDs of the types of items this store will buy from you.
0x0030 4 TblBuyItemCount
0x0034 4 TblSellItem Absolute offset of table of TSTORItemEntries.
0x0038 4 TblSellItemCount
0x003C 4 0x64
0x0040 4 CostIdent Cost of identifying items.
0x0044 8 DialogID ASCIIZ. Dialogue resource containing rumours heard in the bar.
0x004C 4 TblDrink Absolute offset of table of TSTORDrinkEntries.
0x0050 4 TblDrinkCount
0x005C 4 RoomsAvail Lower nibble maps to Royal, Noble, Merchant, Peasant
0x0060 4 RoomCostP Peasant
0x0064 4 RoomCostM Merchant
0x0068 4 RoomCostN Noble
0x006C 4 RoomCostR Royal
0x0070 4 TblSpell Pointer to TSTORSpellEntries (if temple)
0x0074 4 TblSpellCount

    List of items available in the store.

TSTORItemEntry (0x1C bytes)
0x0000 8 ItemID ASCIIZ
0x0008 2 unknown always zero?
0x000A 2 ItemsInPack The number of items in a pack.
0x000C 4 unknown
0x0010 4 BuyBack Boolean controlling if the store will buy the item back.
0x0014 4 PacksInStock The number of these packs in stock.
0x0018 4 Unlimited Boolean controlling 'unlimited supply of item'.

    List of drinks available for order.

TSTORDrinkEntry (0x14 bytes)
0x0000 4
0x0004 4
0x0008 4 DrinkNamePtr TLK resource of drink name.
0x000C 4 DringPrice
0x0010 4 Rumour

    List of spells available. Temples only (see StoType).

TSTORSpellEntry (0x0C bytes)
0x0000 8 SpellID ZTString
0x0008 4 Cost In gold

[ back to index ]

    MOS V1.0

    This structure contains the graphics for the mini-map of an area, and also for various other parts of the game interface. The format have some things in common with the 0x3EB format used for the huge background graphics. The format is one TMOSHeader, followed by a number of palettes, followed by an index of pointers to TGraphicsBlocks. These blocks shall then be arranged in a left-to-right, line by line order when presented. Like this:

Image
Block 1
64*64 pixels
Block 2
64*64 pixels
Block 3
64x64 pixels
Block 4
64*64 pixel
Block 5
x*64 pixels
Block 6
64*y pixels
Block 7
64*y pixels
Block 8
64*y pixels
Block 9
64*y pixels
Block 10
x*y pixels

    The size of the 'border' blocks must be calculated from the width and height fields available in the TMOSHeader.

TMOSHeader (0x18)
0x0000 8 Marker 'MOS V1.0',0x20,0x20
0x0008 2 Width In pixels
0x000a 2 Height In pixels
0x000c 2 Columns In blocks
0x000e 2 Rows In blocks
0x0010 4 BlkSize Width/height of blocks (?)
0x0014 4 BlkBPP Color depth of blocks (?)

    After this header comes the array of TPalette-structures (RGBA*256). There is one such for each graphical datablock in the file as can be computed from columns*rows. This is the format of the palettes used in MOS and other structures. (for n=0 to 0xff):

TPalette (0x400 bytes)
n+0 1 Red
n+1 1 Green
n+2 1 Blue
n+3 1 Alpha Alphachannel. Usually (always) zero.

    Immediately after that comes an index of pointers to TGraphicBlocks, relative from the start of data chunk. One such block consists pixel-data, usually 64*64 bytes but it can be less (see diagram above). This means the maximum size of one of these blocks are 0x1000 bytes. (I may expand on all this later as I have my own implementation written).

[ back to index ]

    WMAPV1.0

    Not much to say, this structure is used for the world map and your progress (areas discovered) in the world is stored here. You find it primarily in a file called worldmap.wmp in your savegame directory, which is built from the worldmap available in default.bif. As usual, all offsets are relative to the root-header, in this case the WMAPV1.0 structure.

TWMAPHeader (0x10 bytes)
0x0000 8 Marker 'WMAPV1.0'
0x0008 4 WorldMapCnt
0x000c 4 WorldMapPtr Offset of first TWorldMap.

    I am not sure these should really be split up, but let's work from that assumption for now since it explains the header above and also makes sense from a design-point-of-view.

TWorldMap (0xB8 bytes)
0x0000 8 MapResName 'WORLDMAP' (MOS map resources)
0x0004 4 unknown 0x280
0x000c 4 unknown 0x3a9
0x0010 4 zero
0x0014 4 unknown 0x3d2f (Friendly Arms Inn TLK-resource - coincidence?)
0x0018 4 zero
0x001c 4 zero
0x0020 4 WMEntryCnt
0x0024 4 WMEntryPtr Offset of first TWorldMapEntry.
0x0028 4 WMExitEntryPtr Offset of first TWorldMapExitEntry.
0x002c 4 WMExitEntryCnt
0x0030 8 MapIconResName Name of the BAM resource containing the graphics for the map icons.
0x0034 4 zero
0x0038 4 unknown another WMExitEntryPtr?

 

TWorldMapEntry (0xF0 bytes)
0x0000 8 AreaID01 'AR2626'
0x0008 8 AreaID02 'AR2600'
0x0010 16 MapAreaID 'MAPAR2600'
0x0030 4 Status 0x00 = Not visible on world map.
0x01 = Visible on world map, but not visited.
0x02 = ? (not visible)
0x03 = ? (see 0x01)
0x0F  = Visited and available for travel.
0x0034 4 BAMFrame Which frame of the MapIconRes (see above) to display for this icon
0x0038 4 XCoord
0x003c 4 YCoord
0x0040 4 LocationNamePtr TLK-resource, or -1 if not available.
0x0044 4 unknownPtr Probably TLK-resource, mostly -1.

    Work in progress.

TWorldMapExitEntry (0xD8 bytes)
0x0000 4 unknown
0x0004 8 ExitID ZTS

[ back to index ]

    WED V1.3

    This structure defines various things about an area, for instance, it contains a list of which graphical 0x3EB resources to load.

TWEDHeader (0x20 bytes)
0x0000 8 Marker 'WED V1.3'
0x0008 4 EnvCnt Count of TWEDEnvEntries (environment graphics & overlays).
0x000c 4 DoorCnt Count of TWEDDoorEntries.
0x0010 4 EnvPtr Offset of first TWEDEnvEntry.
0x0014 4 unkPtr2
0x0018 4 DoorPtr Offset of first TWEDDoorEntry.
0x001c 4 unkPtr4

 

TWEDEnvEntry (0x18 bytes)
0x0000 2 Width In blocks (?)
0x0002 2 Height In blocks (?)
0x0004 8 ResID 'WTWAVE',0,0
0x000c 4 unknown zero?
0x0010 4 unknown size/ptr?
0x0014 4 unknown size/ptr?

 

TWEDDoorEntry (0x?? bytes)
0x0000

[ back to index ]

 

In Depth Discussions and Clarifications

Under this heading I will dwell deeper into some areas that may need explaining.

    Encryption

    For some reason some of the 0x3F0 and 0x3F4 resources are encrypted. I am not sure why Bioware did this, especially      why they chose not to encrypt all resources, but just a selected few. I have as of now (1999-05-03) modified biftool to decrypt all encrypted resources of those types on-the-fly. You can disable this behaviour using the option -nodecrypt.

    The files are encrypted using a polyalphabetic cipher, using the exclusive-or operator and a running 512-bit key. Here is the key in hexa for you: "88 A8 8F BA 8A D3 B9 F5 ED B1 CF EA AA E4 B5 FB EB 82 F9 90 CA C9 B5 E7 DC 8E B7 AC EE F7 E0 CA 8E EA CA 80 CE C5 AD B7 C4 D0 84 93 D5 F0 EB C8 B4 9D CC AF A5 95 BA 99 87 D2 9D E3 91 BA 90 CA". A correct binary key will CRC32 to 0xEAA0399F using the standard polynomial. Any questions? Just mail me.

    If you use this, don't forget to credit us (with a link, thank you) for the research. You know you will feel very bad if you don't and instead try to pass this off as your own work.

    Time

    In the world of the Infinity-engine one day is 7200 units. This means that one hour is 7200/24=300 units, and thus 60 game seconds, which is one round, represents 5 units. We come to the conclusion that the engine is working with a 60/5 = 12s in-game-exposed-to-the-outside granularity, which in real world time is about 1.2s. I'm sure I got something wrong there, but the basic fact of 300 units/hour is correct, you can derive the rest yourself. The thing when computing the time from the TGAMHeader is that there's an extra 7 game-hours (=2100 units) for which you must account. Let me explain; Say the header reads 0x030201 and you want to calculate the time as shown by the load screen. First you must subtract the extra seven hours which gives you 195021. The number of days is then (195021/7200)=27 and the number of hours is ((195021/300) mod 24)=2. 27 days and two hours. See, magic! I'm sure you are very happy that I took the time to explain these higher maths for you ;-)

Tools

Here is a link to Petrs newer utilities. Below are my older command-line tools.

biftool v0.0.62 (~14Kb) Simple *.bif resource extractor. Example usage: 'biftool -extr 1 GUI.bif'
keytool
v0.0.1 (~8Kb) Use this to reverse the bitmaps of the chitin.key file. Usage: 'keytool >keytool.txt'
talktool
v0.0.4 (~8Kb) For us hackers only :-) 'talktool >talktool.txt'
itmtool
v0.0.2 (~8Kb) Dumps the descriptions of an .itm file.

 

Various Tables

Some relevant tables.

TblResourceType (see also the index)
0x0001 'BM', bitmap
0x0002 'Interplay MVE File',0x1A
0x0004 'RIFF','WAVE', sound samples (normal .wav's) and 'WAVCV1.0' (compressed)
0x03E8 'BAM V1'<space><space>, animations and smaller graphics (items and such)
0x03E9 'WED V1.3'
0x03EA 'CHUIV1'
0x03EB '??', area graphics.
0x03EC 'MOS V1', minimap and interface graphics.
0x03ED 'ITM V1', items
0x03EE 'SPL V1', spells
0x03EF 'SC', action scripts (compiled)
0x03F0 0xFF,0xFF (encrypted) or plain text of LUA constants/functions
0x03F1 'CRE V1.0', creature/character data
0x03F2 'AREAV1.0'
0x03F3 'DLG V1.0', dialogue
0x03F4 0xFF,0xFF (encrypted) or '2DA V1.0' (tables used by the game)
0x03F5 'GAMEV1.1'
0x03F6 'STORV1.0', Store (as in 'shop')
0x03F7 'WMAPV1.0', World map (how the different major areas connect to each other)
0x03F8 'EFF V2.0'

 

TblClass
0x01 Mage
0x02 Fighter
0x03 Cleric
0x04 Thief
0x05 Bard
0x06 Paladin
0x07 Fighter/Mage
0x08 Fighter/Cleric
0x09 Fighter/Thief
0x0A Fighter/Thief/Mage
0x0B Druid
0x0C Ranger
0x0D Mage/Thief
0x0E Cleric/Mage
0x0F Cleric/Thief
0x10 Fighter/Druid
0x11 Fighter/Mage/Cleric
0x12 Cleric/Ranger
101 Ankheg
102 Basilisk
103 Greater basilisk
104 Black bear
105 Brown bear
106 Cave bear
107 Polar Bear
108 Carrioncrawler
109 Wild dog
110 War dog
111 Doppleganger
112 Greater doppleganger
113 Drizzt
114 Elminster
115 Ettercap
116 Ghoul
117 Revenant ghoul
118 Ghast ghoul
119 Gibberling
120 Gnoll
121 Hobgoblin
122 Kbold
123 Kbold-Tasloi
124 Kbold-Xvart
125 Ogre
126 Ogre-Mage
127 Ogre-Halfogre
128 Ogre-Ogrllion
129 Sarevok
130 Fairy-Sirine
131 Fairy-Dryad
132 Fairy-Nereid
133 Fairy-Nymph
134 Skeleton
135 Skeleton-Warrior
136 Skeleton-Baneguard
137 Spider-Giant
138 Spider-Huge
139 Spider-Phase
140 Spider-Sword
141 Spider-Wraith
142 Volo
143 Wolf
144 Wolf-Worg
145 Wolf-Dire
146 Wolf-Winter
147 Wolf-Vampiric
148 Wolf-Dread
149 Wyvern
150 Olive slime
151 Mustard jelly
152 Ocre jelly
153 Grey ooze
154 Green slime
155 Innocent
156 Flaming fist
0xFF No class

 

tblItemType

0x00 Book
0x01 Amulet
0x02 Armor
0x03 Belt
0x04 Boots
0x05 Arrow
0x06 Bracers
0x07 Helmet
0x08 none ?
0x09 Potion
0x0A Ring
0x0B Scroll
0x0C Shield
0x0D unknown
0x0E Bullet
0x0F Bow
0x10 Dagger
0x11 Spiked weapon
0x12 Sling
0x13 Small sword
0x14 Large sword
0x15 Warhammer
0x16 Morning star
0x17 Flail
0x18 Dart
0x19 Axe
0x1A Staff
0x1B Crossbow
0x1C unknown
0x1D Spear
0x1E Halbherd
0x1F Bolt
0x20 Cloak
0x21 Gold
0x22 Misc
0x23 Wand

    The table below describes who cannot use an item.

tblItemUsability
0x00000001 Chaotic
0x00000002 Evil
0x00000004 Good
0x00000008 Neutral (neutral/good neutra/evil neutral/true)
0x00000010 Lawful
0x00000020 Neutral (good/neutral neutral/true evil/neutral)
0x00000040 Bard
0x00000080 Cleric
0x00000100 Illusionist
0x00000200 ?
0x00000400 ?
0x00000800 Fighter
0x00001000 ?
0x00002000 ?
0x00004000 ?
0x00008000 ?
0x00010000 ?
0x00020000 ?
0x00040000 Mage
0x00080000 ?
0x00100000 Paladin
0x00200000 Ranger
0x00400000 Thief
0x00800000 Elf

 

tblEffectType
0x00 AC
0x01 ATTACKNO
0x02 AWAKEN
0x03 BERSERK
0x04 CALM
0x05 CHARM
0x06 CHR
0x07 COLORCHANGE
0x08 COLORGLOW SOLID
0x09 COLORGLOW PULSE
0x0A CON
0x0B CUREPOISON
0x0C DAMAGE
0x0D DEATH
0x0E DEFROST
0x0F DEX
0x10 HASTE
0x11 HEAL
0x12 HITPOINTS
0x13 INT
0x14 INVISIBLE
0x15 LORE
0x16 LUCK
0x17 MORALE
0x18 PANIC
0x19 POISON
0x1A REMOVECURSE
0x1B RESISTACID
0x1C RESISTCOLD
0x1D RESISTELECTRICITY
0x1E RESISTFIRE
0x1F RESISTMAGIC
0x20 RESURRECT
0x21 Save (Paralyze/Poison/Death)
0x22 Save (Rod/Staff/Wand)
0x23 Save (Petrify/Polymorph)
0x24 Save (Breath)
0x25 Save (Spell)
0x26 SILENCE
0x27 SLEEP
0x28 SLOW
0x29 SPARKLE
0x2A SPELLMEMORIZATIONMAGE
0x2B STONETOFLESH
0x2C STR
0x2D STUN
0x2E UNSTUN
0x2F VISIBLE
0x30 VOCALIZE
0x31 WIS
0x32 SINGLECOLORPULSEALL
0x33 COLORTINT_SOLID
0x34 COLORLIGHT_SOLID
0x35 ANIMATION_CHANGE
0x36 THAC0
0x37 SLAY
0x38 ALIGNMENTREVERSAL
0x39 ALIGNMENTCHANGE
0x3A DISPELEFFECTS
0x3B SKILLSTEALTH
0x3C CASTINGFAILURE
0x3D Efect: 0x3D
0x3E SPELLMEMORIZETIONCLERIC
0x3F INFRAVISION
0x40 INFRAVISIONOFF
0x41 BLUR
0x42 TRANSCULENT
0x43 SUMMON
0x44 UNSUMMON
0x45 NONDETECTION
0x46 ENDNONDETECTION
0x47 SEXCHANGE
0x48 AICHANGE
0x49 DAMAGEMOD
0x4A BLINDNESS
0x4B CUREBLINDESS
0x4C FEEBLEMINDEDNESS
0x4D CUREFEEBLMINDEDNESS
0x4E DISEASE
0x4F CUREDISEASE
0x50 DEAFNESS
0x51 CUREDEAFNESS
0x52 SETAISCRIPT
0x53 IMMUNITYTOPROJECTILE
0x54 RESISTMAGICFIRE
0x55 RESISTMAGICCOLD
0x56 RESISTSLASHING
0x57 RESISTCRUSHING
0x58 RESISTPIERCING
0x59 RESISTMISSILE
0x5A SKILLLOCKPICKING
0x5B SKILLTRAPS
0x5C SKILLPICKPOCKET
0x5D FATIGUE
0x5E INTOXICATION
0x5F SKILLTRACKING
0x60 LEVEL
0x61 STREXTRA
0x62 REGENERATION
0x63 DURATIONMOD
0x64 PROTECTIONFROMCREATURE
0x65 IMMUNITYTOEFFECT
0x66 IMMUNITYTOSPELLLEVEL
0x67 NAME
0x68 XP
0x69 GOLD
0x6A MORALEBREAK
0x6B PORTRAIT
0x6C REPUTATION
0x6D HOLD_CREATURE
0x6E RETREAT_FROM
0x6F CREATE_WEAPON
0x70 DESTROY_WEAPON
0x71 EQUIP_WEAPON
0x72 DITHER
0x73 DETECT_ALIGNMENT
0x74 DISPEL_INVISIBLE
0x75 SHOW_AREA
0x76 SHOW_CREATURES
0x77 MIRROR_IMAGE
0x78 IMUNITY_TO_WEAPON
0x79 VISUAL_ANIMATION_EFFECT
0x7A CREATE_ITEM
0x7B DESTROY_ITEM
0x7C TELEPORT
0x7D KNOCK
0x7E MOVEMENT_RATE
0x7F RAND