FTL (un)packer for Linux

Update: Added some notes about what is in the various files in data.dat

Recently I bought Faster Than Light (FTL), a game which runs on Linux (and also on Mac and Windows).

I noticed that there was a lot of stuff in two ".dat" files; the format of the ".dat" files turned out to be very simple, and so I wrote a packer and unpacker: ftlpack.py.

Inside data.dat are a lot of .xml and .txt files that can potentially customize the game. It appears to be possible to add new ship types, loadouts, and layouts; add new in-game events; change or add to the outcomes of existing in-game events. resource.dat contains artwork and sound, which also begs for user modifications.

Remember to back up your original data files before using these scripts. Your modifications may make FTL crash or worse.


cp data.dat data.dat.orig
python ftlpack.py --unpack data.dat data_new
... edit inside data_new
python ftlpack.py --pack data_new data.dat

All these comments pertain to the Linux version of the game; I don't know whether they apply to Windows or Mac builds. Additionally, I know there is at least one unixism in the attached Python script (the usage of 'mmap').

As an example, I changed the drop from a 'typical' battle in data.diff.

Here's a very consise summary of the file format: all numbers (offsets and lengths) are 4-byte little-endian values. The file begins with the number of entries (not bytes) in the directory area (some entries may be unused). It is followed by byte offsets to each entry (relative to the start of the file). Unused entries are written zeros.

An individual entry consts of (entry length in bytes) (entry name length in bytes) (entry name) (entry data).

The shipped 'data.dat' has unused entries, but repacking it without unused entries still works. There didn't appear to be any alignment requirements of entries.

Files currently attached to this page:

data.diff841 bytes


Editing <crewBlueprint>s to add items to <powerList> only displays them in the UI. They don't actually add or remove powers from that crew type.

I haven't determined what <bp> is.

It's easy to change the cost of ship upgrades to 0 by changing the <upgradeCost>s. For some systems, you can also enable higher levels; in a few cases there are even texts about <!-- imaginary level 4 --> which might be implemented in gameplay. In one game I increased the maxPower of artillery to a level that apparently gave a 0-second recharge. This worked dandy for a little bit and then the game locked up.

There's a block just begging to be uncommented for the <!-- BOSS-READY SHIP -->, a well-upgraded Kestrel.

autoBlueprints.xml seems to specify random enemy configurations.


Specifies the layout of the ship. "DOOR" and "ROOM" specify fairly obvious things. ROOM specifies room number, upper-left corner X and Y, and width and height. DOOR specifies door location X and Y, connecting rooms (-1 for space), and direction (1=vertical, 0=horizontal). X_OFFSET / Y_OFFSET / VERTICAL control the position of the ship onscreen. ELLIPSE seems to have to do with the shield graphic position.

Deleing the last two DOOR blocks remove the space-facing doors from the north-side airlocks. Removing the block for ROOM 6 screws up the whole ship rendering. Modifying it to

extends the room horizontally (2 changed to 9). Adding the block
adds a second door from shields to medbay. Changing the ROOM 15 block to height 2 gives 4 working teleporter slots.


Doesn't seem possible to do anything but edit images and flavor text here.


Notably, where events have multiple outcomes nothing seems to specify a probability of each outcome. Are these just 50/50 (or 33/33/33)?

<event unique="true"> -- does this mean it can happen at most once per game?

<unlockShip id="###"> (seen events_crystal.xml) -- hm, you could probably toss these in any old event and unlock all the ships. How do the ids relate to the <shipBlueprint>? Hardcoded?


Looks like you can make new sector types here, or change the events that can be kicked off in each sector.

Entry first conceived on 9 October 2012, 2:30 UTC, last modified on 9 October 2012, 18:23 UTC
Website Copyright © 2004-2021 Jeff Epler