Skip to main content
Plugin attributes are assembly-level attributes applied in AssemblyInfo.cs to define plugin metadata and register extensions.

Metadata Attributes

These attributes define basic plugin information displayed in the Frosty UI.

PluginDisplayNameAttribute

Sets the display name shown in the plugin manager. From ~/workspace/source/FrostyPlugin/Attributes/PluginDisplayNameAttribute.cs:9:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class PluginDisplayNameAttribute : Attribute
{
    public string DisplayName { get; private set; }
    
    public PluginDisplayNameAttribute(string displayName)
    {
        DisplayName = displayName;
    }
}
Usage:
[assembly: PluginDisplayName("Texture Editor")]

PluginAuthorAttribute

Specifies the plugin author. From ~/workspace/source/FrostyPlugin/Attributes/PluginAuthorAttribute.cs:9:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class PluginAuthorAttribute : Attribute
{
    public string Author { get; private set; }
    
    public PluginAuthorAttribute(string author)
    {
        Author = author;
    }
}
Usage:
[assembly: PluginAuthor("GalaxyMan2015")]

PluginVersionAttribute

Defines the plugin version. From ~/workspace/source/FrostyPlugin/Attributes/PluginVersionAttribute.cs:9:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class PluginVersionAttribute : Attribute
{
    public string Version { get; private set; }
    
    public PluginVersionAttribute(string version)
    {
        Version = version;
    }
}
Usage:
[assembly: PluginVersion("1.0.1.0")]

Profile Validation Attributes

Control which game profiles load the plugin.

PluginValidForProfileAttribute

Restricts the plugin to specific game profiles. Can be applied multiple times. From ~/workspace/source/FrostyPlugin/Attributes/PluginValidForProfileAttribute.cs:9:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class PluginValidForProfileAttribute : Attribute
{
    public int ProfileVersion { get; private set; }
    
    public PluginValidForProfileAttribute(int profileVersion)
    {
        ProfileVersion = profileVersion;
    }
}
Usage:
[assembly: PluginValidForProfile((int)ProfileVersion.StarWarsBattlefrontII)]
[assembly: PluginValidForProfile((int)ProfileVersion.Battlefield1)]

PluginNotValidForProfileAttribute

Excludes the plugin from specific game profiles. From ~/workspace/source/FrostyPlugin/Attributes/PluginNotValidForProfileAttribute.cs:9:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class PluginNotValidForProfileAttribute : Attribute
{
    public int ProfileVersion { get; private set; }
    
    public PluginNotValidForProfileAttribute(int profileVersion)
    {
        ProfileVersion = profileVersion;
    }
}
Usage:
[assembly: PluginNotValidForProfile((int)ProfileVersion.Anthem)]
Without profile attributes, plugins load for all game profiles by default.

Registration Attributes

These attributes register plugin extensions with the PluginManager.

RegisterAssetDefinitionAttribute

Registers an AssetDefinition for a specific asset type. From ~/workspace/source/FrostyPlugin/Attributes/RegisterAssetDefinitionAttribute.cs:9:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
public class RegisterAssetDefinitionAttribute : Attribute
{
    public string LookupType { get; set; }
    public Type AssetDefinitionType { get; set; }
    
    public RegisterAssetDefinitionAttribute(string lookupType, Type type)
    {
        LookupType = lookupType;
        AssetDefinitionType = type;
    }
}
lookupType
string
required
The asset type name from the game’s type library (e.g., "TextureAsset", "MeshAsset")
type
Type
required
The class type that inherits from AssetDefinition
Usage:
[assembly: RegisterAssetDefinition("TextureAsset", typeof(TextureAssetDefinition))]
[assembly: RegisterAssetDefinition("RigidMeshAsset", typeof(RigidMeshAssetDefinition))]
[assembly: RegisterAssetDefinition("SkinnedMeshAsset", typeof(SkinnedMeshAssetDefinition))]

RegisterMenuExtensionAttribute

Registers a custom menu item. From ~/workspace/source/FrostyPlugin/Attributes/RegisterMenuExtensionAttribute.cs:9:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
public class RegisterMenuExtensionAttribute : Attribute
{
    public Type MenuExtensionType { get; private set; }
    public PluginManagerType ManagerType { get; private set; }
    
