modwright 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (455) hide show
  1. package/LICENSE +35 -0
  2. package/README.md +212 -0
  3. package/assets/claude/agents/mw-explore.md +46 -0
  4. package/assets/claude/agents/mw-fixture.md +33 -0
  5. package/assets/claude/agents/mw-rule-author.md +51 -0
  6. package/assets/claude/agents/mw-scaffold-author.md +48 -0
  7. package/assets/claude/skills/mw-author.md +59 -0
  8. package/assets/claude/skills/mw-new-item.md +51 -0
  9. package/assets/claude/skills/mw-new-spell.md +50 -0
  10. package/assets/claude/skills/mw-scaffold.md +59 -0
  11. package/assets/claude/skills/mw-ship.md +57 -0
  12. package/assets/claude/skills/mw-validate.md +51 -0
  13. package/assets/claude/skills/mw-verify.md +59 -0
  14. package/assets/nivalisnights/extract_resources.py +177 -0
  15. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Config.json +5 -0
  16. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/BootstrapClient.lua +55 -0
  17. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/BootstrapServer.lua +81 -0
  18. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Log.lua +96 -0
  19. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Probes.lua +1038 -0
  20. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/ProbesClient.lua +74 -0
  21. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Protocol.lua +985 -0
  22. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Watch.lua +175 -0
  23. package/bridges/bg3-se/Mods/ModWrightBridge/meta.lsx +45 -0
  24. package/bridges/bg3-se/README.md +99 -0
  25. package/bridges/bg3-se/bridge.json +68 -0
  26. package/bridges/cp2077-cet/ModWrightBridge/init.lua +375 -0
  27. package/bridges/cp2077-cet/ModWrightBridge/probes.lua +1104 -0
  28. package/bridges/cp2077-cet/ModWrightBridge/protocol.lua +1306 -0
  29. package/bridges/cp2077-cet/README.md +165 -0
  30. package/bridges/cp2077-cet/bridge.json +53 -0
  31. package/dist/core/bridge/arm.js +175 -0
  32. package/dist/core/bridge/cet-console.js +26 -0
  33. package/dist/core/bridge/cet-log.js +362 -0
  34. package/dist/core/bridge/index.js +11 -0
  35. package/dist/core/bridge/locate.js +35 -0
  36. package/dist/core/bridge/paths.js +34 -0
  37. package/dist/core/bridge/pending.js +89 -0
  38. package/dist/core/bridge/poll.js +155 -0
  39. package/dist/core/bridge/stage.js +100 -0
  40. package/dist/core/bridge/status.js +97 -0
  41. package/dist/core/bridge/types.js +145 -0
  42. package/dist/core/bridge/validate.js +107 -0
  43. package/dist/core/build/index.js +6 -0
  44. package/dist/core/build/manifest.js +47 -0
  45. package/dist/core/build/paths.js +32 -0
  46. package/dist/core/build/run.js +342 -0
  47. package/dist/core/build/stage.js +265 -0
  48. package/dist/core/build/steps/bg3.js +129 -0
  49. package/dist/core/build/steps/core.js +195 -0
  50. package/dist/core/build/steps/cyberpunk.js +95 -0
  51. package/dist/core/build/steps/listing.js +35 -0
  52. package/dist/core/build/types.js +13 -0
  53. package/dist/core/build/zip.js +148 -0
  54. package/dist/core/compat/check.js +113 -0
  55. package/dist/core/compat/pe.js +220 -0
  56. package/dist/core/compat/types.js +1 -0
  57. package/dist/core/compat/version.js +70 -0
  58. package/dist/core/deploy/guards.js +292 -0
  59. package/dist/core/deploy/index.js +5 -0
  60. package/dist/core/deploy/plan.js +696 -0
  61. package/dist/core/deploy/reload-apply.js +361 -0
  62. package/dist/core/deploy/reload.js +358 -0
  63. package/dist/core/deploy/sources.js +169 -0
  64. package/dist/core/deploy/types.js +1 -0
  65. package/dist/core/epic.js +54 -0
  66. package/dist/core/fsutil.js +191 -0
  67. package/dist/core/home.js +70 -0
  68. package/dist/core/knowledge/facts.js +229 -0
  69. package/dist/core/knowledge/index.js +4 -0
  70. package/dist/core/knowledge/search.js +112 -0
  71. package/dist/core/knowledge/store.js +123 -0
  72. package/dist/core/knowledge/types.js +1 -0
  73. package/dist/core/ledger/check.js +42 -0
  74. package/dist/core/ledger/hooks.js +80 -0
  75. package/dist/core/ledger/index.js +7 -0
  76. package/dist/core/ledger/query.js +17 -0
  77. package/dist/core/ledger/record.js +84 -0
  78. package/dist/core/ledger/status.js +53 -0
  79. package/dist/core/ledger/store.js +98 -0
  80. package/dist/core/ledger/types.js +108 -0
  81. package/dist/core/logs/index.js +4 -0
  82. package/dist/core/logs/registry.js +50 -0
  83. package/dist/core/logs/scan.js +195 -0
  84. package/dist/core/logs/triage.js +160 -0
  85. package/dist/core/logs/types.js +1 -0
  86. package/dist/core/lsx.js +10 -0
  87. package/dist/core/lz4.js +66 -0
  88. package/dist/core/mods.js +229 -0
  89. package/dist/core/process.js +49 -0
  90. package/dist/core/project/build-steps.js +83 -0
  91. package/dist/core/project/describe.js +74 -0
  92. package/dist/core/project/index.js +5 -0
  93. package/dist/core/project/load.js +146 -0
  94. package/dist/core/project/schema.js +264 -0
  95. package/dist/core/project/types.js +3 -0
  96. package/dist/core/prompts.js +72 -0
  97. package/dist/core/registry.js +35 -0
  98. package/dist/core/safety/backup.js +206 -0
  99. package/dist/core/safety/execute.js +188 -0
  100. package/dist/core/safety/index.js +5 -0
  101. package/dist/core/safety/plan.js +122 -0
  102. package/dist/core/safety/restore.js +172 -0
  103. package/dist/core/safety/types.js +1 -0
  104. package/dist/core/scaffold/bootstrap.js +7 -0
  105. package/dist/core/scaffold/catalog.js +28 -0
  106. package/dist/core/scaffold/claude-assets.js +271 -0
  107. package/dist/core/scaffold/collisions.js +64 -0
  108. package/dist/core/scaffold/emit.js +356 -0
  109. package/dist/core/scaffold/engine.js +680 -0
  110. package/dist/core/scaffold/ids.js +78 -0
  111. package/dist/core/scaffold/index.js +10 -0
  112. package/dist/core/scaffold/jsonpath.js +121 -0
  113. package/dist/core/scaffold/load.js +81 -0
  114. package/dist/core/scaffold/render.js +85 -0
  115. package/dist/core/scaffold/sequence.js +396 -0
  116. package/dist/core/scaffold/types.js +309 -0
  117. package/dist/core/steam.js +63 -0
  118. package/dist/core/surfaceutil.js +36 -0
  119. package/dist/core/testplan/check.js +67 -0
  120. package/dist/core/testplan/index.js +5 -0
  121. package/dist/core/testplan/load.js +100 -0
  122. package/dist/core/testplan/registry.js +317 -0
  123. package/dist/core/testplan/run.js +389 -0
  124. package/dist/core/testplan/types.js +82 -0
  125. package/dist/core/text/converters/bg3.js +50 -0
  126. package/dist/core/text/converters/cyberpunk.js +36 -0
  127. package/dist/core/text/converters/index.js +261 -0
  128. package/dist/core/text/diff/cr2w.js +180 -0
  129. package/dist/core/text/diff/index.js +16 -0
  130. package/dist/core/text/diff/loca.js +43 -0
  131. package/dist/core/text/diff/lsx.js +126 -0
  132. package/dist/core/text/handles.js +86 -0
  133. package/dist/core/text/index.js +6 -0
  134. package/dist/core/text/json.js +46 -0
  135. package/dist/core/text/templates/cache.js +71 -0
  136. package/dist/core/text/templates/index.js +3 -0
  137. package/dist/core/text/templates/library.js +245 -0
  138. package/dist/core/text/templates/types.js +51 -0
  139. package/dist/core/text/toolchain.js +16 -0
  140. package/dist/core/text/types.js +1 -0
  141. package/dist/core/text/validate.js +149 -0
  142. package/dist/core/text/xml.js +58 -0
  143. package/dist/core/toolchain/datafetch.js +151 -0
  144. package/dist/core/toolchain/env.js +63 -0
  145. package/dist/core/toolchain/features.js +170 -0
  146. package/dist/core/toolchain/index.js +8 -0
  147. package/dist/core/toolchain/install.js +191 -0
  148. package/dist/core/toolchain/locate.js +275 -0
  149. package/dist/core/toolchain/remember.js +84 -0
  150. package/dist/core/toolchain/run.js +318 -0
  151. package/dist/core/toolchain/specs.js +351 -0
  152. package/dist/core/toolchain/types.js +1 -0
  153. package/dist/core/types.js +1 -0
  154. package/dist/core/userconfig.js +66 -0
  155. package/dist/core/validate/context.js +139 -0
  156. package/dist/core/validate/index.js +5 -0
  157. package/dist/core/validate/registry.js +58 -0
  158. package/dist/core/validate/run.js +131 -0
  159. package/dist/core/validate/suppressions.js +91 -0
  160. package/dist/core/validate/types.js +2 -0
  161. package/dist/core/yamledit.js +51 -0
  162. package/dist/index.js +389 -0
  163. package/dist/server.js +1914 -0
  164. package/dist/surfaces/baldursgate3/compat.js +164 -0
  165. package/dist/surfaces/baldursgate3/identity.js +110 -0
  166. package/dist/surfaces/baldursgate3/index/build.js +331 -0
  167. package/dist/surfaces/baldursgate3/index/index.js +17 -0
  168. package/dist/surfaces/baldursgate3/index/info.js +40 -0
  169. package/dist/surfaces/baldursgate3/index/parsers/loca.js +41 -0
  170. package/dist/surfaces/baldursgate3/index/parsers/lsx.js +137 -0
  171. package/dist/surfaces/baldursgate3/index/parsers/stats.js +45 -0
  172. package/dist/surfaces/baldursgate3/index/parsers/treasuretable.js +57 -0
  173. package/dist/surfaces/baldursgate3/index/parsers/xmlutil.js +142 -0
  174. package/dist/surfaces/baldursgate3/index/queries.js +327 -0
  175. package/dist/surfaces/baldursgate3/index/schema.js +62 -0
  176. package/dist/surfaces/baldursgate3/index.js +3 -0
  177. package/dist/surfaces/baldursgate3/logs.js +278 -0
  178. package/dist/surfaces/baldursgate3/modsettings.js +115 -0
  179. package/dist/surfaces/baldursgate3/pak.js +153 -0
  180. package/dist/surfaces/baldursgate3/settings.js +49 -0
  181. package/dist/surfaces/baldursgate3/surface.js +232 -0
  182. package/dist/surfaces/baldursgate3/validators/bridge.js +7 -0
  183. package/dist/surfaces/baldursgate3/validators/files.js +476 -0
  184. package/dist/surfaces/baldursgate3/validators/items.js +1001 -0
  185. package/dist/surfaces/baldursgate3/validators/progression.js +734 -0
  186. package/dist/surfaces/baldursgate3/validators/stats.js +1076 -0
  187. package/dist/surfaces/baldursgate3/validators/story.js +790 -0
  188. package/dist/surfaces/baldursgate3/validators/templates.js +7 -0
  189. package/dist/surfaces/cyberpunk2077/compat.js +223 -0
  190. package/dist/surfaces/cyberpunk2077/index/build.js +231 -0
  191. package/dist/surfaces/cyberpunk2077/index/index.js +17 -0
  192. package/dist/surfaces/cyberpunk2077/index/info.js +51 -0
  193. package/dist/surfaces/cyberpunk2077/index/model.js +52 -0
  194. package/dist/surfaces/cyberpunk2077/index/parsers/tweak.js +483 -0
  195. package/dist/surfaces/cyberpunk2077/index/parsers/tweakxl-yaml.js +183 -0
  196. package/dist/surfaces/cyberpunk2077/index/queries.js +504 -0
  197. package/dist/surfaces/cyberpunk2077/index/resource.js +135 -0
  198. package/dist/surfaces/cyberpunk2077/index/schema.js +90 -0
  199. package/dist/surfaces/cyberpunk2077/index.js +3 -0
  200. package/dist/surfaces/cyberpunk2077/logs.js +742 -0
  201. package/dist/surfaces/cyberpunk2077/paths.js +12 -0
  202. package/dist/surfaces/cyberpunk2077/surface.js +218 -0
  203. package/dist/surfaces/cyberpunk2077/validators/bridge.js +7 -0
  204. package/dist/surfaces/cyberpunk2077/validators/cr2w.js +349 -0
  205. package/dist/surfaces/cyberpunk2077/validators/garments.js +1181 -0
  206. package/dist/surfaces/cyberpunk2077/validators/mesh.js +338 -0
  207. package/dist/surfaces/cyberpunk2077/validators/modsettings.js +120 -0
  208. package/dist/surfaces/cyberpunk2077/validators/packaging.js +463 -0
  209. package/dist/surfaces/cyberpunk2077/validators/red4ext.js +318 -0
  210. package/dist/surfaces/cyberpunk2077/validators/redscript.js +193 -0
  211. package/dist/surfaces/cyberpunk2077/validators/templates.js +7 -0
  212. package/dist/surfaces/cyberpunk2077/validators/tweaks.js +768 -0
  213. package/dist/surfaces/cyberpunk2077/validators/vehicles.js +531 -0
  214. package/dist/surfaces/cyberpunk2077/validators/xl.js +308 -0
  215. package/dist/surfaces/eldenring/binders.js +111 -0
  216. package/dist/surfaces/eldenring/compat.js +166 -0
  217. package/dist/surfaces/eldenring/dcx.js +49 -0
  218. package/dist/surfaces/eldenring/index.js +13 -0
  219. package/dist/surfaces/eldenring/loaders.js +132 -0
  220. package/dist/surfaces/eldenring/logs.js +67 -0
  221. package/dist/surfaces/eldenring/paramdef.js +256 -0
  222. package/dist/surfaces/eldenring/params.js +129 -0
  223. package/dist/surfaces/eldenring/surface.js +121 -0
  224. package/dist/surfaces/eldenring/tools.js +52 -0
  225. package/dist/surfaces/eldenring/validators/binders.js +193 -0
  226. package/dist/surfaces/eldenring/validators/packages.js +159 -0
  227. package/dist/surfaces/eldenring/validators/params.js +334 -0
  228. package/dist/surfaces/eldenring/validators/profiles.js +287 -0
  229. package/dist/surfaces/index.js +34 -0
  230. package/dist/surfaces/nivalisnights/compat.js +229 -0
  231. package/dist/surfaces/nivalisnights/index/build.js +310 -0
  232. package/dist/surfaces/nivalisnights/index/index.js +5 -0
  233. package/dist/surfaces/nivalisnights/index/queries.js +231 -0
  234. package/dist/surfaces/nivalisnights/index.js +4 -0
  235. package/dist/surfaces/nivalisnights/logs.js +473 -0
  236. package/dist/surfaces/nivalisnights/surface.js +195 -0
  237. package/dist/surfaces/skyrimse/archives.js +229 -0
  238. package/dist/surfaces/skyrimse/compat.js +163 -0
  239. package/dist/surfaces/skyrimse/index.js +12 -0
  240. package/dist/surfaces/skyrimse/loadorder.js +174 -0
  241. package/dist/surfaces/skyrimse/logs.js +241 -0
  242. package/dist/surfaces/skyrimse/plugins.js +149 -0
  243. package/dist/surfaces/skyrimse/records.js +94 -0
  244. package/dist/surfaces/skyrimse/surface.js +240 -0
  245. package/dist/surfaces/skyrimse/validators/archive-records.js +165 -0
  246. package/dist/surfaces/skyrimse/validators/archives.js +110 -0
  247. package/dist/surfaces/skyrimse/validators/plugins.js +374 -0
  248. package/dist/surfaces/skyrimse/validators/records.js +117 -0
  249. package/dist/surfaces/stardewvalley/compat.js +190 -0
  250. package/dist/surfaces/stardewvalley/config.js +42 -0
  251. package/dist/surfaces/stardewvalley/contentpatcher.js +203 -0
  252. package/dist/surfaces/stardewvalley/index/index.js +229 -0
  253. package/dist/surfaces/stardewvalley/index/wiki.js +190 -0
  254. package/dist/surfaces/stardewvalley/index.js +12 -0
  255. package/dist/surfaces/stardewvalley/logs.js +307 -0
  256. package/dist/surfaces/stardewvalley/mods.js +182 -0
  257. package/dist/surfaces/stardewvalley/surface.js +244 -0
  258. package/dist/surfaces/stardewvalley/validators/content.js +321 -0
  259. package/dist/surfaces/stardewvalley/validators/fields.js +147 -0
  260. package/dist/surfaces/stardewvalley/validators/loadorder.js +69 -0
  261. package/dist/surfaces/stardewvalley/validators/manifest.js +221 -0
  262. package/dist/surfaces/subnautica2/compat.js +138 -0
  263. package/dist/surfaces/subnautica2/index.js +5 -0
  264. package/dist/surfaces/subnautica2/logs.js +129 -0
  265. package/dist/surfaces/subnautica2/paks.js +173 -0
  266. package/dist/surfaces/subnautica2/surface.js +151 -0
  267. package/dist/surfaces/subnautica2/validators/packaging.js +298 -0
  268. package/dist/surfaces/valheim/compat.js +171 -0
  269. package/dist/surfaces/valheim/index/index.js +301 -0
  270. package/dist/surfaces/valheim/index/tables.js +103 -0
  271. package/dist/surfaces/valheim/index.js +11 -0
  272. package/dist/surfaces/valheim/logs.js +197 -0
  273. package/dist/surfaces/valheim/packaging.js +131 -0
  274. package/dist/surfaces/valheim/plugins.js +270 -0
  275. package/dist/surfaces/valheim/references.js +121 -0
  276. package/dist/surfaces/valheim/surface.js +223 -0
  277. package/dist/surfaces/valheim/validators/packaging.js +218 -0
  278. package/dist/surfaces/valheim/validators/plugins.js +287 -0
  279. package/dist/surfaces/valheim/validators/references.js +169 -0
  280. package/knowledge/baldursgate3/animations.gr2.yaml +166 -0
  281. package/knowledge/baldursgate3/audio.voice.yaml +182 -0
  282. package/knowledge/baldursgate3/audio.wwise.yaml +104 -0
  283. package/knowledge/baldursgate3/charactercreation.heads-hair.yaml +193 -0
  284. package/knowledge/baldursgate3/communitylibrary.shared-content.yaml +129 -0
  285. package/knowledge/baldursgate3/compatibilityframework.api.yaml +176 -0
  286. package/knowledge/baldursgate3/crash.causes.yaml +90 -0
  287. package/knowledge/baldursgate3/dialogue.dialogbank.yaml +120 -0
  288. package/knowledge/baldursgate3/dialogue.files.yaml +236 -0
  289. package/knowledge/baldursgate3/dialogue.osiris-goals.yaml +386 -0
  290. package/knowledge/baldursgate3/dialogue.yaml +122 -0
  291. package/knowledge/baldursgate3/feats.classes.yaml +164 -0
  292. package/knowledge/baldursgate3/items.cloth-physics.yaml +167 -0
  293. package/knowledge/baldursgate3/items.roottemplates.yaml +320 -0
  294. package/knowledge/baldursgate3/items.visualbank.yaml +628 -0
  295. package/knowledge/baldursgate3/journal.quests.yaml +214 -0
  296. package/knowledge/baldursgate3/loadorder.modsettings.yaml +128 -0
  297. package/knowledge/baldursgate3/localization.handles.yaml +92 -0
  298. package/knowledge/baldursgate3/misc.encoding-and-practice.yaml +111 -0
  299. package/knowledge/baldursgate3/origins.companions.yaml +144 -0
  300. package/knowledge/baldursgate3/osiris.signatures.yaml +211 -0
  301. package/knowledge/baldursgate3/packaging.meta.yaml +155 -0
  302. package/knowledge/baldursgate3/packaging.paks.yaml +79 -0
  303. package/knowledge/baldursgate3/process.launch.yaml +34 -0
  304. package/knowledge/baldursgate3/progressions.yaml +92 -0
  305. package/knowledge/baldursgate3/publishing.modio-nexus.yaml +170 -0
  306. package/knowledge/baldursgate3/publishing.toolkit-modio.yaml +135 -0
  307. package/knowledge/baldursgate3/races.progression.yaml +228 -0
  308. package/knowledge/baldursgate3/scriptextender.console.yaml +257 -0
  309. package/knowledge/baldursgate3/scriptextender.yaml +252 -0
  310. package/knowledge/baldursgate3/stats.boosts.yaml +293 -0
  311. package/knowledge/baldursgate3/stats.equipment-kits.yaml +69 -0
  312. package/knowledge/baldursgate3/stats.interrupts.yaml +45 -0
  313. package/knowledge/baldursgate3/stats.itemcombos.yaml +65 -0
  314. package/knowledge/baldursgate3/stats.spells.yaml +293 -0
  315. package/knowledge/baldursgate3/stats.weapons.yaml +210 -0
  316. package/knowledge/baldursgate3/toolchain.divine.yaml +179 -0
  317. package/knowledge/baldursgate3/toolchain.lslib-formats.yaml +242 -0
  318. package/knowledge/baldursgate3/toolkit.levels.yaml +177 -0
  319. package/knowledge/baldursgate3/ui.icons-atlas.yaml +78 -0
  320. package/knowledge/baldursgate3/ui.icons.yaml +412 -0
  321. package/knowledge/baldursgate3/ui.mcm.yaml +161 -0
  322. package/knowledge/baldursgate3/vfx.materials.yaml +174 -0
  323. package/knowledge/baldursgate3/visuals.characterfix.yaml +73 -0
  324. package/knowledge/cyberpunk2077/animations.anims.yaml +118 -0
  325. package/knowledge/cyberpunk2077/anims.archivexl.yaml +163 -0
  326. package/knowledge/cyberpunk2077/anims.authoring.yaml +579 -0
  327. package/knowledge/cyberpunk2077/anims.encoder.yaml +156 -0
  328. package/knowledge/cyberpunk2077/anims.graph.yaml +629 -0
  329. package/knowledge/cyberpunk2077/anims.method.yaml +360 -0
  330. package/knowledge/cyberpunk2077/anims.pipeline.yaml +352 -0
  331. package/knowledge/cyberpunk2077/anims.roundtrip.yaml +222 -0
  332. package/knowledge/cyberpunk2077/anims.sets.yaml +176 -0
  333. package/knowledge/cyberpunk2077/archivexl.bodytypes.yaml +149 -0
  334. package/knowledge/cyberpunk2077/archivexl.dynamic-appearances.yaml +218 -0
  335. package/knowledge/cyberpunk2077/archivexl.manifest.yaml +214 -0
  336. package/knowledge/cyberpunk2077/audio.events.yaml +168 -0
  337. package/knowledge/cyberpunk2077/audio.sounds.yaml +164 -0
  338. package/knowledge/cyberpunk2077/audio.voicesets.yaml +146 -0
  339. package/knowledge/cyberpunk2077/cet.sandbox.yaml +219 -0
  340. package/knowledge/cyberpunk2077/clothing.garments.yaml +283 -0
  341. package/knowledge/cyberpunk2077/clothing.refits.yaml +215 -0
  342. package/knowledge/cyberpunk2077/codeware.overview.yaml +111 -0
  343. package/knowledge/cyberpunk2077/codeware.systems.yaml +192 -0
  344. package/knowledge/cyberpunk2077/drones.combat.yaml +416 -0
  345. package/knowledge/cyberpunk2077/drones.control.yaml +552 -0
  346. package/knowledge/cyberpunk2077/entities.appearance.yaml +166 -0
  347. package/knowledge/cyberpunk2077/equipmentex.slots.yaml +151 -0
  348. package/knowledge/cyberpunk2077/fx.effects.yaml +246 -0
  349. package/knowledge/cyberpunk2077/fx.lights.yaml +171 -0
  350. package/knowledge/cyberpunk2077/hair.modding.yaml +145 -0
  351. package/knowledge/cyberpunk2077/items.wiring.yaml +246 -0
  352. package/knowledge/cyberpunk2077/loadorder.archives.yaml +71 -0
  353. package/knowledge/cyberpunk2077/mesh.blender.yaml +209 -0
  354. package/knowledge/cyberpunk2077/nativedb.dump.yaml +98 -0
  355. package/knowledge/cyberpunk2077/npc.appearance.yaml +275 -0
  356. package/knowledge/cyberpunk2077/npc.behaviour.yaml +128 -0
  357. package/knowledge/cyberpunk2077/npc.locomotion.yaml +490 -0
  358. package/knowledge/cyberpunk2077/packaging.deploy.yaml +175 -0
  359. package/knowledge/cyberpunk2077/packaging.variants.yaml +176 -0
  360. package/knowledge/cyberpunk2077/player.control.yaml +918 -0
  361. package/knowledge/cyberpunk2077/process.assetbuild.yaml +154 -0
  362. package/knowledge/cyberpunk2077/process.lessons.yaml +276 -0
  363. package/knowledge/cyberpunk2077/quests.minor.yaml +46 -0
  364. package/knowledge/cyberpunk2077/quests.scenes.yaml +282 -0
  365. package/knowledge/cyberpunk2077/quickhacks.tiers.yaml +41 -0
  366. package/knowledge/cyberpunk2077/red4ext.api.yaml +645 -0
  367. package/knowledge/cyberpunk2077/red4ext.plugins.yaml +124 -0
  368. package/knowledge/cyberpunk2077/redhottools.hotreload.yaml +245 -0
  369. package/knowledge/cyberpunk2077/redscript.compile-log.yaml +76 -0
  370. package/knowledge/cyberpunk2077/redscript.modules.yaml +118 -0
  371. package/knowledge/cyberpunk2077/toolchain.wolvenkit.yaml +163 -0
  372. package/knowledge/cyberpunk2077/tweakdb.loot-recipes.yaml +184 -0
  373. package/knowledge/cyberpunk2077/tweakdb.melee.yaml +352 -0
  374. package/knowledge/cyberpunk2077/tweakdb.weapons.yaml +325 -0
  375. package/knowledge/cyberpunk2077/tweakxl.hotreload.yaml +151 -0
  376. package/knowledge/cyberpunk2077/tweakxl.yaml-syntax.yaml +208 -0
  377. package/knowledge/cyberpunk2077/ui.icons.yaml +259 -0
  378. package/knowledge/cyberpunk2077/ui.inkatlas.yaml +81 -0
  379. package/knowledge/cyberpunk2077/ui.modsettings.yaml +204 -0
  380. package/knowledge/cyberpunk2077/vehicles.control.yaml +475 -0
  381. package/knowledge/cyberpunk2077/vehicles.dashboard-ui.yaml +203 -0
  382. package/knowledge/cyberpunk2077/vehicles.entities.yaml +195 -0
  383. package/knowledge/cyberpunk2077/vehicles.wiring.yaml +137 -0
  384. package/knowledge/cyberpunk2077/wolvenkit.cli.yaml +167 -0
  385. package/knowledge/cyberpunk2077/workspot.system.yaml +55 -0
  386. package/knowledge/cyberpunk2077/world.interactions.yaml +41 -0
  387. package/knowledge/cyberpunk2077/world.loot-container.yaml +167 -0
  388. package/knowledge/cyberpunk2077/world.sectors.yaml +233 -0
  389. package/knowledge/eldenring/formats.binders.yaml +237 -0
  390. package/knowledge/eldenring/launcher.me3.yaml +230 -0
  391. package/knowledge/eldenring/launcher.modengine2.yaml +119 -0
  392. package/knowledge/eldenring/params.paramdef.yaml +149 -0
  393. package/knowledge/eldenring/params.regulation.yaml +142 -0
  394. package/knowledge/eldenring/saves.online.yaml +118 -0
  395. package/knowledge/eldenring/toolchain.cli.yaml +256 -0
  396. package/knowledge/nivalisnights/modding.runtime.yaml +157 -0
  397. package/knowledge/skyrimse/archives.bsa.yaml +212 -0
  398. package/knowledge/skyrimse/install.detection.yaml +41 -0
  399. package/knowledge/skyrimse/loadorder.files.yaml +242 -0
  400. package/knowledge/skyrimse/plugins.esl.yaml +189 -0
  401. package/knowledge/skyrimse/plugins.format.yaml +224 -0
  402. package/knowledge/skyrimse/skse.runtime.yaml +283 -0
  403. package/knowledge/skyrimse/toolchain.xedit-spriggit.yaml +336 -0
  404. package/knowledge/stardewvalley/contentpatcher.format.yaml +338 -0
  405. package/knowledge/stardewvalley/distribution.channels.yaml +236 -0
  406. package/knowledge/stardewvalley/game.versions.yaml +202 -0
  407. package/knowledge/stardewvalley/install.layout.yaml +277 -0
  408. package/knowledge/stardewvalley/smapi.loader.yaml +284 -0
  409. package/knowledge/stardewvalley/smapi.logs.yaml +329 -0
  410. package/knowledge/stardewvalley/smapi.manifest.yaml +293 -0
  411. package/knowledge/stardewvalley/toolchain.build.yaml +261 -0
  412. package/knowledge/stardewvalley/wiki.dataformat.yaml +130 -0
  413. package/knowledge/subnautica2/game.build.yaml +331 -0
  414. package/knowledge/subnautica2/modding.state.yaml +210 -0
  415. package/knowledge/subnautica2/ue5.containers.yaml +72 -0
  416. package/knowledge/subnautica2/ue5.paks.yaml +203 -0
  417. package/knowledge/subnautica2/ue5.tooling.yaml +175 -0
  418. package/knowledge/subnautica2/ue5.ue4ss.yaml +203 -0
  419. package/knowledge/valheim/bepinex.loader.yaml +247 -0
  420. package/knowledge/valheim/bepinex.plugins.yaml +251 -0
  421. package/knowledge/valheim/game.versions.yaml +321 -0
  422. package/knowledge/valheim/install.layout.yaml +216 -0
  423. package/knowledge/valheim/jotunn.library.yaml +334 -0
  424. package/knowledge/valheim/thunderstore.packaging.yaml +217 -0
  425. package/knowledge/valheim/toolchain.build.yaml +111 -0
  426. package/package.json +29 -0
  427. package/scaffolds/baldursgate3/new-class-injection.yaml +148 -0
  428. package/scaffolds/baldursgate3/new-item.yaml +264 -0
  429. package/scaffolds/baldursgate3/new-mod.yaml +174 -0
  430. package/scaffolds/baldursgate3/new-passive.yaml +100 -0
  431. package/scaffolds/baldursgate3/new-project.yaml +118 -0
  432. package/scaffolds/baldursgate3/new-quest-stub.yaml +159 -0
  433. package/scaffolds/baldursgate3/new-spell.yaml +102 -0
  434. package/scaffolds/baldursgate3/new-status.yaml +119 -0
  435. package/scaffolds/baldursgate3/sequences/subclass-kit.yaml +50 -0
  436. package/scaffolds/cyberpunk2077/edit-tweak.yaml +70 -0
  437. package/scaffolds/cyberpunk2077/mesh-export-preset.yaml +170 -0
  438. package/scaffolds/cyberpunk2077/new-entity-patch.yaml +255 -0
  439. package/scaffolds/cyberpunk2077/new-garment-refit.yaml +279 -0
  440. package/scaffolds/cyberpunk2077/new-item-chain.yaml +548 -0
  441. package/scaffolds/cyberpunk2077/new-localization.yaml +130 -0
  442. package/scaffolds/cyberpunk2077/new-mod-settings.yaml +133 -0
  443. package/scaffolds/cyberpunk2077/new-player-replacer.yaml +1003 -0
  444. package/scaffolds/cyberpunk2077/new-project.yaml +157 -0
  445. package/scaffolds/cyberpunk2077/new-sector-node.yaml +156 -0
  446. package/scaffolds/cyberpunk2077/new-tweak.yaml +121 -0
  447. package/scaffolds/cyberpunk2077/new-vehicle-livery.yaml +148 -0
  448. package/scaffolds/cyberpunk2077/new-workspot-entity.yaml +177 -0
  449. package/scaffolds/cyberpunk2077/sequences/iconic-weapon.yaml +72 -0
  450. package/scaffolds/cyberpunk2077/sequences/quickhack-takeover.yaml +213 -0
  451. package/scaffolds/stardewvalley/new-cp-patch.yaml +106 -0
  452. package/scaffolds/stardewvalley/new-csharp-mod.yaml +195 -0
  453. package/scaffolds/stardewvalley/new-project.yaml +184 -0
  454. package/scaffolds/stardewvalley/sequences/content-pack.yaml +31 -0
  455. package/scripts/mw-tool.mjs +184 -0
