modwright 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (455) hide show
  1. package/LICENSE +35 -0
  2. package/README.md +212 -0
  3. package/assets/claude/agents/mw-explore.md +46 -0
  4. package/assets/claude/agents/mw-fixture.md +33 -0
  5. package/assets/claude/agents/mw-rule-author.md +51 -0
  6. package/assets/claude/agents/mw-scaffold-author.md +48 -0
  7. package/assets/claude/skills/mw-author.md +59 -0
  8. package/assets/claude/skills/mw-new-item.md +51 -0
  9. package/assets/claude/skills/mw-new-spell.md +50 -0
  10. package/assets/claude/skills/mw-scaffold.md +59 -0
  11. package/assets/claude/skills/mw-ship.md +57 -0
  12. package/assets/claude/skills/mw-validate.md +51 -0
  13. package/assets/claude/skills/mw-verify.md +59 -0
  14. package/assets/nivalisnights/extract_resources.py +177 -0
  15. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Config.json +5 -0
  16. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/BootstrapClient.lua +55 -0
  17. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/BootstrapServer.lua +81 -0
  18. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Log.lua +96 -0
  19. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Probes.lua +1038 -0
  20. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/ProbesClient.lua +74 -0
  21. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Protocol.lua +985 -0
  22. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Watch.lua +175 -0
  23. package/bridges/bg3-se/Mods/ModWrightBridge/meta.lsx +45 -0
  24. package/bridges/bg3-se/README.md +99 -0
  25. package/bridges/bg3-se/bridge.json +68 -0
  26. package/bridges/cp2077-cet/ModWrightBridge/init.lua +375 -0
  27. package/bridges/cp2077-cet/ModWrightBridge/probes.lua +1104 -0
  28. package/bridges/cp2077-cet/ModWrightBridge/protocol.lua +1306 -0
  29. package/bridges/cp2077-cet/README.md +165 -0
  30. package/bridges/cp2077-cet/bridge.json +53 -0
  31. package/dist/core/bridge/arm.js +175 -0
  32. package/dist/core/bridge/cet-console.js +26 -0
  33. package/dist/core/bridge/cet-log.js +362 -0
  34. package/dist/core/bridge/index.js +11 -0
  35. package/dist/core/bridge/locate.js +35 -0
  36. package/dist/core/bridge/paths.js +34 -0
  37. package/dist/core/bridge/pending.js +89 -0
  38. package/dist/core/bridge/poll.js +155 -0
  39. package/dist/core/bridge/stage.js +100 -0
  40. package/dist/core/bridge/status.js +97 -0
  41. package/dist/core/bridge/types.js +145 -0
  42. package/dist/core/bridge/validate.js +107 -0
  43. package/dist/core/build/index.js +6 -0
  44. package/dist/core/build/manifest.js +47 -0
  45. package/dist/core/build/paths.js +32 -0
  46. package/dist/core/build/run.js +342 -0
  47. package/dist/core/build/stage.js +265 -0
  48. package/dist/core/build/steps/bg3.js +129 -0
  49. package/dist/core/build/steps/core.js +195 -0
  50. package/dist/core/build/steps/cyberpunk.js +95 -0
  51. package/dist/core/build/steps/listing.js +35 -0
  52. package/dist/core/build/types.js +13 -0
  53. package/dist/core/build/zip.js +148 -0
  54. package/dist/core/compat/check.js +113 -0
  55. package/dist/core/compat/pe.js +220 -0
  56. package/dist/core/compat/types.js +1 -0
  57. package/dist/core/compat/version.js +70 -0
  58. package/dist/core/deploy/guards.js +292 -0
  59. package/dist/core/deploy/index.js +5 -0
  60. package/dist/core/deploy/plan.js +696 -0
  61. package/dist/core/deploy/reload-apply.js +361 -0
  62. package/dist/core/deploy/reload.js +358 -0
  63. package/dist/core/deploy/sources.js +169 -0
  64. package/dist/core/deploy/types.js +1 -0
  65. package/dist/core/epic.js +54 -0
  66. package/dist/core/fsutil.js +191 -0
  67. package/dist/core/home.js +70 -0
  68. package/dist/core/knowledge/facts.js +229 -0
  69. package/dist/core/knowledge/index.js +4 -0
  70. package/dist/core/knowledge/search.js +112 -0
  71. package/dist/core/knowledge/store.js +123 -0
  72. package/dist/core/knowledge/types.js +1 -0
  73. package/dist/core/ledger/check.js +42 -0
  74. package/dist/core/ledger/hooks.js +80 -0
  75. package/dist/core/ledger/index.js +7 -0
  76. package/dist/core/ledger/query.js +17 -0
  77. package/dist/core/ledger/record.js +84 -0
  78. package/dist/core/ledger/status.js +53 -0
  79. package/dist/core/ledger/store.js +98 -0
  80. package/dist/core/ledger/types.js +108 -0
  81. package/dist/core/logs/index.js +4 -0
  82. package/dist/core/logs/registry.js +50 -0
  83. package/dist/core/logs/scan.js +195 -0
  84. package/dist/core/logs/triage.js +160 -0
  85. package/dist/core/logs/types.js +1 -0
  86. package/dist/core/lsx.js +10 -0
  87. package/dist/core/lz4.js +66 -0
  88. package/dist/core/mods.js +229 -0
  89. package/dist/core/process.js +49 -0
  90. package/dist/core/project/build-steps.js +83 -0
  91. package/dist/core/project/describe.js +74 -0
  92. package/dist/core/project/index.js +5 -0
  93. package/dist/core/project/load.js +146 -0
  94. package/dist/core/project/schema.js +264 -0
  95. package/dist/core/project/types.js +3 -0
  96. package/dist/core/prompts.js +72 -0
  97. package/dist/core/registry.js +35 -0
  98. package/dist/core/safety/backup.js +206 -0
  99. package/dist/core/safety/execute.js +188 -0
  100. package/dist/core/safety/index.js +5 -0
  101. package/dist/core/safety/plan.js +122 -0
  102. package/dist/core/safety/restore.js +172 -0
  103. package/dist/core/safety/types.js +1 -0
  104. package/dist/core/scaffold/bootstrap.js +7 -0
  105. package/dist/core/scaffold/catalog.js +28 -0
  106. package/dist/core/scaffold/claude-assets.js +271 -0
  107. package/dist/core/scaffold/collisions.js +64 -0
  108. package/dist/core/scaffold/emit.js +356 -0
  109. package/dist/core/scaffold/engine.js +680 -0
  110. package/dist/core/scaffold/ids.js +78 -0
  111. package/dist/core/scaffold/index.js +10 -0
  112. package/dist/core/scaffold/jsonpath.js +121 -0
  113. package/dist/core/scaffold/load.js +81 -0
  114. package/dist/core/scaffold/render.js +85 -0
  115. package/dist/core/scaffold/sequence.js +396 -0
  116. package/dist/core/scaffold/types.js +309 -0
  117. package/dist/core/steam.js +63 -0
  118. package/dist/core/surfaceutil.js +36 -0
  119. package/dist/core/testplan/check.js +67 -0
  120. package/dist/core/testplan/index.js +5 -0
  121. package/dist/core/testplan/load.js +100 -0
  122. package/dist/core/testplan/registry.js +317 -0
  123. package/dist/core/testplan/run.js +389 -0
  124. package/dist/core/testplan/types.js +82 -0
  125. package/dist/core/text/converters/bg3.js +50 -0
  126. package/dist/core/text/converters/cyberpunk.js +36 -0
  127. package/dist/core/text/converters/index.js +261 -0
  128. package/dist/core/text/diff/cr2w.js +180 -0
  129. package/dist/core/text/diff/index.js +16 -0
  130. package/dist/core/text/diff/loca.js +43 -0
  131. package/dist/core/text/diff/lsx.js +126 -0
  132. package/dist/core/text/handles.js +86 -0
  133. package/dist/core/text/index.js +6 -0
  134. package/dist/core/text/json.js +46 -0
  135. package/dist/core/text/templates/cache.js +71 -0
  136. package/dist/core/text/templates/index.js +3 -0
  137. package/dist/core/text/templates/library.js +245 -0
  138. package/dist/core/text/templates/types.js +51 -0
  139. package/dist/core/text/toolchain.js +16 -0
  140. package/dist/core/text/types.js +1 -0
  141. package/dist/core/text/validate.js +149 -0
  142. package/dist/core/text/xml.js +58 -0
  143. package/dist/core/toolchain/datafetch.js +151 -0
  144. package/dist/core/toolchain/env.js +63 -0
  145. package/dist/core/toolchain/features.js +170 -0
  146. package/dist/core/toolchain/index.js +8 -0
  147. package/dist/core/toolchain/install.js +191 -0
  148. package/dist/core/toolchain/locate.js +275 -0
  149. package/dist/core/toolchain/remember.js +84 -0
  150. package/dist/core/toolchain/run.js +318 -0
  151. package/dist/core/toolchain/specs.js +351 -0
  152. package/dist/core/toolchain/types.js +1 -0
  153. package/dist/core/types.js +1 -0
  154. package/dist/core/userconfig.js +66 -0
  155. package/dist/core/validate/context.js +139 -0
  156. package/dist/core/validate/index.js +5 -0
  157. package/dist/core/validate/registry.js +58 -0
  158. package/dist/core/validate/run.js +131 -0
  159. package/dist/core/validate/suppressions.js +91 -0
  160. package/dist/core/validate/types.js +2 -0
  161. package/dist/core/yamledit.js +51 -0
  162. package/dist/index.js +389 -0
  163. package/dist/server.js +1914 -0
  164. package/dist/surfaces/baldursgate3/compat.js +164 -0
  165. package/dist/surfaces/baldursgate3/identity.js +110 -0
  166. package/dist/surfaces/baldursgate3/index/build.js +331 -0
  167. package/dist/surfaces/baldursgate3/index/index.js +17 -0
  168. package/dist/surfaces/baldursgate3/index/info.js +40 -0
  169. package/dist/surfaces/baldursgate3/index/parsers/loca.js +41 -0
  170. package/dist/surfaces/baldursgate3/index/parsers/lsx.js +137 -0
  171. package/dist/surfaces/baldursgate3/index/parsers/stats.js +45 -0
  172. package/dist/surfaces/baldursgate3/index/parsers/treasuretable.js +57 -0
  173. package/dist/surfaces/baldursgate3/index/parsers/xmlutil.js +142 -0
  174. package/dist/surfaces/baldursgate3/index/queries.js +327 -0
  175. package/dist/surfaces/baldursgate3/index/schema.js +62 -0
  176. package/dist/surfaces/baldursgate3/index.js +3 -0
  177. package/dist/surfaces/baldursgate3/logs.js +278 -0
  178. package/dist/surfaces/baldursgate3/modsettings.js +115 -0
  179. package/dist/surfaces/baldursgate3/pak.js +153 -0
  180. package/dist/surfaces/baldursgate3/settings.js +49 -0
  181. package/dist/surfaces/baldursgate3/surface.js +232 -0
  182. package/dist/surfaces/baldursgate3/validators/bridge.js +7 -0
  183. package/dist/surfaces/baldursgate3/validators/files.js +476 -0
  184. package/dist/surfaces/baldursgate3/validators/items.js +1001 -0
  185. package/dist/surfaces/baldursgate3/validators/progression.js +734 -0
  186. package/dist/surfaces/baldursgate3/validators/stats.js +1076 -0
  187. package/dist/surfaces/baldursgate3/validators/story.js +790 -0
  188. package/dist/surfaces/baldursgate3/validators/templates.js +7 -0
  189. package/dist/surfaces/cyberpunk2077/compat.js +223 -0
  190. package/dist/surfaces/cyberpunk2077/index/build.js +231 -0
  191. package/dist/surfaces/cyberpunk2077/index/index.js +17 -0
  192. package/dist/surfaces/cyberpunk2077/index/info.js +51 -0
  193. package/dist/surfaces/cyberpunk2077/index/model.js +52 -0
  194. package/dist/surfaces/cyberpunk2077/index/parsers/tweak.js +483 -0
  195. package/dist/surfaces/cyberpunk2077/index/parsers/tweakxl-yaml.js +183 -0
  196. package/dist/surfaces/cyberpunk2077/index/queries.js +504 -0
  197. package/dist/surfaces/cyberpunk2077/index/resource.js +135 -0
  198. package/dist/surfaces/cyberpunk2077/index/schema.js +90 -0
  199. package/dist/surfaces/cyberpunk2077/index.js +3 -0
  200. package/dist/surfaces/cyberpunk2077/logs.js +742 -0
  201. package/dist/surfaces/cyberpunk2077/paths.js +12 -0
  202. package/dist/surfaces/cyberpunk2077/surface.js +218 -0
  203. package/dist/surfaces/cyberpunk2077/validators/bridge.js +7 -0
  204. package/dist/surfaces/cyberpunk2077/validators/cr2w.js +349 -0
  205. package/dist/surfaces/cyberpunk2077/validators/garments.js +1181 -0
  206. package/dist/surfaces/cyberpunk2077/validators/mesh.js +338 -0
  207. package/dist/surfaces/cyberpunk2077/validators/modsettings.js +120 -0
  208. package/dist/surfaces/cyberpunk2077/validators/packaging.js +463 -0
  209. package/dist/surfaces/cyberpunk2077/validators/red4ext.js +318 -0
  210. package/dist/surfaces/cyberpunk2077/validators/redscript.js +193 -0
  211. package/dist/surfaces/cyberpunk2077/validators/templates.js +7 -0
  212. package/dist/surfaces/cyberpunk2077/validators/tweaks.js +768 -0
  213. package/dist/surfaces/cyberpunk2077/validators/vehicles.js +531 -0
  214. package/dist/surfaces/cyberpunk2077/validators/xl.js +308 -0
  215. package/dist/surfaces/eldenring/binders.js +111 -0
  216. package/dist/surfaces/eldenring/compat.js +166 -0
  217. package/dist/surfaces/eldenring/dcx.js +49 -0
  218. package/dist/surfaces/eldenring/index.js +13 -0
  219. package/dist/surfaces/eldenring/loaders.js +132 -0
  220. package/dist/surfaces/eldenring/logs.js +67 -0
  221. package/dist/surfaces/eldenring/paramdef.js +256 -0
  222. package/dist/surfaces/eldenring/params.js +129 -0
  223. package/dist/surfaces/eldenring/surface.js +121 -0
  224. package/dist/surfaces/eldenring/tools.js +52 -0
  225. package/dist/surfaces/eldenring/validators/binders.js +193 -0
  226. package/dist/surfaces/eldenring/validators/packages.js +159 -0
  227. package/dist/surfaces/eldenring/validators/params.js +334 -0
  228. package/dist/surfaces/eldenring/validators/profiles.js +287 -0
  229. package/dist/surfaces/index.js +34 -0
  230. package/dist/surfaces/nivalisnights/compat.js +229 -0
  231. package/dist/surfaces/nivalisnights/index/build.js +310 -0
  232. package/dist/surfaces/nivalisnights/index/index.js +5 -0
  233. package/dist/surfaces/nivalisnights/index/queries.js +231 -0
  234. package/dist/surfaces/nivalisnights/index.js +4 -0
  235. package/dist/surfaces/nivalisnights/logs.js +473 -0
  236. package/dist/surfaces/nivalisnights/surface.js +195 -0
  237. package/dist/surfaces/skyrimse/archives.js +229 -0
  238. package/dist/surfaces/skyrimse/compat.js +163 -0
  239. package/dist/surfaces/skyrimse/index.js +12 -0
  240. package/dist/surfaces/skyrimse/loadorder.js +174 -0
  241. package/dist/surfaces/skyrimse/logs.js +241 -0
  242. package/dist/surfaces/skyrimse/plugins.js +149 -0
  243. package/dist/surfaces/skyrimse/records.js +94 -0
  244. package/dist/surfaces/skyrimse/surface.js +240 -0
  245. package/dist/surfaces/skyrimse/validators/archive-records.js +165 -0
  246. package/dist/surfaces/skyrimse/validators/archives.js +110 -0
  247. package/dist/surfaces/skyrimse/validators/plugins.js +374 -0
  248. package/dist/surfaces/skyrimse/validators/records.js +117 -0
  249. package/dist/surfaces/stardewvalley/compat.js +190 -0
  250. package/dist/surfaces/stardewvalley/config.js +42 -0
  251. package/dist/surfaces/stardewvalley/contentpatcher.js +203 -0
  252. package/dist/surfaces/stardewvalley/index/index.js +229 -0
  253. package/dist/surfaces/stardewvalley/index/wiki.js +190 -0
  254. package/dist/surfaces/stardewvalley/index.js +12 -0
  255. package/dist/surfaces/stardewvalley/logs.js +307 -0
  256. package/dist/surfaces/stardewvalley/mods.js +182 -0
  257. package/dist/surfaces/stardewvalley/surface.js +244 -0
  258. package/dist/surfaces/stardewvalley/validators/content.js +321 -0
  259. package/dist/surfaces/stardewvalley/validators/fields.js +147 -0
  260. package/dist/surfaces/stardewvalley/validators/loadorder.js +69 -0
  261. package/dist/surfaces/stardewvalley/validators/manifest.js +221 -0
  262. package/dist/surfaces/subnautica2/compat.js +138 -0
  263. package/dist/surfaces/subnautica2/index.js +5 -0
  264. package/dist/surfaces/subnautica2/logs.js +129 -0
  265. package/dist/surfaces/subnautica2/paks.js +173 -0
  266. package/dist/surfaces/subnautica2/surface.js +151 -0
  267. package/dist/surfaces/subnautica2/validators/packaging.js +298 -0
  268. package/dist/surfaces/valheim/compat.js +171 -0
  269. package/dist/surfaces/valheim/index/index.js +301 -0
  270. package/dist/surfaces/valheim/index/tables.js +103 -0
  271. package/dist/surfaces/valheim/index.js +11 -0
  272. package/dist/surfaces/valheim/logs.js +197 -0
  273. package/dist/surfaces/valheim/packaging.js +131 -0
  274. package/dist/surfaces/valheim/plugins.js +270 -0
  275. package/dist/surfaces/valheim/references.js +121 -0
  276. package/dist/surfaces/valheim/surface.js +223 -0
  277. package/dist/surfaces/valheim/validators/packaging.js +218 -0
  278. package/dist/surfaces/valheim/validators/plugins.js +287 -0
  279. package/dist/surfaces/valheim/validators/references.js +169 -0
  280. package/knowledge/baldursgate3/animations.gr2.yaml +166 -0
  281. package/knowledge/baldursgate3/audio.voice.yaml +182 -0
  282. package/knowledge/baldursgate3/audio.wwise.yaml +104 -0
  283. package/knowledge/baldursgate3/charactercreation.heads-hair.yaml +193 -0
  284. package/knowledge/baldursgate3/communitylibrary.shared-content.yaml +129 -0
  285. package/knowledge/baldursgate3/compatibilityframework.api.yaml +176 -0
  286. package/knowledge/baldursgate3/crash.causes.yaml +90 -0
  287. package/knowledge/baldursgate3/dialogue.dialogbank.yaml +120 -0
  288. package/knowledge/baldursgate3/dialogue.files.yaml +236 -0
  289. package/knowledge/baldursgate3/dialogue.osiris-goals.yaml +386 -0
  290. package/knowledge/baldursgate3/dialogue.yaml +122 -0
  291. package/knowledge/baldursgate3/feats.classes.yaml +164 -0
  292. package/knowledge/baldursgate3/items.cloth-physics.yaml +167 -0
  293. package/knowledge/baldursgate3/items.roottemplates.yaml +320 -0
  294. package/knowledge/baldursgate3/items.visualbank.yaml +628 -0
  295. package/knowledge/baldursgate3/journal.quests.yaml +214 -0
  296. package/knowledge/baldursgate3/loadorder.modsettings.yaml +128 -0
  297. package/knowledge/baldursgate3/localization.handles.yaml +92 -0
  298. package/knowledge/baldursgate3/misc.encoding-and-practice.yaml +111 -0
  299. package/knowledge/baldursgate3/origins.companions.yaml +144 -0
  300. package/knowledge/baldursgate3/osiris.signatures.yaml +211 -0
  301. package/knowledge/baldursgate3/packaging.meta.yaml +155 -0
  302. package/knowledge/baldursgate3/packaging.paks.yaml +79 -0
  303. package/knowledge/baldursgate3/process.launch.yaml +34 -0
  304. package/knowledge/baldursgate3/progressions.yaml +92 -0
  305. package/knowledge/baldursgate3/publishing.modio-nexus.yaml +170 -0
  306. package/knowledge/baldursgate3/publishing.toolkit-modio.yaml +135 -0
  307. package/knowledge/baldursgate3/races.progression.yaml +228 -0
  308. package/knowledge/baldursgate3/scriptextender.console.yaml +257 -0
  309. package/knowledge/baldursgate3/scriptextender.yaml +252 -0
  310. package/knowledge/baldursgate3/stats.boosts.yaml +293 -0
  311. package/knowledge/baldursgate3/stats.equipment-kits.yaml +69 -0
  312. package/knowledge/baldursgate3/stats.interrupts.yaml +45 -0
  313. package/knowledge/baldursgate3/stats.itemcombos.yaml +65 -0
  314. package/knowledge/baldursgate3/stats.spells.yaml +293 -0
  315. package/knowledge/baldursgate3/stats.weapons.yaml +210 -0
  316. package/knowledge/baldursgate3/toolchain.divine.yaml +179 -0
  317. package/knowledge/baldursgate3/toolchain.lslib-formats.yaml +242 -0
  318. package/knowledge/baldursgate3/toolkit.levels.yaml +177 -0
  319. package/knowledge/baldursgate3/ui.icons-atlas.yaml +78 -0
  320. package/knowledge/baldursgate3/ui.icons.yaml +412 -0
  321. package/knowledge/baldursgate3/ui.mcm.yaml +161 -0
  322. package/knowledge/baldursgate3/vfx.materials.yaml +174 -0
  323. package/knowledge/baldursgate3/visuals.characterfix.yaml +73 -0
  324. package/knowledge/cyberpunk2077/animations.anims.yaml +118 -0
  325. package/knowledge/cyberpunk2077/anims.archivexl.yaml +163 -0
  326. package/knowledge/cyberpunk2077/anims.authoring.yaml +579 -0
  327. package/knowledge/cyberpunk2077/anims.encoder.yaml +156 -0
  328. package/knowledge/cyberpunk2077/anims.graph.yaml +629 -0
  329. package/knowledge/cyberpunk2077/anims.method.yaml +360 -0
  330. package/knowledge/cyberpunk2077/anims.pipeline.yaml +352 -0
  331. package/knowledge/cyberpunk2077/anims.roundtrip.yaml +222 -0
  332. package/knowledge/cyberpunk2077/anims.sets.yaml +176 -0
  333. package/knowledge/cyberpunk2077/archivexl.bodytypes.yaml +149 -0
  334. package/knowledge/cyberpunk2077/archivexl.dynamic-appearances.yaml +218 -0
  335. package/knowledge/cyberpunk2077/archivexl.manifest.yaml +214 -0
  336. package/knowledge/cyberpunk2077/audio.events.yaml +168 -0
  337. package/knowledge/cyberpunk2077/audio.sounds.yaml +164 -0
  338. package/knowledge/cyberpunk2077/audio.voicesets.yaml +146 -0
  339. package/knowledge/cyberpunk2077/cet.sandbox.yaml +219 -0
  340. package/knowledge/cyberpunk2077/clothing.garments.yaml +283 -0
  341. package/knowledge/cyberpunk2077/clothing.refits.yaml +215 -0
  342. package/knowledge/cyberpunk2077/codeware.overview.yaml +111 -0
  343. package/knowledge/cyberpunk2077/codeware.systems.yaml +192 -0
  344. package/knowledge/cyberpunk2077/drones.combat.yaml +416 -0
  345. package/knowledge/cyberpunk2077/drones.control.yaml +552 -0
  346. package/knowledge/cyberpunk2077/entities.appearance.yaml +166 -0
  347. package/knowledge/cyberpunk2077/equipmentex.slots.yaml +151 -0
  348. package/knowledge/cyberpunk2077/fx.effects.yaml +246 -0
  349. package/knowledge/cyberpunk2077/fx.lights.yaml +171 -0
  350. package/knowledge/cyberpunk2077/hair.modding.yaml +145 -0
  351. package/knowledge/cyberpunk2077/items.wiring.yaml +246 -0
  352. package/knowledge/cyberpunk2077/loadorder.archives.yaml +71 -0
  353. package/knowledge/cyberpunk2077/mesh.blender.yaml +209 -0
  354. package/knowledge/cyberpunk2077/nativedb.dump.yaml +98 -0
  355. package/knowledge/cyberpunk2077/npc.appearance.yaml +275 -0
  356. package/knowledge/cyberpunk2077/npc.behaviour.yaml +128 -0
  357. package/knowledge/cyberpunk2077/npc.locomotion.yaml +490 -0
  358. package/knowledge/cyberpunk2077/packaging.deploy.yaml +175 -0
  359. package/knowledge/cyberpunk2077/packaging.variants.yaml +176 -0
  360. package/knowledge/cyberpunk2077/player.control.yaml +918 -0
  361. package/knowledge/cyberpunk2077/process.assetbuild.yaml +154 -0
  362. package/knowledge/cyberpunk2077/process.lessons.yaml +276 -0
  363. package/knowledge/cyberpunk2077/quests.minor.yaml +46 -0
  364. package/knowledge/cyberpunk2077/quests.scenes.yaml +282 -0
  365. package/knowledge/cyberpunk2077/quickhacks.tiers.yaml +41 -0
  366. package/knowledge/cyberpunk2077/red4ext.api.yaml +645 -0
  367. package/knowledge/cyberpunk2077/red4ext.plugins.yaml +124 -0
  368. package/knowledge/cyberpunk2077/redhottools.hotreload.yaml +245 -0
  369. package/knowledge/cyberpunk2077/redscript.compile-log.yaml +76 -0
  370. package/knowledge/cyberpunk2077/redscript.modules.yaml +118 -0
  371. package/knowledge/cyberpunk2077/toolchain.wolvenkit.yaml +163 -0
  372. package/knowledge/cyberpunk2077/tweakdb.loot-recipes.yaml +184 -0
  373. package/knowledge/cyberpunk2077/tweakdb.melee.yaml +352 -0
  374. package/knowledge/cyberpunk2077/tweakdb.weapons.yaml +325 -0
  375. package/knowledge/cyberpunk2077/tweakxl.hotreload.yaml +151 -0
  376. package/knowledge/cyberpunk2077/tweakxl.yaml-syntax.yaml +208 -0
  377. package/knowledge/cyberpunk2077/ui.icons.yaml +259 -0
  378. package/knowledge/cyberpunk2077/ui.inkatlas.yaml +81 -0
  379. package/knowledge/cyberpunk2077/ui.modsettings.yaml +204 -0
  380. package/knowledge/cyberpunk2077/vehicles.control.yaml +475 -0
  381. package/knowledge/cyberpunk2077/vehicles.dashboard-ui.yaml +203 -0
  382. package/knowledge/cyberpunk2077/vehicles.entities.yaml +195 -0
  383. package/knowledge/cyberpunk2077/vehicles.wiring.yaml +137 -0
  384. package/knowledge/cyberpunk2077/wolvenkit.cli.yaml +167 -0
  385. package/knowledge/cyberpunk2077/workspot.system.yaml +55 -0
  386. package/knowledge/cyberpunk2077/world.interactions.yaml +41 -0
  387. package/knowledge/cyberpunk2077/world.loot-container.yaml +167 -0
  388. package/knowledge/cyberpunk2077/world.sectors.yaml +233 -0
  389. package/knowledge/eldenring/formats.binders.yaml +237 -0
  390. package/knowledge/eldenring/launcher.me3.yaml +230 -0
  391. package/knowledge/eldenring/launcher.modengine2.yaml +119 -0
  392. package/knowledge/eldenring/params.paramdef.yaml +149 -0
  393. package/knowledge/eldenring/params.regulation.yaml +142 -0
  394. package/knowledge/eldenring/saves.online.yaml +118 -0
  395. package/knowledge/eldenring/toolchain.cli.yaml +256 -0
  396. package/knowledge/nivalisnights/modding.runtime.yaml +157 -0
  397. package/knowledge/skyrimse/archives.bsa.yaml +212 -0
  398. package/knowledge/skyrimse/install.detection.yaml +41 -0
  399. package/knowledge/skyrimse/loadorder.files.yaml +242 -0
  400. package/knowledge/skyrimse/plugins.esl.yaml +189 -0
  401. package/knowledge/skyrimse/plugins.format.yaml +224 -0
  402. package/knowledge/skyrimse/skse.runtime.yaml +283 -0
  403. package/knowledge/skyrimse/toolchain.xedit-spriggit.yaml +336 -0
  404. package/knowledge/stardewvalley/contentpatcher.format.yaml +338 -0
  405. package/knowledge/stardewvalley/distribution.channels.yaml +236 -0
  406. package/knowledge/stardewvalley/game.versions.yaml +202 -0
  407. package/knowledge/stardewvalley/install.layout.yaml +277 -0
  408. package/knowledge/stardewvalley/smapi.loader.yaml +284 -0
  409. package/knowledge/stardewvalley/smapi.logs.yaml +329 -0
  410. package/knowledge/stardewvalley/smapi.manifest.yaml +293 -0
  411. package/knowledge/stardewvalley/toolchain.build.yaml +261 -0
  412. package/knowledge/stardewvalley/wiki.dataformat.yaml +130 -0
  413. package/knowledge/subnautica2/game.build.yaml +331 -0
  414. package/knowledge/subnautica2/modding.state.yaml +210 -0
  415. package/knowledge/subnautica2/ue5.containers.yaml +72 -0
  416. package/knowledge/subnautica2/ue5.paks.yaml +203 -0
  417. package/knowledge/subnautica2/ue5.tooling.yaml +175 -0
  418. package/knowledge/subnautica2/ue5.ue4ss.yaml +203 -0
  419. package/knowledge/valheim/bepinex.loader.yaml +247 -0
  420. package/knowledge/valheim/bepinex.plugins.yaml +251 -0
  421. package/knowledge/valheim/game.versions.yaml +321 -0
  422. package/knowledge/valheim/install.layout.yaml +216 -0
  423. package/knowledge/valheim/jotunn.library.yaml +334 -0
  424. package/knowledge/valheim/thunderstore.packaging.yaml +217 -0
  425. package/knowledge/valheim/toolchain.build.yaml +111 -0
  426. package/package.json +29 -0
  427. package/scaffolds/baldursgate3/new-class-injection.yaml +148 -0
  428. package/scaffolds/baldursgate3/new-item.yaml +264 -0
  429. package/scaffolds/baldursgate3/new-mod.yaml +174 -0
  430. package/scaffolds/baldursgate3/new-passive.yaml +100 -0
  431. package/scaffolds/baldursgate3/new-project.yaml +118 -0
  432. package/scaffolds/baldursgate3/new-quest-stub.yaml +159 -0
  433. package/scaffolds/baldursgate3/new-spell.yaml +102 -0
  434. package/scaffolds/baldursgate3/new-status.yaml +119 -0
  435. package/scaffolds/baldursgate3/sequences/subclass-kit.yaml +50 -0
  436. package/scaffolds/cyberpunk2077/edit-tweak.yaml +70 -0
  437. package/scaffolds/cyberpunk2077/mesh-export-preset.yaml +170 -0
  438. package/scaffolds/cyberpunk2077/new-entity-patch.yaml +255 -0
  439. package/scaffolds/cyberpunk2077/new-garment-refit.yaml +279 -0
  440. package/scaffolds/cyberpunk2077/new-item-chain.yaml +548 -0
  441. package/scaffolds/cyberpunk2077/new-localization.yaml +130 -0
  442. package/scaffolds/cyberpunk2077/new-mod-settings.yaml +133 -0
  443. package/scaffolds/cyberpunk2077/new-player-replacer.yaml +1003 -0
  444. package/scaffolds/cyberpunk2077/new-project.yaml +157 -0
  445. package/scaffolds/cyberpunk2077/new-sector-node.yaml +156 -0
  446. package/scaffolds/cyberpunk2077/new-tweak.yaml +121 -0
  447. package/scaffolds/cyberpunk2077/new-vehicle-livery.yaml +148 -0
  448. package/scaffolds/cyberpunk2077/new-workspot-entity.yaml +177 -0
  449. package/scaffolds/cyberpunk2077/sequences/iconic-weapon.yaml +72 -0
  450. package/scaffolds/cyberpunk2077/sequences/quickhack-takeover.yaml +213 -0
  451. package/scaffolds/stardewvalley/new-cp-patch.yaml +106 -0
  452. package/scaffolds/stardewvalley/new-csharp-mod.yaml +195 -0
  453. package/scaffolds/stardewvalley/new-project.yaml +184 -0
  454. package/scaffolds/stardewvalley/sequences/content-pack.yaml +31 -0
  455. package/scripts/mw-tool.mjs +184 -0
