跳到主要内容
知仓学习社ZHICANG

writing-bgs-load-order

Use when reading, editing, or generating a Bethesda Game Studio load-order file (plugins.txt / loadorder.txt) for Fallout 4, Skyrim SE/AE/VR, Fallou…

不碰外部(只输出文字)无严重或高危命中hashgraph-online/awesome-codex-plugins

它会碰到什么

扫了多少1 个文本文件,19 KB
它会碰到什么不碰外部(只输出文字)
命中总数1 处
命中统计严重 0 · 高 0 · 中 0 · 低 0

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

Writing a BGS load order (plugins.txt)

> Harness status (2026-07-29): The local prototype harness was destroyed by an unattributed operation and will not be rebuilt. The historical .artifacts/mo2 example below is DEFUNCT. Testing now uses externally-configured Starfield or Fallout 4 MO2 instances; machine-specific details and the forensic record are private.

> Sources for every claim in this skill: Ortham/libloadorder (the library

> behind LOOT), ModOrganizer2/modorganizer/src/profile.cpp,

> ModOrganizer2/modorganizer-basic_games/.../game_plugins.py, and xEdit's

> official docs Section 2.8.1.

Two file formats — know which one applies

| Format | Games | File | Activation marker |

|---|---|---|---|

| Asterisk format (modern) | Fallout 4, Skyrim SE/AE/VR, Fallout 4 VR, Starfield | plugins.txt | leading * = active |

| Textfile-only (legacy) | Skyrim LE, Oblivion, Fallout 3, Fallout NV | plugins.txt (active only) + sibling loadorder.txt (full order) | presence in plugins.txt = active |

This skill covers the asterisk format in depth. If your target is Skyrim

LE / Oblivion / FO3 / FNV, the rules are different — see the "Legacy format"

section at the bottom.

File location

| Context | Path |

|---|---|

| Vanilla install (no MO2) | %LOCALAPPDATA%\<GameFolder>\plugins.txt (e.g. Fallout4, Skyrim Special Edition, Starfield) |

| MO2-managed | <MO2_Root>\profiles\<ProfileName>\plugins.txt |

| MO2-managed sibling | <MO2_Root>\profiles\<ProfileName>\loadorder.txt (full order including inactive; MO2 keeps both) |

| Agent-authored (experiments) | an agent-owned artifacts path — generate your own, pass to xedit_start({ pluginsFile }) |

Ownership in MO2 use: MO2 writes plugins.txt whenever the user toggles

plugin checkboxes in the GUI. LOOT can also write it. If you mutate it under

MO2, do it while MO2 is closed OR via mobase's IPluginList API — live edits

while MO2 is open get overwritten on its next save.

Asterisk format reference

# This file was automatically generated by Mod Organizer.
*Unofficial Fallout 4 Patch.esp        ← * = ACTIVE; loads first among non-vanilla
ArmorKeywords.esm                       ← no * = present-but-INACTIVE; position preserved
*HUDFramework.esm
SomeDisabledMod.esp
*MyMod.esp                              ← bottom = loads LAST = wins conflicts

Verbatim parser rules (from libloadorder/src/load_order/asterisk_based.rs):

  • Blank lines → ignored.
  • Lines starting with # (column 0) → comment, ignored.
  • Lines starting with * → plugin name follows; active.
  • Lines starting with any other character → plugin name; inactive but tracked.
  • No inline comments. # must be at column 0.
  • Encoding: Windows-1252. Plugin names with non-Win1252 characters cannot be

activated until renamed.

  • Line endings: LF and CRLF both accepted on read. Prefer LF on write

