Dynamic Leveled Lists Wiki
An SKSE plugin that merges leveled list records from all mods at runtime. It covers leveled items (LVLI), leveled NPCs (LVLN), and leveled spells (LVSP). When multiple mods edit the same leveled list, Skyrim's last-loaded-wins rule discards changes from all but the final override. Dynamic Leveled Lists merges the lost entries back in automatically, and respects intentional removals.
Quick Start: Install via your mod manager and launch the game. The plugin runs automatically on data load. Check Data/SKSE/Plugins/DynamicLeveledLists.log to see what was merged.
The Problem
Skyrim uses a "last writer wins" rule for records. If three mods edit the same leveled list (e.g. LItemWeaponGreatSword), only the last mod in your load order keeps its changes. Entries added by the other mods are silently lost. This affects loot tables, vendor inventories, NPC spawn lists, spell distribution, and anything else driven by leveled lists.
This is why compatibility patches exist for nearly every weapon/armor mod. Without them, half of the items you installed never actually drop.
The Solution
Dynamic Leveled Lists reads the original leveled list definition from every plugin that touches it, computes what each "loser" mod added or removed, and merges those deltas into the winning record at runtime. The result is the same as if you had built a manual patch, but fully automatic.
How It Works
- Fires on
kDataLoaded, runs once before the main menu - Scans every leveled list form (LVLI, LVLN, LVSP) for multi-source conflicts (3+ plugins touching the same record)
- Parses each plugin's leveled list subrecords directly from disk to reconstruct what each mod intended
- Computes per-mod deltas against the base record using multiplicity-based diffing
- Largest addition/removal wins across losers (no data lost from load order)
- Intentional removals override additions (a mod that deliberately removes an item wins)
- Applies merged deltas to the winning record in memory
Key Features
Overflow Sublists (255 Entry Limit)
Skyrim's engine stores the entry count for leveled lists as a single byte, limiting each list to 255 entries. When many mods add items to popular lists like LItemWeaponGreatSword, the merged result can easily exceed this limit.
Dynamic Leveled Lists solves this by creating overflow sublists at runtime. The engine natively supports nested leveled lists (a leveled list containing other leveled lists), so excess entries are distributed into sublists that the engine resolves recursively. No existing Skyrim mod does this.
UseAll Lists
When a list has the UseAll flag (every entry produces an item), direct entries are kept in the parent and overflow entries go into sublists with the same flag. Every item still appears.
Random Pick Lists
When a list picks one random entry, all entries are distributed evenly across sublists. The engine picks one sublist, then the sublist picks one item. Equal probability is preserved.
Circular Reference Breaking
Leveled lists can reference other leveled lists (nested lists). If the merge creates a circular reference where List A contains List B and List B contains List A, the engine follows the cycle infinitely when resolving loot, causing a crash. This is rare (two unrelated mods would have to independently create both halves of the cycle), but it's a real risk with automatic merging.
After all merges complete, Dynamic Leveled Lists builds a directed graph of every leveled list reference and runs cycle detection across the entire graph. When a circular reference is found, the plugin breaks the cycle at runtime by removing the back-edge entry from the parent list. This is an in-memory change only. Your plugin files on disk are never modified.
Each broken cycle is logged with the full path, the entry that was removed, and instructions for creating a permanent fix in xEdit:
Circular leveled list reference detected: 00035319 -> 000A1234 -> 00035319 Broke circular reference: removed SomeSublist [LVLI:000A1234] from MainList [LVLI:00035319] To permanently fix: open MyMod.esp in xEdit, find MainList [LVLI:00035319], and remove the entry pointing to SomeSublist [LVLI:000A1234]
Always logged: Cycle warnings are always written to the log with readable names regardless of the enablelogs setting, since they indicate crash risk.
Duplicate Weighting
Some mods use duplicate entries to weight drop probabilities. For example, an Iron Bow appearing 3 times in a list gives it 3x the drop chance. Dynamic Leveled Lists tracks multiplicity (how many times an identical entry appears) and preserves it correctly during merges. If Mod A adds 3 copies and Mod B adds 2 copies of the same item, the larger count (3) wins.
INI Settings
Configuration is at Data/SKSE/Plugins/DynamicLeveledLists.ini. If the file doesn't exist, it will be auto-generated with defaults on first launch.
[General] ;Enable detailed merge logging enablelogs = false ;Merge leveled item lists mergeleveledItems = true ;Merge leveled NPC lists mergeleveledNPCs = true ;Merge leveled spell lists mergeleveledSpells = true ;Respect intentional item removals during conflict resolution respectRemovalsItems = true ;Respect intentional NPC removals during conflict resolution respectRemovalsNPCs = true ;Respect intentional spell removals during conflict resolution respectRemovalsSpells = true ;Remove references to empty item sublists after conflict resolution removeEmptySublistsItems = true ;Remove references to empty NPC sublists after conflict resolution removeEmptySublistsNPCs = true ;Remove references to empty spell sublists after conflict resolution removeEmptySublistsSpells = true [Blacklist] ; Mods listed here are skipped during conflict resolution. ; Change OFF to ALL to skip a mod for all list types. ; Or use LVLI, LVLN, or LVSP to skip for a specific type only. ; Entries below were auto-detected from compatibility patches. ; Detected patch: ModA_ModB_Patch.esp ModA.esp = OFF ModB.esp = OFF
Settings Reference
enablelogs
Default: false
When enabled, logs every individual entry added, removed, or skipped per leveled list with form type tags, a final state snapshot, and an aggregate summary of most frequently added items. Useful for debugging but adds startup time due to EditorID lookup.
mergeleveledItems / NPCs / Spells
Default: true
Controls whether conflict resolution runs for each list type. Items are loot tables and vendor inventories. NPCs are spawn lists. Spells are spell distribution lists. Disable a type if you want to skip it entirely.
respectRemovalsItems / NPCs / Spells
Default: true
When a mod deliberately removes an entry from a leveled list, that removal normally cancels any additions of the same entry from other mods. Set to false for a "never lose items" mode where every addition is kept regardless of removals.
removeEmptySublistsItems / NPCs / Spells
Default: true
After conflict resolution, the plugin scans for leveled lists with zero entries and removes references to them from parent lists. If removing an empty sublist makes its parent empty, that parent gets cleaned too (cascading). This prevents the game from rolling on empty lists that produce no loot or spawns.
[Blacklist] Section
Add mod filenames to skip them during conflict resolution. Set the value to ALL to skip for all list types, or LVLI, LVLN, or LVSP to skip for one type only. Set to OFF to disable. The plugin auto-detects compatibility patches and pre-populates entries as OFF for you to review.
Mod Blacklist
The [Blacklist] section in the INI lets you skip specific mods during conflict resolution. This is useful when a compatibility patch already handles the merging for two mods and you want the plugin to leave those entries alone.
On first launch, the plugin scans your load order for files that look like compatibility patches (filename contains "patch" or "compat" and has 2+ non-vanilla masters). For each detected patch, it adds the patch's non-vanilla masters to the [Blacklist] section with value OFF. These entries have no effect until you change them. Review the entries and change OFF to ALL (or a specific type) for any mod you want to skip.
Safe by default: Auto-detected entries are always set to OFF. They do nothing until you enable them. The plugin never skips a mod unless you explicitly tell it to.
Reading the Log
The log at Data/SKSE/Plugins/DynamicLeveledLists.log always shows a summary:
=== DynamicLeveledLists: Merge complete ===
Total leveled lists: 4821
With overrides (base + winner only): 312
With conflicts (3+ sources): 87
Actually merged: 41
Total entries added: 156
Total entries removed: 12
Overflow sublists created: 3
Circular references broken: 1
---
Leveled Items (LVLI): 3200 total, 30 merged
Leveled NPCs (LVLN): 1100 total, 8 merged
Leveled Spells (LVSP): 521 total, 3 merged
---
Data quality warnings:
Null entries stripped: 2 (empty references in leveled lists, likely from broken mods)
Negative counts clamped to 1: 1 (invalid item counts in leveled lists, likely from broken mods)
The data quality section only appears when problems are found. If your mods are clean, you won't see it.
The cycle line always appears: "No circular references detected" when clean, or "Circular references broken: N" when cycles were found. Each cycle is logged individually with the full path, and the entry that was removed to break it:
Circular leveled list reference detected: 00035319 -> 000A1234 -> 00035319 Broke circular reference: removed SomeSublist [LVLI:000A1234] from MainList [LVLI:00035319] To permanently fix: open MyMod.esp in xEdit, find MainList [LVLI:00035319], and remove the entry pointing to SomeSublist [LVLI:000A1234]
With enablelogs=true, each merged list also gets detailed output:
LItemWeaponGreatSword [LVLI:00035319]
Sources: Skyrim.esm, ImmersiveWeapons.esp, HeavyArmory.esp
-- Changes --
+ [WEAP] GreatSwordOfMight x1 @lvl1 [0A012345] (1x, added by ImmersiveWeapons.esp)
+ [WEAP] SteelClaymore x1 @lvl6 [0B023456] (2x, added by ImmersiveWeapons.esp)
-- Carried forward --
. [WEAP] NordicGreatsword x1 @lvl12 [0B034567] (1x)
Result: +3 added, -0 removed
-- Final state --
* [WEAP] IronGreatsword x1 @lvl1 [00012EB7]
* [WEAP] GreatSwordOfMight x1 @lvl1 [0A012345]
* [WEAP] SteelClaymore x1 @lvl6 [0B023456]
* [WEAP] NordicGreatsword x1 @lvl12 [0B034567]
(4 entries total)
At the end of the merge, an aggregate summary shows the most frequently added items:
=== Most frequently added items (top 15) === [WEAP] SteelClaymore [0B023456] - added to 12 leveled lists (from ImmersiveWeapons.esp) [ARMO] NordicShield [0B034568] - added to 8 leveled lists (from HeavyArmory.esp)
Performance note: Detailed logging requires scanning every loaded mod's leveled list records from disk to build an EditorID cache. This adds noticeable startup time. Keep enablelogs=false for normal play.
xEdit Error Checker Script
DynamicLeveledLists includes a companion xEdit script (ST - Dynamic Leveled Lists.pas) for leveled list diagnostics and patching. On launch, choose between two modes: Info Mode (report-only, scans for problems) and Patch Mode (creates an ESP that merges missing entries from losing overrides back into the winning record).
Setup
Copy the .pas file to your xEdit Edit Scripts folder (usually next to SSEEdit.exe). Then in xEdit: select plugins, right-click, Apply Script, and choose ST - Dynamic Leveled Lists.
Info Mode (Report-Only)
Scans your load order for common leveled list problems without modifying anything:
- Broken references -- an entry points to a form that doesn't exist (deleted mod, bad merge)
- Null FormIDs -- an entry references FormID
00000000 - xEdit errors -- built-in xEdit validation catches additional structural problems
- Empty leveled lists -- a list with zero entries (nothing will ever drop)
- Duplicate entries -- same item appears multiple times at the same level (warning, sometimes intentional for weighting)
- Circular references -- a list that references itself (DLL catches these at runtime too, but xEdit lets you fix them permanently)
- EDID renames -- reports when an override changes a leveled list's Editor ID, showing which plugin renamed it
Patch Mode (Create Merged ESP)
Builds an ESP using the same delta-based merge logic as the SKSE plugin. For users who want a permanent xEdit patch instead of relying on DLL's runtime merge. Handles all three leveled list types (LVLI, LVLN, LVSP). When you select Patch Mode, a settings panel lets you configure the merge before building.
- Finds every LVLI with 2+ overrides (base + loser + winner = 3 sources minimum)
- Computes per-loser deltas against the base (master) record, not the winner
- Entry key = (FormID, Level, Count) with multiplicity tracking, same as the SKSE plugin
- Detects both additions (loser added entries) and removals (loser deleted entries)
- Removals cancel additions for the same key (intentional removal intent wins)
- Accounts for winner excess (if the winner already added entries independently, they are not duplicated)
- Copies the winning override to the patch, applies removals, then appends additions from loser source entries
- Merges list-level property changes (
LVLFflags,LVLDChance None) from losers if the winner kept the base value - Carries forward the latest EDID rename (e.g. a mod prefixing
MAG_) to the patch record
Review required: Open the generated ESP in xEdit afterward and verify the merged entries look correct.
Patch Mode Settings
The settings panel appears when you choose either Patch Mode option. All settings are per-type (items, NPCs, spells).
Respect intentional removals (default: ON)
When a mod deliberately removes an entry from a leveled list, that removal normally cancels any additions of the same entry from other mods. Turn this off for a "never lose items" mode where every addition is kept regardless of removals.
Remove empty sublists after merge (default: ON)
After the patch is built, the script scans for leveled lists with zero entries and removes references to them from parent lists. If removing an empty sublist makes its parent empty, that parent gets cleaned too (cascading). This prevents the game from rolling on empty lists that would produce no loot or spawns.
Mod blacklist
Create a file called DLL_Blacklist.txt in your xEdit Edit Scripts folder to skip specific mods during patch creation. Blacklisted mods are ignored completely: they are not selected as the winner and their changes are not merged. Format:
; Lines starting with ; are comments ; TYPE can be LVLI, LVLN, LVSP, or ALL ALL|SomeMod.esp LVLI|AnotherMod.esp LVLN|NPCOverhaul.esp
Filenames are case-insensitive. If the file does not exist, no mods are blacklisted.
Supported Record Types
Both Info Mode and Patch Mode handle all three leveled list types: LVLI (Leveled Items), LVLN (Leveled NPCs), and LVSP (Leveled Spells).
Tip: Run Info Mode before and after installing DynamicLeveledLists. Before, to find pre-existing problems in your load order. After, to verify the runtime merge didn't surface any hidden issues.
Compatibility
- Open World Loot / Morrowloot Ultimate: Fully supported. Their intentional removals are respected even if another mod adds the same item back
- Wrye Bash / Mator Smash: Works alongside them. They handle it at build time, this handles it at runtime for anything they miss. Keeping existing patches won't cause issues
- Dynamic Container Loot: Companion mod. DCL handles container records (CONT), this handles leveled list records (LVLI, LVLN, LVSP). They work on completely different record types and do not interfere
- Dynamic Non-Player Characters: Companion mod. DNPC handles individual NPC records (NPC_), things like a specific NPC's inventory, perks, and spells. This plugin handles leveled NPC lists (LVLN), which control which NPCs can spawn at a location. Different record types, no overlap
- SPID / KID / CLLF: Fully compatible. These distribute items through scripts, not leveled list record edits
- Any load order: Reads plugin data non-destructively. No conflicts with other SKSE plugins
Requirements
- Skyrim SE (1.5.97+), AE (1.6.x), or VR
- SKSE64 (matching your game version)
- Address Library for SKSE Plugins
Link to This Page
Copy a link to share this wiki from your Nexus description or documentation:
