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,338 @@
1
+ game: stardewvalley
2
+ topic: contentpatcher.format
3
+ title: Content Patcher — content.json, the Format version, and every way a patch is silently ignored
4
+ facts:
5
+ - id: stardewvalley.contentpatcher.format.what-a-pack-is
6
+ claim: 'A Content Patcher pack is a folder with `manifest.json` and `content.json`, usually plus an
7
+ `assets/` subfolder, installed under `Mods/` like any other mod. Its manifest declares
8
+ `"ContentPackFor": {"UniqueID": "Pathoschild.ContentPatcher"}` and no `EntryDll`.'
9
+ status: community
10
+ source: 'https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/docs/author-guide.md
11
+ (read 2026-09-11): "A content pack is just a folder with two text files in it: manifest.json
12
+ (which has info like your mod name) and content.json (which tells Content Patcher what you
13
+ want to change). Your folder might also have images or other files, which are usually in an
14
+ assets subfolder by convention"'
15
+ tags:
16
+ - contentpatcher
17
+ - content-pack
18
+ - layout
19
+ - scaffold
20
+ detail: The documented folder-name convention is `[CP] YourModName`. Because there is no compiled
21
+ artifact, a content pack needs no toolchain at all — which is why the validator family for
22
+ this format is the highest-value thing a Stardew surface can build without the game.
23
+ - id: stardewvalley.contentpatcher.format.version-and-smapi-floor
24
+ claim: Content Patcher 2.9.1 is the current release, "Released 14 March 2026 for SMAPI 4.4.0 or
25
+ later", and the README states compatibility as "Content Patcher is compatible with Stardew
26
+ Valley 1.6+ on Linux/macOS/Windows, both single-player and multiplayer."
27
+ status: community
28
+ source: https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/docs/release-notes.md
29
+ and .../docs/README.md, both read 2026-09-11
30
+ tags:
31
+ - contentpatcher
32
+ - version
33
+ - compat
34
+ - rule
35
+ detail: The repository publishes no GitHub releases, so the release-notes headings are the only
36
+ version oracle. The previous feature release is 2.9.0, "Released 11 January 2026 for SMAPI
37
+ 4.4.0 or later".
38
+ - id: stardewvalley.contentpatcher.format.format-field-is-a-cp-version
39
+ claim: "`content.json`'s `Format` field is not a schema number; it is the version of Content Patcher
40
+ the pack was designed for, and is used to keep older packs working. The current value is
41
+ `2.9.0`."
42
+ status: community
43
+ source: 'https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/docs/author-guide.md:
44
+ "That Format field is the version of Content Patcher for which you designed the content pack.
45
+ This is used to keep your content pack compatible with future versions. You should always use
46
+ the latest format version (currently 2.9.0) to enable the latest features, avoid obsolete
47
+ behavior, and reduce startup time."'
48
+ tags:
49
+ - contentpatcher
50
+ - format
51
+ - version
52
+ - migration
53
+ - validator
54
+ detail: Content Patcher ships a migration per format version — roughly forty
55
+ `Framework/Migrations/Migration_*.cs` files from `Migration_1_3` to `Migration_2_9` — so an
56
+ older `Format` still loads. A validator must report a low `Format` as `warn`, never `block`.
57
+ - id: stardewvalley.contentpatcher.format.schema-pins-the-current-version
58
+ claim: 'The published JSON Schema pins `Format` to the current release with `"pattern":
59
+ "^2\\.9\\.[0-9]+$"`, so a pack written against an older format fails the schema while still
60
+ loading fine in game.'
61
+ status: community
62
+ source: https://smapi.io/schemas/content-patcher.json (read 2026-09-11), the `Format` property,
63
+ whose `@errorMessages.pattern` is "Incorrect value '@value'. You should always use the latest
64
+ format version (currently 2.9.0) to enable the latest features, avoid obsolete behavior, and
65
+ reduce load times."
66
+ tags:
67
+ - contentpatcher
68
+ - schema
69
+ - format
70
+ - validator
71
+ - conflict
72
+ detail: 'This is a schema-versus-runtime disagreement that a validator must handle deliberately: the
73
+ schema expires on every Content Patcher release, the runtime does not. Run the schema, then
74
+ downgrade this one finding to `warn`. The schema also sets `required: ["Format", "Changes"]`
75
+ and `additionalProperties: false`.'
76
+ - id: stardewvalley.contentpatcher.format.top-level-fields
77
+ claim: "`content.json`'s top-level fields are `Format`, `Changes`, `ConfigSchema`,
78
+ `CustomLocations`, `DynamicTokens` and `AliasTokenNames`."
79
+ status: inferred
80
+ source: Content Patcher develop,
81
+ https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/Framework/ConfigModels/ContentConfig.cs,
82
+ the constructor parameters; corroborated by the property list in
83
+ https://smapi.io/schemas/content-patcher.json
84
+ tags:
85
+ - contentpatcher
86
+ - content-json
87
+ - fields
88
+ - schema
89
+ - id: stardewvalley.contentpatcher.format.five-actions
90
+ claim: Every patch has an `Action` of `Load`, `EditData`, `EditImage`, `EditMap` or `Include`.
91
+ `Load` "replaces an entire asset with a version you provide"; the three `Edit*` actions can be
92
+ applied by any number of packs to the same asset; `Include` "adds patches from another file".
93
+ status: community
94
+ source: "https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/docs/author-guide.m\
95
+ d, the Actions table; the enum members are confirmed by PatchLoader's own error text
96
+ \"expected one of: {string.Join(\", \", Enum.GetNames(typeof(PatchType)))}\""
97
+ tags:
98
+ - contentpatcher
99
+ - actions
100
+ - patches
101
+ - validator
102
+ detail: The guide advises against `Load` where an `Edit*` will do ("This isn't recommended if you
103
+ can use one of the Edit* actions instead"), because only one pack can `Load` a given asset
104
+ while any number can edit it. That is a real conflict-avoidance rule and worth an `info`
105
+ validator.
106
+ - id: stardewvalley.contentpatcher.format.patch-fields
107
+ claim: A patch's fields are `LogName`, `Action`, `Target`, `TargetLocale`, `Update`, `FromFile`,
108
+ `Enabled`, `When`, `Priority`, `LocalTokens`, `TextOperations`, `FromArea`, `ToArea`,
109
+ `PatchMode`, `Entries`, `Fields`, `MoveEntries`, `TargetField`, `MapProperties`,
110
+ `AddNpcWarps`, `AddWarps` and `MapTiles`.
111
+ status: inferred
112
+ source: Content Patcher develop,
113
+ https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/Framework/ConfigModels/PatchConfig.cs
114
+ tags:
115
+ - contentpatcher
116
+ - patches
117
+ - fields
118
+ - schema
119
+ detail: "`TargetLocale` is documented in source as \"the locale code in the target asset's name to
120
+ match (like fr-FR ...), or an empty string to match only the base unlocalized asset, or null
121
+ to match all localized or unlocalized variants\" — a three-way distinction that is easy to get
122
+ wrong and invisible in testing if the author only plays in English."
123
+ - id: stardewvalley.contentpatcher.format.asset-names-have-no-extension
124
+ claim: 'A `Target` is an asset name, not a file path: it never includes "Content", the language
125
+ code, or the file extension. `Content/Maps/spring_beach.xnb` and
126
+ `Content/Maps/spring_beach.fr-FR.xnb` are both the asset `Maps/spring_beach`.'
127
+ status: community
128
+ source: https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/docs/author-guide.md,
129
+ "What is an asset?"
130
+ tags:
131
+ - contentpatcher
132
+ - target
133
+ - asset
134
+ - index
135
+ - validator
136
+ detail: "A validator that checks a `Target` against a vanilla index must key on this form, and must
137
+ not accept a `.xnb` suffix. SMAPI's 4.0 migration guide makes the same point for C# mods:
138
+ \"When loading assets from helper.GameContent, don't add a .xnb file extension\"."
139
+ - id: stardewvalley.contentpatcher.format.tokens-and-conditions
140
+ claim: "Most fields accept `{{token}}` interpolation, and a patch's `When` block maps token names to
141
+ accepted values; tokens include `{{season}}`, `{{Spouse}}`, `{{Time}}`, `{{Language}}`,
142
+ `{{ModId}}` and `{{i18n: key}}`, plus author-defined `DynamicTokens`, `LocalTokens` and
143
+ `ConfigSchema` values."
144
+ status: community
145
+ source: 'https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/docs/author-guide.md,
146
+ the Tokens & conditions section and its worked examples (`"FromFile":
147
+ "assets/abigail-{{season}}.png"`, `"When": {"Spouse": "Abigail"}`)'
148
+ tags:
149
+ - contentpatcher
150
+ - tokens
151
+ - conditions
152
+ - validator
153
+ - static-analysis
154
+ detail: "Tokens are what makes static validation partial rather than complete: a `FromFile`
155
+ containing a token cannot be resolved to one path. The honest validator resolves tokenless
156
+ paths exactly and, for tokenised ones, checks that at least one file could match, reporting
157
+ `warn` with the reason when it cannot tell."
158
+ - id: stardewvalley.contentpatcher.format.whole-pack-rejection-messages
159
+ claim: "A pack is rejected whole with `Could not load content pack '{name}': {error}.` at Error,
160
+ where the error is one of \"content pack has no content.json file\", \"content pack doesn't
161
+ specify the required Format field.\", \"content pack must specify the Changes or
162
+ CustomLocations fields.\", or a migration failure."
163
+ status: inferred
164
+ source: Content Patcher develop,
165
+ https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/Framework/RawContentPack.cs
166
+ `TryReloadContent(out string? error)`, logged by ContentPatcher/ModEntry.cs
167
+ `GetContentPacks()`
168
+ tags:
169
+ - contentpatcher
170
+ - errors
171
+ - log
172
+ - signature
173
+ - validator
174
+ detail: Two sibling Error lines from the same method are `Error preloading content pack '{name}'.
175
+ Technical details:\n{ex}` and `Error loading configuration for content pack '{name}'.
176
+ Technical details:\n{ex}`, both multi-line.
177
+ - id: stardewvalley.contentpatcher.format.patch-skip-line-shape
178
+ claim: "An individual patch that fails to load is reported as `Ignored {path}: {reason}.` at
179
+ **Warn** — never Error — where `path` is the pack name plus the patch's `LogName`, and the
180
+ reason has its trailing period normalised on."
181
+ status: inferred
182
+ source: Content Patcher develop,
183
+ https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/Framework/PatchLoader.cs,
184
+ the `logSkip` callback and `TrackSkip(string reason, bool warn = true)` (`reason =
185
+ reason.TrimEnd('.', ' '); ... logSkip(reason + '.');`)
186
+ tags:
187
+ - contentpatcher
188
+ - errors
189
+ - log
190
+ - signature
191
+ - warn
192
+ - triage
193
+ detail: "Because it is Warn and not Error, it is easy to lose in a long log. That is exactly the
194
+ case a triage verdict should surface, and it must carry `systemImpact: false` so one broken
195
+ patch does not mark the whole mods system failed."
196
+ - id: stardewvalley.contentpatcher.format.patch-skip-reasons
197
+ claim: "The patch skip reasons include \"must set the Action field\", \"invalid Action value '{x}',
198
+ expected one of: ...\", \"must set the Target field\", \"the Target is invalid: {error}\",
199
+ \"the When field is invalid: {error}\", \"must set the FromFile field for a Load patch.\",
200
+ \"can't use the Target field with an Include patch.\", \"one of Entries, Fields, MoveEntries,
201
+ TextOperations, or FromFile must be specified for an '{action}' change\", \"FromFile is
202
+ mutually exclusive with Entries, Fields, and MoveEntries\", and \"the PatchMode is invalid.
203
+ Expected one of these values: [...]\"."
204
+ status: inferred
205
+ source: Content Patcher develop,
206
+ https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/Framework/PatchLoader.cs,
207
+ the `TrackSkip(...)` call sites in `LoadPatch(...)`
208
+ tags:
209
+ - contentpatcher
210
+ - errors
211
+ - validator
212
+ - block
213
+ - log
214
+ detail: "Each maps 1:1 onto a pre-build validator, so the validator's message can be the exact
215
+ sentence the player would otherwise have to find at Warn in the log. Also present: \"circular
216
+ field reference: Target field can't use the '...' tokens.\", \"the Enabled field is obsolete
217
+ and should be removed\", and \"the Priority value '{x}' is invalid: expected one of [...] or a
218
+ simple offset like '... + 10'\"."
219
+ - id: stardewvalley.contentpatcher.format.disabled-patch-logs-nothing
220
+ claim: 'In a pack whose `Format` is below 1.25.0, a patch with `"Enabled": false` is skipped with
221
+ **no log line at all** — `TrackSkip("Enabled is false", warn: false)` suppresses the warning.
222
+ From Format 1.25.0 on the field is obsolete: any value but the literal `true` skips the patch
223
+ with the Warn line `the Enabled field is obsolete and should be removed`, and `true` is
224
+ ignored.'
225
+ status: inferred
226
+ source: 'Content Patcher develop, ContentPatcher/Framework/PatchLoader.cs: `bool isEnabledAllowed =
227
+ rawContentPack.Content.Format!.IsOlderThan("1.25.0"); if (!isEnabledAllowed) { if
228
+ (!bool.TryParse(entry.Enabled, out bool raw) || !raw) return TrackSkip($"the
229
+ {nameof(PatchConfig.Enabled)} field is obsolete and should be removed"); }` and, below that
230
+ Format, `return TrackSkip($"{nameof(PatchConfig.Enabled)} is false", warn: false);`'
231
+ tags:
232
+ - contentpatcher
233
+ - silent-failure
234
+ - validator
235
+ - gotcha
236
+ - triage
237
+ detail: For a legacy-Format pack this is the classic "my patch does nothing and the log is clean"
238
+ cause, and it is invisible to log triage by construction; a current-Format pack gets one Warn
239
+ line instead, which the `stardewvalley.contentpatcher.patch-ignored` signature matches. It can
240
+ only be caught by a static validator reading `content.json`, which is a strong argument for
241
+ the validator family existing at all. A patch whose `When` conditions never match is similarly
242
+ silent and is visible only through `patch summary`.
243
+ - id: stardewvalley.contentpatcher.format.config-json-and-schema
244
+ claim: "A pack can declare a `ConfigSchema` in `content.json`; Content Patcher then creates and
245
+ reads a `config.json` in the pack folder and exposes each field as a token. Problems with it
246
+ are logged as `Ignored {pack} > {label}: {reason}` at Warn."
247
+ status: community
248
+ source: 'https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/docs/author-guide.md
249
+ (the `ConfigSchema` example with `AllowValues` and `Default`) and
250
+ .../docs/author-guide/config.md; the log line from ContentPatcher/ModEntry.cs (`new
251
+ ConfigFileHandler("config.json", this.ParseCommaDelimitedField, (pack, label, reason) =>
252
+ this.Monitor.Log($"Ignored {pack.Manifest.Name} > {label}: {reason}", LogLevel.Warn))`)'
253
+ tags:
254
+ - contentpatcher
255
+ - config
256
+ - tokens
257
+ - validator
258
+ detail: "`config.json` is generated, not authored, so it must not be shipped in a release zip and
259
+ must not be overwritten by a deploy — the player guide's \"merge update\" instructions exist
260
+ precisely to preserve it."
261
+ - id: stardewvalley.contentpatcher.format.patch-console-commands
262
+ claim: 'Content Patcher adds a `patch` console command family: `patch summary`, `patch update`,
263
+ `patch reload "<pack id>"`, `patch export "<asset>"`, `patch parse "<string>"`, `patch dump
264
+ order`, `patch dump applied` and `patch invalidate "<asset>"`.'
265
+ status: community
266
+ source: https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/docs/author-guide/troubleshooting.md
267
+ (read 2026-09-11)
268
+ tags:
269
+ - contentpatcher
270
+ - console
271
+ - verification
272
+ - bridge
273
+ - probe
274
+ detail: "`patch summary` prints a per-patch `loaded | conditions | applied` table \"along with their
275
+ current values, what they changed, and (if applicable) the reasons they weren't applied\" —
276
+ which answers most of what an in-game bridge probe would, if its output can be captured. That
277
+ is the cheapest verification question to settle on this game."
278
+ - id: stardewvalley.contentpatcher.format.patch-reload-is-real-hot-reload
279
+ claim: "`patch reload \"<content pack ID>\"` reloads one pack's patches while the game is running —
280
+ \"That lets you change your content pack's JSON files while the game is running, and see the
281
+ changes in-game without restarting the game\" — but \"Non-patch content (like config schema
282
+ and dynamic tokens) aren't reloaded\"."
283
+ status: community
284
+ source: https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/docs/author-guide/troubleshooting.md,
285
+ the `reload` section, whose example output is "Content pack reloaded."
286
+ tags:
287
+ - contentpatcher
288
+ - reload
289
+ - deploy
290
+ - hot-reload
291
+ - classifyreload
292
+ detail: "This is the only documented hot reload anywhere in this ecosystem and it makes
293
+ `classifyReload` genuinely useful here: in `ReloadAction`'s vocabulary (`hot | hot-degraded |
294
+ save-reload | restart | unknown`, from src/core/deploy/reload.ts) a `content.json` or asset
295
+ change is `hot` with `via: patch reload \"<pack id>\"`, while a `ConfigSchema` or
296
+ `DynamicTokens` change is `restart`. It also takes an optional second argument naming one
297
+ `Include` file to reload."
298
+ - id: stardewvalley.contentpatcher.format.verbose-log-and-logname
299
+ claim: "Content Patcher logs very little by default. Setting a `LogName` on each patch and enabling
300
+ SMAPI's `VerboseLogging` for `Pathoschild.ContentPatcher` makes it log at three points: when
301
+ loading patches, when SMAPI asks whether it can load or edit an asset, and whenever the
302
+ condition context changes."
303
+ status: community
304
+ source: "https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/docs/author-guide/t\
305
+ roubleshooting.md, \"Verbose log\": \"Content Patcher doesn't log much info. ... This may
306
+ significantly slow down loading, and should normally be left disabled unless you need it.\""
307
+ tags:
308
+ - contentpatcher
309
+ - verbose
310
+ - logging
311
+ - logname
312
+ - troubleshooting
313
+ detail: "The guide's own diagnostic sequence is worth reproducing in `guidance`: did Content Patcher
314
+ load the patch (if it says 'skipped', check `Enabled` or `config.json`); when the context
315
+ updates, is the box ticked next to the patch name (if not, check `When`); when SMAPI checks
316
+ the asset, is the box ticked (if not, check `When` and `Target`). A validator that sets
317
+ `LogName` in every scaffolded patch makes this sequence usable."
318
+ - id: stardewvalley.contentpatcher.format.published-json-schema
319
+ claim: Content Patcher's `content.json` has a published JSON Schema at
320
+ `https://smapi.io/schemas/content-patcher.json`, referenceable from the file with a `$schema`
321
+ field, and validatable in a browser at smapi.io/json.
322
+ status: community
323
+ source: "https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/web.md (\"Available
324
+ schemas ... Content Patcher: content.json | https://smapi.io/schemas/content-patcher.json\")
325
+ and .../ContentPatcher/docs/author-guide/troubleshooting.md (\"You can validate your
326
+ content.json and manifest.json automatically to detect some common issues. (You should still
327
+ test your content pack in-game before releasing it, since the validator won't detect all
328
+ issues.)\")"
329
+ tags:
330
+ - contentpatcher
331
+ - schema
332
+ - validator
333
+ - tooling
334
+ - smapi-io
335
+ detail: "The parenthetical is the whole argument for a ModWright validator family on top of the
336
+ schema: the schema checks JSON shape and cannot tell you that `assets/abigail-winter.png` is
337
+ missing, that a new item id is not namespaced, or that a `Fields` key names a field the model
338
+ does not have."
@@ -0,0 +1,236 @@
1
+ game: stardewvalley
2
+ topic: distribution.channels
3
+ title: Where Stardew mods are published, and the compatibility data that tracks them
4
+ facts:
5
+ - id: stardewvalley.distribution.channels.nexus-is-primary-and-not-fetched
6
+ claim: Nexus Mods is the primary distribution channel for Stardew Valley mods. Per this repository's
7
+ standing rule, no nexusmods.com page was fetched for this research, so every distribution
8
+ claim here is sourced from the wiki or from SMAPI's own update-key vocabulary.
9
+ status: community
10
+ source: "https://stardewvalleywiki.com/Modding:Player_Guide/Getting_Started (read 2026-09-11), the
11
+ mod-sites table: \"Nexus Mods — Most mods are released here. An account is required, but it's
12
+ free\""
13
+ tags:
14
+ - distribution
15
+ - nexus
16
+ - standing-rule
17
+ - provenance
18
+ detail: The practical consequence is that a Stardew surface cannot resolve a Nexus update key to a
19
+ page or a version by itself, and should not try. SMAPI's own web API does that; ModWright's
20
+ job stops at validating the key's shape.
21
+ - id: stardewvalley.distribution.channels.the-five-sites
22
+ claim: "SMAPI recognises five mod sites in update keys: Nexus Mods, CurseForge, ModDrop, GitHub and
23
+ Chucklefish (deprecated). The machine-readable statement of that set is the `UpdateKeys`
24
+ pattern in the published manifest schema."
25
+ status: community
26
+ source: 'https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Update_checks (read 2026-09-11),
27
+ "Valid sites"; the pattern
28
+ `^(?i)(Chucklefish:\d+|Nexus:\d+|GitHub:[A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-]+|ModDrop:\d+|CurseForge:\d+)(?:
29
+ *@ *[a-zA-Z0-9_]+ *)?$` from https://smapi.io/schemas/manifest.json'
30
+ tags:
31
+ - distribution
32
+ - updatekeys
33
+ - sites
34
+ - validator
35
+ detail: "Each site has its own version-detection rule: CurseForge reads the latest file's display
36
+ name (\"a semantic version at the end, with a space before the version\"), GitHub reads the
37
+ release tag, ModDrop reads files under \"Main Versions\", Nexus takes the highest of the mod,
38
+ main files and optional files. GitHub explicitly does not support monorepos."
39
+ - id: stardewvalley.distribution.channels.moddrop-is-discouraged
40
+ claim: 'The wiki actively discourages ModDrop for players: "ModDrop used to be a source for Stardew
41
+ mods but is currently not recommended due to lack of supervision on the part of the site
42
+ owners. Mod developers are encouraged to monitor it for stolen mods, but players should avoid
43
+ it."'
44
+ status: community
45
+ source: https://stardewvalleywiki.com/Modding:Player_Guide/Getting_Started (read 2026-09-11), the
46
+ mod-sites table
47
+ tags:
48
+ - distribution
49
+ - moddrop
50
+ - warning
51
+ - guidance
52
+ detail: "Worth carrying into `guidance` because it is a statement about mod *provenance*, not just
53
+ convenience: a mod obtained from ModDrop may be someone else's work reuploaded. SMAPI still
54
+ supports `ModDrop:` update keys, so the two facts coexist."
55
+ - id: stardewvalley.distribution.channels.no-workshop-no-in-game-browser
56
+ claim: 'There is no Steam Workshop and no in-game mod browser. Mods are installed by unzipping into
57
+ `Mods/`: "To install a mod, just unzip it into the Mods folder in your game folder. Make sure
58
+ each mod has its own subfolder, without trailing numbers."'
59
+ status: community
60
+ source: https://stardewvalleywiki.com/Modding:Player_Guide/Getting_Started (read 2026-09-11)
61
+ tags:
62
+ - distribution
63
+ - install
64
+ - workshop
65
+ - manual
66
+ detail: The guide's own advice to "Download mods into a folder other than Mods, unzip them there,
67
+ and then move their folder(s) into Mods" exists because of the wrapper-folder failure
68
+ (`PineapplesEverywhere-1234567890`), which is one of the most common installation errors.
69
+ - id: stardewvalley.distribution.channels.compatibility-list-repo
70
+ claim: The public mod compatibility list at smapi.io/mods is generated from the
71
+ `Pathoschild/SmapiCompatibilityList` repository's `data/mods.jsonc` and
72
+ `data/broken-content-packs.jsonc`, validated against `data/schema.json`, and republished
73
+ within ten minutes of a merge.
74
+ status: community
75
+ source: 'https://github.com/Pathoschild/SmapiCompatibilityList/blob/develop/docs/README.md (read
76
+ 2026-09-11): "This repository has the compatibility metadata for every Stardew Valley C# mod
77
+ for SMAPI. The mod compatibility list is automatically generated from this data." and "The
78
+ public mod compatibility list will be updated automatically within 10 minutes once the
79
+ proposed change is merged."'
80
+ tags:
81
+ - compat
82
+ - compatibility-list
83
+ - data
84
+ - machine-readable
85
+ detail: "`data/mods.jsonc` is about 940 KB. The repository's default branch is `develop` and it was
86
+ last pushed 2026-06-04. This is a machine-readable compat corpus ModWright can read directly
87
+ rather than scraping a web page."
88
+ - id: stardewvalley.distribution.channels.compatibility-statuses
89
+ claim: A mod's compatibility status is one of `ok`, `optional`, `unofficial`, `workaround`,
90
+ `broken`, `abandoned`, `obsolete`, `unknown`. If not specified it defaults to `unofficial`
91
+ when an `unofficialUpdate` is given, else `broken` when `brokeIn` is specified, else `ok`.
92
+ status: community
93
+ source: 'https://github.com/Pathoschild/SmapiCompatibilityList/blob/develop/data/schema.json (read
94
+ 2026-09-11), `definitions.Mod.properties.status`, whose description enumerates each value —
95
+ e.g. "optional: mod is compatible if you use a secondary download on the mod page", "obsolete:
96
+ mod is no longer needed and should be removed"'
97
+ tags:
98
+ - compat
99
+ - statuses
100
+ - vocabulary
101
+ - enum
102
+ detail: "The `abandoned` status requires an `abandonedReason` of `author`, `hidden` or `deleted`.
103
+ The repository's contribution guidelines are strict about it: \"A mod is not considered
104
+ abandoned just because it hasn't been updated for a while\", and \"Only mark a mod 'broken' if
105
+ it's incompatible. This isn't the place to track general mod bugs.\""
106
+ - id: stardewvalley.distribution.channels.compatibility-record-fields
107
+ claim: Each compatibility record has required fields `name`, `author`, `id`, `nexus`, plus optional
108
+ `github`, `chucklefish`, `curse`, `moddrop`, `url`, `source`, `status`, `summary`, `warnings`,
109
+ `brokeIn`, `unofficialUpdate`, `contentPackFor`, `overrideModData`, `retestWhenCompatible` and
110
+ `developerNotes`.
111
+ status: community
112
+ source: https://github.com/Pathoschild/SmapiCompatibilityList/blob/develop/data/schema.json (read
113
+ 2026-09-11), `definitions.Mod`
114
+ tags:
115
+ - compat
116
+ - schema
117
+ - fields
118
+ - data
119
+ detail: "`brokeIn` is described as \"The SMAPI, Stardew Valley, or other release which broke this
120
+ mod if applicable. This should include both the name and version, like 'Stardew Valley
121
+ 1.6.9'.\" — a parseable field that makes \"which game version broke this\" answerable across
122
+ the whole corpus. `id` may carry alternate or former IDs comma-separated, newest first."
123
+ - id: stardewvalley.distribution.channels.unofficial-update-version-convention
124
+ claim: An unofficial update's version must be the official version incremented by 0.0.1 with
125
+ `-unofficial.N-yourName` appended — so an official `1.2.3` becomes
126
+ `1.2.4-unofficial.1-yourName`. This keeps official update alerts working.
127
+ status: community
128
+ source: "https://github.com/Pathoschild/SmapiCompatibilityList/blob/develop/docs/README.md (read
129
+ 2026-09-11): \"An unofficial version _must_ match the official mod's version, incremented by
130
+ 0.0.1, with -unofficial.1-yourName appended ... This avoids breaking update alerts for the
131
+ official mod versions.\""
132
+ tags:
133
+ - compat
134
+ - versioning
135
+ - unofficial
136
+ - validator
137
+ - pattern
138
+ detail: "Directly checkable: a mod whose version contains `-unofficial.` should match that shape.
139
+ Also relevant to update checks, since a player on a prerelease version is put on the beta
140
+ channel and will see any newer version."
141
+ - id: stardewvalley.distribution.channels.internal-metadata-json
142
+ claim: SMAPI ships its own mod database as `smapi-internal/metadata.json`, maintained in the
143
+ repository as `src/SMAPI.Web/wwwroot/SMAPI.metadata.json`. It overrides compatibility per mod
144
+ with a `Status` of `Obsolete`, `AssumeBroken` or `AssumeCompatible`, plus a
145
+ `StatusReasonPhrase` shown to the player and a `StatusReasonDetails` logged at TRACE.
146
+ status: inferred
147
+ source: https://github.com/Pathoschild/SMAPI/blob/develop/src/SMAPI.Web/wwwroot/SMAPI.metadata.json,
148
+ its own header documentation; read by src/SMAPI/Framework/ModLoading/ModResolver.cs
149
+ `ValidateManifests(...)` via `mod.DataRecord.Status`
150
+ tags:
151
+ - compat
152
+ - metadata
153
+ - on-disk
154
+ - curated
155
+ - no-network
156
+ detail: 'Roughly 45 KB with about 172 `AssumeBroken` entries as of 2026-09-11. It is on disk in
157
+ every SMAPI install, which makes it the cheapest high-value compat input available: it turns
158
+ "this mod was skipped" into "this mod is curated as broken up to version X because <phrase>"
159
+ with no network call. Its keys are version-ranged field overrides of the form `~1.1 | Default
160
+ | Name`, where the version format is `min~max` with either side optionally blank.'
161
+ - id: stardewvalley.distribution.channels.compatibility-list-is-being-deprecated
162
+ claim: SMAPI's unreleased release notes deprecate the mod compatibility list and introduce a
163
+ replacement, the "open mod dataset" at `Pathoschild/StardewModDataset` — "Open data about
164
+ every Stardew Valley mod uploaded to CurseForge, ModDrop, and Nexus Mods".
165
+ status: community
166
+ source: 'https://github.com/Pathoschild/SMAPI/blob/develop/docs/release-notes.md (read 2026-09-11),
167
+ "Upcoming release / For the web UI: Deprecated the mod compatibility list" and "For tool
168
+ maintainers: Added the open mod dataset"; repository description and tree from the GitHub API
169
+ for Pathoschild/StardewModDataset, last pushed 2026-08-30'
170
+ tags:
171
+ - compat
172
+ - deprecation
173
+ - unresolved
174
+ - dataset
175
+ - migration
176
+ detail: This is in an *unreleased* section, so as of SMAPI 4.5.2 the compatibility list is still
177
+ live. The release note's own two links also disagree with each other — the "mod compatibility
178
+ list" text links to smapi.io/stats (the new stats page) rather than smapi.io/mods. A surface
179
+ should not hard-code either source until this settles. The new dataset is laid out as
180
+ `dataset/data/<site>/<bucket>/<id>.json`.
181
+ - id: stardewvalley.distribution.channels.smapi-web-services
182
+ claim: "SMAPI runs three relevant web services: the log parser at smapi.io/log, the JSON validator
183
+ at smapi.io/json, and the update-check API at `https://smapi.io/api/` (the `WebApiBaseUrl`
184
+ setting). The published schemas are at smapi.io/schemas/{manifest,i18n,content-patcher}.json."
185
+ status: community
186
+ source: https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/web.md (read 2026-09-11),
187
+ which documents the log parser, the JSON validator and the schema URLs; `WebApiBaseUrl` and
188
+ `BlacklistUrl` from src/SMAPI/SMAPI.config.json
189
+ tags:
190
+ - smapi-io
191
+ - tooling
192
+ - api
193
+ - schema
194
+ - overlap
195
+ detail: ModWright should read the schemas (they are static files) and should not call the update API
196
+ without first reading its endpoints, rate limits and terms — none of which were established
197
+ here. The log parser and JSON validator are human-facing products over the same rules
198
+ ModWright would implement offline; duplicating their regexes is right, duplicating their UI is
199
+ not.
200
+ - id: stardewvalley.distribution.channels.malicious-mod-blacklist
201
+ claim: 'SMAPI ships and updates a malicious-mod blacklist: `smapi-internal/blacklist.json` shipped,
202
+ `blacklist-updated.json` fetched from `https://smapi.io/SMAPI.blacklist.json`, controlled by
203
+ the `CheckForBlacklistUpdates` setting. A blacklisted mod is refused with a Critical
204
+ "Malicious mod detected." line and SMAPI exits.'
205
+ status: inferred
206
+ source: SMAPI develop, src/SMAPI/Constants.cs (`ApiBlacklistPath`, `ApiBlacklistFetchedPath`),
207
+ src/SMAPI/SMAPI.config.json (`BlacklistUrl`), and src/SMAPI/Framework/Logging/LogManager.cs
208
+ `LogModInfo(...)` (`this.Monitor.LogFatal("Malicious mod detected.")` followed by
209
+ `this.PressAnyKeyToExit()`)
210
+ tags:
211
+ - security
212
+ - blacklist
213
+ - log
214
+ - signature
215
+ - distribution
216
+ detail: 'Added in SMAPI 4.5.0 along with detection of "known malicious loose files in the Mods
217
+ folder". Disabling the updates is itself logged as a Warn: "You disabled mod blacklist
218
+ updates, so you may not be protected from known malicious mods." Both the Critical line and
219
+ that Warn deserve log signatures.'
220
+ - id: stardewvalley.distribution.channels.mod-managers
221
+ claim: Vortex manages Stardew mods — SMAPI's own scanner knows its marker file
222
+ `__folder_managed_by_vortex` and reports an empty one as "it's an empty Vortex folder (is the
223
+ mod disabled in Vortex?)." — but unlike r2modman on Valheim it does not relocate the loader or
224
+ maintain a separate profile tree.
225
+ status: inferred
226
+ source: SMAPI develop, src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs, the
227
+ `VortexMarkerFileName` field and `IsEmptyVortexFolder(...)`
228
+ tags:
229
+ - distribution
230
+ - vortex
231
+ - mod-manager
232
+ - scanning
233
+ - deploy
234
+ detail: So a ModWright deploy into `Mods/` coexists with Vortex rather than competing with it, and
235
+ the only Stardew "profile" mechanism is SMAPI's own `--mods-path` argument. ModWright should
236
+ read a Vortex-managed folder and never write Vortex's metadata.