@@ -0,0 +1,256 @@
1
+ game: eldenring
2
+ topic: toolchain.cli
3
+ title: which elden ring tools can run unattended, and which cannot
4
+ facts:
5
+ - id: eldenring.toolchain.witchybnd-has-a-real-headless-mode
6
+ claim: WitchyBND is the unpack/repack CLI for Elden Ring binder and texture formats and it supports
7
+ genuine unattended use — `-p/--passive` suppresses every prompt and delay, `-s/--silent`
8
+ suppresses console output and implies passive, and `-u/--unpack` or `-r/--repack` pin the
9
+ direction so it cannot guess wrong.
10
+ status: community
11
+ source: "`public class CliOptions` in
12
+ https://github.com/ividyon/WitchyBND/blob/main/WitchyBND/Configuration.cs — `-p, --passive`
13
+ \"Will not prompt the user for any input or cause any delays. Suited for automatic execution
14
+ in scripts.\"; `-s, --silent` \"Will not print any console output. Inherently sets 'passive'
15
+ to true.\"; `-u, --unpack` \"Only perform unpack processing, no repacking.\"; `-r, --repack`
16
+ \"Only perform repack processing, no unpacking.\"; also `-c, --recursive`, `-d, --dcx`, `-f,
17
+ --flexible`, `-l, --location`, `-v, --version`"
18
+ tags:
19
+ - witchybnd
20
+ - cli
21
+ - unattended
22
+ - passive
23
+ - silent
24
+ - toolchain
25
+ - flags
26
+ detail: Note the flag trap - `-c` is `--recursive`, not a "cli mode" switch; there is no `--cli`.
27
+ The Explorer context-menu integration lives in a separate opt-in assembly, so nothing forces
28
+ an interactive screen. Latest release at the time of writing is 3.0.1.0 (2026-07-06), with
29
+ both win-x64 and linux-x64 builds, licensed GPL v3. README format list - "DCX, FFXBND, BND3,
30
+ BND4, BXF3, BXF4, FFXDLSE, FMG, GPARAM, LUAGNL, LUAINFO, TPF, Zero3, FXR1, FXR3, MATBIN, MTD,
31
+ PARAM, MQB, and ENTRYFILELIST".
32
+ - id: eldenring.toolchain.witchybnd-xml-is-the-text-converter
33
+ claim: "WitchyBND's round trip is the Elden Ring equivalent of WolvenKit's cr2w-to-json and divine's
34
+ lsf-to-lsx: unpacking a binder writes a sidecar manifest named `_witchy-<tag>.xml` beside the
35
+ extracted entries, and repacking reads it back. For a regulation/PARAMBND4 the sidecar is
36
+ `_witchy-bnd4.xml`."
37
+ status: community
38
+ source: '`GetFolderXmlFilename` in WitchyBND/Parsers/WFolderParser.cs returns
39
+ `$"_witchy-{name}.xml"`; WitchyBND/Parsers/Binder/WPARAMBND4.cs calls it with "bnd4"; the
40
+ README shows the same pattern for other formats (`_witchy-anibnd4.xml`, `_witchy-tae.xml`)'
41
+ tags:
42
+ - witchybnd
43
+ - xml
44
+ - roundtrip
45
+ - convert
46
+ - sidecar
47
+ - text-converter
48
+ detail: "The sidecar is not cosmetic — it carries the binder's `<version>` element and, for a
49
+ regulation, the regulation version, and repack validates against them. That makes a deleted or
50
+ hand-edited sidecar a real failure mode and a good validator target: a staged binder directory
51
+ with no `_witchy-*.xml` cannot be repacked at all."
52
+ - id: eldenring.toolchain.witchybnd-handles-regulation-encryption-itself
53
+ claim: WitchyBND detects a regulation.bin by filename and routes it through a dedicated PARAMBND4
54
+ parser that decrypts on unpack and re-encrypts on repack, and it refuses to repack a
55
+ regulation whose version is newer than the newest paramdef it bundles. So encryption is not a
56
+ step the caller has to implement.
57
+ status: community
58
+ source: WitchyBND/Parsers/Binder/WPARAMBND4.cs detects a filename containing "regulation" and ending
59
+ ".bin" and dispatches to the regulation decryptor/encryptor; WitchyBND's changelog for
60
+ v2.1.1.0 — "Repacking PARAMBND4 will now perform a dry PARAM unpack attempt on all constituent
61
+ PARAM files, to catch user errors attempting to pack outdated PARAMs into new regulation
62
+ versions" and "Repacking PARAMBND4 will now fail if the regulation version exceeds the latest
63
+ known regulation version in Paramdex"
64
+ tags:
65
+ - witchybnd
66
+ - regulation
67
+ - encryption
68
+ - paramdex
69
+ - version
70
+ - guard
71
+ detail: WitchyBND ships its own vendored Paramdex under WitchyBND/Assets/Paramdex/ER/ with Defs,
72
+ Names, Meta, Tdfs and an Upgrader/version.txt naming the newest regulation it knows. Reading
73
+ that file is a cheap, install-free way for `check_toolchain` to report which regulation
74
+ versions the installed WitchyBND can actually round-trip — a version axis no `--version` flag
75
+ exposes.
76
+ - id: eldenring.toolchain.dsmsportable-is-the-only-unattended-param-editor
77
+ claim: DSMSPortable is the one command-line tool that edits and merges Elden Ring params unattended.
78
+ It takes regulation.bin as its positional argument, defaults to Elden Ring, applies CSV or
79
+ mass-edit scripts, exports and diffs params, and has separate merge modes for FMG, TPF,
80
+ layout, HKS, EMEVD, BND and TAE files.
81
+ status: community
82
+ source: 'DSMSPortable/Program.cs usage output at https://github.com/mountlover/DSMSPortable —
83
+ "Usage: DSMSPortable [paramfile] [-G gametype] [-P gamepath] [-U oldvanillaparams] [-C2M ...]
84
+ [-R paramname:query ...] [-C csvfile ...] [-M[+] masseditfile ...] [-X paramname[:query] ...]
85
+ [-D diffparamfile] [-O outputpath]"; "paramfile — Path to regulation.bin file (or respective
86
+ param file for other FromSoft games) to modify"; "-G gametype ... The default is Elden Ring";
87
+ plus `--fmgentry`, `--fmgmerge`, `--layoutmerge`, `--texturemerge`, `--animerge`,
88
+ `--animdiff`, `--bndmerge`, `--bnddiff`, `--hksmerge`, `--emevdmerge`, `--emevddiff`'
89
+ tags:
90
+ - dsmsportable
91
+ - cli
92
+ - unattended
93
+ - merge
94
+ - massedit
95
+ - regulation
96
+ - build
97
+ detail: Its README is mostly a numbered exit-code table (0 success through 20 "Massedit parse
98
+ error", with a negative code for ".NET not installed"), which is exactly what a toolchain
99
+ adapter needs to classify a failure rather than just reporting non-zero. Program.cs carries
100
+ `VERSION = "1.9"`. Two cautions - it needs the .NET 6 Desktop Runtime, and it is unmaintained
101
+ and absent from the community wiki's tool database, so it is a viable but low-adoption
102
+ dependency rather than a safe default.
103
+ - id: eldenring.toolchain.every-other-editor-is-gui-only
104
+ claim: Smithbox, DSMapStudio, UXM Selective Unpack and DSAnimStudio are all GUI applications with no
105
+ documented command line. ModWright cannot drive any of them; it can only check what they
106
+ produced.
107
+ status: community
108
+ source: https://github.com/vawser/Smithbox README Usage section ("Once installed, click the
109
+ Smithbox.Vulkan.exe to launch the fully featured version of Smithbox") and its Requirements
110
+ section (a Vulkan 1.3 GPU); https://github.com/Nordgaren/UXM-Selective-Unpack README, which
111
+ describes only buttons ("The Unpack button will extract all files from the game archives,
112
+ unless you select files in the \"View Files\" menu"; "The Patch button will modify the
113
+ executable"; "the Restore button will restore the original executable and delete the extracted
114
+ files")
115
+ tags:
116
+ - smithbox
117
+ - dsmapstudio
118
+ - uxm
119
+ - dsanimstudio
120
+ - gui
121
+ - scope
122
+ - boundary
123
+ detail: This is the single biggest structural difference from the Cyberpunk and BG3 surfaces, where
124
+ WolvenKit CLI and divine cover most of the pipeline. Here the scriptable surface is exactly
125
+ two tools — WitchyBND and DSMSPortable — and everything else is a person at a keyboard. A
126
+ surface that claims otherwise will produce build steps that cannot run.
127
+ - id: eldenring.toolchain.souls-formats-is-a-library-not-a-cli
128
+ claim: SoulsFormats, the C# library every one of these tools is built on, ships no command-line
129
+ interface — it is a .NET library, GPL-3.0, and the original repository has been archived since
130
+ 2025-05-26. The maintained continuation is soulsmods/SoulsFormatsNEXT, which is where Elden
131
+ Ring map support lives.
132
+ status: community
133
+ source: https://github.com/JKAnderson/SoulsFormats — archive banner dated May 26, 2025; README "A
134
+ .NET library for reading and writing various FromSoftware file formats, targeting .NET
135
+ Framework 4.6.2 and .NET Standard 2.1. Dark Souls, Demon's Souls, Bloodborne, and Sekiro are
136
+ the main focus, but other From games may be supported to varying degrees."; the repository's
137
+ top level is a solution and a library project with no console project
138
+ tags:
139
+ - soulsformats
140
+ - library
141
+ - license
142
+ - gpl
143
+ - archived
144
+ - soulsformatsnext
145
+ detail: The archived repository's MSB support stops at MSB1/2/3/B/D/N/S — there is no MSBE, so Elden
146
+ Ring map reading is not in it. SoulsFormatsNEXT adds Formats/MSB/MSBE/ and names Elden Ring in
147
+ its supported list. Both are GPL-3.0 libraries, so ModWright's only sound relationship with
148
+ either is to shell out to a tool that embeds them, the way it already shells out to divine and
149
+ WolvenKit CLI rather than linking them.
150
+ - id: eldenring.toolchain.uxm-patching-is-the-other-deploy-target-and-it-is-destructive
151
+ claim: The alternative to a loader overlay is UXM Selective Unpack, which extracts the archives to
152
+ loose files and patches eldenring.exe to read them. It is destructive and mutually exclusive
153
+ with online play, and unpacking without patching, or patching without unpacking, breaks the
154
+ game.
155
+ status: community
156
+ source: https://github.com/Nordgaren/UXM-Selective-Unpack README — "Enables file modding for DS1,
157
+ DS2, SotFS, DS3, Sekiro and Elden Ring by unpacking game archives and patching the executable
158
+ to load loose files instead."; "Patching the executable without also unpacking the archives
159
+ will crash the game, so make sure you do both."; and, under Elden Ring, "You cannot play
160
+ online with an modified exe, so you cannot go online with an unpacked game (Nor can you go
161
+ online with Mod Engine 2)"
162
+ tags:
163
+ - uxm
164
+ - unpack
165
+ - patch
166
+ - deploy
167
+ - destructive
168
+ - online
169
+ - restore
170
+ detail: There is a documented way back — "the Restore button will restore the original executable
171
+ and delete the extracted files" — which makes this reversible but not cheap. DSMapStudio's
172
+ README requires this path for Elden Ring ("Use UXM Selective Unpack to extract the game
173
+ files... at least the map, asset, chr, and msg directories are needed for basic editor
174
+ usage"), whereas Smithbox says "You no longer need to unpack a game for any of the editors"
175
+ and points at Nuxe if you do. A deploy target this coarse is a poor default; the loader
176
+ overlay should be the primary one.
177
+ - id: eldenring.toolchain.dsmsportable-exit-code-table
178
+ claim: "DSMSPortable's exit codes are documented in full: below 0 \".NET not installed\", 1
179
+ Unhandled Exception, 2 Unhandled Exception processing arguments, 3 No gamepath specified, 4
180
+ Could not resolve output path, 5 Unrecognized argument switch, 6 Failed to read TAE file, 7
181
+ Timed out loading param files, 8 Failed to save/overwrite file, 9 Failed to save param file,
182
+ 10 Failed to generate temporary files, 11 Invalid FMG file specified, 12 XML parsing error, 13
183
+ Invalid in-line FMG entry, 14 Invalid sblytbnd file specified, 15 Invalid TPF file specified,
184
+ 16 Invalid BND file specified, 17 Invalid HKS/Lua file specified, 18 Invalid msgbnd file
185
+ specified, 19 Invalid anibnd file specified, 20 Massedit parse error."
186
+ status: community
187
+ source: https://github.com/mountlover/DSMSPortable README.md, "DSMSPortable Error Codes" (read
188
+ 2026-09-11), and its Requirements section naming the .NET 6.0 Desktop Runtime
189
+ tags:
190
+ - dsmsportable
191
+ - exit-code
192
+ - cli
193
+ - toolchain
194
+ - adapter
195
+ - dotnet
196
+ detail: '`src/surfaces/eldenring/tools.ts` carries the table as DSMSPORTABLE_EXIT_CODES with
197
+ `explainDsmsPortableExit`, so a build step can say "No gamepath specified" rather than "exit
198
+ 3". A negative code on a fresh machine means the runtime, not the arguments.'
199
+ related:
200
+ - eldenring.toolchain.dsmsportable-is-the-only-unattended-param-editor
201
+ - id: eldenring.toolchain.witchybnd-version-flag-prints-the-assembly-version
202
+ claim: "`WitchyBND -v` (also `--version`) prints `WitchyBND v<assembly version>`, e.g. `WitchyBND
203
+ v3.0.1.0`, four components from the .NET assembly rather than the release tag."
204
+ status: community
205
+ source: WitchyBND/Program.cs — `if (opt.Version) ... _output.WriteLine($"{assembly.GetName().Name}
206
+ v{assembly.GetName().Version.ToString()}"`; Configuration.cs `[Option('v', "version", HelpText
207
+ = "Display version information.")]`
208
+ tags:
209
+ - witchybnd
210
+ - version
211
+ - cli
212
+ - toolchain
213
+ - flag
214
+ detail: The toolchain spec `witchybnd` probes with `-v` and matches the printed `WitchyBND v` prefix
215
+ followed by the dotted number; the regulation-version axis
216
+ (Assets/Paramdex/ER/Upgrader/version.txt) is a different number and is read separately.
217
+ related:
218
+ - eldenring.toolchain.witchybnd-has-a-real-headless-mode
219
+ - id: eldenring.toolchain.witchybnd-sidecar-shape
220
+ claim: WitchyBND unpacks a binder into a folder named after the file with its dots replaced by
221
+ dashes (`c0000.anibnd.dcx` becomes `c0000-anibnd-dcx`; a name with no dot gains `-unpacked`)
222
+ and writes `_witchy-<tag>.xml` inside it, `<bnd4>` for a BND4 with `<version>`, `<format>`,
223
+ `<bigendian>`, `<bitbigendian>`, `<unicode>`, `<extended>`, `<unk04>`, `<unk05>`, an optional
224
+ `<root>` (the common path prefix it stripped) and `<compression>`, then `<files>` of `<file>`
225
+ elements each carrying `<flags>`, `<id>`, `<path>` and, when two entries share a path, a
226
+ `<suffix>` such as ` (2)` that the on-disk file carries before its extension. Alongside those
227
+ the manifest carries `<filename>` (and `<sourcePath>` when unpacked recursively), which is
228
+ where repack writes the rebuilt binder. Repack reads `<version>` and `<filename>`
229
+ unconditionally and stops with "File not found" on any entry missing from the folder; files
230
+ not named in the sidecar are not packed.
231
+ status: community
232
+ source: WitchyBND/Parsers/WFolderParser.cs `GetUnpackDestPath` (`fileName.Replace('.', '-')`,
233
+ `-unpacked`), `GetFolderXmlFilename` (`$"_witchy-{name}.xml"`), `IsUnpacked` (the root tag
234
+ check), `GetRepackDestPath` ("XML does not have filename."); WitchyBND/Parsers/WParser.cs
235
+ `PrepareXmlManifest` and `AddLocationToXml` (`<compression>`, `<filename>`, `<sourcePath>`,
236
+ `<root>`); WitchyBND/Parsers/Binder/WBND4.cs `Unpack` (the element list) and `Repack`
237
+ (`xml.Element("version")!.Value`); WitchyBND/Parsers/WBinderParser.cs `WriteBinderFiles`
238
+ (`<file>` with flags, id, path, suffix) and `ReadBinderFiles` (`OSPath.Combine(srcDirPath,
239
+ dir, stem + suffix + ext)`, `File not found`)
240
+ tags:
241
+ - witchybnd
242
+ - sidecar
243
+ - xml
244
+ - unpack
245
+ - repack
246
+ - naming
247
+ - validator
248
+ detail: This is what `eldenring.binders.sidecar-entries` and `eldenring.binders.unpacked-in-package`
249
+ rest on. The folder-name test for "looks like an unpack folder" is a heuristic on that naming;
250
+ the sidecar's presence is the real evidence, and the rule says which of the two it saw. "Packs
251
+ only what the sidecar names" holds for the plain binder parsers (`bnd4`, `bnd3`, `bxf4`,
252
+ `bxf3`); WitchyBND's special modes write their own tag and folder suffix
253
+ (`_witchy-anibnd4.xml` in a `-wanibnd` folder) and repack the animation files they find by
254
+ scanning it, so the stray-file check is scoped to the four plain tags.
255
+ related:
256
+ - eldenring.toolchain.witchybnd-xml-is-the-text-converter
@@ -0,0 +1,157 @@
1
+ game: nivalisnights
2
+ topic: modding.runtime
3
+ title: Nivalis Nights modding at runtime — BepInEx 6 IL2CPP, the studio's developer mode, saves and
4
+ sidecars, and decoding the build's assets
5
+ facts:
6
+ - id: nivalisnights.modding.runtime.bepinex-be788-il2cpp-loads-plugins
7
+ claim: "BepInEx 6 bleeding-edge #788 in its Unity.IL2CPP build loads plugins on Nivalis Nights: a
8
+ net6.0 `BasePlugin` compiled against `BepInEx/core` and the generated `BepInEx/interop` loads,
9
+ and its HarmonyX patches on game methods fire."
10
+ status: verified
11
+ verified_on: "25680465"
12
+ source: ModWright field verification
13
+ tags:
14
+ - bepinex
15
+ - il2cpp
16
+ - loader
17
+ - harmony
18
+ - interop
19
+ - plugins
20
+ detail: The first launch after installing downloaded the Unity base libraries from
21
+ unity.bepinex.dev, ran Cpp2IL and generated 125 interop assemblies in about 25 s at a black
22
+ screen, so it needs network access. Patches on GameSceneManager.LoadArea and the
23
+ PlayerInventory.Money setter fired. The installed .NET 8 SDK built the net6.0 plugin after
24
+ fetching the 6.0.36 reference pack.
25
+ - id: nivalisnights.modding.runtime.devmode-postfix-opens-developer-options
26
+ claim: A Harmony postfix forcing `Nivalis.DevOptions.DevMode.IsDevMode` to true, applied in the
27
+ plugin's `Load()`, populates the studio's Developer Options catalogue, and
28
+ `DevOptionMenuRevised.Instance.Open()` shows its window from the main menu. Esc closes it.
29
+ status: verified
30
+ verified_on: "25680465"
31
+ source: ModWright field verification
32
+ tags:
33
+ - devmode
34
+ - developer-options
35
+ - harmony
36
+ - bridge
37
+ - cheats
38
+ detail: The catalogue held 58 options on this build (55 on 25603526). The probe read their display
39
+ names and shortcuts at runtime from DevOptionMenuRevised._methodDisplayString, e.g. F3 'Toggle
40
+ UI Shown' and F11 'Toggle No Clip'. The postfix must be in place before the _Global scene's UI
41
+ loads, because the menu's Awake builds the catalogue once. Opening through Instance.Open()
42
+ bypasses the Ctrl+Shift+F12 hotkey and the BuildDeveloperOptionsEnabled asset flag.
43
+ - id: nivalisnights.modding.runtime.isdevmode-log-line-precedes-postfix
44
+ claim: "`Player.log` prints `isDevMode:False` even while a plugin's postfix has forced developer
45
+ mode on, because the game logs inside the getter before the postfix changes the return value;
46
+ that line is no evidence the force failed."
47
+ status: verified
48
+ verified_on: "25680465"
49
+ source: ModWright field verification
50
+ tags:
51
+ - devmode
52
+ - logs
53
+ - triage
54
+ - player-log
55
+ - id: nivalisnights.modding.runtime.articy-script-runner-returns-run-success
56
+ claim: "`Nivalis.Dialogue.ArticyScriptRunner.DoArticyScript(string)` returns whether the script ran,
57
+ not the expression's value. To read a story variable, use
58
+ `ArticyDatabase.DefaultGlobalVariables.Variables`, a name-to-value dictionary."
59
+ status: verified
60
+ verified_on: "25680465"
61
+ source: ModWright field verification
62
+ tags:
63
+ - articy
64
+ - story-variables
65
+ - bridge
66
+ - scripting
67
+ detail: "'Ava.ControlRoomUnlocked == false' returned True while the variable read True, and the
68
+ variable was unchanged afterwards. The dictionary held 1,822 variables on this build."
69
+ - id: nivalisnights.modding.runtime.save-sidecar-round-trip
70
+ claim: "A plugin can keep its own state beside a save: a file written from a
71
+ `SerializationManager.Save(string, bool)` postfix as
72
+ `<persistentDataPath>/<saveName>.modwright.json` and read back from a
73
+ `SerializationManager.Load(string)` prefix survives a save and reload, with no errors from the
74
+ game's save loader."
75
+ status: verified
76
+ verified_on: "25680465"
77
+ source: ModWright field verification
78
+ tags:
79
+ - saves
80
+ - sidecar
81
+ - persistence
82
+ - mod-state
83
+ related:
84
+ - id: nivalisnights.modding.runtime.save-loader-cannot-skip-unknown-packet
85
+ detail: the reason mod state belongs in a sidecar and never in a new save packet
86
+ - id: nivalisnights.modding.runtime.steam-cloud-syncs-only-sav-and-png
87
+ claim: Steam Auto-Cloud for Nivalis Nights tracks only `.sav` and `.png` files in the save folder,
88
+ so a mod's sidecar file next to a save stays on the machine and does not follow the player to
89
+ another PC.
90
+ status: verified
91
+ verified_on: "25680465"
92
+ source: ModWright field verification
93
+ tags:
94
+ - saves
95
+ - steam-cloud
96
+ - sidecar
97
+ - id: nivalisnights.modding.runtime.save-loader-cannot-skip-unknown-packet
98
+ claim: The save loader (`ManagersSave.Load`) cannot skip a manager packet it does not recognise. It
99
+ logs `No packet found for guid <id>` and reads on from the wrong place, so a mod must never
100
+ add a save packet.
101
+ status: inferred
102
+ source: ModWright research
103
+ tags:
104
+ - saves
105
+ - packets
106
+ - compatibility
107
+ - uninstall
108
+ detail: "Packets carry a length-prefixed id and no length field, so the bytes after an unknown id
109
+ cannot be stepped over. Ghost blocks are different: they carry int64 absolute end offsets and
110
+ an unknown prefab is skipped. This was read from code; no save with an unknown packet has been
111
+ loaded."
112
+ - id: nivalisnights.modding.runtime.stripped-typetrees-decode-with-attribute-dummy-dlls
113
+ claim: The build's MonoBehaviour and ScriptableObject fields decode with UnityPy only through type
114
+ trees generated from Cpp2IL dummy DLLs made with `--use-processor
115
+ attributeanalyzer,attributeinjector`. TypeTreeGeneratorAPI's own IL2CPP loader fails on this
116
+ build, and the generated base nodes put `m_Script` 3 bytes off.
117
+ status: inferred
118
+ source: ModWright research
119
+ tags:
120
+ - index
121
+ - unitypy
122
+ - cpp2il
123
+ - typetrees
124
+ - il2cpp
125
+ detail: "Measured by the index build rather than observed in the engine. load_il2cpp fails with
126
+ 'Sequence contains no matching element'. Without the attribute processors, private
127
+ [SerializeField] fields are missing. m_Script is read from the raw bytes instead: FileID int32
128
+ at 16, PathID int64 at 20. On build 25680465 every definition in the default folders decoded,
129
+ including the 1,589 NPCs reached through PeopleDatabase."
130
+ - id: nivalisnights.modding.runtime.serializereference-folders-do-not-decode
131
+ claim: The `quests`, `skills`, `ghosts` and `backgroundnpcconversations` Resources folders do not
132
+ decode through generated type trees. Their `[SerializeReference]` polymorphic fields either
133
+ fail ('Failed to get ref type node') or make the generator run away.
134
+ status: inferred
135
+ source: ModWright research
136
+ tags:
137
+ - index
138
+ - serializereference
139
+ - quests
140
+ - skills
141
+ - unitypy
142
+ detail: The quests decode passed 12 GB of memory before it was killed. newsarticles fail
143
+ differently, with a consistent 44-byte shortfall. The index lists all five as not indexed,
144
+ with these reasons.
145
+ - id: nivalisnights.modding.runtime.bepinex6-chainloader-wording
146
+ claim: BepInEx 6's chainloader words its lines differently from BepInEx 5. It writes `1 plugin to
147
+ load`, not `1 plugin(s) to load`, and `Error loading [x]:` with no space before the colon. It
148
+ also reworded both dependency errors. BepInEx 5 log patterns miss these lines.
149
+ status: inferred
150
+ source: BepInEx at 5b766a3, BepInEx.Core/Bootstrap/BaseChainloader.cs;
151
+ test/fixtures/logs/nivalisnights/real/LogOutput.head.log
152
+ tags:
153
+ - bepinex
154
+ - logs
155
+ - triage
156
+ - signatures
157
+ detail: The banner, plugin count and roll-call lines also match the real log from the field run.
@@ -0,0 +1,212 @@
1
+ game: skyrimse
2
+ topic: archives.bsa
3
+ title: BSA archives — the v105 format, and how an archive gets loaded at all
4
+ facts:
5
+ - id: sse.archives.bsa.version-105
6
+ claim: Skyrim Special Edition uses BSA version 105 (0x69). Skyrim LE uses 104 (0x68) and Oblivion
7
+ 103 (0x67). The version field is a uint32 at offset 4 of a 36-byte header that begins with the
8
+ literal "BSA\0".
9
+ status: community
10
+ source: en.uesp.net "Skyrim Mod:Archive File Format", the intro and the Header table's version row
11
+ ("Currently 104 (0x68) for Skyrim or 105 (0x69) for Skyrim Special Edition"); the same mapping
12
+ appears in Ryan-rsm-McKenzie/bsa include/bsa/tes4.hpp
13
+ tags:
14
+ - bsa
15
+ - archive
16
+ - version
17
+ - byte-layout
18
+ - parser
19
+ detail: UESP's stated reason for the split - "Bethesda serializes structs directly, including
20
+ undefined padding bits" - explains why the difference is purely in the folder record's
21
+ padding.
22
+ - id: sse.archives.bsa.v105-uses-lz4
23
+ claim: A compressed file block in a v105 (Skyrim SE) archive is a uint32 original size followed by
24
+ LZ4-compressed data. v104 (Skyrim LE) uses zlib for the same block.
25
+ status: community
26
+ source: en.uesp.net "Skyrim Mod:Archive File Format", section "Compressed File block" ("File data
27
+ that has been compressed with zlib (v104) or LZ4 (v105)"); Ryan-rsm-McKenzie/bsa
28
+ include/bsa/tes4.hpp ("The v105 format uses lz4")
29
+ tags:
30
+ - bsa
31
+ - archive
32
+ - compression
33
+ - lz4
34
+ - zlib
35
+ - parser
36
+ - id: sse.archives.bsa.folder-record-is-24-bytes-in-v105
37
+ claim: The v104 to v105 structural difference is the folder record. v104's is 16 bytes (8-byte name
38
+ hash, uint32 count, uint32 offset); v105's is 24, inserting a uint32 padding after count and
39
+ another after offset. The folder offset needs totalFileNameLength subtracted to become a real
40
+ file offset.
41
+ status: community
42
+ source: en.uesp.net "Skyrim Mod:Archive File Format", section "Folder Record"
43
+ tags:
44
+ - bsa
45
+ - archive
46
+ - byte-layout
47
+ - parser
48
+ - v104-vs-v105
49
+ detail: The file record stays 16 bytes in both (8-byte hash, uint32 size, uint32 offset). Folders
50
+ and files must be sorted by their 64-bit hash values.
51
+ - id: sse.archives.bsa.compressed-flag-means-default-not-all
52
+ claim: Archive flag 0x4 ("Compressed Archive") does not mean every file is compressed; it means
53
+ files are compressed by default. Bit 30 (0x40000000) of a file record's size field inverts
54
+ that default for the individual file.
55
+ status: community
56
+ source: en.uesp.net "Skyrim Mod:Archive File Format", the archiveFlags table ("This does not mean
57
+ all files are compressed. It means they are compressed by default") and the File Record
58
+ section
59
+ tags:
60
+ - bsa
61
+ - archive
62
+ - compression
63
+ - flags
64
+ - parser
65
+ - gotcha
66
+ detail: A reader that assumes the archive flag applies uniformly will decompress uncompressed data
67
+ on any archive with mixed content.
68
+ - id: sse.archives.bsa.directory-and-file-name-flags-are-required
69
+ claim: Archive flags 0x1 (Include Directory Names) and 0x2 (Include File Names) are set in every
70
+ official BSA, and UESP notes for each that the game may not load a BSA without the bit set.
71
+ status: community
72
+ source: en.uesp.net "Skyrim Mod:Archive File Format", archiveFlags table, bits 1 and 2
73
+ tags:
74
+ - bsa
75
+ - archive
76
+ - flags
77
+ - validation
78
+ detail: Other archiveFlags of note - 0x40 Xbox360 (all numbers and hashes big-endian), 0x100 Embed
79
+ File Names, 0x200 XMem codec (Xbox 360 only, requires 0x4). fileFlags is a separate
80
+ content-type mask - 0x1 Meshes, 0x2 Textures, 0x4 Menus, 0x8 Sounds, 0x10 Voices, 0x20
81
+ Shaders, 0x40 Trees, 0x80 Fonts, 0x100 Miscellaneous.
82
+ - id: sse.archives.bsa.two-ini-keys-under-archive-section
83
+ claim: The archive list lives in skyrim.ini under the [Archive] section in TWO keys,
84
+ SResourceArchiveList and SResourceArchiveList2. The second exists because the value is capped
85
+ - a joined list longer than 255 characters is split at the last comma before position 256.
86
+ status: community
87
+ source: ModOrganizer2/modorganizer-game_skyrimse src/skyrimsedataarchives.cpp
88
+ (SkyrimSEDataArchives::archives reads both keys; writeArchiveList performs the split);
89
+ modorganizer-game_gamebryo src/gamebryo/gamebryodataarchives.cpp getArchivesFromKey, which
90
+ passes the literal section name L"Archive" to GetPrivateProfileStringW
91
+ tags:
92
+ - bsa
93
+ - archive
94
+ - ini
95
+ - skyrim-ini
96
+ - sresourcearchivelist
97
+ - gotcha
98
+ detail: Reading only the first key silently misses every archive in a long list's tail. MO2 reads
99
+ skyrim.ini from the profile directory when profile-specific INI files are enabled, and from
100
+ Documents\My Games\<name> otherwise.
101
+ - id: sse.archives.bsa.seventeen-vanilla-archives
102
+ claim: Skyrim SE ships seventeen vanilla archives - Skyrim - Textures0 through Textures8, Meshes0
103
+ and Meshes1, Voices_en0, Sounds, Interface, Animations, Shaders and Misc.
104
+ status: community
105
+ source: ModOrganizer2/modorganizer-game_skyrimse src/skyrimsedataarchives.cpp,
106
+ SkyrimSEDataArchives::vanillaArchives
107
+ tags:
108
+ - bsa
109
+ - archive
110
+ - vanilla
111
+ - inventory
112
+ - id: sse.archives.bsa.bsarch-is-part-of-xedit
113
+ claim: BSArch, the command-line BSA packer, lives inside the xEdit repository at Tools/BSArchive and
114
+ is what xEdit itself uses - xEdit's own .bsa/.ba2 code was replaced by BSArch's.
115
+ status: community
116
+ source: github.com/TES5Edit/TES5Edit Tools/BSArchive/bsarch.dpr (program bsarch; {$APPTYPE CONSOLE}
117
+ sVersion = '0.7', MPL 1.1); whatsnew.md ("xEdit specific code for .bsa/.ba2 has been
118
+ completely replaced with the code from BSArch")
119
+ tags:
120
+ - bsa
121
+ - bsarch
122
+ - toolchain
123
+ - xedit
124
+ - packing
125
+ - id: sse.archives.bsa.bsarch-pack-syntax
126
+ claim: BSArch packs a Skyrim SE archive with `bsarch pack <folder> <archive.bsa> -sse [-z] [-share]
127
+ [-mt]`, where -sse selects the v105 format, -z compresses, -share deduplicates
128
+ binary-identical files and -mt runs multi-threaded.
129
+ status: community
130
+ source: github.com/TES5Edit/TES5Edit Tools/BSArchive/bsarch.dpr, the help text, whose SSE example is
131
+ `bsarch pack "d:\my mod\data" "d:\my mod\data\new.bsa" -sse -z`
132
+ tags:
133
+ - bsa
134
+ - bsarch
135
+ - cli
136
+ - packing
137
+ - build-step
138
+ - toolchain
139
+ detail: The -af and -ff flag overrides apply to "Oblivion, Fallout 3/NV and Skyrim LE archives
140
+ only". BSArch's exit code is 1 only on an unhandled exception - there are no granular codes.
141
+ - id: sse.archives.bsa.compressed-archives-break-sound
142
+ claim: Sounds and voices do not work in compressed archives in any Bethesda game. A single sound or
143
+ voice file among thousands forces the whole archive to be uncompressed.
144
+ status: community
145
+ source: github.com/TES5Edit/TES5Edit Tools/BSArchive/bsarch.dpr, the -z parameter's help text ("Keep
146
+ in mind that sounds and voices don't work in compressed archives in all Bethesda games! Even
147
+ if your archive contains a single sound/voice file out of thousands, it must be
148
+ uncompressed.")
149
+ tags:
150
+ - bsa
151
+ - compression
152
+ - audio
153
+ - gotcha
154
+ - build-step
155
+ - validator
156
+ detail: A build step that packs with -z should refuse, or warn, when the staged tree contains
157
+ anything under sound/ or a .fuz/.xwm/.wav file. The symptom in game is silence, not an error.
158
+ - id: sse.archives.bsa.file-record-blocks-and-name-block
159
+ claim: "After the folder records come the file record blocks, one per folder in folder-record order:
160
+ a bzstring folder name (a length byte, the lower-case backslash-separated name, a terminating
161
+ \\0) when archive flag 0x1 is set, then that folder's 16-byte file records (8-byte name hash,
162
+ uint32 size, uint32 offset from the start of the file). Then, when flag 0x2 is set, the file
163
+ name block: every file's lower-case name with no path, \\0-terminated, in the same order as
164
+ the records. The folder record's offset field is the block's offset plus totalFileNameLength."
165
+ status: community
166
+ source: en.uesp.net "Skyrim Mod:Archive File Format" (read 2026-09-11), sections "File Record
167
+ blocks" ("name | bzstring | Name of the folder. Only present if Bit 1 of archiveFlags is
168
+ set."), "File Record" ("offset ... is offset from file byte zero (start), NOT from this
169
+ location"), "File Name block" ("If archive flag 0x2 is not set, this block is omitted. A block
170
+ of lower case file names, one after another, each ending in a \0. They are ordered in the same
171
+ order as those generated with the file folder block contents"), and "Folder Record" ("Subtract
172
+ totalFileNameLength to get the actual offset within the file.")
173
+ tags:
174
+ - bsa
175
+ - archive
176
+ - byte-layout
177
+ - parser
178
+ - names
179
+ detail: With both name flags set (every official archive), the whole table is a deterministic length
180
+ from the header alone (header, folder records, the folder names plus one length byte each, the
181
+ file records, the file names), so a reader can fetch exactly the table and never the payloads.
182
+ The page was readable on 2026-09-11 without the Cloudflare challenge met earlier in ModWright
183
+ research; the same-base-name loading rule is still not on it.
184
+ - id: sse.archives.bsa.name-hash-algorithm
185
+ claim: "A record's 64-bit hash is the Tes4/Tes5 pair: the name lower-cased with forward slashes made
186
+ backslashes; for a file, split at the last dot into root and extension. The low 32 bits are
187
+ (last root char) | (second-last root char << 8, when the root is longer than two) | (root
188
+ length << 16) | (first root char << 24), with 0x80 (.kf), 0x8000 (.nif), 0x8080 (.dds) or
189
+ 0x80000000 (.wav) set on top for those four extensions. The high 32 bits are the sum of two
190
+ folds with multiplier 0x1003f: over the root's characters from the second to the third-last,
191
+ and over the extension including its dot. A folder hashes whole, with no extension split and
192
+ no leading or trailing slash."
193
+ status: community
194
+ source: "en.uesp.net \"Oblivion Mod:Hash Calculation\" (read 2026-09-11): the Overview (\"The hash
195
+ cannot be calculated using / (forward slashes) or upper case characters ... Folder hash values
196
+ must not include leading or trailing slashes ... The extension must include the '.'\") and its
197
+ Python and C implementations, which agree on these four extensions; the transcription follows
198
+ the Python, which compares the whole extension string, rather than the C, which loads four
199
+ bytes at the dot and so would also set the bit for a longer extension beginning \".nif\",
200
+ \".dds\" or \".wav\"; the reference Python was run to produce the test vectors in
201
+ test/unit/skyrimse/archive-records.test.ts"
202
+ tags:
203
+ - bsa
204
+ - archive
205
+ - hash
206
+ - parser
207
+ - validator
208
+ detail: "This is what lets a validator check every record's hash against the name the archive
209
+ carries for it, with no game: a hash that is not its name's (a tool that hashed a
210
+ differently-cased or slash-separated name) leaves the entry unreachable by name. UESP's
211
+ \"Files and Dirs order\" section adds that folders and files must be sorted by these hash
212
+ values."