Skip to main content

Overview

The BundleEntry class represents asset bundles in the Frostbite engine. Bundles are containers that group related assets together for loading and organization.

Class Definition

public class BundleEntry
{
    public string DisplayName => Name;
    
    public string Name;
    public int SuperBundleId;
    public EbxAssetEntry Blueprint;
    public BundleType Type;
    public bool Added;
}
Location: FrostySdk/Managers/AssetManager.cs:114

Properties

Name
string
Bundle name/path (e.g., "win32/levels/mp/mp_001"). May be a hash for some games.
DisplayName
string
Display name for UI - currently returns the same value as Name.
SuperBundleId
int
Index of the parent superbundle containing this bundle.
Blueprint
EbxAssetEntry
Reference to the blueprint EBX asset defining this bundle (for sublevel/blueprint bundles).
Type
BundleType
Type of bundle: None, SubLevel, BlueprintBundle, or SharedBundle.
Added
bool
True if this bundle was added via modding (not in base game).

Bundle Types

None
BundleType
Unknown or uninitialized bundle type.
SubLevel
BundleType
Sublevel bundle containing level/world data. Associated with SubWorldData assets.
BlueprintBundle
BundleType
Blueprint bundle containing entity blueprint data. Associated with BlueprintBundle assets.
SharedBundle
BundleType
Shared bundle containing common assets used across multiple levels/blueprints.

SuperBundle Entry

Superbundles are top-level containers that group multiple bundles:
public class SuperBundleEntry
{
    public string Name;
    public bool Added;
}
Name
string
Superbundle name (e.g., "levels/mp/mp_001").
Added
bool
True if this superbundle was added via modding.

Usage Examples

Getting a Bundle

// Get bundle by name
BundleEntry bundle = assetManager.GetBundleEntry("win32/levels/mp/mp_001");

if (bundle != null)
{
    Console.WriteLine($"Bundle: {bundle.Name}");
    Console.WriteLine($"Type: {bundle.Type}");
    
    if (bundle.Blueprint != null)
    {
        Console.WriteLine($"Blueprint: {bundle.Blueprint.Name}");
    }
}

Enumerating Bundles

// Enumerate all bundles
foreach (BundleEntry bundle in assetManager.EnumerateBundles())
{
    Console.WriteLine($"{bundle.Name} ({bundle.Type})");
}

// Enumerate only blueprint bundles
foreach (BundleEntry bundle in assetManager.EnumerateBundles(
    type: BundleType.BlueprintBundle))
{
    Console.WriteLine($"Blueprint: {bundle.Name}");
}

// Enumerate only modified bundles
foreach (BundleEntry bundle in assetManager.EnumerateBundles(
    modifiedOnly: true))
{
    Console.WriteLine($"Modified: {bundle.Name}");
}

Enumerating Assets in Bundle

BundleEntry bundle = assetManager.GetBundleEntry("win32/gameplay/weapons");

// Get all EBX assets in bundle
foreach (EbxAssetEntry ebx in assetManager.EnumerateEbx(bundle))
{
    Console.WriteLine($"EBX: {ebx.Name} ({ebx.Type})");
}

// Get all resource assets in bundle
foreach (ResAssetEntry res in assetManager.EnumerateRes(bundle))
{
    Console.WriteLine($"RES: {res.Name} ({res.Type})");
}

// Get all chunks in bundle
foreach (ChunkAssetEntry chunk in assetManager.EnumerateChunks(bundle))
{
    Console.WriteLine($"Chunk: {chunk.Id}");
}

Creating a New Bundle

// Get or create superbundle
SuperBundleEntry sb = assetManager.AddSuperBundle("custom/mybundle");
int sbIndex = assetManager.GetSuperBundleId(sb);

// Create bundle
BundleEntry bundle = assetManager.AddBundle(
    name: "win32/custom/mybundle",
    type: BundleType.SharedBundle,
    sbIndex: sbIndex
);

Console.WriteLine($"Created bundle: {bundle.Name}");
Console.WriteLine($"Bundle is new: {bundle.Added}");

Adding Assets to Bundle

BundleEntry bundle = assetManager.GetBundleEntry("win32/custom/weapons");
int bundleId = assetManager.GetBundleId(bundle);

// Add EBX to bundle
EbxAssetEntry ebx = assetManager.GetEbxEntry("weapons/rifle_01");
ebx.AddToBundle(bundleId);

// Add resource to bundle
ResAssetEntry res = assetManager.GetResEntry("weapons/rifle_01");
res.AddToBundle(bundleId);

// Add chunk to bundle
ChunkAssetEntry chunk = assetManager.GetChunkEntry(chunkId);
chunk.AddToBundle(bundleId);

Working with Blueprint Bundles

