Skip to content

Asobo Save Game File Format Specification

widberg edited this page May 20, 2024 · 35 revisions

This is the save game format used in FUEL. Other games have different formats. Saves are located in %USERPROFILE%\Documents\My Games\FUEL this directory contains one subdirectory for each GFWL profile name, where the name of the subdirectory is the same as the name of the profile. Each of these subdirectories contains a single FUEL_SAVE_V14.sav file which is the save game for that profile. Note that save games use the Alternate CRC-32 algorithm and not the primary one. For more information about the compression used, see the Asobo Arithmetic Coding Compression entry.

The fuel-save-editor repository contains a tool for unpacking and packing FUEL save files.

struct SaveGame
{
    std::uint32_t xliveHeaderSize;
        // Always 4
        // Written by xlive
    std::uint32_t saveGameDataCRC32Checksum0;
        // Alternate CRC-32 Checksum of saveGameData taken as a raw byte buffer
        // Equals saveGameDataCRC32Checksum1
        // Written by xlive
    SaveGameData saveGameData;
        // 199996 bytes
    std::uint32_t saveGameDataCRC32Checksum1;
        // Alternate CRC-32 Checksum of saveGameData taken as a raw byte buffer
        // Equals saveGameDataCRC32Checksum0
};
struct SaveGameData 
{
    std::uint32_t dataCompressedSize;
        // Includes the sizes of dataCompressedSize and dataDecompressedSize
    std::uint32_t dataDecompressedSize;
    std::uint8_t data[dataCompressedSize - 4 - 4];
        // dataCompressedSize and dataDecompressedSize are part of the compressed data so we subtract their size from the data array
        // Data is compressed using Asobo's Order 1 Arithmetic Coding
    std::uint8_t zeros[199996 - dataCompressedSize - 1];
        // Filled with 0x00
        // Used to pad the SaveGameData structure size to 199996 bytes
    std::uint8_t version;
        // Always equals 61
};

The following is an 010 Editor template for the decompressed save data. One of the unnamed fields must be the trick count (when the guy does weird shit with his legs on bikes and quads).

struct AlignedCString
{
    local int len = ReadStringLength(FTell());
    char str[len];

    local int a = 4;
    local int x = FTell() + 1;
    local int r = x % a;
    FSeek(r ? x + (a - r) : x);
};

struct
{
    AlignedCString SectionName;
    uint32 version; // always 636
    byte x[66];
    int32 fuel;
    int32 total_fuel_drums_found;
    int32 camera_distance;
    int32 y;
    int32 hub_index;
    int32 yy;
    int32 selected_vehicle_index;
    int32 unk2;
    int32 head_type_index;
    int32 chest_type_index;
    int32 legs_type_index;
    int32 head_livery_index;
    int32 chest_livery_index;
    int32 legs_livery_index;
    int32 body_livery_index;
    int32 body_color_index;
    byte race_info;
    byte ranking_info;
    byte speed_meter;
    byte gps;
    byte length_uint; // miles = 1, km = 0
    byte brightness; // 1 = changed, 0 = default
    byte padding[2];
    float xxx; // always 1
    float yyy; // always 0.25
    float zzz; // always 1
    int32 h; // always 5
    int32 distance_covered_in_free_ride_km;
    float distance_covered_in_free_ride_m;
    int32 distance_covered_in_race_ride_km;
    float distance_covered_in_race_ride_m;
    int32 distance_covered_on_road_km;
    float distance_covered_on_road_m;
    int32 distance_covered_off_road_km;
    float distance_covered_off_road_m;
    float longest_jump;
    float highest_jump;
    int32 unk4;
    uint32 developer_flags; // 0x1 on = hide huds
    int32 z;
    int32 zzzzz;
    int32 zzzz;
    int32 sessions_played_and_finished;
    int32 sessions_ranked_1st;
    byte zz[12];
    float max_time_spent_in_air;
    float peak_speed; // stored as m/s which is 0.277778 * km/h
    int32 number_of_times_heliports_used;
    int32 time_played; // milliseconds
    int32 ww;
    int32 www;
    float brightness;
    int32 o;
    int32 music_volume; // [0-16]
    int32 sfx_volume; // [0-16]
    byte g[21];
    byte x_axis; // 1 = inverted, 0 = normal
    short vibrations;
    int32 bbbb;
    byte b[12];
    int32 y_axis;
} SECTION_SAVESTRUCT_INFOS;

struct
{
    AlignedCString SectionName;
    uint32 version; // always 2000
    int vehicles_size;
    struct
    {
        uint32 vehicle_crc32;
        byte unlocked;
        byte owned;
        byte pad0;
        byte pad1;
        float distance;
    } vehicles[vehicles_size];
} SECTION_VEHICLES_INFOS;

struct
{
    AlignedCString SectionName;
    uint32 version; // always 2344
    uint32 datasizebytes;
    // data begins
    uint32 context_count;
    struct Context
    {
        uint32 actions_size;
        struct Action
        {
            uint32 primary;
            uint32 secondary
            uint32 controls_index;
        } actions[actions_size] <optimize=false>;
    } contexts[context_count] <optimize=false>;
    // data ends
} SECTION_INPUT;

struct
{
    AlignedCString SectionName;
    uint32 version; // always 200
    int actionsSize;
    struct
    {
        int index;
        byte unlocked;
        byte completed;
    } actions[actionsSize];
} SECTION_TUTORIAL;

struct
{
    AlignedCString SectionName;
    uint32 version; // always 84
    int unlockeds_size;
    struct
    {
        byte unk1;
        byte unk2;
    } unlockeds[unlockeds_size] <optimize=false>;
} SECTION_HUB_INFOS;

struct
{
    AlignedCString SectionName;
    uint32 version; // always 540
    int hubs_size;
    struct
    {
        int unlockeds_size;
        short unlockeds[unlockeds_size] <optimize=false>;
    } hubs[hubs_size] <optimize=false>;
} SECTION_VISTAPOINT_INFOS;

struct
{
    AlignedCString SectionName;
    uint32 version; // always 23440
    local int editedRacesSize = 10;
    struct
    {
        uint32 b;
        uint32 c;
        uint32 d;
        byte e;
        byte f;
        byte g; // 1 if used, 0 otherwise
        byte h; // -1 if slot unused
        uint32 numUsedCheckpoints;
        local int numCheckpoints = 32;
        struct
        {
            float x;
            float z;
            float y;
            uint32 a;
            uint32 b;
            uint32 c;
            float d;
            uint32 e;
            uint32 f;
        } checkpoints[numCheckpoints];
    } editedRaces[editedRacesSize] <optimize=true>;
} SECTION_EDITEDRACE_INFOS;

struct
{
    AlignedCString SectionName;
    uint32 version; // always 21576
    uint32 hubs_ssize;
    struct
    {
        uint32 hub_index;
        uint32 unk3;
        uint32 careers_ssize;
        struct
        {
            byte x[40];
        } careers[careers_ssize] <optimize=false>;
        uint32 challenges_size;
        struct
        {
            byte x[40];
        } challenges[challenges_size] <optimize=false>;
    } hubs[hubs_ssize] <optimize=false>;
} SECTION_MISSION_INFOS;

struct
{
    AlignedCString SectionName;
    uint32 version; // always 1024
    uint32 hubs_size;
    struct
    {
        uint32 traffics_size;
        struct
        {
            uint32 crc32;
            byte spotted;
            byte found;
        } traffics[traffics_size] <optimize=false>;
    } hubs[hubs_size] <optimize=false>;
} SECTION_TRAFFIC_INFOS;

struct
{
    AlignedCString SectionName;
    uint32 version; // always 2884
    uint32 hubs_size;
    struct
    {
        uint32 liveries_size;
        struct
        {
            uint32 crc32;
            byte spotted;
            byte found;
        } liveries[liveries_size] <optimize=false>;
    } hubs[hubs_size] <optimize=false>;
} SECTION_VEHICLES_LIVERIES_INFOS;

struct
{
    AlignedCString SectionName;
    uint32 version; // always 508
    int unlockeds_size;
    byte unlockeds[unlockeds_size];
    int selected_size;
    struct
    {
        uint32 slot_crc32;
        int32 item_index;
    } selected[selected_size];
} SECTION_PILOT_LIVERIES_INFOS;

Home
FAQ

For FMTK Users and Mod Developers

Read the Docs

For FMTK Developers

Asobo BigFile Format Specification
Asobo Classes
      Animation_Z
      Binary_Z
      Bitmap_Z
      Camera_Z
      CollisionVol_Z
      Fonts_Z
      GameObj_Z
      GenWorld_Z
      GwRoad_Z
      Keyframer*_Z
      Light_Z
      LightData_Z
      Lod_Z
      LodData_Z
      Material_Z
      MaterialAnim_Z
      MaterialObj_Z
      Mesh_Z
      MeshData_Z
      Node_Z
      Omni_Z
      Particles_Z
      ParticlesData_Z
      RotShape_Z
      RotShapeData_Z
      Rtc_Z
      Skel_Z
      Skin_Z
      Sound_Z
      Spline_Z
      SplineGraph_Z
      Surface_Z
      SurfaceDatas_Z
      UserDefine_Z
      Warp_Z
      World_Z
      WorldRef_Z
Asobo File Format Idioms
Asobo CRC32
Asobo LZ Compression
Asobo Arithmetic Coding Compression
Asobo Save Game File Format Specification
Asobo Audio Formats
TotemTech/ToonTech/Zouna/ACE/BSSTech/Opal Timeline
Zouna Modding Resources
Miscellaneous

Clone this wiki locally