    public RegisterMenuExtensionAttribute(Type type)
    {
        MenuExtensionType = type;
        ManagerType = PluginManagerType.Editor;
    }
    
    public RegisterMenuExtensionAttribute(Type type, PluginManagerType managerType)
    {
        MenuExtensionType = type;
        ManagerType = managerType;
    }
}
type
Type
required
Class that inherits from MenuExtension
managerType
PluginManagerType
default:"Editor"
Where to show the menu: Editor, ModManager, or Both
Usage:
// Editor only (default)
[assembly: RegisterMenuExtension(typeof(MyMenuExtension))]

// Both Editor and Mod Manager
[assembly: RegisterMenuExtension(typeof(MyMenuExtension), PluginManagerType.Both)]

RegisterDataExplorerContextMenuAttribute

Registers a context menu item for the Data Explorer. From ~/workspace/source/FrostyPlugin/Attributes/RegisterDataExplorerContextMenuAttribute.cs:11:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = true)]
public class RegisterDataExplorerContextMenuAttribute : Attribute
{
    public Type ContextMenuItemExtensionType { get; private set; }
    
    public RegisterDataExplorerContextMenuAttribute(Type type)
    {
        ContextMenuItemExtensionType = type;
    }
}
type
Type
required
Class that inherits from DataExplorerContextMenuExtension
Usage:
[assembly: RegisterDataExplorerContextMenu(typeof(DuplicateContextMenuItem))]

RegisterCustomHandlerAttribute

Registers a custom handler for specific asset or resource types. From ~/workspace/source/FrostyPlugin/Attributes/RegisterCustomHandlerAttribute.cs:12:
public enum CustomHandlerType
{
    Ebx,   // EBX asset handler
    Res    // Resource handler
}

[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class RegisterCustomHandlerAttribute : Attribute
{
    public CustomHandlerType HandlerType { get; set; }
    public Type HandlerClassType { get; set; }
    public string EbxType { get; set; }           // For Ebx handlers
    public ResourceType ResType { get; set; }     // For Res handlers
    
    public RegisterCustomHandlerAttribute(
        CustomHandlerType inType, 
        Type inClassType, 
        ResourceType resType = ResourceType.Invalid, 
        string ebxType = "")
    {
        HandlerType = inType;
        HandlerClassType = inClassType;
        ResType = resType;
        EbxType = ebxType;
    }
}
inType
CustomHandlerType
required
CustomHandlerType.Ebx or CustomHandlerType.Res
inClassType
Type
required
Handler class implementing ICustomActionHandler
resType
ResourceType
Resource type for Res handlers
ebxType
string
EBX asset type name for Ebx handlers
Usage:
// EBX handler
[assembly: RegisterCustomHandler(
    CustomHandlerType.Ebx,
    typeof(MyEbxHandler),
    ebxType: "MyAssetType")]

// Resource handler
[assembly: RegisterCustomHandler(
    CustomHandlerType.Res,
    typeof(ShaderBlockDepotCustomActionHandler),
    resType: ResourceType.ShaderBlockDepot)]

RegisterExecutionAction

Registers an action to run during mod execution (Mod Manager only). From ~/workspace/source/FrostyPlugin/Attributes/RegisterExecutionAction.cs:7:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class RegisterExecutionAction : Attribute
{
    public Type ExecutionActionType { get; private set; }
    
    public RegisterExecutionAction(Type type)
    {
        ExecutionActionType = type;
    }
}
type
Type
required
Class that inherits from ExecutionAction
Usage:
[assembly: RegisterExecutionAction(typeof(MyExecutionAction))]

RegisterTabExtensionAttribute

Registers a custom tab in the editor. From ~/workspace/source/FrostyPlugin/Attributes/RegisterTabExtensionAttribute.cs:10:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = true)]
public class RegisterTabExtensionAttribute : Attribute
{
    public Type TabExtensionType { get; private set; }
    
    public RegisterTabExtensionAttribute(Type type)
    {
        TabExtensionType = type;
    }
}
type
Type
required
Class that inherits from TabExtension
Usage:
[assembly: RegisterTabExtension(typeof(MyCustomTab))]

