Cosmic's

Technology & Life

Fallout 3 save parser

· ,

I reinstalled Fallout 3 recently, a game I sunk dozens of hours into and loved every minute of. I wanted to bring my old saves back online after 14 years on the shelf and experience where I left off rather than creating a new character. But there was a hitch: I needed the my old mods reinstalled in order to properly load the old saves, and I didn't remember exactly which ones I had installed.

I figured I could parse the save files since they must keep a record of which mods were in use at save time, and it turns out it's not too difficult at all. My initial version took 10+ seconds to parse my saves, then 4 seconds with System.IO, now less than 1 with the break to leave the file after parsing completes. Now, it does exactly what I want and it's super fast. I love it.

Hopefully this will help someone out one day. Enjoy!

Script

# Configure
$SourceDir = '{0}\Saves' -f $PSScriptRoot
$ShowESM = $True
$ShowESP = $True

# Check for source dir
If (-Not (Test-Path -Path $SourceDir)) { 'Saves directory not found.'; Exit 1; }

# Main
$Files = (Get-ChildItem -Path $SourceDir -Filter '*.fos' | Sort-Object LastWriteTime)
ForEach ($File in $Files)
{
    # Store the output
    $ESMList = @()
    $ESPList = @()

    ForEach ($Line in [System.IO.File]::ReadLines(('{0}\{1}' -f $SourceDir, $File.Name)))
    {
        If (($ShowESM -and ($Line -Match '\.esm')) -or ($ShowESP -and ($Line -Match '\.esp')))
        {
            # All of the plugins are on the same line, following Fallout3.esm
            If ($Line -Match 'Fallout3\.esm')
            {
                ForEach ($Record in $Line.Split('|'))
                {
                    If ($ShowESM -and ($Record -Match '[a-zA-Z0-9._-].esm$'))
                    {
                        $ESMList += $Record
                    }

                    If ($ShowESP -and ($Record -Match '[a-zA-Z0-9._-].esp$'))
                    {
                        $ESPList += $Record
                    }
                }
                
                # Done with this file
                Break
            }
        }
    }

    # Show header
    $Header = '{0} - {1}' -f $File.Name, $File.LastWriteTime
    "{0}`n{1}" -f $Header, ("=" * $Header.Length)

    # Show output
    If ($ShowESM) { $ESMList }
    If ($ShowESP) { $ESPList }
    ""
}

Results

Here are some samples from running the script against my old saves folder. These are probably not the same save file over time since I was using a couple saves in parallel for different adventures.

Save 1 - Cosmic, Vault 101, 01.05.51.fos - 2008-11-24 22:14:01
===============================================================
Fallout3.esm

...

Save 26 - Cosmic, Lucas Simms' House, 53.53.14.fos - 2009-01-03 02:09:18
================================================================================
Fallout3.esm
Enhanced Pipboy Light.esp
Companion Mods.esp
Invincible Caravans.esp
Megaton Names.esp
Silenced G3.esp
PoisonousHat.esp

...

Save 34 - Cosmic, The Capital Wasteland, 68.10.25.fos - 2010-03-24 21:11:12
===================================================================================
Fallout3.esm
Enhanced Pipboy Light.esp
Companion Mods.esp
Invincible Caravans.esp
MaxLevelWorkaround-HP.esp
Megaton Names.esp
GNR Fix.esp
Xepha's Darker Nights.esp
DarkerInteriorsFallOut3.esp

Worked great! Then I was able to get my old mods from TES Nexus Nexus Mods and boot up my old saves again, fully working and intact.