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.
- package/LICENSE +35 -0
- package/README.md +212 -0
- package/assets/claude/agents/mw-explore.md +46 -0
- package/assets/claude/agents/mw-fixture.md +33 -0
- package/assets/claude/agents/mw-rule-author.md +51 -0
- package/assets/claude/agents/mw-scaffold-author.md +48 -0
- package/assets/claude/skills/mw-author.md +59 -0
- package/assets/claude/skills/mw-new-item.md +51 -0
- package/assets/claude/skills/mw-new-spell.md +50 -0
- package/assets/claude/skills/mw-scaffold.md +59 -0
- package/assets/claude/skills/mw-ship.md +57 -0
- package/assets/claude/skills/mw-validate.md +51 -0
- package/assets/claude/skills/mw-verify.md +59 -0
- package/assets/nivalisnights/extract_resources.py +177 -0
- package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Config.json +5 -0
- package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/BootstrapClient.lua +55 -0
- package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/BootstrapServer.lua +81 -0
- package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Log.lua +96 -0
- package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Probes.lua +1038 -0
- package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/ProbesClient.lua +74 -0
- package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Protocol.lua +985 -0
- package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Watch.lua +175 -0
- package/bridges/bg3-se/Mods/ModWrightBridge/meta.lsx +45 -0
- package/bridges/bg3-se/README.md +99 -0
- package/bridges/bg3-se/bridge.json +68 -0
- package/bridges/cp2077-cet/ModWrightBridge/init.lua +375 -0
- package/bridges/cp2077-cet/ModWrightBridge/probes.lua +1104 -0
- package/bridges/cp2077-cet/ModWrightBridge/protocol.lua +1306 -0
- package/bridges/cp2077-cet/README.md +165 -0
- package/bridges/cp2077-cet/bridge.json +53 -0
- package/dist/core/bridge/arm.js +175 -0
- package/dist/core/bridge/cet-console.js +26 -0
- package/dist/core/bridge/cet-log.js +362 -0
- package/dist/core/bridge/index.js +11 -0
- package/dist/core/bridge/locate.js +35 -0
- package/dist/core/bridge/paths.js +34 -0
- package/dist/core/bridge/pending.js +89 -0
- package/dist/core/bridge/poll.js +155 -0
- package/dist/core/bridge/stage.js +100 -0
- package/dist/core/bridge/status.js +97 -0
- package/dist/core/bridge/types.js +145 -0
- package/dist/core/bridge/validate.js +107 -0
- package/dist/core/build/index.js +6 -0
- package/dist/core/build/manifest.js +47 -0
- package/dist/core/build/paths.js +32 -0
- package/dist/core/build/run.js +342 -0
- package/dist/core/build/stage.js +265 -0
- package/dist/core/build/steps/bg3.js +129 -0
- package/dist/core/build/steps/core.js +195 -0
- package/dist/core/build/steps/cyberpunk.js +95 -0
- package/dist/core/build/steps/listing.js +35 -0
- package/dist/core/build/types.js +13 -0
- package/dist/core/build/zip.js +148 -0
- package/dist/core/compat/check.js +113 -0
- package/dist/core/compat/pe.js +220 -0
- package/dist/core/compat/types.js +1 -0
- package/dist/core/compat/version.js +70 -0
- package/dist/core/deploy/guards.js +292 -0
- package/dist/core/deploy/index.js +5 -0
- package/dist/core/deploy/plan.js +696 -0
- package/dist/core/deploy/reload-apply.js +361 -0
- package/dist/core/deploy/reload.js +358 -0
- package/dist/core/deploy/sources.js +169 -0
- package/dist/core/deploy/types.js +1 -0
- package/dist/core/epic.js +54 -0
- package/dist/core/fsutil.js +191 -0
- package/dist/core/home.js +70 -0
- package/dist/core/knowledge/facts.js +229 -0
- package/dist/core/knowledge/index.js +4 -0
- package/dist/core/knowledge/search.js +112 -0
- package/dist/core/knowledge/store.js +123 -0
- package/dist/core/knowledge/types.js +1 -0
- package/dist/core/ledger/check.js +42 -0
- package/dist/core/ledger/hooks.js +80 -0
- package/dist/core/ledger/index.js +7 -0
- package/dist/core/ledger/query.js +17 -0
- package/dist/core/ledger/record.js +84 -0
- package/dist/core/ledger/status.js +53 -0
- package/dist/core/ledger/store.js +98 -0
- package/dist/core/ledger/types.js +108 -0
- package/dist/core/logs/index.js +4 -0
- package/dist/core/logs/registry.js +50 -0
- package/dist/core/logs/scan.js +195 -0
- package/dist/core/logs/triage.js +160 -0
- package/dist/core/logs/types.js +1 -0
- package/dist/core/lsx.js +10 -0
- package/dist/core/lz4.js +66 -0
- package/dist/core/mods.js +229 -0
- package/dist/core/process.js +49 -0
- package/dist/core/project/build-steps.js +83 -0
- package/dist/core/project/describe.js +74 -0
- package/dist/core/project/index.js +5 -0
- package/dist/core/project/load.js +146 -0
- package/dist/core/project/schema.js +264 -0
- package/dist/core/project/types.js +3 -0
- package/dist/core/prompts.js +72 -0
- package/dist/core/registry.js +35 -0
- package/dist/core/safety/backup.js +206 -0
- package/dist/core/safety/execute.js +188 -0
- package/dist/core/safety/index.js +5 -0
- package/dist/core/safety/plan.js +122 -0
- package/dist/core/safety/restore.js +172 -0
- package/dist/core/safety/types.js +1 -0
- package/dist/core/scaffold/bootstrap.js +7 -0
- package/dist/core/scaffold/catalog.js +28 -0
- package/dist/core/scaffold/claude-assets.js +271 -0
- package/dist/core/scaffold/collisions.js +64 -0
- package/dist/core/scaffold/emit.js +356 -0
- package/dist/core/scaffold/engine.js +680 -0
- package/dist/core/scaffold/ids.js +78 -0
- package/dist/core/scaffold/index.js +10 -0
- package/dist/core/scaffold/jsonpath.js +121 -0
- package/dist/core/scaffold/load.js +81 -0
- package/dist/core/scaffold/render.js +85 -0
- package/dist/core/scaffold/sequence.js +396 -0
- package/dist/core/scaffold/types.js +309 -0
- package/dist/core/steam.js +63 -0
- package/dist/core/surfaceutil.js +36 -0
- package/dist/core/testplan/check.js +67 -0
- package/dist/core/testplan/index.js +5 -0
- package/dist/core/testplan/load.js +100 -0
- package/dist/core/testplan/registry.js +317 -0
- package/dist/core/testplan/run.js +389 -0
- package/dist/core/testplan/types.js +82 -0
- package/dist/core/text/converters/bg3.js +50 -0
- package/dist/core/text/converters/cyberpunk.js +36 -0
- package/dist/core/text/converters/index.js +261 -0
- package/dist/core/text/diff/cr2w.js +180 -0
- package/dist/core/text/diff/index.js +16 -0
- package/dist/core/text/diff/loca.js +43 -0
- package/dist/core/text/diff/lsx.js +126 -0
- package/dist/core/text/handles.js +86 -0
- package/dist/core/text/index.js +6 -0
- package/dist/core/text/json.js +46 -0
- package/dist/core/text/templates/cache.js +71 -0
- package/dist/core/text/templates/index.js +3 -0
- package/dist/core/text/templates/library.js +245 -0
- package/dist/core/text/templates/types.js +51 -0
- package/dist/core/text/toolchain.js +16 -0
- package/dist/core/text/types.js +1 -0
- package/dist/core/text/validate.js +149 -0
- package/dist/core/text/xml.js +58 -0
- package/dist/core/toolchain/datafetch.js +151 -0
- package/dist/core/toolchain/env.js +63 -0
- package/dist/core/toolchain/features.js +170 -0
- package/dist/core/toolchain/index.js +8 -0
- package/dist/core/toolchain/install.js +191 -0
- package/dist/core/toolchain/locate.js +275 -0
- package/dist/core/toolchain/remember.js +84 -0
- package/dist/core/toolchain/run.js +318 -0
- package/dist/core/toolchain/specs.js +351 -0
- package/dist/core/toolchain/types.js +1 -0
- package/dist/core/types.js +1 -0
- package/dist/core/userconfig.js +66 -0
- package/dist/core/validate/context.js +139 -0
- package/dist/core/validate/index.js +5 -0
- package/dist/core/validate/registry.js +58 -0
- package/dist/core/validate/run.js +131 -0
- package/dist/core/validate/suppressions.js +91 -0
- package/dist/core/validate/types.js +2 -0
- package/dist/core/yamledit.js +51 -0
- package/dist/index.js +389 -0
- package/dist/server.js +1914 -0
- package/dist/surfaces/baldursgate3/compat.js +164 -0
- package/dist/surfaces/baldursgate3/identity.js +110 -0
- package/dist/surfaces/baldursgate3/index/build.js +331 -0
- package/dist/surfaces/baldursgate3/index/index.js +17 -0
- package/dist/surfaces/baldursgate3/index/info.js +40 -0
- package/dist/surfaces/baldursgate3/index/parsers/loca.js +41 -0
- package/dist/surfaces/baldursgate3/index/parsers/lsx.js +137 -0
- package/dist/surfaces/baldursgate3/index/parsers/stats.js +45 -0
- package/dist/surfaces/baldursgate3/index/parsers/treasuretable.js +57 -0
- package/dist/surfaces/baldursgate3/index/parsers/xmlutil.js +142 -0
- package/dist/surfaces/baldursgate3/index/queries.js +327 -0
- package/dist/surfaces/baldursgate3/index/schema.js +62 -0
- package/dist/surfaces/baldursgate3/index.js +3 -0
- package/dist/surfaces/baldursgate3/logs.js +278 -0
- package/dist/surfaces/baldursgate3/modsettings.js +115 -0
- package/dist/surfaces/baldursgate3/pak.js +153 -0
- package/dist/surfaces/baldursgate3/settings.js +49 -0
- package/dist/surfaces/baldursgate3/surface.js +232 -0
- package/dist/surfaces/baldursgate3/validators/bridge.js +7 -0
- package/dist/surfaces/baldursgate3/validators/files.js +476 -0
- package/dist/surfaces/baldursgate3/validators/items.js +1001 -0
- package/dist/surfaces/baldursgate3/validators/progression.js +734 -0
- package/dist/surfaces/baldursgate3/validators/stats.js +1076 -0
- package/dist/surfaces/baldursgate3/validators/story.js +790 -0
- package/dist/surfaces/baldursgate3/validators/templates.js +7 -0
- package/dist/surfaces/cyberpunk2077/compat.js +223 -0
- package/dist/surfaces/cyberpunk2077/index/build.js +231 -0
- package/dist/surfaces/cyberpunk2077/index/index.js +17 -0
- package/dist/surfaces/cyberpunk2077/index/info.js +51 -0
- package/dist/surfaces/cyberpunk2077/index/model.js +52 -0
- package/dist/surfaces/cyberpunk2077/index/parsers/tweak.js +483 -0
- package/dist/surfaces/cyberpunk2077/index/parsers/tweakxl-yaml.js +183 -0
- package/dist/surfaces/cyberpunk2077/index/queries.js +504 -0
- package/dist/surfaces/cyberpunk2077/index/resource.js +135 -0
- package/dist/surfaces/cyberpunk2077/index/schema.js +90 -0
- package/dist/surfaces/cyberpunk2077/index.js +3 -0
- package/dist/surfaces/cyberpunk2077/logs.js +742 -0
- package/dist/surfaces/cyberpunk2077/paths.js +12 -0
- package/dist/surfaces/cyberpunk2077/surface.js +218 -0
- package/dist/surfaces/cyberpunk2077/validators/bridge.js +7 -0
- package/dist/surfaces/cyberpunk2077/validators/cr2w.js +349 -0
- package/dist/surfaces/cyberpunk2077/validators/garments.js +1181 -0
- package/dist/surfaces/cyberpunk2077/validators/mesh.js +338 -0
- package/dist/surfaces/cyberpunk2077/validators/modsettings.js +120 -0
- package/dist/surfaces/cyberpunk2077/validators/packaging.js +463 -0
- package/dist/surfaces/cyberpunk2077/validators/red4ext.js +318 -0
- package/dist/surfaces/cyberpunk2077/validators/redscript.js +193 -0
- package/dist/surfaces/cyberpunk2077/validators/templates.js +7 -0
- package/dist/surfaces/cyberpunk2077/validators/tweaks.js +768 -0
- package/dist/surfaces/cyberpunk2077/validators/vehicles.js +531 -0
- package/dist/surfaces/cyberpunk2077/validators/xl.js +308 -0
- package/dist/surfaces/eldenring/binders.js +111 -0
- package/dist/surfaces/eldenring/compat.js +166 -0
- package/dist/surfaces/eldenring/dcx.js +49 -0
- package/dist/surfaces/eldenring/index.js +13 -0
- package/dist/surfaces/eldenring/loaders.js +132 -0
- package/dist/surfaces/eldenring/logs.js +67 -0
- package/dist/surfaces/eldenring/paramdef.js +256 -0
- package/dist/surfaces/eldenring/params.js +129 -0
- package/dist/surfaces/eldenring/surface.js +121 -0
- package/dist/surfaces/eldenring/tools.js +52 -0
- package/dist/surfaces/eldenring/validators/binders.js +193 -0
- package/dist/surfaces/eldenring/validators/packages.js +159 -0
- package/dist/surfaces/eldenring/validators/params.js +334 -0
- package/dist/surfaces/eldenring/validators/profiles.js +287 -0
- package/dist/surfaces/index.js +34 -0
- package/dist/surfaces/nivalisnights/compat.js +229 -0
- package/dist/surfaces/nivalisnights/index/build.js +310 -0
- package/dist/surfaces/nivalisnights/index/index.js +5 -0
- package/dist/surfaces/nivalisnights/index/queries.js +231 -0
- package/dist/surfaces/nivalisnights/index.js +4 -0
- package/dist/surfaces/nivalisnights/logs.js +473 -0
- package/dist/surfaces/nivalisnights/surface.js +195 -0
- package/dist/surfaces/skyrimse/archives.js +229 -0
- package/dist/surfaces/skyrimse/compat.js +163 -0
- package/dist/surfaces/skyrimse/index.js +12 -0
- package/dist/surfaces/skyrimse/loadorder.js +174 -0
- package/dist/surfaces/skyrimse/logs.js +241 -0
- package/dist/surfaces/skyrimse/plugins.js +149 -0
- package/dist/surfaces/skyrimse/records.js +94 -0
- package/dist/surfaces/skyrimse/surface.js +240 -0
- package/dist/surfaces/skyrimse/validators/archive-records.js +165 -0
- package/dist/surfaces/skyrimse/validators/archives.js +110 -0
- package/dist/surfaces/skyrimse/validators/plugins.js +374 -0
- package/dist/surfaces/skyrimse/validators/records.js +117 -0
- package/dist/surfaces/stardewvalley/compat.js +190 -0
- package/dist/surfaces/stardewvalley/config.js +42 -0
- package/dist/surfaces/stardewvalley/contentpatcher.js +203 -0
- package/dist/surfaces/stardewvalley/index/index.js +229 -0
- package/dist/surfaces/stardewvalley/index/wiki.js +190 -0
- package/dist/surfaces/stardewvalley/index.js +12 -0
- package/dist/surfaces/stardewvalley/logs.js +307 -0
- package/dist/surfaces/stardewvalley/mods.js +182 -0
- package/dist/surfaces/stardewvalley/surface.js +244 -0
- package/dist/surfaces/stardewvalley/validators/content.js +321 -0
- package/dist/surfaces/stardewvalley/validators/fields.js +147 -0
- package/dist/surfaces/stardewvalley/validators/loadorder.js +69 -0
- package/dist/surfaces/stardewvalley/validators/manifest.js +221 -0
- package/dist/surfaces/subnautica2/compat.js +138 -0
- package/dist/surfaces/subnautica2/index.js +5 -0
- package/dist/surfaces/subnautica2/logs.js +129 -0
- package/dist/surfaces/subnautica2/paks.js +173 -0
- package/dist/surfaces/subnautica2/surface.js +151 -0
- package/dist/surfaces/subnautica2/validators/packaging.js +298 -0
- package/dist/surfaces/valheim/compat.js +171 -0
- package/dist/surfaces/valheim/index/index.js +301 -0
- package/dist/surfaces/valheim/index/tables.js +103 -0
- package/dist/surfaces/valheim/index.js +11 -0
- package/dist/surfaces/valheim/logs.js +197 -0
- package/dist/surfaces/valheim/packaging.js +131 -0
- package/dist/surfaces/valheim/plugins.js +270 -0
- package/dist/surfaces/valheim/references.js +121 -0
- package/dist/surfaces/valheim/surface.js +223 -0
- package/dist/surfaces/valheim/validators/packaging.js +218 -0
- package/dist/surfaces/valheim/validators/plugins.js +287 -0
- package/dist/surfaces/valheim/validators/references.js +169 -0
- package/knowledge/baldursgate3/animations.gr2.yaml +166 -0
- package/knowledge/baldursgate3/audio.voice.yaml +182 -0
- package/knowledge/baldursgate3/audio.wwise.yaml +104 -0
- package/knowledge/baldursgate3/charactercreation.heads-hair.yaml +193 -0
- package/knowledge/baldursgate3/communitylibrary.shared-content.yaml +129 -0
- package/knowledge/baldursgate3/compatibilityframework.api.yaml +176 -0
- package/knowledge/baldursgate3/crash.causes.yaml +90 -0
- package/knowledge/baldursgate3/dialogue.dialogbank.yaml +120 -0
- package/knowledge/baldursgate3/dialogue.files.yaml +236 -0
- package/knowledge/baldursgate3/dialogue.osiris-goals.yaml +386 -0
- package/knowledge/baldursgate3/dialogue.yaml +122 -0
- package/knowledge/baldursgate3/feats.classes.yaml +164 -0
- package/knowledge/baldursgate3/items.cloth-physics.yaml +167 -0
- package/knowledge/baldursgate3/items.roottemplates.yaml +320 -0
- package/knowledge/baldursgate3/items.visualbank.yaml +628 -0
- package/knowledge/baldursgate3/journal.quests.yaml +214 -0
- package/knowledge/baldursgate3/loadorder.modsettings.yaml +128 -0
- package/knowledge/baldursgate3/localization.handles.yaml +92 -0
- package/knowledge/baldursgate3/misc.encoding-and-practice.yaml +111 -0
- package/knowledge/baldursgate3/origins.companions.yaml +144 -0
- package/knowledge/baldursgate3/osiris.signatures.yaml +211 -0
- package/knowledge/baldursgate3/packaging.meta.yaml +155 -0
- package/knowledge/baldursgate3/packaging.paks.yaml +79 -0
- package/knowledge/baldursgate3/process.launch.yaml +34 -0
- package/knowledge/baldursgate3/progressions.yaml +92 -0
- package/knowledge/baldursgate3/publishing.modio-nexus.yaml +170 -0
- package/knowledge/baldursgate3/publishing.toolkit-modio.yaml +135 -0
- package/knowledge/baldursgate3/races.progression.yaml +228 -0
- package/knowledge/baldursgate3/scriptextender.console.yaml +257 -0
- package/knowledge/baldursgate3/scriptextender.yaml +252 -0
- package/knowledge/baldursgate3/stats.boosts.yaml +293 -0
- package/knowledge/baldursgate3/stats.equipment-kits.yaml +69 -0
- package/knowledge/baldursgate3/stats.interrupts.yaml +45 -0
- package/knowledge/baldursgate3/stats.itemcombos.yaml +65 -0
- package/knowledge/baldursgate3/stats.spells.yaml +293 -0
- package/knowledge/baldursgate3/stats.weapons.yaml +210 -0
- package/knowledge/baldursgate3/toolchain.divine.yaml +179 -0
- package/knowledge/baldursgate3/toolchain.lslib-formats.yaml +242 -0
- package/knowledge/baldursgate3/toolkit.levels.yaml +177 -0
- package/knowledge/baldursgate3/ui.icons-atlas.yaml +78 -0
- package/knowledge/baldursgate3/ui.icons.yaml +412 -0
- package/knowledge/baldursgate3/ui.mcm.yaml +161 -0
- package/knowledge/baldursgate3/vfx.materials.yaml +174 -0
- package/knowledge/baldursgate3/visuals.characterfix.yaml +73 -0
- package/knowledge/cyberpunk2077/animations.anims.yaml +118 -0
- package/knowledge/cyberpunk2077/anims.archivexl.yaml +163 -0
- package/knowledge/cyberpunk2077/anims.authoring.yaml +579 -0
- package/knowledge/cyberpunk2077/anims.encoder.yaml +156 -0
- package/knowledge/cyberpunk2077/anims.graph.yaml +629 -0
- package/knowledge/cyberpunk2077/anims.method.yaml +360 -0
- package/knowledge/cyberpunk2077/anims.pipeline.yaml +352 -0
- package/knowledge/cyberpunk2077/anims.roundtrip.yaml +222 -0
- package/knowledge/cyberpunk2077/anims.sets.yaml +176 -0
- package/knowledge/cyberpunk2077/archivexl.bodytypes.yaml +149 -0
- package/knowledge/cyberpunk2077/archivexl.dynamic-appearances.yaml +218 -0
- package/knowledge/cyberpunk2077/archivexl.manifest.yaml +214 -0
- package/knowledge/cyberpunk2077/audio.events.yaml +168 -0
- package/knowledge/cyberpunk2077/audio.sounds.yaml +164 -0
- package/knowledge/cyberpunk2077/audio.voicesets.yaml +146 -0
- package/knowledge/cyberpunk2077/cet.sandbox.yaml +219 -0
- package/knowledge/cyberpunk2077/clothing.garments.yaml +283 -0
- package/knowledge/cyberpunk2077/clothing.refits.yaml +215 -0
- package/knowledge/cyberpunk2077/codeware.overview.yaml +111 -0
- package/knowledge/cyberpunk2077/codeware.systems.yaml +192 -0
- package/knowledge/cyberpunk2077/drones.combat.yaml +416 -0
- package/knowledge/cyberpunk2077/drones.control.yaml +552 -0
- package/knowledge/cyberpunk2077/entities.appearance.yaml +166 -0
- package/knowledge/cyberpunk2077/equipmentex.slots.yaml +151 -0
- package/knowledge/cyberpunk2077/fx.effects.yaml +246 -0
- package/knowledge/cyberpunk2077/fx.lights.yaml +171 -0
- package/knowledge/cyberpunk2077/hair.modding.yaml +145 -0
- package/knowledge/cyberpunk2077/items.wiring.yaml +246 -0
- package/knowledge/cyberpunk2077/loadorder.archives.yaml +71 -0
- package/knowledge/cyberpunk2077/mesh.blender.yaml +209 -0
- package/knowledge/cyberpunk2077/nativedb.dump.yaml +98 -0
- package/knowledge/cyberpunk2077/npc.appearance.yaml +275 -0
- package/knowledge/cyberpunk2077/npc.behaviour.yaml +128 -0
- package/knowledge/cyberpunk2077/npc.locomotion.yaml +490 -0
- package/knowledge/cyberpunk2077/packaging.deploy.yaml +175 -0
- package/knowledge/cyberpunk2077/packaging.variants.yaml +176 -0
- package/knowledge/cyberpunk2077/player.control.yaml +918 -0
- package/knowledge/cyberpunk2077/process.assetbuild.yaml +154 -0
- package/knowledge/cyberpunk2077/process.lessons.yaml +276 -0
- package/knowledge/cyberpunk2077/quests.minor.yaml +46 -0
- package/knowledge/cyberpunk2077/quests.scenes.yaml +282 -0
- package/knowledge/cyberpunk2077/quickhacks.tiers.yaml +41 -0
- package/knowledge/cyberpunk2077/red4ext.api.yaml +645 -0
- package/knowledge/cyberpunk2077/red4ext.plugins.yaml +124 -0
- package/knowledge/cyberpunk2077/redhottools.hotreload.yaml +245 -0
- package/knowledge/cyberpunk2077/redscript.compile-log.yaml +76 -0
- package/knowledge/cyberpunk2077/redscript.modules.yaml +118 -0
- package/knowledge/cyberpunk2077/toolchain.wolvenkit.yaml +163 -0
- package/knowledge/cyberpunk2077/tweakdb.loot-recipes.yaml +184 -0
- package/knowledge/cyberpunk2077/tweakdb.melee.yaml +352 -0
- package/knowledge/cyberpunk2077/tweakdb.weapons.yaml +325 -0
- package/knowledge/cyberpunk2077/tweakxl.hotreload.yaml +151 -0
- package/knowledge/cyberpunk2077/tweakxl.yaml-syntax.yaml +208 -0
- package/knowledge/cyberpunk2077/ui.icons.yaml +259 -0
- package/knowledge/cyberpunk2077/ui.inkatlas.yaml +81 -0
- package/knowledge/cyberpunk2077/ui.modsettings.yaml +204 -0
- package/knowledge/cyberpunk2077/vehicles.control.yaml +475 -0
- package/knowledge/cyberpunk2077/vehicles.dashboard-ui.yaml +203 -0
- package/knowledge/cyberpunk2077/vehicles.entities.yaml +195 -0
- package/knowledge/cyberpunk2077/vehicles.wiring.yaml +137 -0
- package/knowledge/cyberpunk2077/wolvenkit.cli.yaml +167 -0
- package/knowledge/cyberpunk2077/workspot.system.yaml +55 -0
- package/knowledge/cyberpunk2077/world.interactions.yaml +41 -0
- package/knowledge/cyberpunk2077/world.loot-container.yaml +167 -0
- package/knowledge/cyberpunk2077/world.sectors.yaml +233 -0
- package/knowledge/eldenring/formats.binders.yaml +237 -0
- package/knowledge/eldenring/launcher.me3.yaml +230 -0
- package/knowledge/eldenring/launcher.modengine2.yaml +119 -0
- package/knowledge/eldenring/params.paramdef.yaml +149 -0
- package/knowledge/eldenring/params.regulation.yaml +142 -0
- package/knowledge/eldenring/saves.online.yaml +118 -0
- package/knowledge/eldenring/toolchain.cli.yaml +256 -0
- package/knowledge/nivalisnights/modding.runtime.yaml +157 -0
- package/knowledge/skyrimse/archives.bsa.yaml +212 -0
- package/knowledge/skyrimse/install.detection.yaml +41 -0
- package/knowledge/skyrimse/loadorder.files.yaml +242 -0
- package/knowledge/skyrimse/plugins.esl.yaml +189 -0
- package/knowledge/skyrimse/plugins.format.yaml +224 -0
- package/knowledge/skyrimse/skse.runtime.yaml +283 -0
- package/knowledge/skyrimse/toolchain.xedit-spriggit.yaml +336 -0
- package/knowledge/stardewvalley/contentpatcher.format.yaml +338 -0
- package/knowledge/stardewvalley/distribution.channels.yaml +236 -0
- package/knowledge/stardewvalley/game.versions.yaml +202 -0
- package/knowledge/stardewvalley/install.layout.yaml +277 -0
- package/knowledge/stardewvalley/smapi.loader.yaml +284 -0
- package/knowledge/stardewvalley/smapi.logs.yaml +329 -0
- package/knowledge/stardewvalley/smapi.manifest.yaml +293 -0
- package/knowledge/stardewvalley/toolchain.build.yaml +261 -0
- package/knowledge/stardewvalley/wiki.dataformat.yaml +130 -0
- package/knowledge/subnautica2/game.build.yaml +331 -0
- package/knowledge/subnautica2/modding.state.yaml +210 -0
- package/knowledge/subnautica2/ue5.containers.yaml +72 -0
- package/knowledge/subnautica2/ue5.paks.yaml +203 -0
- package/knowledge/subnautica2/ue5.tooling.yaml +175 -0
- package/knowledge/subnautica2/ue5.ue4ss.yaml +203 -0
- package/knowledge/valheim/bepinex.loader.yaml +247 -0
- package/knowledge/valheim/bepinex.plugins.yaml +251 -0
- package/knowledge/valheim/game.versions.yaml +321 -0
- package/knowledge/valheim/install.layout.yaml +216 -0
- package/knowledge/valheim/jotunn.library.yaml +334 -0
- package/knowledge/valheim/thunderstore.packaging.yaml +217 -0
- package/knowledge/valheim/toolchain.build.yaml +111 -0
- package/package.json +29 -0
- package/scaffolds/baldursgate3/new-class-injection.yaml +148 -0
- package/scaffolds/baldursgate3/new-item.yaml +264 -0
- package/scaffolds/baldursgate3/new-mod.yaml +174 -0
- package/scaffolds/baldursgate3/new-passive.yaml +100 -0
- package/scaffolds/baldursgate3/new-project.yaml +118 -0
- package/scaffolds/baldursgate3/new-quest-stub.yaml +159 -0
- package/scaffolds/baldursgate3/new-spell.yaml +102 -0
- package/scaffolds/baldursgate3/new-status.yaml +119 -0
- package/scaffolds/baldursgate3/sequences/subclass-kit.yaml +50 -0
- package/scaffolds/cyberpunk2077/edit-tweak.yaml +70 -0
- package/scaffolds/cyberpunk2077/mesh-export-preset.yaml +170 -0
- package/scaffolds/cyberpunk2077/new-entity-patch.yaml +255 -0
- package/scaffolds/cyberpunk2077/new-garment-refit.yaml +279 -0
- package/scaffolds/cyberpunk2077/new-item-chain.yaml +548 -0
- package/scaffolds/cyberpunk2077/new-localization.yaml +130 -0
- package/scaffolds/cyberpunk2077/new-mod-settings.yaml +133 -0
- package/scaffolds/cyberpunk2077/new-player-replacer.yaml +1003 -0
- package/scaffolds/cyberpunk2077/new-project.yaml +157 -0
- package/scaffolds/cyberpunk2077/new-sector-node.yaml +156 -0
- package/scaffolds/cyberpunk2077/new-tweak.yaml +121 -0
- package/scaffolds/cyberpunk2077/new-vehicle-livery.yaml +148 -0
- package/scaffolds/cyberpunk2077/new-workspot-entity.yaml +177 -0
- package/scaffolds/cyberpunk2077/sequences/iconic-weapon.yaml +72 -0
- package/scaffolds/cyberpunk2077/sequences/quickhack-takeover.yaml +213 -0
- package/scaffolds/stardewvalley/new-cp-patch.yaml +106 -0
- package/scaffolds/stardewvalley/new-csharp-mod.yaml +195 -0
- package/scaffolds/stardewvalley/new-project.yaml +184 -0
- package/scaffolds/stardewvalley/sequences/content-pack.yaml +31 -0
- 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."
|