RegisterGlobalTypeEditorAttribute

Registers a custom editor for a specific type, used globally across all property grids.
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
public class RegisterGlobalTypeEditorAttribute : Attribute
{
    public string LookupName { get; set; }
    public Type EditorType { get; set; }
}
lookupName
string
required
The type name to match
editorType
Type
required
Custom editor control type
Usage:
[assembly: RegisterGlobalTypeEditor("Vec3", typeof(Vector3Editor))]

RegisterTypeOverrideAttribute

Overrides the default type handling with a custom class.
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class RegisterTypeOverrideAttribute : Attribute
{
    public string LookupName { get; set; }
    public Type EditorType { get; set; }
}
Usage:
[assembly: RegisterTypeOverride("UnlockDataCollection", typeof(CustomUnlockDataCollection))]

RegisterStartupActionAttribute

Registers an action that runs when Frosty starts, before profile loading. From ~/workspace/source/FrostyPlugin/Attributes/RegisterStartupActionAttribute.cs:6:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class RegisterStartupActionAttribute : Attribute
{
    public Type StartupActionType { get; private set; }
    
    public RegisterStartupActionAttribute(Type inActionType)
    {
        StartupActionType = inActionType;
    }
}
Usage:
[assembly: RegisterStartupAction(typeof(MyStartupAction))]

RegisterOptionsExtensionAttribute

Registers an options page in the settings dialog.
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class RegisterOptionsExtensionAttribute : Attribute
{
    public Type OptionsType { get; set; }
    public PluginManagerType ManagerType { get; set; }
}
Usage:
[assembly: RegisterOptionsExtension(typeof(MeshOptions))]

RegisterProfileAttribute

Registers a custom game profile.
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class RegisterProfileAttribute : Attribute
{
    public Type ProfileType { get; set; }
}
Usage:
[assembly: RegisterProfile(typeof(MyGameProfile))]

RegisterThirdPartyDllAttribute

Marks a DLL as a third-party dependency that shouldn’t be treated as a plugin.
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class RegisterThirdPartyDllAttribute : Attribute
{
    public string DllName { get; set; }
}
Usage:
[assembly: RegisterThirdPartyDll("Newtonsoft.Json.dll")]

RegisterLocalizedStringDatabaseAttribute

Registers a custom localized string database implementation. From ~/workspace/source/FrostyPlugin/Attributes/RegisterLocalizedStringDatabaseAttribute.cs:9:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class RegisterLocalizedStringDatabaseAttribute : Attribute
{
    public Type LocalizedStringDatabaseType { get; private set; }
    
    public RegisterLocalizedStringDatabaseAttribute(Type type)
    {
        LocalizedStringDatabaseType = type;
    }
}
type
Type
required
Class that implements ILocalizedStringDatabase interface
Usage:
[assembly: RegisterLocalizedStringDatabase(typeof(MyLocalizedStringDatabase))]

RegisterShaderAttribute

Registers a custom vertex, pixel, or compute shader for use in the editor viewport. From ~/workspace/source/FrostyPlugin/Attributes/RegisterShaderAttribute.cs:28:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class RegisterShaderAttribute : Attribute
{
    public ShaderType ShaderType { get; private set; }
    public string ResourceName { get; set; }
    public string KeyName { get; set; }
    
    public RegisterShaderAttribute(ShaderType type, string key, string name)
    {
        ShaderType = type;
        KeyName = key;
        ResourceName = name;
    }
}
type
ShaderType
required
Type of shader: VertexShader, PixelShader, or ComputeShader
key
string
required
Key name to retrieve the shader from FrostyShaderDb
name
string
required
Embedded resource name in Namespace.ResourceName format
Usage:
[assembly: RegisterShader(
    ShaderType.PixelShader,
    "CustomShader",
    "MyPlugin.Shaders.CustomShader.bin")]

RegisterUserShaderAttribute

