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,629 @@
1
+ game: cyberpunk2077
2
+ topic: anims.graph
3
+ title: player_melee.animgraph / player_base.animgraph serialization and state-to-clip mapping
4
+ facts:
5
+ - id: cp2077.anims.graph.serialize-graphs-for-ground-truth
6
+ claim: Serializing player_melee.animgraph and player_base.animgraph with `WolvenKit convert
7
+ serialize` produces roughly 16 MB of JSON that answers state-to-clip and post-pass questions
8
+ in minutes; this is the reliable way to find out which clips actually play and which weight
9
+ sources drive a post-pass, rather than inferring either from clip names or record fields.
10
+ status: inferred
11
+ source: ModWright research
12
+ tags:
13
+ - animgraph
14
+ - serialize
15
+ - wolvenkit
16
+ - ground-truth
17
+ - state-to-clip
18
+ detail: Used to settle, among other things, that the state->clip mapping the project had assumed was
19
+ wrong twice (hold_loop_01 was assumed to be the standing base; melee_safepose, not
20
+ melee_crouchpose, is what crouch-still settles into).
21
+ - id: cp2077.anims.graph.record-index-equals-clip-index
22
+ claim: "One counter drives both the TweakDB attack record lookup and the clip CSV lookup:
23
+ meleeTransitions.script concatenates stateName + attackNumber to fetch the record (GetAttack),
24
+ and the same meleeAttackNumber value is written into slotData.comboNumber to select the clip."
25
+ status: inferred
26
+ source: ModWright research
27
+ tags:
28
+ - attacknumber
29
+ - record-lookup
30
+ - clip-lookup
31
+ - slotdata
32
+ - combonumber
33
+ detail: This is why the record and clip always stay in lockstep as the attack counter advances
34
+ through a chain.
35
+ - id: cp2077.anims.graph.five-swing-chain-old-belief
36
+ claim: An earlier project note stated that AttacksNumber = 4 produces a "5-swing chain" (4 combo
37
+ hits plus a Final attack).
38
+ status: contradicted
39
+ source: ModWright research
40
+ tags:
41
+ - attacksnumber
42
+ - swing-count
43
+ - off-by-one
44
+ - dead-belief
45
+ detail: Off by one. See cp2077.anims.graph.attacksnumber-n-gives-n-swings for the corrected rule,
46
+ confirmed independently by two script reachability analyses and matching both the user's own
47
+ 4-swing spec and an in-game log reading "COMBO 0 / COMBO 1 / COMBO 2 / FINAL counter=3".
48
+ - id: cp2077.anims.graph.attacksnumber-n-gives-n-swings
49
+ claim: "AttacksNumber = N gives exactly N total swings: combo attacks occupy counters 0..N-2 and the
50
+ FINAL attack occupies counter N-1 (CheckIfFinalAttack evaluates to (counter+1) >=
51
+ AttacksNumber, checked against the counter BEFORE it increments)."
52
+ status: inferred
53
+ supersedes: cp2077.anims.graph.five-swing-chain-old-belief
54
+ source: ModWright research
55
+ tags:
56
+ - attacksnumber
57
+ - swing-count
58
+ - combo
59
+ - final-attack
60
+ detail: Raising AttacksNumber to N requires a record named MeleeFinalAttack(N-1); the combo record
61
+ at that same index is never consulted, because the final-attack transition list is evaluated
62
+ before the combo-attack list (see cp2077.anims.graph.final-wins-over-combo-at-boundary).
63
+ - id: cp2077.anims.graph.final-wins-over-combo-at-boundary
64
+ claim: At the top attack counter, both a combo-attack state and the final-attack state can be
65
+ enterable (a weapon family may author a combo record at that same index too), but the
66
+ final-attack state wins because statemachine_melee.tweak lists allMeleeFinalAttacks BEFORE
67
+ allMeleeComboAttacks in the meleeComboAttack.transitionTo array.
68
+ status: inferred
69
+ source: ModWright research
70
+ tags:
71
+ - final-attack
72
+ - combo-attack
73
+ - transition-order
74
+ - state-machine-priority
75
+ detail: No explicit priority/weight field was found on transitionTo entries (every
76
+ transitionCondition is an empty string), so ordered-list evaluation is inferred rather than
77
+ directly read off a priority field; it is corroborated by vanilla behavior at a lower
78
+ AttacksNumber and by the mod's own in-game log showing FINAL winning at the top counter.
79
+ - id: cp2077.anims.graph.hit-deflect-variant-selection-is-reactive
80
+ claim: The _hit and _deflect clip variants are chosen by two sibling PSM states inside Attack
81
+ (Attack -> Hit on CompositeSimultaneous[BoolFeature(MeleeData.hasHitAnim==1),
82
+ ExternalEvent(MeleeHitNPC)]; Attack -> Deflect similarly on MeleeHitStatic), each reading its
83
+ own CSV keyed by the SAME (attackType, comboNumber) pair as the base clip; selection is
84
+ reactive, on contact, not predictive.
85
+ status: inferred
86
+ source: ModWright research
87
+ tags:
88
+ - hit-variant
89
+ - deflect-variant
90
+ - csv
91
+ - reactive-selection
92
+ - crossfade
93
+ detail: Crossfade to Hit is 0.0667 s, to Deflect 0.0333 s. A swing that connects with nothing plays
94
+ the base clip to the end and never touches either variant.
95
+ - id: cp2077.anims.graph.hashitanim-hasdeflectanim-flags
96
+ claim: hasHitAnim and hasDeflectAnim both default to false in the Attack_Melee schema; Attacks.Slash
97
+ sets both true, and MacheteComboAttackAbstract / MacheteFinalAttackAbstract both derive from
98
+ Slash without overriding, so every light-chain swing built on that lineage needs both a _hit
99
+ and a _deflect variant authored.
100
+ status: inferred
101
+ source: ModWright research
102
+ tags:
103
+ - hashitanim
104
+ - hasdeflectanim
105
+ - slash
106
+ - variant-requirement
107
+ detail: For contrast, MacheteStrongAttackAbstract sets hasDeflectAnim=false / hasHitAnim=true, so a
108
+ heavy attack on that lineage needs only a _hit variant, not a _deflect one.
109
+ - id: cp2077.anims.graph.gameplay-hit-timing-is-record-side-only
110
+ claim: "Gameplay hit timing is 100% record-side and clip-independent: MeleeAttackEvents.OnUpdate
111
+ fires the hit the instant GetInStateTime() >= attackData.attackEffectDelay; no animEvent in
112
+ the clip gates it, so nothing an authored clip does can move when the gameplay hit lands —
113
+ only editing the record's attackEffectDelay can."
114
+ status: inferred
115
+ source: ModWright research
116
+ tags:
117
+ - gameplay-hit
118
+ - attackeffectdelay
119
+ - record-side
120
+ - clip-independent
121
+ detail: This is why the project routinely clones a record (e.g. the ComboAttack1 pattern) purely to
122
+ change attackEffectDelay when a swing's contact frame needs to move, rather than trying to
123
+ move an animEvent in the clip.
124
+ - id: cp2077.anims.graph.combo-pacing-is-clip-independent-via-retimer
125
+ claim: "The visual pacing of a combo swing is also largely clip-independent: the Attack Switch's
126
+ blend weight is literally the expression string `\"input > 0\"` over `\"startupDuration +
127
+ activeDuration + recoverDuration\"` (read directly out of the serialized animgraph JSON, no
128
+ bytecode decoding needed); a positive sum selects a three-segment retimer driven by the clip's
129
+ own animAnimEvent_Phase markers, so every combo swing under the machete records plays at a
130
+ fixed 1.834 s on screen regardless of the donor clip's own authored length."
131
+ status: inferred
132
+ source: ModWright research
133
+ tags:
134
+ - combo-attack
135
+ - retimer
136
+ - phase-marker
137
+ - expression-string
138
+ - pacing
139
+ detail: The retimer stretches the katana clips' three segments by 1.5x-2.7x per segment to hit the
140
+ fixed total. The machete FINAL leaves all three durations at 0/0/0, which routes it to a
141
+ whole-clip 1:1 path instead of the retimer.
142
+ - id: cp2077.anims.graph.melee-idlepose-is-universal-terminal-hub
143
+ claim: All 43 vanilla katana attack clips (15 base + 14 _hit + 14 _deflect) end EXACTLY on
144
+ melee_idlepose frame 0 (worst measured deviation 0.155 mm on drawn bones, 0.179 mm over all
145
+ 152 bones); melee_idlepose, a 2-frame static pose, is the universal terminal hub for the whole
146
+ melee state machine — block_end, melee_crouch_to_idle, melee_safe_to_idle, melee_slide_end,
147
+ melee_equip and melee_sprint_stop all land on it too.
148
+ status: inferred
149
+ source: ModWright research
150
+ tags:
151
+ - melee_idlepose
152
+ - terminal-pose
153
+ - recovery
154
+ - universal-hub
155
+ detail: This measured convention is what makes "end every authored swing on our own re-posed idle"
156
+ the correct terminal target for a custom weapon's chain.
157
+ - id: cp2077.anims.graph.attack-clips-start-at-launching-states-own-pose
158
+ claim: "Attack clips do NOT share a common start pose; each starts exactly at the pose of the state
159
+ that launched it (idle, crouchpose, block, hold_loop, or safepose). Measured spread of
160
+ base-attack START poses across the whole set: median 331 mm / 114 degrees at RightHand, max
161
+ 713 mm / 180 degrees."
162
+ status: inferred
163
+ source: ModWright research
164
+ tags:
165
+ - attack-clip
166
+ - start-pose
167
+ - launching-state
168
+ - no-shared-start
169
+ detail: "Concrete pairings measured: combo_attack_01 and jump_attack open at the idle; crouch_attack
170
+ at melee_crouchpose; block_attack at block; heavy_attack_01/02 at hold_loop_01/02; safe_attack
171
+ and sprint_attack at melee_safepose."
172
+ - id: cp2077.anims.graph.attack-clips-are-full-body-base-clips-not-additives
173
+ claim: Combo/heavy/final attack clips are full-body BASE clips (convertToAdditive = 0 on all 12 live
174
+ AnimDatabase nodes measured), a different node class from the ambient sway additives; despite
175
+ this, all 43 vanilla attack clips still hold Root/Trajectory/Hips/Spine..Spine3/
176
+ Neck/Head/legs at exact identity for their whole duration, moving only shoulder translations,
177
+ the arm chains, the weapon/gun-space/IK bones, and the FPP camera joints.
178
+ status: inferred
179
+ source: ModWright research
180
+ tags:
181
+ - attack-clip
182
+ - base-clip
183
+ - additive
184
+ - torso
185
+ - spine
186
+ - convert-to-additive
187
+ detail: Because these are base clips, not additives, the engine-limit rule that an FPP ADDITIVE only
188
+ reaches LeftArm/RightArm and below does not apply to them — Spine3 and the shoulders are
189
+ technically reachable in an attack clip, even though vanilla itself never uses that reach
190
+ (treated as a design convention per
191
+ cp2077.anims.method.additive-silence-rule-is-scoped-to-additives).
192
+ - id: cp2077.anims.graph.engine-cuts-in-a-window-not-at-authored-join-frame
193
+ claim: The engine does not cut a chained attack at the frame animators put the successor's frame 0
194
+ at; MeleeAttackGenericDecisions.ExitCondition allows exiting into the next attack (or
195
+ block/idle/a parry) any time state-time falls within [attackWindowClosed, idleTransitionTime]
196
+ once the matching input is pressed, so a late-chaining player can land up to 174 mm off the
197
+ authored join pose (measured on one swing's mapped cut window).
198
+ status: inferred
199
+ source: ModWright research
200
+ tags:
201
+ - cut-window
202
+ - exitcondition
203
+ - attackwindowclosed
204
+ - chain-pop
205
+ - late-chain
206
+ detail: A player who mashes the input cuts at the earliest allowed frame and lands on the authored
207
+ join almost exactly (0.0-0.3 mm on two measured swings); a player who chains late can pop by
208
+ up to 174 mm. Whether vanilla itself pops this way on a very late cut (measured up to 568 mm
209
+ under katana records) is unresolved — see
210
+ cp2077.anims.graph.inertialization-fields-unexercised.
211
+ - id: cp2077.anims.graph.inertialization-fields-unexercised
212
+ claim: animAnimNode_AnimDatabase nodes carry applyInertializationOnAnimSetSwap and pushSafeCutTag
213
+ fields that were found in the serialized graph but never investigated or exercised; whether
214
+ vanilla itself visibly pops on a very late chain cut, or some inertialization path smooths it,
215
+ is an open, unresolved question.
216
+ status: unverified
217
+ source: ModWright research
218
+ tags:
219
+ - inertialization
220
+ - animdatabase
221
+ - pushsafecuttag
222
+ - open-question
223
+ detail: "Proposed cheapest offline experiment: play the vanilla katana chain in Blender exactly as
224
+ the engine would sequence it (hard cut mid-clip to the next clip's frame 0) and see whether it
225
+ visibly pops there too."
226
+ - id: cp2077.anims.graph.entry-transition-is-hard-cut-zero-duration
227
+ claim: The global transition INTO the Attack state has duration 0 and canRequestInertialization 0
228
+ (also supportBlendFromPose 0), so if the current idle's grip pose differs from the launching
229
+ attack clip's own frame-0 pose, the very first rendered frame of the attack snaps
230
+ instantaneously with no blend.
231
+ status: inferred
232
+ source: ModWright research
233
+ tags:
234
+ - entry-transition
235
+ - hard-cut
236
+ - inertialization
237
+ - attack-entry
238
+ detail: "Measured concretely on this mod before its attack clips were re-authored: the re-posed
239
+ idle's grip span (0.5124 m) vs the pristine katana attack clips' own frame-0 span (0.0929 m)
240
+ is a 0.4195 m difference at the same joint — an instantaneous 0.42 m hand snap on the first
241
+ frame of any light attack, until the attack clip's own frame 0 was re-authored to match."
242
+ - id: cp2077.anims.graph.no-root-motion-in-melee-attack-clips
243
+ claim: motionExtraction is null and modelSpacePositionX/Y/Z are constant zero on every
244
+ combo/final/heavy clip across all nine measured player-FPP melee donor sets; there is no root
245
+ motion of any kind in a vanilla melee attack clip.
246
+ status: inferred
247
+ source: ModWright research
248
+ tags:
249
+ - root-motion
250
+ - motionextraction
251
+ - model-space-position
252
+ - no-root-motion
253
+ detail: "Practical consequence: any forward step, lunge or displacement for a custom finisher has to
254
+ be authored at the record/script level (e.g. RequestPlayerPositionAdjustment /
255
+ AddAttackImpulse), never via clip translation."
256
+ - id: cp2077.anims.graph.melee-fpp-arms-are-pure-fk
257
+ claim: "Melee FPP arms are pure FK: the left-arm animAnimNode_Ik2 in player_base.animgraph is
258
+ weight-gated by the ikLeftArm anim feature, which vanilla scripts raise ONLY for climbing
259
+ (locomotionTransitions.script:3457); the Ik2Constraint node itself lives in the Vault state,
260
+ not in any melee state."
261
+ status: inferred
262
+ source: ModWright research
263
+ tags:
264
+ - ik2
265
+ - ikleftarm
266
+ - fk
267
+ - vault-state
268
+ - anim-feature
269
+ detail: This was proven "without a launch" specifically by grepping tools\redmod\scripts for who
270
+ raises the anim feature, rather than assuming from graph structure alone (see
271
+ cp2077.anims.method.grep-anim-feature-source-in-redmod-scripts).
272
+ - id: cp2077.anims.graph.left-ik-jnt-overwritten-by-multipleparentconstraint
273
+ claim: Torso_LeftArm_Hand_IK_JNT is overwritten every frame by a weight-1 MultipleParentConstraint
274
+ blending arm_left_ik_offset (the gun-space chain) against Torso_World_LeftArm_Hand_IK_JNT via
275
+ the leftHandWorldSpace float track, which every vanilla clip holds at exactly 0 — so the
276
+ constraint's effective target is always arm_left_ik_offset, and any rotation or position
277
+ authored directly onto Torso_LeftArm_Hand_IK_JNT is discarded at runtime.
278
+ status: inferred
279
+ source: ModWright research
280
+ tags:
281
+ - torso-leftarm-hand-ik-jnt
282
+ - multipleparentconstraint
283
+ - lefthandworldspace
284
+ - gun-space
285
+ detail: Keep clip data on these JNT targets anyway — vault/climb states do read them, and matching
286
+ the vanilla invariant (leftHandWorldSpace held at 0) is what keeps melee behavior unaffected.
287
+ - id: cp2077.anims.graph.ik2-rebuilds-left-arm-from-cached-effector
288
+ claim: animAnimNode_Ik2, in the main (not state-gated) flow of player_base.animgraph, rebuilds
289
+ LeftArm/LeftForeArm every frame so that LeftHand reaches an effector cached from
290
+ Torso_LeftArm_Hand_IK_JNT; consequently, the in-game left-hand POSITION follows the clip's
291
+ arm_left_ik_offset target, not whatever pose is directly authored onto LeftArm/LeftForeArm.
292
+ status: inferred
293
+ source: ModWright research
294
+ tags:
295
+ - ik2
296
+ - left-arm
297
+ - effector
298
+ - arm-left-ik-offset
299
+ - gun-space
300
+ detail: This discovery is the reason the project's sway-measurement tooling switched to measuring
301
+ "what the engine will draw" (the ik target in gun space) rather than the authored LeftHand
302
+ bone, and it is the mechanistic root of why authoring an arm-only fix into the sway additive
303
+ could never have worked (see
304
+ cp2077.anims.authoring.no-base-independent-fix-for-full-ambient-sway).
305
+ - id: cp2077.anims.graph.block-never-sees-additives-old-belief
306
+ claim: An earlier project comment/belief held that the Block state never sees the ambient sway
307
+ additive machine — i.e. that a different, separate additive plays while blocking.
308
+ status: contradicted
309
+ source: ModWright research
310
+ tags:
311
+ - block-state
312
+ - ambient-sway
313
+ - dead-belief
314
+ - stale-comment
315
+ detail: Retracted the same session it was disproven — the stale comment "nearly derailed the graph
316
+ reading" per the project's own working-method notes.
317
+ - id: cp2077.anims.graph.block-runs-same-additive-machine-as-idle
318
+ claim: "The Block state runs the exact SAME ambient-sway additive machine at the same weight (1) as
319
+ the standing idle: base melee_idlepose plus add_melee_idle out of combat, damped-blended to
320
+ add_melee_idle_combat in combat — the same instances also drive Ready, Targeting Throwable and
321
+ bodyslam."
322
+ status: inferred
323
+ supersedes: cp2077.anims.graph.block-never-sees-additives-old-belief
324
+ source: ModWright research
325
+ tags:
326
+ - block-state
327
+ - ambient-sway
328
+ - additive-machine
329
+ - ready-state
330
+ detail: This is why the sway fix (SWAY_GUNROT_CONST) helps the block's already-good reading too, and
331
+ why the block reading identical to the idle's under a shared additive was the strongest early
332
+ clue toward the eventual encoder root cause.
333
+ - id: cp2077.anims.graph.hold-loop-is-attack-charge-old-belief
334
+ claim: An earlier hypothesis treated hold_loop_01 as a possible better candidate for "what plays
335
+ while standing" than melee_idlepose, since it is a 21-frame loop rather than a 2-frame static
336
+ pose.
337
+ status: contradicted
338
+ source: ModWright research
339
+ tags:
340
+ - hold-loop
341
+ - standing-base
342
+ - dead-belief
343
+ detail: Struck in place per the project's own doc-hygiene practice, so a later reader landing on the
344
+ open-questions section would not re-author against the wrong base.
345
+ - id: cp2077.anims.graph.hold-loop-is-attack-charge-not-standing-base
346
+ claim: hold_loop_01/02 is the ATTACK-CHARGE hold, entered via Ready > Hold on MeleeData.isHolding,
347
+ not the standing idle base.
348
+ status: inferred
349
+ supersedes: cp2077.anims.graph.hold-loop-is-attack-charge-old-belief
350
+ source: ModWright research
351
+ tags:
352
+ - hold-loop
353
+ - attack-charge
354
+ - meleedata-isholding
355
+ - ready-state
356
+ detail: Confirmed directly from the serialized player_melee.animgraph rather than inferred from clip
357
+ content.
358
+ - id: cp2077.anims.graph.add-block-family-are-directional-reactions
359
+ claim: The nine add_block_* additives (AdditiveWithoutFirstFrame type) are directional BLOCK
360
+ REACTIONS (up/down/left/right plus bullet deflects), not ambient sway, and are distinct from
361
+ the four continuous Additive-type ambient-sway clips (add_melee_idle, add_melee_idle_combat,
362
+ add_walk_melee_0, add_jog_melee_0).
363
+ status: inferred
364
+ source: ModWright research
365
+ tags:
366
+ - add-block
367
+ - directional-reaction
368
+ - additivewithoutfirstframe
369
+ - ambient-sway
370
+ detail: This distinction matters when deciding which additive family a given sway-related fix or
371
+ measurement should even touch.
372
+ - id: cp2077.anims.graph.safe-state-is-script-gated-not-idle-timer
373
+ claim: The Safe state (melee_safepose) is entered through a script gate (MeleeData.isSafe, set by
374
+ defaultTransition.script's ShouldEnterSafe on conditions like aiming at a friendly, terminals,
375
+ scanning, or takedowns), not by a plain "stood still long enough" idle timer; crouch-still
376
+ specifically settles into melee_safepose, not melee_crouchpose.
377
+ status: inferred
378
+ source: ModWright research
379
+ tags:
380
+ - safe-state
381
+ - meleedata-issafe
382
+ - crouch-still
383
+ - melee_safepose
384
+ detail: This corrected an earlier assumption that crouch-still used melee_crouchpose, which affected
385
+ where a crouch-related sway or grip fix needed to be pinned.
386
+ - id: cp2077.anims.graph.no-machete-anims-file-old-belief
387
+ claim: An earlier project note treated the non-prefixed default_melee_weapon.anims file as the
388
+ machete/chainsword/axe FPP anim set.
389
+ status: contradicted
390
+ source: ModWright research
391
+ tags:
392
+ - machete
393
+ - default-melee-weapon
394
+ - dead-belief
395
+ detail: Wrong in three places in the project's own notes. See
396
+ cp2077.anims.graph.machete-plays-one-handed-blunt-set for the corrected mapping.
397
+ - id: cp2077.anims.graph.machete-plays-one-handed-blunt-set
398
+ claim: A depot-wide survey (regex over every content archive, 6451 unique .anims paths) found NO
399
+ pwa_machete/pma_machete, chainsword, axe or one-hand-blade player FPP set anywhere in the game
400
+ — the only "machete" resources are three NPC clips. Machete, axe, chainsword, one-hand blade
401
+ and one-hand blunt all share the single set
402
+ base\animations\weapon\one_handed_blunt\pwa_one_handed_blunt.anims (pma_ twin for male). The
403
+ priority and gating rule for that set is recorded at
404
+ cp2077.anims.sets.weapon-family-set-is-the-fallback; this fact records only the depot survey
405
+ that rules out a per-weapon file.
406
+ status: inferred
407
+ supersedes: cp2077.anims.graph.no-machete-anims-file-old-belief
408
+ source: ModWright research
409
+ tags:
410
+ - machete
411
+ - one-hand-blunt
412
+ - friendlyname
413
+ - animwrapper
414
+ - shared-set
415
+ detail: "default_melee_weapon.anims is a SEPARATE, always-mounted priority-200 fallback with only 17
416
+ float tracks and no Phase events at all — it must never be used as a donor for anything
417
+ requiring Phase-marker timing. Its own combo_attack_01/02 are left-arm actions with the weapon
418
+ hand nearly frozen (RightHand path 0.178 m vs LeftHand 1.386 m). The complete player-FPP melee
419
+ set list with gating variables was tabulated from the EP1 player ent:
420
+ w_melee_katana/pwa_katana, w_melee_knife + knife_thumb_override/pwa_knife,
421
+ w_melee_baton/pwa_baton, w_melee_one_hand_blunt + additives/pwa_one_handed_blunt,
422
+ w_two_hand_blunt/pwa_two_handed_blunt, w_melee_hammer/pwa_two_handed_hammer, w_melee_fists +
423
+ StrongArms/pwa_fists (all 128), mantis_blade and mono_wires at 128, dildo at 127, and the
424
+ ungated 200 trio default_melee_weapon / pwa_strongarms / pwa_katana_finisher."
425
+ - id: cp2077.anims.graph.custom-set-mount-priority-competitor
426
+ claim: A machete-derived custom weapon INHERITS friendlyName = w_melee_one_hand_blunt from its base
427
+ preset and sets no override, so the weapon-family set pwa_one_handed_blunt is co-mounted at
428
+ priority 128 whenever the weapon is out; a custom set at priority 127 therefore wins every
429
+ shared clip name by exactly ONE number, and every name it does not supply falls through to
430
+ that family set. Setting a unique friendlyName (e.g. w_melee_<mod>) on the custom weapon's own
431
+ item record removes the competitor entirely, at the cost of no longer inheriting anything from
432
+ that mount.
433
+ status: inferred
434
+ source: ModWright research
435
+ tags:
436
+ - priority
437
+ - animwrapper
438
+ - friendlyname
439
+ - fallback-order
440
+ - co-mount
441
+ detail: The priority ordering rule itself (lower number wins; sets override by shared clip NAME) is
442
+ cp2077.anims.sets.lower-priority-number-wins, and the fall-through order is
443
+ cp2077.anims.sets.weapon-family-set-is-the-fallback; this fact records only the custom-weapon
444
+ consequence of inheriting a base preset's friendlyName.
445
+ - id: cp2077.anims.graph.anim-set-gating-variable-is-native-old-belief
446
+ claim: An earlier project note observed that the gating AnimWrapper variable name for a per-weapon
447
+ anim set (e.g. w_melee_katana) appears in none of tools\redmod\tweaks and hypothesized it must
448
+ be native (C++) behavior with no moddable yaml lever.
449
+ status: contradicted
450
+ source: ModWright research
451
+ tags:
452
+ - animwrapper
453
+ - friendlyname
454
+ - dead-belief
455
+ - native-hypothesis
456
+ detail: See cp2077.anims.sets.weapon-family-set-is-the-fallback for the resolved mechanism — the
457
+ gating variable is the weapon record's own friendlyName field, raised natively via
458
+ SetAnimWrapperWeight, and therefore fully moddable from yaml.
459
+ - id: cp2077.anims.graph.three-numbering-systems-for-swing-index
460
+ claim: 'Three different numbering conventions for "the same" swing index coexist and are the cause
461
+ of most stale documentation claims in this project: TweakDB attack records are 1-based
462
+ (MacheteComboAttack1..4), the attackName/state index is 0-based (MeleeComboAttack0..3), and
463
+ clip/CSV names are 1-based two-digit (combo_attack_01..09).'
464
+ status: inferred
465
+ source: ModWright research
466
+ tags:
467
+ - numbering-convention
468
+ - record-index
469
+ - clip-index
470
+ - attackname
471
+ detail: '"Never written down together before" per the source document; explicitly called out as the
472
+ single biggest source of off-by-one documentation errors across the project.'
473
+ - id: cp2077.anims.graph.sk-speedanim-subtree-is-dead-old-belief
474
+ claim: An earlier project belief held that the live animgraph only has 4 combo, 5 final and 2 heavy
475
+ attack slots, based on a subtree of literal-clip-name animAnimNode_SkSpeedAnim nodes.
476
+ status: contradicted
477
+ source: ModWright research
478
+ tags:
479
+ - skspeedanim
480
+ - dead-subtree
481
+ - slot-count
482
+ - dead-belief
483
+ detail: Four separate research agents independently read this ceiling off the dead subtree before it
484
+ was checked against reachability.
485
+ - id: cp2077.anims.graph.real-swing-ceiling-is-nine-slot-csv
486
+ claim: "The literal-clip-name animAnimNode_SkSpeedAnim subtree is unreachable dead legacy code: two
487
+ independent reachability walks of the live, 138-139-handle Attack pose graph found zero
488
+ SkSpeedAnim nodes and only three two-input Switches, with the named handle for the subtree
489
+ (h1125) having zero HandleRefId references anywhere in the 16.6 MB serialized file. The real
490
+ ceiling on swing count is the CSV motion database's 9 slots per attack class
491
+ (combo/heavy/final), not the animgraph's node structure."
492
+ status: inferred
493
+ supersedes: cp2077.anims.graph.sk-speedanim-subtree-is-dead-old-belief
494
+ source: ModWright research
495
+ tags:
496
+ - csv-ceiling
497
+ - nine-slots
498
+ - reachability
499
+ - skspeedanim
500
+ detail: Names like heavy_attack_03, final_attack_01/02, final_attack_06..09 and combo_attack_05..09
501
+ are all addressable CSV slots with no clip in any mounted set — an authoring gap, not an
502
+ engine limit.
503
+ - id: cp2077.anims.graph.numframes-engine-read-question
504
+ claim: Whether the engine reads a clip's numFrames field directly, or derives the played sample
505
+ count purely from the duration field, has never been directly observed in game.
506
+ status: unverified
507
+ source: ModWright research
508
+ tags:
509
+ - numframes
510
+ - duration
511
+ - engine-behavior
512
+ - open-question
513
+ detail: "Why it matters: the shipped build carries a numFrames-vs-duration off-by-one on 44 of 96
514
+ entries (see cp2077.anims.pipeline.numframes-off-by-one-defect), and the source estimates the
515
+ cost of a lost terminal frame at 3.3-20.6 mm / 0.45-6.6 deg on drawn bones — which would break
516
+ exactly the terminal-pose convention the chain relies on. The cheapest resolution offered is
517
+ to make the question MOOT: assert the invariant `numFrames - 1 == round(duration * 30)` in the
518
+ builder and always fix the field, rather than proving which one the engine reads. If it must
519
+ be observed, the source suggests picking a clip with a large last-frame delta (safe_attack,
520
+ 16.8 mm / 6.6 deg) and looking. A duplicate of this open question previously also sat in the
521
+ encoder topic and was merged here."
522
+ - id: cp2077.anims.graph.final-attack-04-renders-once-steering-removed
523
+ claim: Using a mod's own console command to bypass the finisher's steering script, the counter-3
524
+ slot's own final_attack_04 entry (present in the mod's katana-clone anim set) was confirmed in
525
+ game to resolve and render correctly — a rising slash, the katana's own combo_attack_04 shape
526
+ — proving the mounted set's final_attack_04 slot works and the steering script's original
527
+ justification (the previously mounted set lacking that entry) had expired.
528
+ status: verified
529
+ source: ModWright field verification
530
+ tags:
531
+ - final-attack-04
532
+ - animsteering
533
+ - console-test
534
+ - verified
535
+ detail: This result licensed authoring directly into final_attack_04 and retiring the mod's finisher
536
+ redirect in redscript at ship time.
537
+ - id: cp2077.anims.graph.animsteering-is-pure-visual-redirect
538
+ claim: A melee weapon mod's steering script only ever touches attack counter 3 (matching literal
539
+ slot names MeleeComboAttack3 / MeleeFinalAttack3), and rewrites MeleeSlotData to
540
+ (attackType=1, comboNumber=0) = CSV(1,0) = heavy_attack_01; its blendPercent=30 knob and its
541
+ trailAttackSide copy are both dead in the shipped configuration (the chosen visual record's
542
+ durations default to 0, so the else-branch always runs; no machete record sets
543
+ trailAttackSide). It is therefore a pure (attackType, index) visual redirect and nothing more.
544
+ status: inferred
545
+ source: ModWright research
546
+ tags:
547
+ - animsteering
548
+ - heavy_attack_01
549
+ - meleeslotdata
550
+ - dead-code
551
+ detail: Two of its three coded effects are inert in the shipped configuration; only the (attackType,
552
+ comboNumber) rewrite does anything observable.
553
+ - id: cp2077.anims.graph.steered-finisher-was-timing-out-of-band
554
+ claim: The steered heavy_attack_01 finisher fires its gameplay hit about 160 ms out of band from its
555
+ own clip's visual contact frame, and the state exits before the clip finishes (truncated at
556
+ frame 36 of 42, landing 45-49 mm short of the clip's own authored end pose); playing the set's
557
+ own final_attack_04 instead (exactly 1.200 s, plays to its last frame) puts the hit back
558
+ inside vanilla's measured -27 ms to +70 ms band.
559
+ status: inferred
560
+ source: ModWright research
561
+ tags:
562
+ - steered-finisher
563
+ - heavy_attack_01
564
+ - timing
565
+ - truncation
566
+ detail: This quantifies why retiring the steering script in favor of authoring final_attack_04
567
+ directly was a strict improvement, not just a cosmetic preference.
568
+ - id: cp2077.anims.graph.gameplay-hit-lands-near-active-phase-event
569
+ claim: Across every vanilla family measured where records and clips are matched, the gameplay hit
570
+ lands within -27 ms to +70 ms of the clip's own `active` animAnimEvent_Phase event; expressed
571
+ as a retimer-invariant fraction, the authored contact frame should sit at attackEffectDelay /
572
+ startupDuration (measured as 0.899 of the startup segment for the machete-record/katana-clip
573
+ pairing used here) when the three-segment retimer is engaged, or at the record's absolute
574
+ attackEffectDelay time when the durations are 0/0/0 (whole-clip route).
575
+ status: inferred
576
+ source: ModWright research
577
+ tags:
578
+ - gameplay-hit
579
+ - active-phase-event
580
+ - contact-frame
581
+ - retimer-invariant
582
+ detail: Expressing the target as a fraction rather than an absolute time matters because
583
+ MeleeAttackData's attackSpeed field scales the window fields and the phase durations together,
584
+ so the ratio stays invariant under speed modifiers; no melee record in the game sets
585
+ DontScaleWithAttackSpeed.
586
+ - id: cp2077.anims.graph.lunge-mechanism-is-move-to-target-not-perk-leap
587
+ claim: "A vanilla \"blades\" perk leap and the Byakko katana's iconic-mod leap are the SAME
588
+ mechanism (both simply add BaseStats.CanMeleeLeap), and that flag's only gameplay consumer,
589
+ the meleeLeap PSM state, is structurally unreachable from a light-attack-chain finisher:
590
+ meleeLeap is absent from meleeFinalAttack.transitionTo and its entry condition requires a
591
+ charged strong-attack-hold release. The mechanism that DOES reach a light-chain finisher is
592
+ the ordinary, non-perk-gated enableAdjustingPlayerPositionToTarget record boolean, read by
593
+ MeleeAttackGenericEvents.OnEnter for every attack type including MeleeFinalAttackEvents."
594
+ status: inferred
595
+ source: ModWright research
596
+ tags:
597
+ - lunge
598
+ - canmeleeleap
599
+ - meleeleap
600
+ - enableadjustingplayerpositiontotarget
601
+ - finisher
602
+ detail: No token "leap" occurs anywhere in the 16.6 MB serialized player_melee.animgraph.json, and
603
+ no clip named *leap*/*dash*/*lunge* exists in any of the nine player-FPP melee sets — the leap
604
+ state's "animation" is just the engine sliding the capsule during a held charged pose.
605
+ - id: cp2077.anims.graph.move-to-target-lunge-geometry
606
+ claim: With enableAdjustingPlayerPositionToTarget=true, the move-to-target slide searches a 4.0 m
607
+ radius (weapon Range 2.0 + MoveToTargetSearchDistance 2.0) within a 10-degree pitch-and-yaw
608
+ cone of the crosshair, pulls back 0.25 m from the target's Center slot, completes over
609
+ attackData.attackEffectDelay seconds (0.240 s stock on the machete finisher), issues no
610
+ rotation (rotationDuration = -1.0), and only fires when the player's Melee Aim Assist setting
611
+ resolves to AllAttacks (which every selectable setting level does by default). A -45-degree
612
+ pitch gate applies, and the target must be an active, non-friendly puppet closest to the
613
+ crosshair.
614
+ status: inferred
615
+ source: ModWright research
616
+ tags:
617
+ - lunge
618
+ - move-to-target
619
+ - attackeffectdelay
620
+ - aim-assist
621
+ - adjustplayerposition
622
+ detail: "Practical travel range given the pull-back is 0 to about 3.75 m, target-relative; the mod's
623
+ own in-game-tested tuning of this record (distance and attackEffectDelay) across several
624
+ deploys treated this geometry as confirmed and adjusted only the specific numbers. On the
625
+ settings chain: AimAssistMelee_Default sets moveToTargetEnabledAttacks = 2 (AllAttacks), and
626
+ Settings_MeleeCombat maps ALL THREE user aim-assistance levels (light, standard and heavy)
627
+ onto the same AimAssistConfigPreset_MeleeCombat, whose default_index is 2 = Standard — so on a
628
+ default install IsMoveToTargetEnabled reduces to the single record boolean and the attack type
629
+ is never consulted."