Skip to content

en Basic VaultLoaden

HoCha113 edited this page Jun 22, 2026 · 9 revisions

Documentation moved: This page is archived. See the up-to-date guide at innovault.wiki.

Expanded coverage on innovault.wiki

中文版本

What is VaultLoadenAttribute?

VaultLoadenAttribute auto-loads textures, sounds, shaders, etc. onto static fields, properties, or classes, replacing hand-written ModContent.Request calls.

Basic Features

  • Automatically loads textures, sounds, effects, and other resources for static fields or properties
  • Supports class-level tags for batch management of all resource members in a class
  • Supports intelligent path completion, namespace replacement, and class path replacement
  • Supports cross-mod resource referencing
  • Supports arrays and lists for batch loading
  • Supports custom loaders to extend new resource types
  • Resource type can be auto-inferred or manually specified

Supported Resource Types

Single Resources

Resource Type Member Type AssetMode Value Notes
Sound SoundStyle AssetMode.Sound
Texture (lazy) Asset<Texture2D> AssetMode.Texture Recommended, loads on demand
Texture (immediate) Texture2D AssetMode.TextureValue Loads into memory immediately
Shader (lazy) Asset<Effect> AssetMode.Effects
Shader (immediate) Effect AssetMode.EffectValue
Armor Shader ArmorShaderData AssetMode.ArmorShader
Misc Shader MiscShaderData AssetMode.MiscShader

Collection Resources (Arrays / Lists)

All of the above types support batch loading via arrays T[] or IList<T>. The system automatically loads by numeric suffix (e.g., _0, _1, _2...).

Resource Type Member Type AssetMode Value
Sound Array SoundStyle[] AssetMode.SoundArray
Texture Array Asset<Texture2D>[] AssetMode.TextureArray
Shader Array Asset<Effect>[] AssetMode.EffectArray

Usage

Apply the [VaultLoaden] attribute to a field or property, optionally specifying the path and asset type.

[VaultLoaden("Assets/Sounds/MySound", AssetMode.Sound)]
public static SoundStyle MySoundEffect;

Simplified Path (Auto-completing Field Name)

If the path ends with /, the field name will be automatically appended as the resource file name:

[VaultLoaden("Assets/Textures/UI/", AssetMode.Texture)]
public static Asset<Texture2D> ButtonBackground;
// Actual path: Assets/Textures/UI/ButtonBackground

Namespace Replacement

You can use the {@namespace} placeholder in the path to automatically replace with the namespace path:

namespace MyMod.Content.UI {
    [VaultLoaden("{@namespace}/Panels/", AssetMode.Texture)]
    public static Asset<Texture2D> MainPanel;
}
// Actual path: MyMod/Content/UI/Panels/MainPanel

Class Path Replacement

You can use the {@classPath} placeholder in the path, which will be replaced with the full tag path of the class where the member resides:

namespace MyMod.Content.Items {
    public class MyWeapon {
        [VaultLoaden("{@classPath}/Icon")]
        public static Asset<Texture2D> WeaponIcon;
    }
}
// Actual path: MyMod/Content/Items/MyWeapon/Icon

If the class itself is also marked with [VaultLoaden], then {@classPath} will use the class tag's Path value:

namespace MyMod.Content.Items {
    [VaultLoaden("Assets/Weapons/")]
    public class MyWeapon {
        [VaultLoaden("{@classPath}Icon")]
        public static Asset<Texture2D> WeaponIcon;
    }
}
// Actual path: Assets/Weapons/Icon

Auto-Inferring Resource Type

If AssetMode is not specified, the type will be inferred from the field type:

[VaultLoaden("Assets/Sounds/MenuOpen")]
public static SoundStyle MenuOpenSound;
// Automatically inferred as AssetMode.Sound
[VaultLoaden("Assets/Effects/Glow/")]
public static Asset<Effect> GlowEffect;
// Auto-completes field name, final path: Assets/Effects/Glow/GlowEffect

