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,293 @@
1
+ game: baldursgate3
2
+ topic: stats.spells
3
+ title: Spell stat fields, reskinning, and spell mechanics
4
+ facts:
5
+ - id: bg3.spells.using-reskin-idiom
6
+ claim: The correct spell reskin idiom is using "<VanillaEntry>" plus override only the deltas. This
7
+ inherits animations, sounds, VFX, flags — everything you don't restate.
8
+ status: verified
9
+ verified_on: 4.73.98.727 (Patch 8)
10
+ source: ModWright field verification
11
+ tags:
12
+ - spells
13
+ - reskin
14
+ - using
15
+ - inheritance
16
+ detail: Statuses support `using` too (e.g. SHILLELAGH_DRYAD using "SHILLELAGH" restates only
17
+ Boosts). A child status inherits StackId, flags and groups; restating Boosts REPLACES the
18
+ whole line — there is no append. Never author a spell without a SpellAnimation or a `using`
19
+ parent that has one (see bg3.crash.spell-missing-spellanimation).
20
+ - id: bg3.spells.inherited-tooltip-fields
21
+ claim: Inherited tooltip fields (via `using`) carry the PARENT's data. TooltipDamageList,
22
+ DescriptionParams, TooltipUpcastDescriptionParams, and VerbalIntent all inherit. If the reskin
23
+ changes what the spell DOES, these must be cleared or overridden or the tooltip lies.
24
+ status: verified
25
+ verified_on: 4.73.98.727 (Patch 8)
26
+ source: ModWright field verification
27
+ tags:
28
+ - spells
29
+ - tooltips
30
+ - using
31
+ - inheritance
32
+ - reskin
33
+ detail: 'Observed symptoms: a slot-restore spell showed "1~10 Healing"; a Psychic reskin showed
34
+ "Thunder" upcast. Fix: override TooltipDamageList "", set the right
35
+ TooltipUpcastDescriptionParams "DealDamage(1d8,<Type>)", and fix VerbalIntent.'
36
+ - id: bg3.spells.spellsavedc-literal-only
37
+ claim: "SpellSaveDC() should be treated as taking LITERAL integer arguments only: ceil() and dynamic
38
+ Level expressions appear in zero vanilla SpellSaveDC usages (all vanilla uses are literal
39
+ ints), so a dynamic form is unverified engine syntax."
40
+ status: inferred
41
+ source: ModWright research
42
+ tags:
43
+ - spells
44
+ - save-dc
45
+ - conditions
46
+ - literal
47
+ detail: To add a scaling DC bonus, distribute hidden SpellSaveDC(1) passives across levels, or swap
48
+ one passive per tier via PassivesRemoved/PassivesAdded. A class mod ships six such passives
49
+ granted via PassivesAdded at class levels 1/3/5/7/9/11 — identical numbers to
50
+ ceil(ClassLevel/2) and multiclass-correct. The passives (not progression Boosts) form was
51
+ chosen because vanilla never carries SpellSaveDC in progression Boosts.
52
+ - id: bg3.spells.upcast-variants-auto-linked
53
+ claim: 'Upcast variants are separate _N entries with using "<base>", data "RootSpellID" "<base>",
54
+ data "PowerLevel" "N", and a higher UseCosts "...;SpellSlotsGroup:1:1:N". They are
55
+ auto-linked, NOT list-added: grant only the base and the engine offers the _N children as
56
+ upcast options.'
57
+ status: verified
58
+ verified_on: 4.73.98.727 (Patch 8)
59
+ source: ModWright field verification
60
+ tags:
61
+ - spells
62
+ - upcast
63
+ - variants
64
+ - powerlevel
65
+ - slotcosts
66
+ detail: "Works for Shout summons too, not just damage spells — a class mod's diagnostic proved
67
+ summon upcast DOES route to the _N child, so the slot→variant mechanism itself works. Two open
68
+ questions hang off the _N children: whether SpellId() in an OnCast passive sees the child id
69
+ (bg3.spells.spellid-child-id-risk) and whether a +1-target boost stacks on a child's own
70
+ AmountOfTargets (bg3.spells.modifynumberoftargets-upcast-stacking)."
71
+ - id: bg3.spells.spellpowerlevel-reads-1-under-free-cast
72
+ claim: A free-cast that replaces the spell slot
73
+ (ModifyUseCosts(Replace,SpellSlotsGroup,0,-1,SpellSlotsGroup), the Arcane-Battery idiom) makes
74
+ SpellPowerLevel read 1 for EVERY cast, regardless of the upcast level the player picked. The
75
+ upcast level is carried by the consumed slot; remove the slot and the number that reaches an
76
+ OnCast passive's functors is 1.
77
+ status: verified
78
+ verified_on: 4.73.98.727 (Patch 8)
79
+ source: ModWright field verification
80
+ tags:
81
+ - spells
82
+ - free-cast
83
+ - powerlevel
84
+ - slot-replacement
85
+ detail: "What was seen: with the free-cast toggle on, a cast at a L2 slot summoned the level-2 (3d8)
86
+ weapon and another spell at L2 hit 2 targets — the spell EFFECTS upcast correctly — but
87
+ DealDamage(SELF, MaxHP*SpellPowerLevel*15/200, Force) dealt only the level-1 amount. Assume
88
+ the same flattening hides other per-cast level reads under a slot-free cast and verify with a
89
+ marker. Workaround (Option B): replace the scaling functor with N mutually-exclusive groups,
90
+ one per slot level, each guarded by IF(SpellId('child_A') or SpellId('child_B') or ...). That
91
+ workaround's premise is itself unproven — see bg3.spells.spellid-child-id-risk."
92
+ - id: bg3.spells.spellid-child-id-risk
93
+ claim: "Unproven: whether SpellId() inside an OnCast passive matches the upcast CHILD id
94
+ (<ModSpell>_2) or only the root (<ModSpell>). Every per-slot SpellId() enumeration used to
95
+ work around the flattened SpellPowerLevel depends on it."
96
+ status: unverified
97
+ source: ModWright research
98
+ tags:
99
+ - spells
100
+ - upcast
101
+ - spellid
102
+ - powerlevel
103
+ - free-cast
104
+ - unverified
105
+ detail: "Why it is in doubt: SpellPowerLevel reading 1 under a slot-free cast proves the engine
106
+ flattens some per-cast info, so the child id may be invisible too
107
+ (bg3.spells.spellpowerlevel-reads-1-under-free-cast). Acceptance test from the source: at L4+,
108
+ with the free-cast toggle on, 27 MaxHP, cast the spell at a L2 slot → expect 4 Force
109
+ self-damage, not 2. If it is still 2, SpellId() sees only the root and the enumeration fails.
110
+ Plan B: per-child charges written into each child spell's own SpellProperties, appended to
111
+ existing effects rather than clobbering them."
112
+ - id: bg3.spells.modifynumberoftargets-upcast-stacking
113
+ claim: "Unproven: whether ModifyNumberOfTargets(AdditiveBase,1,false) inside UnlockSpellVariant
114
+ stacks additively on an upcast child's own AmountOfTargets — i.e. whether child _2 with
115
+ AmountOfTargets 2 plus a subclass +1 yields 3 targets. Confirm in-engine before relying on the
116
+ stack."
117
+ status: unverified
118
+ source: ModWright research
119
+ tags:
120
+ - spells
121
+ - upcast
122
+ - targets
123
+ - unlockspellvariant
124
+ - subclass
125
+ - unverified
126
+ detail: "Acceptance test: cast a multi-target spell at a 2nd-level slot as a level-3 member of a
127
+ subclass that grants the +1 → expect 3 targets. The mod's testing notes call this
128
+ make-or-break and document a fallback that was not built. What IS vanilla-attested is the
129
+ surrounding mechanism: an ARBITRARY SpellId('X') eligibility inside UnlockSpellVariant (Undead
130
+ Thrall Cursed Tome,
131
+ UnlockSpellVariant(SpellId('Target_CursedTome_WakeTheDead'),ModifyNumberOfTargets(AdditiveFin\
132
+ al,1,false)), SharedDev Passive.txt). There is no compound SpellId(A) or SpellId(B) inside one
133
+ UnlockSpellVariant in vanilla, so enumerate the base AND every upcast _N child separately.
134
+ AdditiveBase,1 (not AdditiveFinal) matches Sorcerer Twinned / Split-Enchantment."
135
+ - id: bg3.spells.spellid-guard-check
136
+ claim: "A hardcoded per-slot SpellId() enumeration silently rots: re-levelling, adding or removing
137
+ any slot-costed spell must update it or the charge desyncs with zero runtime error. Guard it
138
+ with a static checker that re-derives the effective UseCosts/RitualCosts set and asserts every
139
+ slot-costed non-ritual spell appears at its level."
140
+ status: verified
141
+ verified_on: 4.73.98.727 (Patch 8)
142
+ source: ModWright field verification
143
+ tags:
144
+ - spells
145
+ - powerlevel
146
+ - checker
147
+ - automation
148
+ detail: "A class mod's checker script is the reference implementation; run it before every pack, and
149
+ have the passive carry a MAINTAINERS comment pointing at it. Inclusion rule for the
150
+ enumeration: effective SpellSlotsGroup:1:1:N (own UseCosts, else resolved up the `using` chain
151
+ into vanilla) AND no effective RitualCosts — a ritual casts free via the ritual path the
152
+ slot-replacement never touches (that mod's lone ritual spell). Base spells that are themselves
153
+ >L1 must be enumerated at their base level."
154
+ - id: bg3.spells.level-conditions-in-spellproperties
155
+ claim: "Default cast-time conditions work in SpellProperties/SpellSuccess IF():
156
+ IF(ClassLevelHigherOrEqualThan(N,'Class')), IF(CharacterLevelGreaterThan(N)),
157
+ IF(HasStatus('X',context.Source)) — all evaluate against the CASTER. This is the reliable
158
+ place for character-level logic."
159
+ status: verified
160
+ verified_on: 4.73.98.727 (Patch 8)
161
+ source: ModWright field verification
162
+ tags:
163
+ - spells
164
+ - conditions
165
+ - level
166
+ - class
167
+ - spellproperties
168
+ detail: Contrast with a passive weapon-item status Boosts IF(), where CharacterLevelGreaterThan does
169
+ NOT resolve the wielder and silently never fires — see
170
+ bg3.boosts.weapon-level-gating-fails-passive. The spell evaluates in the casting context,
171
+ where the caster is known.
172
+ - id: bg3.spells.untilrest-free-cast-pattern
173
+ claim: "A 1/long-rest innate spell (racial-style, no spell slot) is the AddSpells 6th arg UntilRest:
174
+ AddSpells(<list>,,<Ability>,,AlwaysPrepared,UntilRest). The spell then casts for free once per
175
+ long rest, independent of its own UseCosts. Arg slots: (list, selectorId, saveAbility,
176
+ cooldown, prepareType, replenishType)."
177
+ status: verified
178
+ verified_on: 4.73.98.727 (Patch 8)
179
+ source: ModWright field verification
180
+ tags:
181
+ - spells
182
+ - free-cast
183
+ - rest
184
+ - addspells
185
+ detail: "Caveat: the granted spell still keeps its own effective UseCosts for other purposes — a
186
+ reskin `using` a vanilla leveled spell (e.g. Target_Knock = L2 slot) inherits that
187
+ SpellSlotsGroup, so a slot-cost-scanning check still counts it even though it is cast free via
188
+ UntilRest. One open question hangs off the grant — see bg3.spells.untilrest-levelup-card."
189
+ - id: bg3.spells.addspells-autogrant-pattern
190
+ claim: AddSpells(listUUID,,,,AlwaysPrepared) in a progression Selectors auto-grants a whole spell
191
+ list at that level with no player pick. SelectSpells(list,pick,...) makes the player choose
192
+ pick from the list.
193
+ status: verified
194
+ verified_on: 4.73.98.727 (Patch 8)
195
+ source: ModWright field verification
196
+ tags:
197
+ - spells
198
+ - addspells
199
+ - selectspells
200
+ - progression
201
+ detail: Use AddSpells for "you just get these". Note that a direct AddSpells grant renders no
202
+ level-up card — see bg3.progressions.addspells-no-levelup-card.
203
+ - id: bg3.spells.untilrest-levelup-card
204
+ claim: "Unproven: whether dropping UntilRest from a merged AddSpells grant removes the level-up card
205
+ the grant otherwise renders automatically. If it does, each granted spell needs pairing with a
206
+ display-only Highlighted;ForceShowInCC passive to keep its Class Features card."
207
+ status: unverified
208
+ source: ModWright research
209
+ tags:
210
+ - spells
211
+ - addspells
212
+ - untilrest
213
+ - levelup-card
214
+ - progressions
215
+ - unverified
216
+ detail: "The question arises when a 1/long-rest innate spell is converted to the
217
+ custom-ActionResource recharge pattern, which drops UntilRest from the grant in favour of an
218
+ explicit UseCosts token. Acceptance test implied by the source: level a character through the
219
+ node that carries the merged grant and check whether the granted spell still renders a Class
220
+ Features card at level-up. The remedy if it does not is the display-only passive described in
221
+ bg3.progressions.addspells-no-levelup-card."
222
+ - id: bg3.spells.child-status-inherits-parent-stackid-and-is-replaced-by-it
223
+ claim: "A StatusData entry that `using`s a vanilla status without restating StackId shares the
224
+ parent's stack: applying the parent afterwards removes the child (the combat log shows \"lost
225
+ <child>\" immediately before \"received <parent>\"). A scaffolded or reskinned status that
226
+ should coexist with its parent needs its own `data \"StackId\"`."
227
+ status: verified
228
+ verified_on: 4.73.98.727 (Patch 8)
229
+ source: ModWright field verification
230
+ tags:
231
+ - statuses
232
+ - using
233
+ - stackid
234
+ - inheritance
235
+ - scaffold
236
+ related:
237
+ - bg3.spells.using-reskin-idiom
238
+ detail: An earlier application with duration 12.0 was already gone at its first read 27 seconds
239
+ later, before any BLESS was applied; that is the duration expiring out of combat, not the
240
+ stack. The engine's StackId semantics (same id replaces) are the vanilla rule; the observation
241
+ here is that `using` carries the id across.
242
+ - id: bg3.spells.empty-statuspropertyflags-value-is-a-vanilla-form-and-keeps-the-status-visible
243
+ claim: '`data "StatusPropertyFlags" ""` is a form vanilla StatusData uses (30 entries carry the
244
+ empty value in the Patch 8 stats, beside the 622 carrying
245
+ "DisableOverhead;DisableCombatlog;DisablePortraitIndicator"), the extender reads it back as an
246
+ empty flag set, and a status written that way shows on the portrait under its own name and
247
+ writes its "received Condition" line to the combat log.'
248
+ status: verified
249
+ verified_on: 4.73.98.727 (Patch 8)
250
+ source: ModWright field verification
251
+ tags:
252
+ - statuses
253
+ - statuspropertyflags
254
+ - scaffold
255
+ - vanilla-precedent
256
+ detail: The scaffold's `statusPropertyFlags` input defaults to empty and is written as this line
257
+ rather than omitted, on the strength of the vanilla count; the two are not known to differ in
258
+ effect, only the written form was observed.
259
+ - id: bg3.spells.statuspropertyflags-combatlog-flag-is-spelt-disablecombatlog
260
+ claim: 'The StatusPropertyFlags value that hides a status from the combat log is DisableCombatlog
261
+ (lower-case l). "DisableCombatLog" is not recognised: a status carrying
262
+ "DisableCombatLog;DisableOverhead;DisablePortraitIndicator" still wrote "received Condition"
263
+ lines to the combat log.'
264
+ status: verified
265
+ verified_on: 4.73.98.727 (Patch 8)
266
+ source: ModWright field verification
267
+ tags:
268
+ - statuses
269
+ - statuspropertyflags
270
+ - combat-log
271
+ - spelling
272
+ - scaffold
273
+ detail: "Whether the engine drops the whole flags string or only the unknown token was not
274
+ separated: the overhead text was not watched for, and by the time the portrait was read the
275
+ status had already been replaced by its parent, so DisableOverhead and
276
+ DisablePortraitIndicator are untested here."
277
+ - id: bg3.spells.createexplosion-projectile-needs-a-donor-with-a-rendering-effect-chain
278
+ claim: "A Projectile entry written from scratch (no `using`) and fired through CreateExplosion(...)
279
+ deals its damage silently: no effect, no sound. Basing it on Projectile_Fireball (`using
280
+ \"Projectile_Fireball\"` with SpellRoll/SpellSuccess/SpellFail/UseCosts blanked and
281
+ SpellProperties, ExplodeRadius and TargetConditions overridden) keeps Fireball's CastSound and
282
+ HitEffect — the recipe a class mod's explosion spell uses, the one CreateExplosion chain
283
+ confirmed to render. Not every projectile renders through CreateExplosion (a biped Steel
284
+ Watcher attempt in that mod did not)."
285
+ status: verified
286
+ verified_on: 4.73.98.727 (Patch 8)
287
+ source: ModWright field verification
288
+ tags:
289
+ - spells
290
+ - projectile
291
+ - createexplosion
292
+ - vfx
293
+ - fireball
@@ -0,0 +1,210 @@
1
+ game: baldursgate3
2
+ topic: stats.weapons
3
+ title: Custom summoned weapons, damage scaling, actions, and properties
4
+ facts:
5
+ - id: bg3.weapons.summoned-custom-recipe
6
+ claim: "To summon a weapon with custom damage TYPE you need a custom Weapon stat + a custom
7
+ RootTemplate (no boost can change base damage type). The template is authored at
8
+ Public/<Mod>/RootTemplates/_merged.lsx and shipped as _merged.lsf; the weapon stat lives in
9
+ Public/<Mod>/Stats/Generated/Data/Weapon.txt. Two-way link: the template's Stats field points
10
+ at the weapon stat, the weapon stat's RootTemplate points at the template UUID."
11
+ status: verified
12
+ verified_on: 4.73.98.727 (Patch 8)
13
+ source: ModWright field verification
14
+ tags:
15
+ - weapons
16
+ - summoned
17
+ - custom
18
+ - roottemplate
19
+ - damage-type
20
+ detail: "Recipe: (1) extract a vanilla weapon's GameObject from a pak's
21
+ Public/<Mod>/RootTemplates/_merged.lsf (the weapon STAT tells you which mod dir), convert to
22
+ lsx, grep the template UUID, copy that one <node id=\"GameObjects\"> block. (2) Author your
23
+ template wrapped in <save><region id=\"Templates\"><node id=\"Templates\"><children>, changing
24
+ MapKey (new UUID), Name and Stats; REUSE the vanilla VisualTemplate, PhysicsTemplate, Icon and
25
+ Bounds for a placeholder look. Convert lsx→_merged.lsf and ship only the .lsf. (3) Weapon
26
+ stat: using \"<vanilla base>\", data \"RootTemplate\" \"<template UUID>\", override Damage
27
+ Type / Damage / DefaultBoosts, fresh ValueUUID. (4) Summon:
28
+ SummonInInventory(<templateUUID>,-1,1,true,true,true,,,STATUS_A,STATUS_B,...) — -1 duration =
29
+ permanent, and it accepts MULTIPLE trailing statuses (vanilla: ...,PactBlade,PACT_BLADE)."
30
+ - id: bg3.weapons.pact-blade-pattern
31
+ claim: PACT_BLADE (SharedDev Status_BOOST) is the canonical "bound weapon" status to model —
32
+ WeaponProperty(Magical);IntrinsicSummonerProficiency();IntrinsicSourceProficiency();ItemReturnToOwner();
33
+ Attribute(InventoryBound);WeaponAttackRollAbilityOverride(Charisma);CannotBeDisarmed(). Omit
34
+ ItemReturnToOwner() if the weapon shouldn't return when thrown.
35
+ status: verified
36
+ verified_on: 4.73.98.727 (Patch 8)
37
+ source: ModWright field verification
38
+ tags:
39
+ - weapons
40
+ - summoned
41
+ - boosts
42
+ - proficiency
43
+ - disarm
44
+ detail: Apply it (or a trimmed copy) as a SummonInInventory trailing status. Custom RootTemplates
45
+ work and don't crash if the structure is valid — the risky-sounding part is routine once you
46
+ copy a vanilla node.
47
+ - id: bg3.weapons.summoned-damage-scaling-finicky
48
+ claim: Scaling a summoned weapon's damage die by slot is finicky. WeaponDamageDieOverride(Nd8) does
49
+ NOT reliably apply; typeless WeaponDamage(Nd8) silently does NOT register either; only TYPED
50
+ WeaponDamage(Nd8, <Type>) applies. For a clean single-die display the reliable route is a
51
+ separate per-slot weapon stat + RootTemplate with the damage baked in, summoned by the
52
+ matching upcast child.
53
+ status: verified
54
+ verified_on: 4.73.98.727 (Patch 8)
55
+ source: ModWright field verification
56
+ tags:
57
+ - weapons
58
+ - summoned
59
+ - damage
60
+ - scaling
61
+ - upcast
62
+ detail: Verbose (6 slot tiers × N elements) but rock-solid and clean — a single die like 3d8 instead
63
+ of "2d8 + 1d8". A class mod shipped 18 per-slot weapon stats (3 elements × 6 slot tiers) plus
64
+ 18 generated RootTemplates, with all 18 summon children repointed at their per-slot template.
65
+ The same diagnostic confirmed summon upcast DOES route to the _N child, so the slot→variant
66
+ mechanism itself works.
67
+ - id: bg3.weapons.charisma-attack-roll-override
68
+ claim: WeaponAttackRollAbilityOverride(Charisma) makes attacks use CHA to-hit. BG3 then adds that
69
+ same ability modifier to DAMAGE automatically (like a pact weapon) — you get CHA-to-damage
70
+ "for free" and must BlockAbilityModifierDamageBonus() to suppress it.
71
+ status: verified
72
+ verified_on: 4.73.98.727 (Patch 8)
73
+ source: ModWright field verification
74
+ tags:
75
+ - weapons
76
+ - charisma
77
+ - attack-roll
78
+ - ability-modifier
79
+ detail: WeaponAttackRollAbilityOverride(SpellCastingAbility) also exists (uses the class's
80
+ spellcasting ability), and WeaponEnchantment(N) = "+N weapon" (visible +N to hit/damage AND
81
+ counts as magical). A class mod suppresses CHA-to-damage on the S1–S3 slot tiers with
82
+ BlockAbilityModifierDamageBonus() and leaves it active S4+, because character level cannot be
83
+ read in weapon boosts.
84
+ - id: bg3.weapons.weapon-actions-from-stat-unlocks
85
+ claim: Weapon actions (Flourish, Piercing Strike, Pommel Strike, Whirlwind…) are added via the
86
+ weapon stat's BoostsOnEquipMainHand "UnlockSpell(<actionSpell>)". Default weapon actions come
87
+ from the weapon TYPE, not the stat, and setting BoostsOnEquipMainHand REPLACES the
88
+ type-default action set.
89
+ status: verified
90
+ verified_on: 4.73.98.727 (Patch 8)
91
+ source: ModWright field verification
92
+ tags:
93
+ - weapons
94
+ - actions
95
+ - unlockspell
96
+ - boosts
97
+ detail: The earlier belief that BoostsOnEquipMainHand only ADDS and that removing type defaults
98
+ needs Script Extender was WRONG for this case. To curate a weapon's actions, list exactly the
99
+ ones you want; the type defaults drop. To KEEP some standard actions, re-list them
100
+ (UnlockSpell(Target_PommelStrike);UnlockSpell(Rush_SpringAttack); UnlockSpell(<custom>)) —
101
+ which is exactly what vanilla magic weapons do. Whirlwind = Shout_MAG_WhirlwindAttack (using
102
+ Shout_Whirlwind, IsDefaultWeaponAction, short-rest recharge).
103
+ - id: bg3.weapons.reach-is-weapon-property
104
+ claim: Reach (Glaive/Halberd/Pike) is a "Weapon Properties" entry on the stat, NOT a boost — so
105
+ extended reach requires editing the weapon stat's properties, i.e. a custom weapon stat.
106
+ status: verified
107
+ verified_on: 4.73.98.727 (Patch 8)
108
+ source: ModWright field verification
109
+ tags:
110
+ - weapons
111
+ - reach
112
+ - properties
113
+ detail: A class mod added Reach to its weapon's Weapon Properties
114
+ ("Finesse;Light;Melee;Dippable;Reach"); reach was confirmed at L2 in a later test batch.
115
+ - id: bg3.weapons.attack-spell-override
116
+ claim: A custom basic-attack animation uses AttackSpellOverride(<CustomAttack>,
117
+ Target_MainHandAttack) in BoostsOnEquipMainHand. Author <CustomAttack> as using
118
+ "Target_MainHandAttack" and override its SpellAnimation (+ sounds) to the desired motion. It
119
+ still deals MainMeleeWeapon damage, runs ExecuteWeaponFunctors and dual-wields — a real weapon
120
+ attack, just re-animated.
121
+ status: verified
122
+ verified_on: 4.73.98.727 (Patch 8)
123
+ source: ModWright field verification
124
+ tags:
125
+ - weapons
126
+ - animations
127
+ - attack-override
128
+ - custom
129
+ detail: "The mechanism was learned from the Whips Expanded mod (#19277), which uses it to make
130
+ functional whips with no custom animations, and then re-implemented self-contained: a class
131
+ mod's own attack spell copies the whip SpellAnimation and ThornWhip sounds (vanilla animation
132
+ UUIDs, so no dependency on their spell entry). Caveat: AttackSpellOverride basic attacks run
133
+ the override's mechanics but fire NONE of its cast VFX/animation — only a real cast (an
134
+ UnlockSpell'ed action) plays those."
135
+ - id: bg3.weapons.custom-equipment-type
136
+ claim: A custom EquipmentType (Public/<Mod>/EquipmentTypes/EquipmentTypes.lsx, region
137
+ EquipmentTypes) defines idle/sheath handling and the fallback animation set via
138
+ WeaponType_OneHanded (Slashing1H, Sling1H = the throw/whip look, …) plus sheath bones
139
+ (Dummy_Sheath_Hip_L for hip). A weapon's RootTemplate points at it via EquipmentTypeID (the
140
+ type's UUID).
141
+ status: community
142
+ source: https://www.nexusmods.com/baldursgate3/mods/19277
143
+ tags:
144
+ - weapons
145
+ - equipment-type
146
+ - animation
147
+ - sheath
148
+ detail: A class mod consumed Whips Expanded's EquipmentTypeID (e9b4ae39) on all 18 of its weapon
149
+ templates for testing and wrote its own drop-in stub (UUID
150
+ 30d6bb2d-327d-5270-94d1-1ff1e50d296f), but its notes record swapping to that own EquipmentType
151
+ as the "ONLY BEFORE-RELEASE ITEM LEFT" — so authoring and loading a mod's own EquipmentType
152
+ was never observed here. Referencing an external one also creates a hard load-order dependency
153
+ (see bg3.loadorder.external-guid-dependencies).
154
+ - id: bg3.weapons.no-new-base-weapon-type
155
+ claim: 'There is no new base weapon TYPE in BG3, but you can fake one: whips use Proficiency Group
156
+ "Flails;SimpleWeapons", Weapon Properties "Finesse;Reach;Melee;Dippable", a custom
157
+ EquipmentType for handling, and AttackSpellOverride for the lash. That is the whole "whip" —
158
+ an existing proficiency + a re-animated attack + a model/EquipmentType.'
159
+ status: verified
160
+ verified_on: 4.73.98.727 (Patch 8)
161
+ source: ModWright field verification
162
+ tags:
163
+ - weapons
164
+ - proficiency
165
+ - properties
166
+ - custom
167
+ detail: BG3 has no whip weapon type and no whip animations — a whip model swings on a finesse-weapon
168
+ animation set. A brand-new MODEL (not a reskin) is a Blender→GR2 job in BG3's own GR2 flavour,
169
+ a separate and much larger effort. The EquipmentType half of this recipe is the part not
170
+ proven here — see bg3.weapons.custom-equipment-type.
171
+ - id: bg3.weapons.weapon-category-gated-equipment-bonus
172
+ claim: IF(IsWeaponOfProficiencyGroup('Flails', GetAttackWeapon()) and
173
+ IsMeleeWeaponAttack()):RollBonus(Attack, 1) in an equip passive's Boosts WORKS, despite having
174
+ no vanilla precedent — vanilla only ever uses IsWeaponOfProficiencyGroup in spell/interrupt
175
+ conditions and ships zero weapon-category attack items.
176
+ status: verified
177
+ verified_on: 4.73.98.727 (Patch 8)
178
+ source: ModWright field verification
179
+ tags:
180
+ - weapons
181
+ - equipment
182
+ - proficiency-group
183
+ - conditions
184
+ - bonus
185
+ detail: "Group string = the Proficiency Group value; pipe-separated multi-group works in the vanilla
186
+ spell usages ('Clubs|Quarterstaffs'). Unattested tokens like this one are exactly the case for
187
+ pairing a diagnostic with the first attempt (see bg3.practice.unproven-token-verification).
188
+ Note a conflicting note in the same source: an earlier design note records the gloves' LOOK as
189
+ verified but the \"+1 mechanic still untested\"; a later distillation states the mechanic as
190
+ verified in-game."
191
+ - id: bg3.weapons.proficiency-on-the-weapon
192
+ claim: 'A weapon can grant its own proficiency: data "Boosts" "Proficiency(Glaives)" on the Weapon
193
+ stat (vanilla WPN_Glaive_Pact does exactly this), and/or an equip passive whose Boosts carry
194
+ "Proficiency(...)" plus a Highlighted card (vanilla MAG_OfArchery_Gloves_Passive:
195
+ Proficiency(Longbows);Proficiency(Shortbows)). Proficiency(<group>) takes the Proficiency
196
+ Group name.'
197
+ status: unverified
198
+ source: ModWright research
199
+ tags:
200
+ - weapons
201
+ - proficiency
202
+ - boosts
203
+ - passive
204
+ - equipment
205
+ related:
206
+ - id: bg3.weapons.no-new-base-weapon-type
207
+ detail: The group name in Proficiency(<group>) is the same Proficiency Group value that fact uses.
208
+ detail: The stat-side Boosts route needs no passive and no card; the passive route is what vanilla
209
+ uses when the proficiency should be visible in the tooltip. Either way the token is the
210
+ Proficiency Group (Glaives, Longbows, ...), not the weapon stat name.