Registers a user-editable shader with XML descriptor. From ~/workspace/source/FrostyPlugin/Attributes/RegisterUserShaderAttribute.cs:3:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class RegisterUserShaderAttribute : Attribute
{
    public string ShaderName { get; set; }
    public string XmlDescriptor { get; set; }
    
    public RegisterUserShaderAttribute(string shaderName, string xmlDescriptor)
    {
        ShaderName = shaderName;
        XmlDescriptor = xmlDescriptor;
    }
}
shaderName
string
required
Name of the shader
xmlDescriptor
string
required
Path to XML descriptor file
Usage:
[assembly: RegisterUserShader("MyShader", "Shaders/MyShader.xml")]

RegisterCustomAssetManagerAttribute

Registers a custom asset manager for handling specific asset types. From ~/workspace/source/FrostyPlugin/Attributes/RegisterCustomAssetManagerAttribute.cs:10:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class RegisterCustomAssetManagerAttribute : Attribute
{
    public Type CustomAssetManagerClassType { get; set; }
    public string CustomAssetManagerType { get; set; }
    
    public RegisterCustomAssetManagerAttribute(string type, Type classType)
    {
        CustomAssetManagerClassType = classType;
        CustomAssetManagerType = type;
    }
}
type
string
required
Asset manager type identifier
classType
Type
required
Class that implements ICustomAssetManager interface
Usage:
[assembly: RegisterCustomAssetManager("custom", typeof(MyCustomAssetManager))]

Complete Example

Here’s a complete AssemblyInfo.cs from the MeshSetPlugin:
using MeshSetPlugin;
using Frosty.Core.Attributes;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
using MeshSetPlugin.Handlers;
using FrostySdk.Managers;

[assembly: ComVisible(false)]
[assembly: Guid("4b612468-9b6a-4304-88a5-055c3575eb3d")]

[assembly: ThemeInfo(
    ResourceDictionaryLocation.None,
    ResourceDictionaryLocation.SourceAssembly
)]

// Plugin metadata
[assembly: PluginDisplayName("MeshSet Editor")]
[assembly: PluginAuthor("GalaxyMan2015")]
[assembly: PluginVersion("1.0.1.0")]

// Register options
[assembly: RegisterOptionsExtension(typeof(MeshOptions))]

// Register asset definitions
[assembly: RegisterAssetDefinition("RigidMeshAsset", typeof(RigidMeshAssetDefinition))]
[assembly: RegisterAssetDefinition("SkinnedMeshAsset", typeof(SkinnedMeshAssetDefinition))]
[assembly: RegisterAssetDefinition("CompositeMeshAsset", typeof(CompositeMeshAssetDefinition))]

// Register custom handler
[assembly: RegisterCustomHandler(
    CustomHandlerType.Res,
    typeof(ShaderBlockDepotCustomActionHandler),
    resType: ResourceType.ShaderBlockDepot)]

Attribute Load Phases

Startup Phase

Loaded before profile selection:
  • RegisterProfileAttribute
  • RegisterTypeOverrideAttribute
  • RegisterGlobalTypeEditorAttribute
  • RegisterStartupActionAttribute

Initialize Phase

Loaded after profile is selected:
  • RegisterAssetDefinitionAttribute
  • RegisterMenuExtensionAttribute
  • RegisterOptionsExtensionAttribute
  • RegisterThirdPartyDllAttribute
  • RegisterLocalizedStringDatabaseAttribute
  • RegisterShaderAttribute
  • RegisterTabExtensionAttribute
  • RegisterDataExplorerContextMenuAttribute
  • RegisterExecutionAction
  • RegisterCustomHandlerAttribute
See ~/workspace/source/FrostyPlugin/PluginManager.cs:419 for the implementation.

Best Practices

Always use AllowMultiple = true attributes (like RegisterAssetDefinition) multiple times rather than trying to register multiple items in one attribute.
[assembly: RegisterAssetDefinition("TypeA", typeof(DefinitionA))]
[assembly: RegisterAssetDefinition("TypeB", typeof(DefinitionB))]
[assembly: RegisterAssetDefinition("TypeC", typeof(DefinitionC))]
  • Use descriptive display names
  • Version using semantic versioning (major.minor.patch.build)
  • Match asset type names exactly as they appear in the game’s type library
Only use profile validation when necessary:
  • Game-specific features that won’t work in other games
  • Features that conflict with other games’ implementations
  • Otherwise, let plugins work universally

Build docs developers (and LLMs) love