Help us improve
Share bugs, ideas, or general feedback.
From unity-master
Guides Unity modding architectures: asset loading via Addressables/Bundles, Lua/MoonSharp scripting, Harmony patching, mod managers, Steam Workshop, extensible designs for community mods.
npx claudepluginhub josiahsiegel/claude-plugin-marketplace --plugin unity-masterHow this skill is triggered — by the user, by Claude, or both
Slash command
/unity-master:unity-moddingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Guide for designing Unity games that support community modding. Covers asset loading systems, scripted mod APIs, mod manager patterns, distribution platforms, and techniques for modding existing games.
Defines explicit grouping, loading, update, and fallback rules for Unity Addressables to replace ad hoc content loading. Useful when managing downloadable content, memory, and patching.
Unity 6 packages and services guide. Use when working with Package Manager, installing/updating packages, scoped registries, or Unity Gaming Services (Authentication, Cloud Save, Analytics, Leaderboards, Matchmaker). Covers essential packages list and version compatibility. Based on Unity 6.3 LTS documentation.
Builds high-performance Unity games with optimized C# scripts, modern rendering pipelines (URP/HDRP), and cross-platform deployment. Covers DOTS, Burst Compiler, profiling, and asset management.
Share bugs, ideas, or general feedback.
Guide for designing Unity games that support community modding. Covers asset loading systems, scripted mod APIs, mod manager patterns, distribution platforms, and techniques for modding existing games.
| Tier | What Modders Can Do | Complexity |
|---|---|---|
| Data Mods | Replace textures, sounds, configs (JSON/XML) | Low |
| Asset Mods | Add new models, maps, items via Asset Bundles | Medium |
| Script Mods | Custom game logic via Lua/scripting API | High |
| Code Mods | Patch game assemblies via Harmony/BepInEx | Expert |
Design your game to support at least Tier 1-2 from the start. Tiers 3-4 require deliberate API design.
Addressables provide a unified API for loading assets from local bundles, remote servers, or mod directories.
// Load a mod's asset catalog at runtime
public async Awaitable LoadModCatalog(string modPath)
{
string catalogPath = Path.Combine(modPath, "catalog.json");
var locator = await Addressables.LoadContentCatalogAsync(catalogPath);
Debug.Log($"Loaded mod catalog with {locator.Keys.Count()} assets");
}
// Load an asset by address (works for both base game and mods)
var prefab = await Addressables.LoadAssetAsync<GameObject>("enemies/goblin");
Instantiate(prefab);
Mod workflow:
public async Awaitable<AssetBundle> LoadModBundle(string path)
{
var request = AssetBundle.LoadFromFileAsync(path);
await request;
return request.assetBundle;
}
// Load specific asset from bundle
var bundle = await LoadModBundle("mods/weapons/swords.bundle");
var swordPrefab = bundle.LoadAsset<GameObject>("BroadSword");
Key rules:
bundle.Unload(true)AssetBundle.LoadFromFileAsync for local files (not LoadFromMemory)For simple data mods (JSON configs, CSV tables):
public T LoadModConfig<T>(string modPath, string fileName)
{
string filePath = Path.Combine(modPath, fileName);
if (!File.Exists(filePath)) return default;
string json = File.ReadAllText(filePath);
return JsonUtility.FromJson<T>(json);
}
Use FileSystemWatcher to detect changes and hot-reload during development.
MoonSharp is a Lua interpreter written in C# that runs on all Unity platforms.
Install via NuGet or download the DLL. Register safe API surfaces for modders:
public class ModScriptEngine
{
Script _lua;
public void Initialize()
{
_lua = new Script();
// Register safe game API
_lua.Globals["SpawnEntity"] = (Func<string, float, float, float, bool>)SpawnEntity;
_lua.Globals["GetPlayerHealth"] = (Func<float>)(() => player.Health);
_lua.Globals["ShowMessage"] = (Action<string>)ShowMessage;
_lua.Globals["RegisterEvent"] = (Action<string, DynValue>)RegisterEvent;
}
public void LoadMod(string luaFilePath)
{
string code = File.ReadAllText(luaFilePath);
_lua.DoString(code);
}
bool SpawnEntity(string id, float x, float y, float z)
{
// Validate and spawn - never trust mod input
if (!entityRegistry.Contains(id)) return false;
var pos = new Vector3(x, y, z);
if (!IsValidSpawnPosition(pos)) return false;
entityRegistry.Spawn(id, pos);
return true;
}
}
-- my_mod/init.lua
RegisterEvent("OnPlayerEnterZone", function(zoneName)
if zoneName == "boss_arena" then
SpawnEntity("dragon_boss", 0, 5, 0)
ShowMessage("A dragon appears!")
end
end)
| Risk | Mitigation |
|---|---|
| File system access | Do NOT expose System.IO to Lua |
| Infinite loops | Set instruction count limits: script.Options.InstructionLimit = 100000 |
| Memory abuse | Limit table sizes, monitor allocation |
| Network access | Never expose HTTP/socket APIs |
| Reflection abuse | MoonSharp sandboxes by default, but validate registered types |
Game
├── ModManager (singleton)
│ ├── DiscoverMods(modsFolder) // Scan for mod manifests
│ ├── ValidateMod(manifest) // Version compat, dependencies
│ ├── LoadMod(modId) // Load assets + scripts
│ ├── UnloadMod(modId) // Clean teardown
│ └── GetLoadOrder() // Dependency-sorted order
├── ModManifest (ScriptableObject / JSON)
│ ├── id, name, version, author
│ ├── dependencies[]
│ ├── gameVersionMin / gameVersionMax
│ └── entryPoint (script path)
└── ModSandbox
├── Lua scripting environment
└── Restricted API surface
{
"id": "com.author.mymod",
"name": "My Awesome Mod",
"version": "1.2.0",
"author": "ModAuthor",
"description": "Adds new enemies and weapons",
"gameVersionMin": "1.0.0",
"gameVersionMax": "2.0.0",
"dependencies": ["com.author.corelib@1.0.0"],
"entryPoint": "scripts/init.lua",
"assets": "bundles/"
}
Use Steamworks.NET or Facepunch.Steamworks for Steam Workshop integration:
SteamUGC.CreateItem + SteamUGC.SubmitItemUpdateSteamUGC.GetSubscribedItems() at startupSteamUGC.GetItemInstallInfo path into ModManagerHarmony is used by modders (via BepInEx/MelonLoader) to patch compiled game code at runtime.
[HarmonyPatch(typeof(PlayerHealth), "TakeDamage")]
class DamageModifier
{
// Prefix: runs before original method
static bool Prefix(ref float damage)
{
damage *= 0.5f; // Halve all damage
return true; // true = continue to original
}
// Postfix: runs after original method
static void Postfix(PlayerHealth __instance)
{
Debug.Log($"Health after damage: {__instance.CurrentHealth}");
}
}
If designing a game intended to be modded via Harmony, avoid aggressive code obfuscation and keep method signatures stable across updates.
references/mod-framework-detail.md -- Complete mod manager implementation, dependency resolution algorithm, mod load ordering, versioned API patterns, hot-reload systems, mod testing frameworks, BepInEx/MelonLoader setup guide