Setting Effect Pass Name (for Effect and ArmorShader)

[VaultLoaden("Assets/Effects/Glow/GlowEffect", AssetMode.ArmorShader, "CustomPass")]
public static ArmorShaderData CustomShader;
// Uses effect pass name "CustomPass"

If effectPassname is omitted, it defaults to {EffectName}Pass.

Cross-Mod Resource Referencing

To load a resource from another mod, prefix the path with @ModName/:

[VaultLoaden("@ExampleMod/Assets/Textures/ExtraBar", AssetMode.Texture)]
public static Asset<Texture2D> ExtraBarTex;
// Loads resource from mod named ExampleMod

Class-Level Tags

Marking [VaultLoaden] on a class provides default loading rules for all untagged static members in the class, and recursively applies to nested classes.

// Automatically load all resource members in the class
[VaultLoaden("Assets/Image/")]
public class AssetClass2
{
    public static Asset<Texture2D> Image1; // Loads "Assets/Image/Image1"
    public static Asset<Texture2D> Image2; // Loads "Assets/Image/Image2"
    public static Asset<Texture2D> Image3; // Loads "Assets/Image/Image3"
}

// It's optional to end the path with '/', the system will auto-complete
[VaultLoaden("Assets/Image")]
public class AssetClass3
{
    public static Asset<Texture2D> Image1; // Loads "Assets/Image/Image1"
    public static Asset<Texture2D> Image2; // Loads "Assets/Image/Image2"
    // Class-level and member-level tags do not conflict;
    // class management will skip members that have their own tag
    [VaultLoaden("@OtherMod/Textures/")]
    public static Asset<Texture2D> MyFaceImage; // Loads "OtherMod/Textures/MyFaceImage"
}

Path Concatenation Extension (PathConcatenation)

Only applicable to class-level tags. When enabled, member names are split by underscore _ into subdirectory paths:

[VaultLoaden("Assets/UI/", AssetMode.None, "", 0, 0, true)]
public class UIAssets
{
    public static Asset<Texture2D> Button_Primary_Hover;
    // Member name "Button_Primary_Hover" is split by underscore
    // Final path: Assets/UI/Button/Primary/Hover
    
    public static Asset<Texture2D> Panel_Main_Background;
    // Final path: Assets/UI/Panel/Main/Background
}

Class-Level Tag AssetMode Filtering

When AssetMode is specified on a class-level tag, only members matching that type will be processed:

[VaultLoaden("Assets/Textures/", AssetMode.Texture)]
public class TextureAssets
{
    public static Asset<Texture2D> Icon;       // ✅ Will be loaded
    public static SoundStyle ClickSound;       // ❌ Type mismatch, skipped
}

Array and List Loading

Supports loading resources as arrays or IList<T>. The system loads by numeric suffix _0, _1, _2... in order.

// Method 1: Pre-initialize array length, system auto-infers count
[VaultLoaden("Assets/Textures/Frames/Walk")]
public static Asset<Texture2D>[] WalkFrames = new Asset<Texture2D>[8];
// Loads: Walk_0, Walk_1, Walk_2 ... Walk_7

// Method 2: Specify count via arrayCount parameter
[VaultLoaden("Assets/Textures/Frames/Run", AssetMode.None, "", 0, 6)]
public static Asset<Texture2D>[] RunFrames;
// Loads: Run_0, Run_1 ... Run_5

// Method 3: Specify start index
[VaultLoaden("Assets/Textures/Frames/Attack", 1, 4)]
public static Asset<Texture2D>[] AttackFrames;
// Loads: Attack_1, Attack_2, Attack_3, Attack_4

Custom Loader (VaultLoadenHandle)

If the built-in resource types are not enough, you can extend the system by inheriting VaultLoadenHandle to support new loading types.