@@ -0,0 +1,293 @@
1
+ game: stardewvalley
2
+ topic: smapi.manifest
3
+ title: manifest.json — the fields, the exact validation rules, and the published JSON Schema
4
+ facts:
5
+ - id: stardewvalley.smapi.manifest.every-mod-has-one
6
+ claim: Every SMAPI mod and every content pack must have a `manifest.json` in its folder; SMAPI uses
7
+ it to identify and load the mod and to perform update checks, and the parsed manifest is
8
+ available to mods at runtime through `this.ModManifest` and the mod registry.
9
+ status: community
10
+ source: 'https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest (read 2026-09-11): "Every
11
+ SMAPI mod or content pack must have a manifest.json file in its folder. SMAPI uses this to
12
+ identify and load the mod, perform update checks, etc."'
13
+ tags:
14
+ - manifest
15
+ - required
16
+ - mods
17
+ - scanning
18
+ - id: stardewvalley.smapi.manifest.fields
19
+ claim: The manifest fields are `Name`, `Author`, `Version`, `Description`, `UniqueID`,
20
+ `MinimumApiVersion`, `MinimumGameVersion`, `EntryDll`, `ContentPackFor`, `Dependencies` and
21
+ `UpdateKeys`. Any other field is kept in `IManifest.ExtraFields` and ignored by SMAPI.
22
+ status: community
23
+ source: https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest ("Any other fields will be
24
+ stored in the IManifest.ExtraFields dictionary, which is available through the mod registry.
25
+ Extra fields are ignored by SMAPI, but may be useful for extended metadata intended for other
26
+ mods."); the same set is the constructor signature of
27
+ src/SMAPI.Toolkit/Serialization/Models/Manifest.cs, which carries `[JsonExtensionData] public
28
+ IDictionary<string, object> ExtraFields`
29
+ tags:
30
+ - manifest
31
+ - fields
32
+ - extrafields
33
+ - validator
34
+ detail: "The published JSON Schema sets `additionalProperties: false`, which contradicts the
35
+ runtime. The runtime is authoritative: a validator should report an unknown field at `info`,
36
+ never block on it."
37
+ - id: stardewvalley.smapi.manifest.entrydll-xor-contentpackfor
38
+ claim: A mod must declare exactly one of `EntryDll` (a C# mod) or `ContentPackFor` (a content pack).
39
+ SMAPI's first validation check is `if (hasDll == isContentPack)`, failing with "manifest sets
40
+ both EntryDll and ContentPackFor, which are mutually exclusive." or "manifest has no EntryDll
41
+ or ContentPackFor field; must specify one."
42
+ status: inferred
43
+ source: SMAPI develop,
44
+ https://github.com/Pathoschild/SMAPI/blob/develop/src/SMAPI.Toolkit/Framework/ManifestValidator.cs,
45
+ `TryValidateFields(...)`; stated for authors at
46
+ https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest ("These are mutually
47
+ exclusive — you can't specify both.")
48
+ tags:
49
+ - manifest
50
+ - validator
51
+ - block
52
+ - entrydll
53
+ - contentpackfor
54
+ detail: This is checked before anything else and it is the most common concrete manifest error. A
55
+ `block`-severity validator with SMAPI's own wording is the right shape. The same condition
56
+ also decides the mod's *type* during scanning, so getting it wrong makes the folder
57
+ `ModType.Invalid` rather than producing a partially working mod.
58
+ - id: stardewvalley.smapi.manifest.validation-order
59
+ claim: "SMAPI validates the manifest in a fixed order and returns on the first failure:
60
+ EntryDll/ContentPackFor exclusivity, then EntryDll filename characters, then ContentPackFor's
61
+ required UniqueID, then missing required fields (Name, Version, UniqueID), then the UniqueID
62
+ slug format, then each dependency entry."
63
+ status: inferred
64
+ source: SMAPI develop, src/SMAPI.Toolkit/Framework/ManifestValidator.cs,
65
+ `TryValidateFields(IManifest manifest, out string error)`
66
+ tags:
67
+ - manifest
68
+ - validator
69
+ - order
70
+ - errors
71
+ detail: "The method's own header comment explains why every message is a sentence fragment: \"SMAPI
72
+ assumes that it can grammatically append the returned sentence in the form `failed loading
73
+ <mod> because its <error>`. Any errors returned should be valid in that format\". That is what
74
+ makes them matchable in a log."
75
+ - id: stardewvalley.smapi.manifest.version-zero-counts-as-missing
76
+ claim: "A `Version` of `\"0.0.0\"` is treated as *missing*, not as a version: SMAPI's required-field
77
+ check is `if (manifest.Version == null || manifest.Version.ToString() == \"0.0.0\")`."
78
+ status: inferred
79
+ source: SMAPI develop, src/SMAPI.Toolkit/Framework/ManifestValidator.cs, `TryValidateFields(...)`
80
+ required-fields block
81
+ tags:
82
+ - manifest
83
+ - version
84
+ - validator
85
+ - block
86
+ - gotcha
87
+ detail: No JSON Schema expresses this — `0.0.0` matches the published SemanticVersion pattern
88
+ perfectly — so a validator that only runs the schema will pass a manifest SMAPI will refuse
89
+ with "manifest is missing required fields (Version)." It is a realistic default value for a
90
+ generated project file, which is why it is worth a dedicated rule.
91
+ - id: stardewvalley.smapi.manifest.uniqueid-format
92
+ claim: "`UniqueID` must match `^[a-zA-Z0-9_.-]+$` (letters, numbers, underscores, periods, hyphens)
93
+ to pass the published schema; SMAPI's runtime check (`PathUtilities.IsSlug`, rejection class
94
+ `[^\\p{L}\\d_\\.\\-]`) accepts any Unicode letter, so a non-ASCII id loads and only the schema
95
+ objects. The recommended format is `<your name>.<mod name>`, and once published it must never
96
+ change, because other mods reference it."
97
+ status: community
98
+ source: 'Pattern and its provenance from https://smapi.io/schemas/manifest.json (`"ModID": { "type":
99
+ "string", "pattern": "^[a-zA-Z0-9_.-]+$", "$comment": "derived from
100
+ SMAPI.Toolkit.Utilities.PathUtilities.IsSlug" }`); the runtime check from SMAPI develop,
101
+ src/SMAPI.Toolkit/Utilities/PathUtilities.cs: `return string.IsNullOrEmpty(str) ||
102
+ !Regex.IsMatch(str, @"[^\p{L}\d_\.\-]", RegexOptions.IgnoreCase);`; the rule and the "do not
103
+ change this unique ID in future versions of the same mod" instruction from
104
+ https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest'
105
+ tags:
106
+ - manifest
107
+ - uniqueid
108
+ - slug
109
+ - validator
110
+ - block
111
+ detail: SMAPI's own failure text is "manifest specifies an invalid ID (IDs must only contain
112
+ letters, numbers, underscores, periods, or hyphens)." The same slug rule applies to every
113
+ `Dependencies[].UniqueID`.
114
+ - id: stardewvalley.smapi.manifest.semantic-version-pattern
115
+ claim: "`Version` must match
116
+ `^(?>(?:0|[1-9]\\d*))\\.(?>(?:0|[1-9]\\d*))(?>(?:\\.(?:0|[1-9]\\d*))?)(?:-(?:(?>[a-zA-Z0-9]+[\
117
+ \\-\\.]?)+))?$` or be the literal string `%ProjectVersion%` to pass the published schema. The
118
+ patch segment is optional. Build metadata (`+...`) is rejected by the schema but parsed by
119
+ SMAPI's runtime `SemanticVersionReader`, so a `1.2.0+build5` loads; the runtime is
120
+ authoritative and a validator should warn, not block."
121
+ status: community
122
+ source: "https://smapi.io/schemas/manifest.json, `definitions.SemanticVersion` (with `\"$comment\":
123
+ \"derived from SMAPI.Toolkit.SemanticVersion\"`) and the `anyOf` on the `Version` property;
124
+ the runtime's build-metadata branch from SMAPI develop,
125
+ src/SMAPI.Toolkit/Framework/SemanticVersionReader.cs: `// read optional build tag / if
126
+ (TryParseLiteral(raw, ref i, '+') && !TryParseTag(raw, ref i, out buildMetadata)) return
127
+ false;` — reached whether or not `allowNonStandard` is set"
128
+ tags:
129
+ - manifest
130
+ - version
131
+ - semver
132
+ - validator
133
+ - pattern
134
+ detail: "Two consequences a hand-written rule gets wrong: `1.2` is valid (the patch part is
135
+ optional), and `1.2.0+build5` fails the schema while loading in SMAPI
136
+ (src/SMAPI.Toolkit/Framework/SemanticVersionReader.cs parses the build-metadata segment). The
137
+ schema's own error message is \"Invalid Value. This must be formatted like 1.2.0 or
138
+ 1.2.0-prerelease.tags ..., or the exact string '%ProjectVersion%'.\""
139
+ - id: stardewvalley.smapi.manifest.project-version-token
140
+ claim: "`\"Version\": \"%ProjectVersion%\"` in a manifest is replaced with the `.csproj`'s
141
+ `<Version>` at build time by the ModBuildConfig NuGet package, in both the deployed copy and
142
+ the release zip."
143
+ status: community
144
+ source: 'https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/mod-package.md, "Manifest
145
+ tokens": "you can use `%ProjectVersion%` in your manifest.json. This will be replaced with
146
+ your project version automatically in your game folder and the release zip."'
147
+ tags:
148
+ - manifest
149
+ - version
150
+ - build
151
+ - modbuildconfig
152
+ - scaffold
153
+ detail: Added in ModBuildConfig 4.4.0 (13 April 2025). A scaffold for a C# mod should use it, since
154
+ it removes an entire class of "the manifest says 1.0.0 and the DLL says 1.2.0" drift. It also
155
+ works for bundled content packs.
156
+ - id: stardewvalley.smapi.manifest.entrydll-must-exist
157
+ claim: "`EntryDll` must match `^[a-zA-Z0-9_.-]+\\.dll$`, must contain no invalid filename
158
+ characters, and must name a file that actually exists in the mod folder — SMAPI refuses the
159
+ mod with \"its DLL '{EntryDll}' doesn't exist.\""
160
+ status: inferred
161
+ source: Pattern from https://smapi.io/schemas/manifest.json; the character check and the existence
162
+ check from SMAPI develop, src/SMAPI.Toolkit/Framework/ManifestValidator.cs and
163
+ src/SMAPI/Framework/ModLoading/ModResolver.cs `ValidateManifests(...)`
164
+ tags:
165
+ - manifest
166
+ - entrydll
167
+ - validator
168
+ - block
169
+ - filesystem
170
+ detail: "The existence check is a pure filesystem check with no game, no index and no toolchain, and
171
+ it catches a mod that will not load at all. Highest value per line of code of any rule in this
172
+ file. It applies to the manifest SMAPI reads, the deployed one: a C# project's source manifest
173
+ sits beside its .csproj and the DLL is a build output (the build package assembles that
174
+ folder, the manifest beside the DLL with %ProjectVersion% substituted, when it deploys or
175
+ zips), so a validator reading the source tree must not block on it there."
176
+ - id: stardewvalley.smapi.manifest.dependencies-shape
177
+ claim: "`Dependencies` is a list of `{ UniqueID, MinimumVersion?, IsRequired? }`. `MinimumVersion`
178
+ is optional (\"If specified, older versions won't meet the requirement\"); `IsRequired: false`
179
+ makes the dependency optional — \"It will be loaded first if it's installed, otherwise it'll
180
+ be ignored.\""
181
+ status: community
182
+ source: https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest, the Dependencies section
183
+ and its two worked examples
184
+ tags:
185
+ - manifest
186
+ - dependencies
187
+ - load-order
188
+ - validator
189
+ detail: Note that an optional dependency still *orders* the load when present — the flag only
190
+ decides whether a missing one is fatal, exactly as BepInEx's SoftDependency does on Valheim.
191
+ Validation rejects a null entry, a blank `UniqueID`, or a non-slug `UniqueID`, each with its
192
+ own message.
193
+ - id: stardewvalley.smapi.manifest.contentpackfor-shape
194
+ claim: '`ContentPackFor` is `{ UniqueID, MinimumVersion? }` naming the framework mod that reads this
195
+ pack — for Content Patcher, `{"UniqueID": "Pathoschild.ContentPatcher"}`. A blank `UniqueID`
196
+ fails with "manifest declares ContentPackFor without its required UniqueID field."'
197
+ status: community
198
+ source: https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest ("For a content pack,
199
+ ContentPackFor specifies which mod can read it. The MinimumVersion is optional."); the failure
200
+ text from src/SMAPI.Toolkit/Framework/ManifestValidator.cs
201
+ tags:
202
+ - manifest
203
+ - contentpackfor
204
+ - content-pack
205
+ - scaffold
206
+ detail: The `UniqueID` here names the *framework* that reads the pack, not the pack itself, so it
207
+ stays `Pathoschild.ContentPatcher` while every other id in the file is the author's own — an
208
+ easy thing to overwrite when a scaffold's placeholders are filled in by hand. No source says
209
+ this explicitly; it follows from the wiki's own definition ("ContentPackFor specifies which
210
+ mod can read it") and from `ModResolver` resolving the id against an installed mod.
211
+ - id: stardewvalley.smapi.manifest.minimum-versions
212
+ claim: '`MinimumApiVersion` and `MinimumGameVersion` set the minimum SMAPI and Stardew Valley
213
+ versions needed. A player below either sees the mod skipped with "it needs SMAPI {v} or
214
+ later..." or "it needs Stardew Valley {v} or later...".'
215
+ status: community
216
+ source: https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest ("If a player tries to use
217
+ the mod with an older version, they'll see a friendly message saying they need to update
218
+ it."); the two messages from src/SMAPI/Framework/ModLoading/ModResolver.cs
219
+ `ValidateManifests(...)`
220
+ tags:
221
+ - manifest
222
+ - version
223
+ - compat
224
+ - validator
225
+ detail: "Worth a validator of its own: a mod declaring `MinimumApiVersion` higher than the SMAPI
226
+ installed on the machine under test will silently not load during testing, and the reason will
227
+ be in a list most people do not scroll to."
228
+ - id: stardewvalley.smapi.manifest.update-keys
229
+ claim: "`UpdateKeys` entries must match
230
+ `^(?i)(Chucklefish:\\d+|Nexus:\\d+|GitHub:[A-Za-z0-9_\\-\\.]+/[A-Za-z0-9_\\-]+|ModDrop:\\d+|C\
231
+ urseForge:\\d+)(?: *@ *[a-zA-Z0-9_]+ *)?$` — five sites plus an optional `@subkey`."
232
+ status: community
233
+ source: https://smapi.io/schemas/manifest.json, the `UpdateKeys` item pattern, whose error message
234
+ is "Invalid update key; see
235
+ https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest#Update_checks for more info."
236
+ tags:
237
+ - manifest
238
+ - updatekeys
239
+ - distribution
240
+ - validator
241
+ - pattern
242
+ detail: This regex is also the machine-readable statement of which distribution channels SMAPI knows
243
+ about. Chucklefish is marked deprecated on the wiki. A bad key breaks update alerts rather
244
+ than the mod, so `warn`, not `block`.
245
+ - id: stardewvalley.smapi.manifest.update-subkeys
246
+ claim: An update subkey (`"Nexus:2400@GeodeCrusher"`) narrows an update check to files whose title
247
+ or description contains `@GeodeCrusher`, for the case of several mods sharing one mod page. If
248
+ no file matches the subkey SMAPI ignores it and does a normal check.
249
+ status: community
250
+ source: https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Update_checks (read 2026-09-11),
251
+ "Update subkeys"
252
+ tags:
253
+ - manifest
254
+ - updatekeys
255
+ - subkey
256
+ - distribution
257
+ detail: "Two documented caveats: CurseForge subkeys in a file description are not visible through
258
+ its API, and GitHub subkeys do nothing because only the latest release is fetched."
259
+ - id: stardewvalley.smapi.manifest.name-brackets-are-rewritten
260
+ claim: SMAPI strips newlines from every manifest string field, and in `Name` only it replaces `[`
261
+ with `(` and `]` with `)`, with the in-source reason that this "is used in the mod name to
262
+ avoid breaking the log format".
263
+ status: inferred
264
+ source: SMAPI develop, src/SMAPI.Toolkit/Serialization/Models/Manifest.cs, `NormalizeField(string?
265
+ input, bool replaceSquareBrackets = false)`
266
+ tags:
267
+ - manifest
268
+ - name
269
+ - log
270
+ - signature
271
+ - gotcha
272
+ detail: "Relevant to log signatures: a mod's display name in a log line can never contain a square
273
+ bracket, which is what lets SMAPI's own `MessageHeaderPattern` end the source capture at the
274
+ first `]`. It also means a pack folder named `[CP] Something` will appear in the log as `(CP)
275
+ Something` if that string is also its `Name`."
276
+ - id: stardewvalley.smapi.manifest.published-json-schema
277
+ claim: 'SMAPI publishes a JSON Schema for the manifest at `https://smapi.io/schemas/manifest.json`,
278
+ referenceable from a file with `"$schema": "https://smapi.io/schemas/manifest.json"`. Its
279
+ required set is `["Name", "Author", "Version", "Description", "UniqueID"]`.'
280
+ status: community
281
+ source: https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/web.md, "Using a schema
282
+ file directly", which tabulates the three published schemas; the required set read from
283
+ https://smapi.io/schemas/manifest.json on 2026-09-11
284
+ tags:
285
+ - manifest
286
+ - schema
287
+ - validator
288
+ - smapi-io
289
+ - tooling
290
+ detail: No other ModWright surface has a first-party machine-readable schema for its authored
291
+ format. Validating against it and adding only the rules it cannot state — the `0.0.0` case,
292
+ the EntryDll existence check, and the additionalProperties disagreement — is strictly better
293
+ than maintaining an independent opinion. The web validator that uses it is at smapi.io/json.
@@ -0,0 +1,261 @@
1
+ game: stardewvalley
2
+ topic: toolchain.build
3
+ title: Building a Stardew mod — the ModBuildConfig NuGet package, the release zip, and XNB unpacking
4
+ facts:
5
+ - id: stardewvalley.toolchain.build.modbuildconfig-package
6
+ claim: The build toolchain is one NuGet package, `Pathoschild.Stardew.ModBuildConfig`, currently
7
+ 4.4.0 (13 April 2025) "for SMAPI 4.1.0 or later". It finds the game folder, adds the game and
8
+ SMAPI assembly references, deploys the mod and builds a release zip.
9
+ status: community
10
+ source: https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/mod-package.md ("an
11
+ open-source NuGet package which automates the MSBuild configuration for SMAPI mods and related
12
+ tools"); version list from
13
+ https://api.nuget.org/v3-flatcontainer/pathoschild.stardew.modbuildconfig/index.json and the
14
+ release notes at docs/technical/mod-package-release-notes.md, both read 2026-09-11
15
+ tags:
16
+ - build
17
+ - nuget
18
+ - msbuild
19
+ - csharp
20
+ - toolchain
21
+ detail: A content pack needs none of this — there is nothing to compile — which is why a Stardew
22
+ surface can do most of its work with no toolchain at all.
23
+ - id: stardewvalley.toolchain.build.assembly-references
24
+ claim: "The package adds exactly seven references, all resolved out of the installed game folder:
25
+ `Stardew Valley.dll`, `StardewValley.GameData.dll`, `MonoGame.Framework.dll`, `xTile.dll`,
26
+ `StardewModdingAPI.dll`, `smapi-internal\\SMAPI.Toolkit.CoreInterfaces.dll`, and — only when
27
+ `EnableHarmony` is true — `smapi-internal\\0Harmony.dll`."
28
+ status: inferred
29
+ source: SMAPI develop,
30
+ https://github.com/Pathoschild/SMAPI/blob/develop/src/SMAPI.ModBuildConfig/build/smapi.targets,
31
+ the `<Reference>` ItemGroup
32
+ tags:
33
+ - build
34
+ - references
35
+ - csharp
36
+ - dist
37
+ - validator
38
+ detail: "These seven names are exactly the never-ships list for a dist validator: they are game and
39
+ loader assemblies, copy-local only when `BundleExtraAssemblies` includes `Game`, which the
40
+ docs mark as \"a specialized option. Most mods should not change this option.\" A mod folder
41
+ or release zip containing any of them is a packaging error of the same shape as ModWright's
42
+ existing `vanilla-extract-never-ships` rule."
43
+ - id: stardewvalley.toolchain.build.requires-the-game-installed
44
+ claim: 'The build package hard-fails when the game or SMAPI is missing, with three MSBuild errors:
45
+ the game folder not existing, the folder not containing `Stardew Valley.dll`, and the folder
46
+ not containing `StardewModdingAPI.dll` ("You need to install SMAPI before building the
47
+ mod.").'
48
+ status: inferred
49
+ source: SMAPI develop, src/SMAPI.ModBuildConfig/build/smapi.targets, the `BeforeBuild` target's
50
+ three `<Error Condition="!Exists(...)">` elements
51
+ tags:
52
+ - build
53
+ - requires-game
54
+ - csharp
55
+ - blocking
56
+ - testing
57
+ detail: So a C# Stardew mod **cannot be compiled on a machine without the game and SMAPI installed**
58
+ — a sharper constraint than any other supported game, where the payload is data. A content
59
+ pack has no such constraint. This is the main argument for making a first Stardew project a
60
+ content pack.
61
+ - id: stardewvalley.toolchain.build.anycpu-warning
62
+ claim: "The package warns when the target platform is not `AnyCPU`: \"The target platform should be
63
+ set to 'Any CPU' for compatibility with both 32-bit and 64-bit versions of Stardew Valley
64
+ (currently set to '{x}').\""
65
+ status: inferred
66
+ source: SMAPI develop, src/SMAPI.ModBuildConfig/build/smapi.targets, the `BeforeBuild` target's
67
+ `<Warning Condition="'$(Platform)' != 'AnyCPU'" ...>`
68
+ tags:
69
+ - build
70
+ - csproj
71
+ - validator
72
+ - warn
73
+ detail: Checkable statically from the `.csproj`, so it is a validator ModWright can run before
74
+ MSBuild does. The internal value is `AnyCPU`; Visual Studio shows it as "Any CPU".
75
+ - id: stardewvalley.toolchain.build.deploy-and-zip-properties
76
+ claim: "The build package deploys and zips by default: `EnableModDeploy` (default true) copies the
77
+ mod into `$(GameModsPath)`, which defaults to `$(GamePath)/Mods`; `EnableModZip` (default
78
+ true) writes a release zip into `$(ModZipPath)`, which defaults to the project's `bin` folder;
79
+ `ModFolderName` defaults to the project name."
80
+ status: inferred
81
+ source: SMAPI develop, src/SMAPI.ModBuildConfig/build/smapi.targets, the default PropertyGroup;
82
+ documented at https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/mod-package.md
83
+ under "Available properties"
84
+ tags:
85
+ - build
86
+ - deploy
87
+ - zip
88
+ - msbuild
89
+ - conflict
90
+ detail: "This collides with ModWright owning deploy: MSBuild would copy the same files with no
91
+ backup and no write plan. A ModWright-managed project should set
92
+ `<EnableModDeploy>false</EnableModDeploy>` and `<EnableModZip>false</EnableModZip>` so deploy
93
+ stays a `WritePlan` over `core/safety` with a rollback. That should be a documented
94
+ requirement of the scaffold, not a surprise discovered when two systems write the same files."
95
+ - id: stardewvalley.toolchain.build.release-zip-shape
96
+ claim: The release zip is named `{ModFolderName} {Version}.zip` and its entries are
97
+ `{ModFolderName}/{relative path}`, with forward slashes regardless of OS — so unzipping it
98
+ into `Mods/` produces a correctly nested mod folder.
99
+ status: inferred
100
+ source: 'SMAPI develop,
101
+ https://github.com/Pathoschild/SMAPI/blob/develop/src/SMAPI.ModBuildConfig/DeployModTask.cs:
102
+ `string zipName = this.EscapeInvalidFilenameCharacters($"{this.ModFolderName}
103
+ {manifest.Version}.zip");` and `archivePath = $"{this.ModFolderName}/{relativePath}"` with the
104
+ comment "zip files use forward slashes regardless of OS"'
105
+ tags:
106
+ - build
107
+ - zip
108
+ - packaging
109
+ - verify
110
+ - validator
111
+ detail: "A ModWright build's verify step can assert exactly this: one top-level folder named after
112
+ the mod, containing `manifest.json`. Bundled content packs nest one level deeper as
113
+ `{ModFolderName}/{contentPackFolder}/...`."
114
+ - id: stardewvalley.toolchain.build.ignore-properties
115
+ claim: "`IgnoreModFilePaths` (a comma-delimited list of literal paths relative to `bin`) and
116
+ `IgnoreModFilePatterns` (a comma-delimited list of regexes) exclude files from both the deploy
117
+ and the zip. Path delimiters in a pattern should be written `[/\\\\]` for crossplatform use."
118
+ status: community
119
+ source: https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/mod-package.md,
120
+ "Specialized properties", with the worked example `<IgnoreModFilePatterns>\.txt$, \.pdf$,
121
+ assets[/\\]paths.png</IgnoreModFilePatterns>`
122
+ tags:
123
+ - build
124
+ - packaging
125
+ - exclude
126
+ - msbuild
127
+ detail: "The literal-path list is case-sensitive but normalises path delimiters. Relevant to a dist
128
+ validator: if a project excludes a file here, the file is still in `bin` and a naive staging
129
+ step that copies `bin` wholesale would ship it."
130
+ - id: stardewvalley.toolchain.build.bundled-content-packs
131
+ claim: A C# mod can bundle content packs with a `<ContentPacks Include="..." Version="$(Version)"
132
+ />` item group; they are grouped under a parent folder in both the deploy and the zip, and the
133
+ package validates that each bundled pack's manifest version matches the declared `Version`.
134
+ status: community
135
+ source: https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/mod-package.md, "Bundled
136
+ content packs", and the per-item property table (`Include`, `Version`, `FolderName`,
137
+ `ValidateManifest`, `IgnoreModFilePaths`, `IgnoreModFilePatterns`)
138
+ tags:
139
+ - build
140
+ - content-pack
141
+ - bundling
142
+ - validator
143
+ detail: "The version cross-check is a validator ModWright can perform statically and should: a mod
144
+ whose bundled pack's version drifts from the parent's produces out-of-sync update alerts,
145
+ which is exactly what the `Version` property exists to prevent."
146
+ - id: stardewvalley.toolchain.build.code-analyzers
147
+ claim: "The package ships Roslyn analyzers that raise two Stardew-specific warnings at build time:
148
+ \"'{{expression}}' is a {{net type}} field; consider using the {{property name}} property
149
+ instead.\" and \"The '{{old field}}' field is obsolete and should be replaced with '{{new
150
+ field}}'.\""
151
+ status: community
152
+ source: https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/mod-package.md, "Code
153
+ warnings"; the analyzers themselves are src/SMAPI.ModBuildConfig.Analyzer/NetFieldAnalyzer.cs
154
+ and ObsoleteFieldAnalyzer.cs
155
+ tags:
156
+ - build
157
+ - analyzer
158
+ - csharp
159
+ - validator
160
+ - netfield
161
+ detail: These are compile-time checks ModWright should not duplicate — they run inside MSBuild and
162
+ are strictly better placed there. A ModWright build step should surface them from the build
163
+ output rather than reimplement them. ModBuildConfig 4.3.1 removed the implicit net-field
164
+ conversion warnings, "which were removed in Stardew Valley 1.6.9".
165
+ - id: stardewvalley.toolchain.build.unit-test-settings
166
+ claim: The documented settings for a unit-test or framework project using this package are
167
+ `<EnableGameDebugging>false</EnableGameDebugging>`,
168
+ `<EnableModDeploy>false</EnableModDeploy>`, `<EnableModZip>false</EnableModZip>` and
169
+ `<BundleExtraAssemblies>All</BundleExtraAssemblies>` — and the docs note "you still need a
170
+ game install on the machine running the tests."
171
+ status: community
172
+ source: https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/mod-package.md, "Unit tests"
173
+ tags:
174
+ - build
175
+ - tests
176
+ - csharp
177
+ - requires-game
178
+ detail: "Confirms the constraint from the other direction: even a test project for a Stardew C# mod
179
+ needs the game present, because the references resolve out of the game folder."
180
+ - id: stardewvalley.toolchain.build.dotnet-is-the-only-compiler-tool
181
+ claim: Building a C# Stardew mod needs nothing but the .NET SDK — `dotnet build` — plus the NuGet
182
+ package and an installed game. There is no game-specific packer, archiver or asset compiler in
183
+ the pipeline.
184
+ status: inferred
185
+ source: Derived from src/SMAPI.ModBuildConfig/build/smapi.targets (an ordinary MSBuild targets file
186
+ with one custom task, `DeployModTask`) and from the absence of any other tool in
187
+ https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/mod-package.md
188
+ tags:
189
+ - build
190
+ - dotnet
191
+ - toolchain
192
+ - toolspec
193
+ detail: So the only new `ToolSpec` a Stardew surface needs for building is `dotnet` (`--version`,
194
+ which prints a bare version) — the same spec a Valheim surface needs, which argues for adding
195
+ it once centrally rather than twice.
196
+ - id: stardewvalley.toolchain.build.stardewxnbhack
197
+ claim: The recommended XNB unpacker is StardewXnbHack, currently 1.1.2 (6 November 2024). It is
198
+ one-way — "It can't pack files back into .xnb, but you rarely need to" — and its output is
199
+ already Content Patcher-compatible.
200
+ status: community
201
+ source: https://stardewvalleywiki.com/Modding:Editing_XNB_files (read 2026-09-11); version from the
202
+ GitHub releases API for Pathoschild/StardewXnbHack, read 2026-09-11
203
+ tags:
204
+ - xnb
205
+ - unpack
206
+ - index
207
+ - toolspec
208
+ - requires-game
209
+ detail: Because it is one-way there is no round trip to verify, so it belongs in `index` as an
210
+ extraction step and not in `core/text` as a converter — the converter contract there is built
211
+ on round-trip verification.
212
+ - id: stardewvalley.toolchain.build.stardewxnbhack-installs-into-the-game-folder
213
+ claim: StardewXnbHack is installed *into the game folder* — "Unzip the download into your game
214
+ folder, so StardewXnbHack.exe is in the same folder as StardewValley.exe" — and is run by
215
+ double-clicking it, producing a `Content (unpacked)` folder beside `Content`.
216
+ status: community
217
+ source: "https://stardewvalleywiki.com/Modding:Editing_XNB_files (read 2026-09-11), the
218
+ StardewXnbHack section: \"Install SMAPI. Download StardewXnbHack ... Unzip the download into
219
+ your game folder ... it'll unpack the files into a Content (unpacked) folder. The unpacked
220
+ files will already be compatible with Content Patcher.\""
221
+ tags:
222
+ - xnb
223
+ - unpack
224
+ - toolspec
225
+ - candidates
226
+ - install
227
+ detail: "Two consequences for a `ToolSpec`: its primary candidate path is derived from a
228
+ `GameInstall` rather than from a convention, which no existing spec does; and it requires
229
+ SMAPI to be installed first, so it is not usable on a machine without the game at all. No CLI
230
+ version flag was confirmed from the project's own docs, so `versionArgs` should be left unset
231
+ rather than guessed."
232
+ - id: stardewvalley.toolchain.build.xnbcli-is-not-recommended
233
+ claim: "The alternative unpacker xnbcli can pack as well as unpack, but the wiki steers away from
234
+ it: it \"can't unpack XNB files containing data models (like Data\\FishPondData or
235
+ Data\\Movies); use StardewXnbHack if you need those\", and its data output needs a manual
236
+ post-processing step."
237
+ status: community
238
+ source: https://stardewvalleywiki.com/Modding:Editing_XNB_files (read 2026-09-11), the xnbcli
239
+ section and its "removing the XNB metadata" instructions
240
+ tags:
241
+ - xnb
242
+ - unpack
243
+ - toolspec
244
+ - rejected
245
+ detail: The manual step is to delete everything except the `content` field from the emitted JSON,
246
+ leaving the bare lookup — a documented footgun. Adding xnbcli as a second `ToolSpec` would be
247
+ adding that footgun to ModWright, so the recommendation is not to.
248
+ - id: stardewvalley.toolchain.build.repacking-is-unnecessary
249
+ claim: "There is no need to repack anything for a modern mod: \"There's no need to repack game files
250
+ if you're using Content Patcher! Just use the .json, .png, .tmx, or .tbin file directly in
251
+ your content.json.\""
252
+ status: community
253
+ source: https://stardewvalleywiki.com/Modding:Editing_XNB_files (read 2026-09-11), "Pack game files"
254
+ tags:
255
+ - xnb
256
+ - contentpatcher
257
+ - build
258
+ - assets
259
+ detail: "This is why a Stardew surface needs no text converters and no archive packer: every
260
+ authored asset ships in its source format. Maps are `.tmx`/`.tbin`, images are PNG, data is
261
+ JSON."