(libloadorder's default).

  • Order: first line = lowest load-order index = loaded first. Last line = wins

conflicts.

排序判断 / Ordering judgment

Ordering is not list housekeeping. It decides which plugin record or archive

payload the game actually sees when two mods touch the same thing: later wins.

For loose files, remember the separate asset layer: loose files can win over

BA2/BSA archive contents even when their plugin loads earlier. Use ordering to

choose whole-record / whole-archive winners; use a patch when you need one final

record stitched from multiple mods.

Iron law: **if the desired result cannot be expressed as "one later plugin wins

over one earlier plugin," stop sorting and audit/patch the conflict.**

The source-mined principle comes from BB84's Vortex-era sorting lesson and the

later xEdit "终极奥义": order is theoretically replaceable by a final

compatibility patch, but patching every conflicting FormID in a real pack is not

realistic. A sane order reduces the patch surface; it does not eliminate patching.

digraph sort_or_patch {
  rankdir=TB;
  start [label="Conflict or ordering question", shape=doublecircle];
  exists [label="Do the involved plugins actually load and have valid masters?", shape=diamond];
  fixfile [label="Fix plugins.txt/loadorder.txt validity first", shape=box];
  author [label="Does the mod author specify order or patch requirement?", shape=diamond];
  obey [label="Follow author instruction; verify with xEdit/readback", shape=box];
  winner [label="Can one plugin/archive win wholesale without losing needed data?", shape=diamond];
  sort [label="Solve by order: later winner goes after earlier loser; mirror loadorder.txt in MO2", shape=box];
  stitch [label="Need fields/data from multiple plugins in one final state?", shape=diamond];
  patch [label="Hand off to xedit-conflict-audit / xedit-automation and build or inspect a patch", shape=box];
  group [label="Is this about a per-game group template (lighting/weather/major compatibility-fix style)?", shape=diamond];
  kb [label="Query KB domain=load-order for the target game; if silent, mark [GAP]", shape=box];
  done [label="Verify winning override / loaded file chain", shape=doublecircle];

  start -> exists;
  exists -> fixfile [label="no"];
  exists -> author [label="yes"];
  fixfile -> done;
  author -> obey [label="yes"];
  author -> winner [label="no"];
  obey -> done;
  winner -> sort [label="yes"];
  winner -> stitch [label="no"];
  sort -> done;
  stitch -> patch [label="yes"];
  stitch -> group [label="not sure"];
  patch -> done;
  group -> kb [label="yes"];
  group -> patch [label="no"];
  kb -> done;
}

Judgment rules

  • Sort solves priority: which complete plugin record or BA2/BSA archive wins

after a later-wins cascade.

  • Patch solves composition: which fields from multiple plugins must be

preserved together in one final winning record.

  • Group ordering is a scale tool, not magic. Put mods into purpose-based groups

so order can be reasoned about in batches; same-group conflicts still need a

specific winner or a patch.

  • Masters and official early-loading plugins are not discretionary. Infer them

from the current runtime as described below; user-managed patches generally

live late because they intentionally carry final stitched decisions.

  • Prefer the later winner that expresses the pack's system rule over incidental

edits from a content mod. Example principle: if one mod imposes the pack-wide

equipment-slot rule and another content mod casually edits one vanilla slot,

the system-rule mod usually belongs later. Verify the actual records.

  • Do not inline per-game group templates here. For lighting, weather,

major compatibility-fix placement, major overhauls, or game-specific community group layouts,

query the KB first:

  bgs_kb_query({ query: "load order group template lighting weather patch", games: ["<Game>"], domains: ["load-order"] })

If the KB is silent, mark [GAP] instead of inventing a generic position.

LOOT / automatic sort vs manual sort

| Situation | Default |

|---|---|

| Beginner / small pack, no author instruction, no known conflict | Use LOOT or the manager's automatic sort as a baseline, then validate. |

| Author specifies order, dependency, or required compatibility patch | Follow the author first; verify with xEdit/readback. |

| xEdit shows the automatic result chose the wrong winner | Manually reorder if one winner is enough; patch if fields must be stitched. |

| Per-game group placement question | Query KB load-order records; do not hardcode a cross-game template in this skill. |

| Recurring conflict family across many mods | Create/adjust a group rule, then patch only the records the group rule cannot express. |

Red flags

| Thought | Reality |

|---|---|

| "排序无所谓,xEdit能补一切." | True only in principle; exhaustive FormID stitching is not realistic at pack scale. Sort first to reduce the patch surface. |

| "LOOT / auto-sort ran, so ordering judgment is done." | Auto-sort is a baseline. It cannot know every pack-specific winner or every author-required exception. |

| "Same group means no conflict." | Same group means conflicts should be rare. When two same-group mods touch the same record, decide winner or patch. |

| "Manager UI shows no conflict, so there is no conflict." | Record conflicts require xEdit readback. Asset/archive conflicts require asset-precedence inspection. |

| "Just put every patch last and forget the rest." | Patches late is correct, but a patch can only express decisions you actually audited. |

| "Lighting/weather/major compatibility-fix placement is universal." | Those are per-game template facts. Query KB and mark [GAP] if the pack has no record. |

Rationalizations

| Excuse | Reality |

|---|---|

| "I'll patch everything later." | That is the impossible endgame. A sane order is how you avoid patching irrelevant conflicts one by one. |

| "Manual sorting is just vibes." | Manual sorting is only legitimate when tied to a known winner, author instruction, group rule, or xEdit readback. |

| "The content mod should win because it adds new things." | Content mods often carry incidental edits. A systemic-rule mod may be the right later winner. |

| "If two mods are incompatible, sorting harder will fix it." | Some conflicts are ordering conflicts; some are real incompatibilities. Escalate to audit instead of looping order changes. |

| "Archive conflicts are invisible, so ignore them." | Invisibility is why BA2/BSA precedence must be inspected rather than guessed. |

If sorting does not produce the intended winning override, hand off to

xedit-conflict-audit: inspect the record, name the winning override, decide

whether the current winner is safe, and only then route to patch authoring.

Official / vanilla masters — infer them from the current game, do not hardcode

The engine loads each game's official plugins at fixed positions before reading

the user-managed plugins.txt. The exact set depends on the target game,

installed DLC, and any Creation Club / verified-content bundles.

Do not hardcode a per-game vanilla-master list in your workflow. Instead,

derive the official masters from the user's actual MO2-managed runtime:

  1. Read <MO2_Root>\ModOrganizer.ini to learn gameName and gamePath.
  2. Once xEdit is ready, call xedit_call({ command: "files.list", args: {} })

and look at the earliest, auto-loaded official plugins. Treat those as the

immutable official master set.

  1. If xEdit is not ready yet, inspect the MO2-managed game root (<gamePath>\Data)

and known official DLC/content files there. Do not add, remove, or reorder

them in your generated plugins.txt.

libloadorder's writer skips these early-loading official plugins on save; MO2

re-injects them as active at read time. So whether they appear in the file or

not, they load first.

Practical rule for agent-authored plugins.txt: omit the official masters

you inferred from the actual target runtime. Start your file with user-managed

plugins instead.

Six operations the agent does most often

1. Enable a currently-disabled plugin

Prefix the line with *. Position unchanged.

Before:

ArmorKeywords.esm

After:

*ArmorKeywords.esm

2. Disable without removing

Strip the leading *. Position preserved (the plugin stays in the file).

Before:

*HUDFramework.esm

After:

HUDFramework.esm

3. Remove a plugin entirely

Delete the whole line. Position is dropped. (MO2 will re-append it as inactive

at the end of loadorder.txt on next read — plugins.txt itself stays clean.)

4. Reorder (move X to load AFTER Y)

Cut the line, paste it after Y. **Mirror the change in loadorder.txt if it

exists** (MO2 maintains both files; out-of-sync state confuses MO2).

5. Add a brand-new plugin

Append at the bottom with * if you want it active.

*MyExistingMod.esp
*JustInstalledMod.esp          ← new line at the end

The bottom = loads last = wins conflicts with everything above. If you don't

want it to win conflicts, move it higher.

6. ESL conversion (ESP → light ESP)

Do NOT do this by editing plugins.txt. The light-plugin flag lives in

the plugin's file header, not in the load-order file. Route through the xEdit

daemon:

  1. xedit_call({ command: "plugin.esl.analyze", args: { file: "MyMod.esp" } }) — checks whether the plugin's FormIDs fit in the ESL FE-slot range.
  2. If verdict says yes: xedit_call({ command: "plugin.esl.apply", args: { file: "MyMod.esp" } }) — sets the light-plugin flag in the file header.

After flagging, the file extension stays .esp. The engine reads the new

flag at load time and remaps the plugin into the shared FE slot.

plugins.txt does NOT change as part of ESL conversion.

Routing matrix: plugins.txt edit vs xEdit daemon command

| Operation | Right path | Why |

|---|---|---|

| Activate / deactivate a plugin | Edit plugins.txt (toggle ) | No daemon verb exists for activation; the daemon manipulates plugin contents*, not the activation file. |

| Reorder plugins | Edit plugins.txt + mirror in loadorder.txt | xEdit docs 2.3 (verbatim): "Load order cannot be changed with xEdit." |

| Remove a plugin entry | Edit plugins.txt | Same reason. |

| Add new plugin to load order | Edit plugins.txt (append) | Daemon doesn't write the activation file. MO2 will project the mod's .esp via VFS once the file references it. |

| Check a plugin's masters | xedit_call({command:"files.get_masters", args:{file:"..."}}) | Reads the plugin header. |

| Add a missing master to a plugin | xedit_call({command:"files.add_required_masters", args:{...}}) | Mutates the file header. |

| Convert ESP → ESL | plugin.esl.analyzeplugin.esl.apply | Sets header flag; load-order file unchanged. |

| Clean ITM / UDR | xEdit launcher with -quickAutoClean OR daemon files.clean_masters | Both work; CLI faster for batch. |

| Sort the load order | External LOOT | Neither xEdit nor MO2 sorts; LOOT does, then writes plugins.txt. |

| Verify a load order is valid | Combine: read plugins.txt, then daemon files.list to confirm each *-prefixed file exists with required masters present. | Two-sided: file presence (libloadorder) + header consistency (xEdit). |

The rule of thumb: **plugins.txt is an activation surface owned by MO2 (or

LOOT, or the agent). The xEdit daemon never touches it.** The daemon's domain

ends at the file header of individual plugins.

Generating a custom plugins.txt for xEdit experiments

When you want xEdit to load only a subset of mods (e.g., to isolate a

conflict between two specific plugins), generate a custom plugins.txt under

an agent-owned artifacts path and pass it to xedit_start:

// 1. Write the file
const customPlugins = `# Agent-generated for conflict isolation between PluginA + PluginB
*<PrimaryGameMaster>.esm
*<OptionalCommunityFix>.esp
*PluginA.esp
*PluginB.esp
`;
await writeFile("<agent-owned-artifacts-path>/foo-vs-bar/plugins.txt", customPlugins);

// 2. Start xEdit pointing at the custom file + the right Data dir
await xedit_start({
  pluginsFile: "<agent-owned-artifacts-path>/foo-vs-bar/plugins.txt",
  dataPath: "<MO2_Root>/<managed game root>/Data",
  gameMode: "<GameMode>",
});

Notes for the experimental file:

  • You MAY include the target game's primary / official masters here if you want

to make the experiment self-describing, but you do not need to. xEdit auto-

loads the official masters from the Data dir regardless.

  • Order matters even for a 3-plugin file. Top = loads first.
  • The file must be Windows-1252 encodable (UTF-8 works as long as you stay

in ASCII).

plugins.txt vs modlist.txt — common confusion

| File | What it lists | Prefix convention | Where |

|---|---|---|---|

| plugins.txt | .esp/.esm/.esl plugin filenames | * = active, no prefix = inactive | <profile>/plugins.txt |

| modlist.txt | MO2 mod folder names (under mods/) | + = enabled, - = disabled, * = foreign | <profile>/modlist.txt |

**The * in modlist.txt means "foreign mod" (MO2-managed but externally

owned), NOT "active."** Mixing the two formats is the #1 way to corrupt a

profile. Never copy/paste between them.

MO2 path inspection (so you know which Data dir xEdit should target)

Before launching xEdit via the agent, read MO2's config to learn the

managed game path:

# <MO2_Root>\ModOrganizer.ini contains lines like:
gameName=Fallout 4
gamePath=@ByteArray(D:\\awesome-bgs-mod-master\\.artifacts\\mo2\\Stock Game\\Fallout 4)

The gamePath value (strip the @ByteArray(...) wrapper) is where the

agent's xedit_start({ dataPath: ... }) should point. Specifically, the Data

directory is <gamePath>\Data. Without an explicit dataPath, xEdit falls

back to the Windows registry — which points at the platform install path,

not necessarily the MO2-managed game root. That's the source of "wrong Data"

bugs.

Validation

Three options for catching a malformed plugins.txt before launching xEdit

into a broken state:

  1. xEdit one-shot smoke: launch xEdit with -quickAutoClean against the

file. Non-zero exit = a master is missing or a *-prefixed plugin doesn't

resolve. Cheap and authoritative.

   xEdit.exe -fo4 -D:"...\Data\" -P:"...\plugins.txt" -veryquickshowconflicts
  1. LOOT CLI: uses libloadorder under the hood and surfaces validation

errors in its GUI / log.

  1. Manual checks: each *-prefixed plugin must exist as a file in the

Data dir; no duplicate lines; under 255 active full plugins + under 4096

active light plugins (.esl + flagged-ESP).

What makes a file invalid:

  • More than 255 active full plugins (light plugins counted separately, see

next bullet).

  • More than 4096 active light plugins.
  • Duplicate plugin lines.
  • A *-prefixed line whose file does not exist in the Data dir.
  • A line with a Windows-1252-unencodable filename.

Legacy format (Skyrim LE / Oblivion / FO3 / FNV)

The OLD format used by pre-asterisk games:

  • **No prefix.* Presence of a plugin line in plugins.txt means it's

active. Absence means it's not loaded.

  • loadorder.txt is the canonical full-order file (active + inactive).

plugins.txt contains only active plugins.

  • plugins.txt uses Windows-1252 encoding; loadorder.txt uses **UTF-8

without BOM**.

  • Max 255 active plugins (no ESL concept in these engines).
  • CRLF line endings standard.

This format does NOT apply to FO4 / SSE / Starfield. If you're targeting one

of these older games, use this section's rules; for everything else, use the

asterisk format above.

See also

  • xedit-automation — hub skill for all xEdit work; routing doctrine,

anti-patterns, sub-agent recipes.

  • BGS KB records under knowledge/bgs-kb/packs/core/records/ — daemon command,

error-code, save-semantics, and glossary facts formerly kept in the retired

xedit-automation/xedit-knowledgebase.md redirect.

  • setting-up-bgs-modding-environment — explains how to inspect MO2's

ModOrganizer.ini for gamePath before launching xEdit.

  • xEdit official docs Section 2.8.1 — launcher flag reference for -P:,

-D:, and friends.

  • Ortham/libloadorder documentation — the authoritative source for the

asterisk format semantics.

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。

它属于哪个仓库

星标★ 1,027
本站分层T1
该仓技能数1910
原文件路径plugins/BB-84C/bgs-modding-superpowers/skills/writing-bgs-load-order/SKILL.md

同一个仓库里的其他技能

看这个仓库的全部 1910 个技能