public class MyCustomLoader : VaultLoadenHandle
{
    // The target type this loader handles
    public override Type TargetType => typeof(MyCustomResource);
    
    // Priority (higher value = higher priority, default is 0)
    public override int Priority => 0;

    // Core loading method
    public override object HandleLoad(MemberInfo member, VaultLoadenAttribute attribute) {
        // Load and return your custom resource based on attribute.Path
        return LoadMyResource(attribute.Path);
    }

    // Cleanup logic on unload
    public override void HandleUnload(MemberInfo member, object currentValue) {
        // Clean up resources
    }
}

The system automatically scans and registers all classes that inherit from VaultLoadenHandle — no manual registration required.


Constructor Parameter Reference

VaultLoadenAttribute provides multiple constructor overloads. The complete parameter list is as follows:

Parameter Type Default Description
path string (required) Resource path, supports placeholders and cross-mod prefix
assetMode AssetMode None Resource type, None means auto-infer
effectPassname string "" Shader pass name, empty for auto-generated
startIndex int 0 Start index for collection resources
arrayCount int 0 Number of collection elements, 0 means infer from initialized collection
pathConcatenation bool false Class-level tag only, splits member name by underscore to extend path

Limitations

  • Only supports static fields or properties
  • Properties must have a setter (public or non-public), i.e., must be writable
  • When loading collections without specifying arrayCount, the collection must be pre-initialized to determine length
  • Non-resource types (e.g., string, int) are not supported unless a corresponding custom loader exists

Common Errors & Troubleshooting

Error Message Cause
Cannot determine asset mode for ... Resource type cannot be inferred. Specify AssetMode manually.
Property ... has no setter. Property lacks a setter and cannot be assigned.
Member ... couldn't find Mod "xxx" Specified mod name does not exist or is misspelled.
Attribute path on member ... is empty or invalid Path is empty or formatted incorrectly.
After the Effect is loaded, there is an error message saying "Pass or Filters.Scene" Incorrect EffectPassname or the Effect file does not contain that pass.

Full example

public class AssetClass1
{
    // Auto-inferred as Sound
    [VaultLoaden("Assets/Sounds/Click")]
    public static SoundStyle ClickSound;

    // Auto-inferred as Texture (field name used: ButtonBackground)
    [VaultLoaden("Assets/Textures/")]
    public static Asset<Texture2D> ButtonBackground;

    // Namespace replacement example
    [VaultLoaden("{@namespace}/Icons/Warning", AssetMode.Texture)]
    public static Asset<Texture2D> WarningIcon;

    // Load effect and specify pass name
    [VaultLoaden("Effects/Beam", AssetMode.Effects, "GlowPass")]
    public static Asset<Effect> BeamEffect;

    // Load ArmorShaderData
    [VaultLoaden("Effects/Armor/ColdShader", AssetMode.ArmorShader)]
    public static ArmorShaderData ColdArmorShader;

    // Load resource from another mod
    [VaultLoaden("@OtherMod/Textures/Cursor", AssetMode.Texture)]
    public static Asset<Texture2D> OtherCursor;

    // Texture array loading
    [VaultLoaden("Assets/Textures/Anim/Frame", 0, 5)]
    public static Asset<Texture2D>[] AnimFrames;
    // Loads: Frame_0, Frame_1, Frame_2, Frame_3, Frame_4
}

// InnoVault's own resource class is a good example of class-level tags
[VaultLoaden("Assets/")]
public class VaultAsset : IVaultLoader
{
    public static Asset<Texture2D> placeholder;       // Assets/placeholder
    public static Asset<Texture2D> placeholder2;      // Assets/placeholder2
    public static Asset<Texture2D> placeholder3;      // Assets/placeholder3
    public static Asset<Texture2D> Light;             // Assets/Light
    public static Asset<Texture2D> GearWheel;         // Assets/GearWheel
}

Navigation

Previous Home Next
Mod Prerequisite Reference Home Basic PRT System

Clone this wiki locally