// Find all blueprint bundles
foreach (BundleEntry bundle in assetManager.EnumerateBundles(
    BundleType.BlueprintBundle))
{
    if (bundle.Blueprint != null)
    {
        Console.WriteLine($"Blueprint Bundle: {bundle.Name}");
        Console.WriteLine($"  Blueprint Asset: {bundle.Blueprint.Name}");
        Console.WriteLine($"  Blueprint Type: {bundle.Blueprint.Type}");
        
        // Load blueprint to examine contents
        EbxAsset blueprintAsset = assetManager.GetEbx(bundle.Blueprint);
        // ... work with blueprint data ...
    }
}

Working with Sublevel Bundles

// Find sublevel bundles
foreach (BundleEntry bundle in assetManager.EnumerateBundles(
    BundleType.SubLevel))
{
    Console.WriteLine($"Sublevel: {bundle.Name}");
    
    if (bundle.Blueprint != null && 
        bundle.Blueprint.Type == "SubWorldData")
    {
        Console.WriteLine($"  World: {bundle.Blueprint.Name}");
    }
}

Getting Bundle Hierarchy

BundleEntry bundle = assetManager.GetBundleEntry("win32/levels/mp/mp_001");

// Get parent superbundle
SuperBundleEntry superBundle = 
    assetManager.GetSuperBundleEntry(bundle.SuperBundleId);
    
Console.WriteLine($"Bundle: {bundle.Name}");
Console.WriteLine($"SuperBundle: {superBundle.Name}");

Filtering Bundles by Path

// Get all bundles under a path
string basePath = "win32/levels";

foreach (BundleEntry bundle in assetManager.EnumerateBundles())
{
    if (bundle.Name.StartsWith(basePath + "/", 
        StringComparison.OrdinalIgnoreCase))
    {
        Console.WriteLine($"Level bundle: {bundle.Name}");
    }
}

Checking Asset Bundle Membership

EbxAssetEntry asset = assetManager.GetEbxEntry("characters/hero");

// Check which bundles contain this asset
Console.WriteLine($"Asset in {asset.Bundles.Count} bundles:");
foreach (int bundleId in asset.EnumerateBundles())
{
    BundleEntry bundle = assetManager.GetBundleEntry(bundleId);
    Console.WriteLine($"  - {bundle.Name}");
}

Creating Bundle with Assets

// Create superbundle and bundle
SuperBundleEntry sb = assetManager.AddSuperBundle("custom/weapons");
int sbId = assetManager.GetSuperBundleId(sb);
BundleEntry bundle = assetManager.AddBundle(
    "win32/custom/weapons", BundleType.SharedBundle, sbId);
int bundleId = assetManager.GetBundleId(bundle);

// Create assets in the bundle
EbxAsset weaponAsset = new EbxAsset();
// ... configure weapon asset ...

EbxAssetEntry weaponEntry = assetManager.AddEbx(
    "weapons/custom_rifle",
    weaponAsset,
    bundles: bundleId
);

Console.WriteLine($"Created asset in bundle: {weaponEntry.Name}");

Removing Bundle (Revert)

BundleEntry bundle = assetManager.GetBundleEntry("win32/custom/mybundle");

if (bundle.Added)
{
    // Only added bundles can be reverted
    assetManager.RevertBundle(bundle);
    Console.WriteLine("Bundle removed");
}

Bundle Organization Patterns

Level Bundles

win32/levels/mp/mp_001              (SubLevel)
├── win32/levels/mp/mp_001_art      (SharedBundle)
├── win32/levels/mp/mp_001_audio    (SharedBundle)
└── win32/levels/mp/mp_001_logic    (BlueprintBundle)

Character Bundles

win32/characters/hero                (BlueprintBundle)
├── characters/hero (EBX)            
├── characters/hero (RES - MeshSet)
└── [chunks] (mesh data)

Shared Asset Bundles

win32/shared/weapons                 (SharedBundle)
├── Multiple weapon EBX assets
├── Shared textures and materials
└── Common audio/effects

Bundle Name Hashing

In some games (SWBF2, BFV), bundle names are hashed:
// For games with hashed bundle names
if (ProfilesLibrary.DataVersion == (int)ProfileVersion.StarWarsBattlefrontII ||
    ProfilesLibrary.DataVersion == (int)ProfileVersion.Battlefield5)
{
    // Bundle name may be a hex hash
    if (bundle.Name.Length == 8 && IsHex(bundle.Name))
    {
        Console.WriteLine($"Hashed bundle: 0x{bundle.Name}");
        
        // Name gets resolved from blueprint asset
        if (bundle.Blueprint != null)
        {
            bundle.Name = "win32/" + bundle.Blueprint.Name;
        }
    }
}

Build docs developers (and LLMs) love