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,284 @@
|
|
|
1
|
+
game: stardewvalley
|
|
2
|
+
topic: smapi.loader
|
|
3
|
+
title: SMAPI as the mod loader — versions, mod scanning, load order, and every skip reason
|
|
4
|
+
facts:
|
|
5
|
+
- id: stardewvalley.smapi.loader.version-and-game-floor
|
|
6
|
+
claim: 'SMAPI 4.5.2 is the current release and it requires Stardew Valley 1.6.14 or later with no
|
|
7
|
+
upper bound: `MinimumGameVersion` is `new GameVersion("1.6.14")` and `MaximumGameVersion` is
|
|
8
|
+
`null`.'
|
|
9
|
+
status: inferred
|
|
10
|
+
source: SMAPI develop, src/SMAPI/Constants.cs (`internal static string RawApiVersion = "4.5.2";`,
|
|
11
|
+
`public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.6.14");`,
|
|
12
|
+
`public static ISemanticVersion? MaximumGameVersion { get; } = null;`); corroborated by
|
|
13
|
+
docs/release-notes.md, "## 4.5.2 / Released 14 March 2026 for Stardew Valley 1.6.14 or later"
|
|
14
|
+
tags:
|
|
15
|
+
- smapi
|
|
16
|
+
- version
|
|
17
|
+
- compat
|
|
18
|
+
- floor
|
|
19
|
+
- rule
|
|
20
|
+
detail: "This is the one hard version floor in the whole matrix and it is a literal in SMAPI's
|
|
21
|
+
source, so a `CompatRule` with `min: \"1.6.14\"` and no `max` is exactly right. A surface that
|
|
22
|
+
invents a maximum would be wrong today: the installed game (1.6.15) is one patch above the
|
|
23
|
+
floor and SMAPI declares no ceiling at all."
|
|
24
|
+
- id: stardewvalley.smapi.loader.release-notes-date-differs-from-tag
|
|
25
|
+
claim: "SMAPI's release-notes date and its GitHub tag date differ by several days and consistently
|
|
26
|
+
so: 4.5.2 says \"Released 14 March 2026\" against a tag published 2026-03-22; 4.5.1 says 25
|
|
27
|
+
January 2026 against 2026-01-28; 4.4.0 says 10 January 2026 against 2026-01-11."
|
|
28
|
+
status: inferred
|
|
29
|
+
source: https://github.com/Pathoschild/SMAPI/blob/develop/docs/release-notes.md compared against the
|
|
30
|
+
GitHub releases API for Pathoschild/SMAPI, both read 2026-09-11
|
|
31
|
+
tags:
|
|
32
|
+
- version
|
|
33
|
+
- date
|
|
34
|
+
- conflict
|
|
35
|
+
- provenance
|
|
36
|
+
detail: Quote the release-notes date when citing a release and never treat the tag timestamp as the
|
|
37
|
+
release date. The same care is needed for Content Patcher, whose release notes carry dates
|
|
38
|
+
while its repository publishes no GitHub releases at all.
|
|
39
|
+
- id: stardewvalley.smapi.loader.a-mod-is-a-folder-with-a-manifest
|
|
40
|
+
claim: "A mod is any folder containing a `manifest.json`, found at any depth under `Mods/`. Its type
|
|
41
|
+
is decided entirely by the manifest: `isContentPack = ContentPackFor?.UniqueID` non-empty,
|
|
42
|
+
`isSmapi = EntryDll` non-empty, and `if (isContentPack == isSmapi) type = ModType.Invalid`."
|
|
43
|
+
status: inferred
|
|
44
|
+
source: SMAPI develop, src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs `ReadFolder(...)`
|
|
45
|
+
tags:
|
|
46
|
+
- mods
|
|
47
|
+
- scanning
|
|
48
|
+
- manifest
|
|
49
|
+
- content-pack
|
|
50
|
+
- modroots
|
|
51
|
+
detail: So the same folder shape carries both kinds of mod, which is why this game has one mod root
|
|
52
|
+
rather than one per system. `readManifest` returning `undefined` here means "this folder is
|
|
53
|
+
not a mod", a stronger statement than on Valheim where a bare DLL is normal.
|
|
54
|
+
- id: stardewvalley.smapi.loader.scanner-ignore-lists
|
|
55
|
+
claim: "When deciding whether a folder is empty, SMAPI's scanner ignores filesystem entries matching
|
|
56
|
+
`^__folder_managed_by_vortex$`, `(?:^\\._|^\\.DS_Store$|^__MACOSX$|^mcs$)` and
|
|
57
|
+
`^(?:desktop\\.ini|Thumbs\\.db)$`, plus files with any of these extensions: .doc .docx .md
|
|
58
|
+
.rtf .txt .bmp .gif .ico .jpeg .jpg .png .psd .tif .xcf .rar .zip .7z .tar .tar.gz .backup
|
|
59
|
+
.bak .old .url .lnk."
|
|
60
|
+
status: inferred
|
|
61
|
+
source: SMAPI develop, src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs, the
|
|
62
|
+
`IgnoreFilesystemNames` and `IgnoreFileExtensions` fields
|
|
63
|
+
tags:
|
|
64
|
+
- scanning
|
|
65
|
+
- mods
|
|
66
|
+
- packaging
|
|
67
|
+
- validator
|
|
68
|
+
detail: "Useful in two directions: a `list_mods` that mirrors it agrees with the game, and a
|
|
69
|
+
packaging validator can warn when a release zip carries `.DS_Store`, `__MACOSX`, `Thumbs.db`
|
|
70
|
+
or `desktop.ini` — harmless to SMAPI, but noise in a published download."
|
|
71
|
+
- id: stardewvalley.smapi.loader.xnb-mod-detection
|
|
72
|
+
claim: A folder holding only `.xgs`, `.xnb`, `.xsb` or `.xwb` files (optionally with
|
|
73
|
+
`.json`/`.yaml`) and no `manifest.json` is classified `ModType.Xnb` with the message "it's not
|
|
74
|
+
a SMAPI mod (see https://smapi.io/xnb for info)."
|
|
75
|
+
status: inferred
|
|
76
|
+
source: SMAPI develop, src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs, the
|
|
77
|
+
`StrictXnbModExtensions` / `PotentialXnbModExtensions` sets and the `IsXnbMod(...)` branch
|
|
78
|
+
tags:
|
|
79
|
+
- xnb
|
|
80
|
+
- legacy
|
|
81
|
+
- scanning
|
|
82
|
+
- validator
|
|
83
|
+
- block
|
|
84
|
+
detail: "XNB mods replace files in the game's `Content` folder and are the deprecated pre-SMAPI mod
|
|
85
|
+
style. A validator that sees this shape in a build output should block: SMAPI will refuse the
|
|
86
|
+
folder outright."
|
|
87
|
+
- id: stardewvalley.smapi.loader.other-scanner-failure-texts
|
|
88
|
+
claim: "The scanner's other named failures, verbatim, are \"it's an empty Vortex folder (is the mod
|
|
89
|
+
disabled in Vortex?).\", \"it's an empty folder.\", \"the SMAPI installer isn't a mod (you can
|
|
90
|
+
delete this folder after running the installer file).\", \"it contains files, but none of them
|
|
91
|
+
are manifest.json.\", \"its manifest is invalid.\" and \"parsing its manifest failed:
|
|
92
|
+
{message}\"."
|
|
93
|
+
status: inferred
|
|
94
|
+
source: SMAPI develop, src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs `ReadFolder(...)`
|
|
95
|
+
tags:
|
|
96
|
+
- scanning
|
|
97
|
+
- errors
|
|
98
|
+
- log
|
|
99
|
+
- signature
|
|
100
|
+
detail: "Each of these reaches the log as the `because {reason}` half of a skipped-mods line, so
|
|
101
|
+
they are matchable text, not just internal states. The \"SMAPI installer isn't a mod\" case is
|
|
102
|
+
a real user error: people unzip the installer into `Mods/`."
|
|
103
|
+
- id: stardewvalley.smapi.loader.load-order-is-a-dependency-sort
|
|
104
|
+
claim: There is no load-order file. SMAPI computes order as a depth-first topological sort over each
|
|
105
|
+
mod's `Dependencies`, preceded by `ApplyLoadOrderOverrides` which moves the ids listed in the
|
|
106
|
+
config's `ModsToLoadEarly` and `ModsToLoadLate` to the front and back.
|
|
107
|
+
status: inferred
|
|
108
|
+
source: SMAPI develop, src/SMAPI/Framework/ModLoading/ModResolver.cs, `ProcessDependencies(...)` and
|
|
109
|
+
`ApplyLoadOrderOverrides(mods, modIdsToLoadEarly, modIdsToLoadLate)`
|
|
110
|
+
tags:
|
|
111
|
+
- load-order
|
|
112
|
+
- dependencies
|
|
113
|
+
- modresolver
|
|
114
|
+
detail: "So `load_order` has a genuine but partial answer here, unlike Valheim where it has none:
|
|
115
|
+
the two override lists are real, file-backed and diffable, while the rest of the order is
|
|
116
|
+
derived and has no file."
|
|
117
|
+
- id: stardewvalley.smapi.loader.load-order-override-lists
|
|
118
|
+
claim: "`ModsToLoadEarly` and `ModsToLoadLate` in `smapi-internal/config.json` are lists of mod
|
|
119
|
+
UniqueIDs that force load order. They can be overridden by `smapi-internal/config.user.json`
|
|
120
|
+
and by `Mods/SMAPI-config.json`, and `smapi-internal/config.json` itself is reset on every
|
|
121
|
+
SMAPI update."
|
|
122
|
+
status: community
|
|
123
|
+
source: "The shipped file's own documentation comment
|
|
124
|
+
(https://github.com/Pathoschild/SMAPI/blob/develop/src/SMAPI/SMAPI.config.json): \"This lets
|
|
125
|
+
you manually fix the load order if needed, but this is a last resort — SMAPI automatically
|
|
126
|
+
adjusts the load order based on mods' dependencies\"; the three paths are `ApiConfigPath`,
|
|
127
|
+
`ApiUserConfigPath` and `ApiModGroupConfigPath` in src/SMAPI/Constants.cs"
|
|
128
|
+
tags:
|
|
129
|
+
- load-order
|
|
130
|
+
- config
|
|
131
|
+
- loadorderfile
|
|
132
|
+
- override
|
|
133
|
+
detail: "Entries are UniqueIDs, which resolve to installed mods with confidence, so a
|
|
134
|
+
`loadOrderFile` implementation can set `modId` on every entry — unlike BG3's UUID-in-a-pak
|
|
135
|
+
case. The override precedence matters: read the per-mods-folder file first, then the user
|
|
136
|
+
file, then the shipped one."
|
|
137
|
+
- id: stardewvalley.smapi.loader.load-order-override-warnings
|
|
138
|
+
claim: "SMAPI warns at startup when the override lists name mods that are not installed, or name the
|
|
139
|
+
same mod in both lists, with three distinct lines ending \"which aren't installed: '...'.\"
|
|
140
|
+
and \"These will be loaded early.\""
|
|
141
|
+
status: inferred
|
|
142
|
+
source: "SMAPI develop, src/SMAPI/Framework/SCore.cs: the three `The 'smapi-internal/config.json'
|
|
143
|
+
file lists mod IDs in ...` log calls at LogLevel.Warn"
|
|
144
|
+
tags:
|
|
145
|
+
- load-order
|
|
146
|
+
- validator
|
|
147
|
+
- log
|
|
148
|
+
- signature
|
|
149
|
+
- cross-check
|
|
150
|
+
detail: All three are checks ModWright can perform statically, before the game runs — the rare case
|
|
151
|
+
where a surface can report a load-order problem before the loader says anything.
|
|
152
|
+
- id: stardewvalley.smapi.loader.skip-reasons
|
|
153
|
+
claim: "Every reason SMAPI gives for skipping a mod is a sentence fragment designed to be appended
|
|
154
|
+
after \"failed loading <mod> because \". The dependency ones are \"it requires mods which
|
|
155
|
+
aren't installed ({names}).\", \"it needs newer versions of some mods: {name} (needs {version}
|
|
156
|
+
or later).\", \"it needs the '{name}' mod, which couldn't be loaded.\" and \"its dependencies
|
|
157
|
+
have a circular reference: {a} => {b} => {c}).\"."
|
|
158
|
+
status: inferred
|
|
159
|
+
source: SMAPI develop, src/SMAPI/Framework/ModLoading/ModResolver.cs, the
|
|
160
|
+
`SetStatus(ModMetadataStatus.Failed, ModFailReason.MissingDependencies, ...)` calls
|
|
161
|
+
tags:
|
|
162
|
+
- errors
|
|
163
|
+
- dependencies
|
|
164
|
+
- log
|
|
165
|
+
- signature
|
|
166
|
+
- triage
|
|
167
|
+
detail: "The first is the root cause and the third is the cascade, exactly the BepInEx pattern: one
|
|
168
|
+
Error naming the real problem, then one per downstream mod. `triage_logs` must rank the first
|
|
169
|
+
above the third or it will report the wrong mod."
|
|
170
|
+
- id: stardewvalley.smapi.loader.version-skip-reasons
|
|
171
|
+
claim: "The version-related skip reasons are \"it needs SMAPI {version} or later. Please update
|
|
172
|
+
SMAPI to the latest version to use this mod.\", \"it needs Stardew Valley {version} or later.
|
|
173
|
+
Please update your game to the latest version to use this mod.\", \"it's obsolete: {phrase}\"
|
|
174
|
+
and \"{phrase}. Please check for a newer version at {urls}\" (or \"... version newer than {v}
|
|
175
|
+
at ...\")."
|
|
176
|
+
status: inferred
|
|
177
|
+
source: SMAPI develop, src/SMAPI/Framework/ModLoading/ModResolver.cs `ValidateManifests(...)`; the
|
|
178
|
+
last two come from the mod's record in `smapi-internal/metadata.json`, not from anything on
|
|
179
|
+
disk in the mod folder
|
|
180
|
+
tags:
|
|
181
|
+
- errors
|
|
182
|
+
- version
|
|
183
|
+
- compat
|
|
184
|
+
- log
|
|
185
|
+
- signature
|
|
186
|
+
detail: "The last two are the important distinction: they are *curated* verdicts from SMAPI's
|
|
187
|
+
internal database, not detected incompatibilities. A triage verdict that reports them as a
|
|
188
|
+
version mismatch is misleading — the right next action is to look the mod up on the
|
|
189
|
+
compatibility list, not to change versions. `updateUrls` always ends with
|
|
190
|
+
`https://smapi.io/mods`."
|
|
191
|
+
- id: stardewvalley.smapi.loader.duplicate-and-dll-skip-reasons
|
|
192
|
+
claim: "Two more skip reasons are filesystem facts: \"its DLL '{EntryDll}' doesn't exist.\" and
|
|
193
|
+
\"you have multiple copies of this mod installed. To fix this, delete these folders and
|
|
194
|
+
reinstall the mod: {folders}.\"."
|
|
195
|
+
status: inferred
|
|
196
|
+
source: SMAPI develop, src/SMAPI/Framework/ModLoading/ModResolver.cs `ValidateManifests(...)` — the
|
|
197
|
+
`EntryDll` file-existence check and the `duplicatesById` grouping, which is case-insensitive
|
|
198
|
+
on `UniqueID`
|
|
199
|
+
tags:
|
|
200
|
+
- errors
|
|
201
|
+
- duplicate
|
|
202
|
+
- entrydll
|
|
203
|
+
- validator
|
|
204
|
+
- conflict
|
|
205
|
+
detail: "Both are checkable before the game runs. The duplicate check in particular is the reason
|
|
206
|
+
`find_conflicts` on this game must key on `UniqueID` rather than on file paths: two mods in
|
|
207
|
+
different folders with the same id genuinely contend, and two mods with the same file names in
|
|
208
|
+
different folders do not."
|
|
209
|
+
- id: stardewvalley.smapi.loader.rewrites-mods-for-compatibility
|
|
210
|
+
claim: SMAPI rewrites older mod assemblies at load time so they keep working against a newer game,
|
|
211
|
+
controlled by the `RewriteMods` setting (default true). Disabling it logs "You disabled
|
|
212
|
+
rewriting broken mods, so many older mods may fail to load. You can undo this by reinstalling
|
|
213
|
+
SMAPI."
|
|
214
|
+
status: inferred
|
|
215
|
+
source: 'SMAPI develop, src/SMAPI/SMAPI.config.json (`"RewriteMods": true`, with the comment
|
|
216
|
+
"Disabling this may prevent older mods from loading"),
|
|
217
|
+
src/SMAPI/Framework/Logging/LogManager.cs `LogSettingsHeader`, and the roughly one hundred
|
|
218
|
+
`*Facade.cs` files under src/SMAPI/Framework/ModLoading/Rewriters/StardewValley_1_6/'
|
|
219
|
+
tags:
|
|
220
|
+
- compat
|
|
221
|
+
- rewriting
|
|
222
|
+
- loader
|
|
223
|
+
- advisory
|
|
224
|
+
- guidance
|
|
225
|
+
detail: "No other loader ModWright supports repairs its mods. It inverts the usual compat advice: on
|
|
226
|
+
this game a mod that fails to load is more often on the curated broken list than genuinely
|
|
227
|
+
version-incompatible, so a `check_compat` advisory should say to read the skip reason before
|
|
228
|
+
assuming a version problem."
|
|
229
|
+
- id: stardewvalley.smapi.loader.harmony-is-bundled-and-opt-in
|
|
230
|
+
claim: SMAPI bundles Harmony at `smapi-internal/0Harmony.dll`, patches it to work with the game
|
|
231
|
+
(`FixHarmony`, default true), suppresses Harmony debug mode by default
|
|
232
|
+
(`SuppressHarmonyDebugMode`, default true), and the build package references it only when
|
|
233
|
+
`EnableHarmony` is set to true (default false).
|
|
234
|
+
status: inferred
|
|
235
|
+
source: SMAPI develop, src/SMAPI.ModBuildConfig/build/smapi.targets (`<Reference Include="0Harmony"
|
|
236
|
+
Condition="'$(EnableHarmony)' == 'true'" HintPath="$(GamePath)\smapi-internal\0Harmony.dll"
|
|
237
|
+
...>`, `<EnableHarmony Condition="'$(EnableHarmony)' == ''">false</EnableHarmony>`) and
|
|
238
|
+
src/SMAPI/SMAPI.config.json
|
|
239
|
+
tags:
|
|
240
|
+
- harmony
|
|
241
|
+
- build
|
|
242
|
+
- compat
|
|
243
|
+
- config
|
|
244
|
+
detail: "`FixHarmony`'s own config comment is \"If you disable this, mods which use Harmony are
|
|
245
|
+
likely to cause game crashes\", and `SuppressHarmonyDebugMode`'s is \"Debug mode should never
|
|
246
|
+
be enabled by a released mod\". Both are readable from disk and both change what a log means,
|
|
247
|
+
so both deserve a compat rule. The console command `harmony_summary [S:search]` lists live
|
|
248
|
+
patches."
|
|
249
|
+
- id: stardewvalley.smapi.loader.console-is-stdin-only
|
|
250
|
+
claim: "SMAPI's console reads commands from standard input, gated by the `ListenForConsoleInput`
|
|
251
|
+
setting; there is no documented file-based channel for SMAPI console commands. The game's own
|
|
252
|
+
debug commands do have one: `debug runmacro <filename>` runs a list of slash-prefixed commands
|
|
253
|
+
from a `.txt` file in the game folder."
|
|
254
|
+
status: community
|
|
255
|
+
source: "https://stardewvalleywiki.com/Modding:Console_commands (read 2026-09-11): \"You can enter
|
|
256
|
+
console commands directly into the SMAPI console window\" and, under Macros, \"Instead of
|
|
257
|
+
entering each command directly into the SMAPI console, you can also use the `debug runmacro`
|
|
258
|
+
command to a list of debug commands from a text file. (This doesn't work with the non-debug
|
|
259
|
+
commands.)\"; `ListenForConsoleInput` from src/SMAPI/SMAPI.config.json"
|
|
260
|
+
tags:
|
|
261
|
+
- console
|
|
262
|
+
- bridge
|
|
263
|
+
- transport
|
|
264
|
+
- debug
|
|
265
|
+
- verification
|
|
266
|
+
detail: "`debug runmacro` is a payload transport, not a trigger — someone still has to type it once
|
|
267
|
+
— so it does not replace a bridge. It is still the cheapest way to get a batch of game state
|
|
268
|
+
changes into a test session."
|
|
269
|
+
- id: stardewvalley.smapi.loader.console-commands-mod-is-bundled
|
|
270
|
+
claim: 'The console commands are supplied by a bundled mod SMAPI installs into `Mods/`, with
|
|
271
|
+
manifest `{"Name": "Console Commands", "Author": "SMAPI", "UniqueId": "SMAPI.ConsoleCommands",
|
|
272
|
+
"EntryDll": "ConsoleCommands.dll"}`; the other bundled mod is `SMAPI.SaveBackup`.'
|
|
273
|
+
status: inferred
|
|
274
|
+
source: "https://github.com/Pathoschild/SMAPI/blob/develop/src/SMAPI.Mods.ConsoleCommands/manifest.\
|
|
275
|
+
json; both ids appear in src/SMAPI/SMAPI.config.json's `\"SuppressUpdateChecks\":
|
|
276
|
+
[\"SMAPI.ConsoleCommands\", \"SMAPI.SaveBackup\"]`"
|
|
277
|
+
tags:
|
|
278
|
+
- console
|
|
279
|
+
- bundled
|
|
280
|
+
- manifest
|
|
281
|
+
- validator
|
|
282
|
+
detail: Note the field is spelled `UniqueId` in that file, not `UniqueID`. SMAPI's JSON binding is
|
|
283
|
+
case-insensitive so it loads fine — which means a ModWright validator must be case-insensitive
|
|
284
|
+
on manifest field names too, or it will reject a file SMAPI itself ships.
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
game: stardewvalley
|
|
2
|
+
topic: smapi.logs
|
|
3
|
+
title: SMAPI-latest.txt — location, the exact line format, the startup lines, and SMAPI's own parser
|
|
4
|
+
facts:
|
|
5
|
+
- id: stardewvalley.smapi.logs.path-and-name
|
|
6
|
+
claim: The SMAPI log is written to `%APPDATA%\StardewValley\ErrorLogs\SMAPI-latest.txt`. The crash
|
|
7
|
+
log beside it is `SMAPI-crash.txt`, and it is deliberately not deleted when SMAPI purges old
|
|
8
|
+
logs.
|
|
9
|
+
status: inferred
|
|
10
|
+
source: 'SMAPI develop, src/SMAPI/Constants.cs: `LogDir = Path.Combine(Constants.DataPath,
|
|
11
|
+
"ErrorLogs")`, `LogNamePrefix = "SMAPI-"`, `LogFilename = $"{LogNamePrefix}latest"`,
|
|
12
|
+
`LogExtension = "txt"`, `FatalCrashLog = Path.Combine(LogDir, "SMAPI-crash.txt")`;
|
|
13
|
+
`PurgeNormalLogs()` in src/SMAPI/Framework/SCore.cs skips `FatalCrashLog`'
|
|
14
|
+
tags:
|
|
15
|
+
- log
|
|
16
|
+
- path
|
|
17
|
+
- appdata
|
|
18
|
+
- logsource
|
|
19
|
+
- crash
|
|
20
|
+
detail: "The wiki states the same in prose: \"It's output to the game's ErrorLogs data folder ...
|
|
21
|
+
The log file is always created (even if there are no errors) and it's written continuously (so
|
|
22
|
+
you don't need to exit the game to see the log so far).\""
|
|
23
|
+
- id: stardewvalley.smapi.logs.player-numbered-fallbacks
|
|
24
|
+
claim: If `SMAPI-latest.txt` already exists and is in use, SMAPI walks `SMAPI-latest.player-2.txt`,
|
|
25
|
+
`SMAPI-latest.player-3.txt` and so on until it finds a free name, so a log source must declare
|
|
26
|
+
candidates rather than one path.
|
|
27
|
+
status: inferred
|
|
28
|
+
source: 'SMAPI develop, src/SMAPI/Framework/SCore.cs `GetLogPath()`: the loop `for (int i = 2; i <
|
|
29
|
+
int.MaxValue; i++)` over `$"{Constants.LogFilename}.player-{i}.{Constants.LogExtension}"`'
|
|
30
|
+
tags:
|
|
31
|
+
- log
|
|
32
|
+
- candidates
|
|
33
|
+
- logsource
|
|
34
|
+
- split-screen
|
|
35
|
+
- multi-instance
|
|
36
|
+
detail: "Same shape as BepInEx's `LogOutput.log.1`-`.4` fallbacks on Valheim, for a different
|
|
37
|
+
reason: here it is a second running instance (local co-op through two game processes), not a
|
|
38
|
+
file lock."
|
|
39
|
+
- id: stardewvalley.smapi.logs.one-file-per-run-autoflush
|
|
40
|
+
claim: "The log is opened as `new StreamWriter(path, append: false) { AutoFlush = true }` and every
|
|
41
|
+
line is written with an explicit `\\r\\n`, so it is one fresh file per run, complete up to the
|
|
42
|
+
instant it is read."
|
|
43
|
+
status: inferred
|
|
44
|
+
source: SMAPI develop,
|
|
45
|
+
https://github.com/Pathoschild/SMAPI/blob/develop/src/SMAPI/Framework/Logging/LogFileManager.cs;
|
|
46
|
+
the line-ending comment is "always use Windows-style line endings for convenience (Linux/macOS
|
|
47
|
+
editors are fine with them, Windows editors often require them)"
|
|
48
|
+
tags:
|
|
49
|
+
- log
|
|
50
|
+
- run-scope
|
|
51
|
+
- truncation
|
|
52
|
+
- autoflush
|
|
53
|
+
detail: "Good for `core/logs` run scoping: a plain whole-file read is already run-scoped, with none
|
|
54
|
+
of the Cyberpunk redscript in-place-truncation trap, and the file can be read while the game
|
|
55
|
+
is running without waiting for a flush."
|
|
56
|
+
- id: stardewvalley.smapi.logs.line-format
|
|
57
|
+
claim: 'Every line is `[HH:mm:ss LEVEL source] message`, built by `$"[{DateTime.Now:HH:mm:ss}
|
|
58
|
+
{levelStr}{(playerIndex != null ? $" screen_{playerIndex}" : "")} {source}]"` followed by a
|
|
59
|
+
space and the message. The timestamp is local time with no date.'
|
|
60
|
+
status: inferred
|
|
61
|
+
source: SMAPI develop,
|
|
62
|
+
https://github.com/Pathoschild/SMAPI/blob/develop/src/SMAPI/Framework/Monitor.cs,
|
|
63
|
+
`GenerateMessagePrefix(string source, ConsoleLogLevel level)` and `LogImpl(...)`'s `string
|
|
64
|
+
fullMessage = $"{prefix} {message}";`
|
|
65
|
+
tags:
|
|
66
|
+
- log
|
|
67
|
+
- format
|
|
68
|
+
- signature
|
|
69
|
+
- timestamp
|
|
70
|
+
- regex
|
|
71
|
+
detail: The wiki's own worked example agrees exactly — `[18:00:00 TRACE NameOfMod] a trace message`
|
|
72
|
+
through `[18:00:00 ERROR NameOfMod] an error message`. Because there is a timestamp,
|
|
73
|
+
`SourceStatus.timestamps` is true for this source, which is a first among ModWright's text-log
|
|
74
|
+
surfaces; but with no date it can only order lines within one run.
|
|
75
|
+
- id: stardewvalley.smapi.logs.level-padding-and-the-overflow
|
|
76
|
+
claim: The level is uppercased and right-padded to `MaxLevelLength`, which is computed over
|
|
77
|
+
`LogLevel` (Trace, Debug, Info, Warn, Error, Alert) and is therefore 5 — giving `TRACE`,
|
|
78
|
+
`DEBUG`, `INFO `, `WARN `, `ERROR`, `ALERT`. But the lookup is keyed on `ConsoleLogLevel`,
|
|
79
|
+
which also has `Critical` and `Success`, so `CRITICAL` (8) and `SUCCESS` (7) overflow the
|
|
80
|
+
column and are not padded.
|
|
81
|
+
status: inferred
|
|
82
|
+
source: "SMAPI develop, src/SMAPI/Framework/Monitor.cs: `MaxLevelLength =
|
|
83
|
+
Enum.GetValues<LogLevel>().Max(level => level.ToString().Length)` and `LogStrings =
|
|
84
|
+
Enum.GetValues<ConsoleLogLevel>().ToDictionary(level => level, level =>
|
|
85
|
+
level.ToString().ToUpperInvariant().PadRight(Monitor.MaxLevelLength))`; the two extra members
|
|
86
|
+
are in src/SMAPI.Internal/ConsoleWriting/ConsoleLogLevel.cs"
|
|
87
|
+
tags:
|
|
88
|
+
- log
|
|
89
|
+
- format
|
|
90
|
+
- signature
|
|
91
|
+
- gotcha
|
|
92
|
+
- regex
|
|
93
|
+
- critical
|
|
94
|
+
detail: "A signature written against fixed columns will miss exactly the lines that matter most:
|
|
95
|
+
`Monitor.LogFatal` emits `Critical`, and `LogManager` calls it for \"Malicious mod detected.\"
|
|
96
|
+
Match the level as `[A-Z]+` with one or more following spaces, exactly as SMAPI's own parser
|
|
97
|
+
does. Same class of trap as BepInEx's ten-character source padding on Valheim."
|
|
98
|
+
- id: stardewvalley.smapi.logs.source-is-the-display-name
|
|
99
|
+
claim: The bracketed source is one of `SMAPI`, `game`, or a mod's **display name** — never its
|
|
100
|
+
UniqueID. SMAPI registers monitors as `GetMonitor("SMAPI", "SMAPI")`, `GetMonitor("game",
|
|
101
|
+
"game")` and `GetMonitor(manifest.UniqueID, mod.DisplayName)`.
|
|
102
|
+
status: inferred
|
|
103
|
+
source: SMAPI develop, src/SMAPI/Framework/Logging/LogManager.cs (constructor) and
|
|
104
|
+
src/SMAPI/Framework/SCore.cs (`this.LogManager.GetMonitor(manifest.UniqueID,
|
|
105
|
+
mod.DisplayName)`)
|
|
106
|
+
tags:
|
|
107
|
+
- log
|
|
108
|
+
- source
|
|
109
|
+
- signature
|
|
110
|
+
- inventory
|
|
111
|
+
- uniqueid
|
|
112
|
+
detail: So a log-derived mod inventory is keyed on a human-facing name that can change between
|
|
113
|
+
versions, and joining it back to a manifest id requires the `Loaded N mods:` block or a bridge
|
|
114
|
+
probe over `helper.ModRegistry`. It is also why the manifest's `Name` field has its square
|
|
115
|
+
brackets rewritten.
|
|
116
|
+
- id: stardewvalley.smapi.logs.split-screen-field
|
|
117
|
+
claim: In split-screen the prefix gains a ` screen_<N>` field between the level and the source,
|
|
118
|
+
emitted only when the screen id is non-null.
|
|
119
|
+
status: inferred
|
|
120
|
+
source: "SMAPI develop, src/SMAPI/Framework/Monitor.cs `GenerateMessagePrefix`; SMAPI's own parser
|
|
121
|
+
matches it as `(?: +screen_(?<screen>\\d+))?` and sets `log.IsSplitScreen = true` when any
|
|
122
|
+
message has a non-zero screen id (src/SMAPI.Web/Framework/LogParsing/LogParser.cs)"
|
|
123
|
+
tags:
|
|
124
|
+
- log
|
|
125
|
+
- format
|
|
126
|
+
- split-screen
|
|
127
|
+
- signature
|
|
128
|
+
- regex
|
|
129
|
+
- id: stardewvalley.smapi.logs.console-input-and-blank-lines
|
|
130
|
+
claim: Console input the player typed is written to the log file only (not the console, where it
|
|
131
|
+
already appeared) as `{prefix} $>{input}`, and `Monitor.Newline()` writes genuinely empty
|
|
132
|
+
lines that separate the mod list, the content-pack list and the warning blocks.
|
|
133
|
+
status: inferred
|
|
134
|
+
source: SMAPI develop, src/SMAPI/Framework/Monitor.cs `LogUserInput(string input)`
|
|
135
|
+
(`this.LogFile.WriteLine($"{prefix} $>{input}")`) and `Newline()`; the section separations are
|
|
136
|
+
the `this.Monitor.Newline()` calls in src/SMAPI/Framework/Logging/LogManager.cs `LogModInfo`
|
|
137
|
+
tags:
|
|
138
|
+
- log
|
|
139
|
+
- console
|
|
140
|
+
- format
|
|
141
|
+
- parsing
|
|
142
|
+
- bridge
|
|
143
|
+
detail: The `$>` line means a console session is partially reconstructable from the log alone.
|
|
144
|
+
Whether a command's *output* also reaches the log was not confirmed without a real run — if it
|
|
145
|
+
does, `patch summary` becomes readable without a bridge, which would be the cheapest
|
|
146
|
+
verification win on this game.
|
|
147
|
+
- id: stardewvalley.smapi.logs.banner-line
|
|
148
|
+
claim: "The first line of every run is `SMAPI {ApiVersion} with Stardew Valley
|
|
149
|
+
{Game1.GetVersionString()} on {platform}` at Info, followed by `Mods go here: {path}` and `Log
|
|
150
|
+
started at {DateTime.UtcNow:s} UTC`."
|
|
151
|
+
status: inferred
|
|
152
|
+
source: SMAPI develop, src/SMAPI/Framework/Logging/LogManager.cs `LogIntro(...)`
|
|
153
|
+
tags:
|
|
154
|
+
- log
|
|
155
|
+
- banner
|
|
156
|
+
- version
|
|
157
|
+
- compat
|
|
158
|
+
- signature
|
|
159
|
+
detail: "This is where both live version axes come from in one line, and the `Log started at ...
|
|
160
|
+
UTC` line is the **only** absolute timestamp in the file — a run-scoping implementation should
|
|
161
|
+
anchor on it and treat every `HH:mm:ss` as an offset from it. When `--mods-path` was used, an
|
|
162
|
+
extra line reads `(Using custom --mods-path argument. Game folder: {path}.)`."
|
|
163
|
+
- id: stardewvalley.smapi.logs.mod-list-block
|
|
164
|
+
claim: Loaded mods are reported as `Loaded {N} mods:` (or `Loaded 0 mods.`) at Info, followed by one
|
|
165
|
+
indented line per mod of the form ` {DisplayName} {Version} by {Author} | {Description}`,
|
|
166
|
+
and then the same shape for `Loaded {N} content packs:` with an extra ` | for {parent mod}`
|
|
167
|
+
segment.
|
|
168
|
+
status: inferred
|
|
169
|
+
source: SMAPI develop, src/SMAPI/Framework/Logging/LogManager.cs `LogModInfo(...)`
|
|
170
|
+
tags:
|
|
171
|
+
- log
|
|
172
|
+
- inventory
|
|
173
|
+
- signature
|
|
174
|
+
- success
|
|
175
|
+
- content-pack
|
|
176
|
+
detail: The author and description segments are omitted when blank, so a pattern must make both
|
|
177
|
+
optional — SMAPI's own parser does exactly that. The list is ordered `OrderBy(p =>
|
|
178
|
+
p.DisplayName)`, i.e. **alphabetically, not in load order**; treating it as a load order is a
|
|
179
|
+
trap a naive implementation walks straight into.
|
|
180
|
+
- id: stardewvalley.smapi.logs.skipped-mods-block
|
|
181
|
+
claim: Failed mods appear under a fixed three-line header at Error — ` Skipped mods`, then three
|
|
182
|
+
spaces plus fifty hyphens, then ` These mods could not be added to your game.` — followed
|
|
183
|
+
by one line per mod of the form ` - {DisplayName} {Version} because {reason}`.
|
|
184
|
+
status: inferred
|
|
185
|
+
source: "SMAPI develop, src/SMAPI/Framework/Logging/LogManager.cs `LogModWarnings(...)`:
|
|
186
|
+
`this.Monitor.Log(\" \" + \"\".PadRight(50, '-'), LogLevel.Error)` and `string message =
|
|
187
|
+
$\" - {mod.DisplayName}{(\" \" +
|
|
188
|
+
mod.Manifest?.Version?.ToString()).TrimEnd()}{technicalInfo} because {mod.Error}\";`"
|
|
189
|
+
tags:
|
|
190
|
+
- log
|
|
191
|
+
- errors
|
|
192
|
+
- skipped
|
|
193
|
+
- signature
|
|
194
|
+
- triage
|
|
195
|
+
detail: "With `LogTechnicalDetailsForBrokenMods` enabled the line gains ` (ID: {UniqueID}, path:
|
|
196
|
+
{relative path})` before `because`, which is the only place the UniqueID appears alongside the
|
|
197
|
+
display name. A duplicate mod is logged once, without its version. Any `ErrorDetails` follows
|
|
198
|
+
on the next line as ` ({details})` at Trace."
|
|
199
|
+
- id: stardewvalley.smapi.logs.mod-warning-groups
|
|
200
|
+
claim: 'SMAPI prints named warning groups after the skipped list, each a heading plus a blurb:
|
|
201
|
+
"Broken mods" (Error), "Patched game code without Harmony fix" (Warn), "Changed save
|
|
202
|
+
serializer" (Warn), "Patched game code" (Info), "Bypassed safety checks" (Info), "Direct
|
|
203
|
+
console access" (Trace), "Direct system access" (Debug, paranoid mode only) and "No update
|
|
204
|
+
keys" (Debug).'
|
|
205
|
+
status: inferred
|
|
206
|
+
source: SMAPI develop, src/SMAPI/Framework/Logging/LogManager.cs `LogModWarnings(...)`, the
|
|
207
|
+
`LogModWarningGroup(...)` calls
|
|
208
|
+
tags:
|
|
209
|
+
- log
|
|
210
|
+
- warnings
|
|
211
|
+
- harmony
|
|
212
|
+
- signature
|
|
213
|
+
- triage
|
|
214
|
+
detail: '"Patched game code" is how the log alone tells a content pack, a plain C# mod, and a
|
|
215
|
+
game-patching C# mod apart — genuinely useful triage information no other supported game gives
|
|
216
|
+
for free. "Changed save serializer" is the one warning with a save-corruption consequence:
|
|
217
|
+
"They may corrupt your save files, or make them unusable if you uninstall these mods."'
|
|
218
|
+
- id: stardewvalley.smapi.logs.startup-progress-lines
|
|
219
|
+
claim: "The startup sequence's own markers are, in order, `Loading mod metadata...` (Debug),
|
|
220
|
+
`Loading mods...` (Debug), `Launching mods...` (Debug) and `Mods loaded and ready!` (Debug),
|
|
221
|
+
with one Trace line per mod in between of the form ` {DisplayName} (from {path}\\{EntryDll},
|
|
222
|
+
ID: {UniqueID}, assembly version: {version})...` or ` {DisplayName} (from {path}, ID:
|
|
223
|
+
{UniqueID}) [content pack]...`."
|
|
224
|
+
status: inferred
|
|
225
|
+
source: SMAPI develop, src/SMAPI/Framework/SCore.cs, the `Monitor.Log` calls in `LoadMods(...)` and
|
|
226
|
+
around it
|
|
227
|
+
tags:
|
|
228
|
+
- log
|
|
229
|
+
- startup
|
|
230
|
+
- signature
|
|
231
|
+
- success
|
|
232
|
+
- inventory
|
|
233
|
+
detail: "These Trace lines are the only place in the log where a mod's display name, folder path,
|
|
234
|
+
UniqueID and assembly version appear together, so they are the best source for a log-derived
|
|
235
|
+
inventory — better than the Info-level `Loaded N mods:` block. A failed mod's line is followed
|
|
236
|
+
by ` Failed: {ErrorDetails ?? Error}`."
|
|
237
|
+
- id: stardewvalley.smapi.logs.loose-files-error
|
|
238
|
+
claim: Files placed directly in `Mods/` rather than in a per-mod subfolder produce the Error line
|
|
239
|
+
"Detected mod files directly inside the '{Mods}' folder. These will be ignored. Each mod must
|
|
240
|
+
have its own subfolder instead.", followed by a Trace line listing them.
|
|
241
|
+
status: inferred
|
|
242
|
+
source: SMAPI develop, src/SMAPI/Framework/SCore.cs, in the mod-metadata loading block
|
|
243
|
+
tags:
|
|
244
|
+
- log
|
|
245
|
+
- errors
|
|
246
|
+
- mods
|
|
247
|
+
- signature
|
|
248
|
+
- common-failure
|
|
249
|
+
detail: One of the most common real installation mistakes and one of the few that SMAPI reports at
|
|
250
|
+
Error with an actionable instruction, so it should be a high-ranking triage finding.
|
|
251
|
+
- id: stardewvalley.smapi.logs.crash-and-update-lines
|
|
252
|
+
claim: "Crash and update lines worth signatures: \"The game crashed last time you played. If it
|
|
253
|
+
happens repeatedly, see 'get help' on https://smapi.io.\" (Error), \"The game failed to
|
|
254
|
+
launch: {summary}\" (Error), \"SMAPI failed to initialize: {summary}\" (Error), \"Malicious
|
|
255
|
+
mod detected.\" (Critical), \"You can update SMAPI to {version}: {url}\" (Alert) and \"You can
|
|
256
|
+
update {N} mods:\" (Alert)."
|
|
257
|
+
status: inferred
|
|
258
|
+
source: SMAPI develop, src/SMAPI/Framework/Logging/LogManager.cs (`HandleMarkerFiles` for the crash
|
|
259
|
+
line, `MonitorForGame` for the launch failure, and `LogModInfo`'s `LogFatal("Malicious mod
|
|
260
|
+
detected.")`) and src/SMAPI/Framework/SCore.cs (`CheckForUpdatesAsync(...)` for the two Alert
|
|
261
|
+
update lines, and the `SMAPI failed to initialize` catch block)
|
|
262
|
+
tags:
|
|
263
|
+
- log
|
|
264
|
+
- crash
|
|
265
|
+
- update
|
|
266
|
+
- alert
|
|
267
|
+
- signature
|
|
268
|
+
detail: 'Alert is a level mods are told almost never to use — the wiki: "This is mainly meant for
|
|
269
|
+
SMAPI itself, and should almost never be used by mods" — so an Alert line from a mod source is
|
|
270
|
+
itself worth reporting.'
|
|
271
|
+
- id: stardewvalley.smapi.logs.first-party-parser-regexes
|
|
272
|
+
claim: "SMAPI publishes the parser behind smapi.io/log, and its message-header regex is
|
|
273
|
+
`^\\[(?<time>\\d\\d[:\\.]\\d\\d[:\\.]\\d\\d) (?<level>[a-z]+)(?: +screen_(?<screen>\\d+))?
|
|
274
|
+
+(?<modName>[^\\]]+)\\] ` compiled case-insensitively, with thirteen more patterns for the
|
|
275
|
+
banner, the mod list, the content-pack list, the skipped list and the update lists."
|
|
276
|
+
status: inferred
|
|
277
|
+
source: https://github.com/Pathoschild/SMAPI/blob/develop/src/SMAPI.Web/Framework/LogParsing/LogParser.cs,
|
|
278
|
+
the `MessageHeaderPattern`, `InfoLinePattern`, `ModPathPattern`, `GamePathPattern`,
|
|
279
|
+
`LogStartedAtPattern`, `ModListStartPattern`, `ModListEntryPattern`,
|
|
280
|
+
`ContentPackListStartPattern`, `ContentPackListEntryPattern`, `SkippedModListStartPattern`,
|
|
281
|
+
`SkippedModListEntryPattern`, `ModUpdateListStartPattern`, `ModUpdateListEntryPattern` and
|
|
282
|
+
`SmapiUpdatePattern` fields
|
|
283
|
+
tags:
|
|
284
|
+
- log
|
|
285
|
+
- parser
|
|
286
|
+
- signature
|
|
287
|
+
- smapi-io
|
|
288
|
+
- tooling
|
|
289
|
+
detail: "This is the single most valuable artifact for a Stardew `logSignatures` set: fourteen
|
|
290
|
+
patterns written by SMAPI's own author against the format SMAPI emits, already proven against
|
|
291
|
+
real uploads. Note the time pattern accepts `.` as well as `:` (some locales), the level is
|
|
292
|
+
`[a-z]+` with no length assumption (which is how it survives CRITICAL), and there is one or
|
|
293
|
+
more space before the source."
|
|
294
|
+
- id: stardewvalley.smapi.logs.multiline-messages-need-reassembly
|
|
295
|
+
claim: Multi-line messages are ordinary in this log — every stack trace, every `Technical
|
|
296
|
+
details:\n{ex}`, every `GetLogSummary()` — and their continuation lines carry no prefix at
|
|
297
|
+
all. SMAPI's parser reassembles them by treating any line that fails the message-header
|
|
298
|
+
pattern as a continuation of the previous message.
|
|
299
|
+
status: inferred
|
|
300
|
+
source: SMAPI develop, src/SMAPI.Web/Framework/LogParsing/LogParser.cs, `GetMessages(string
|
|
301
|
+
logText)` and the `MessageHeaderPattern` fallthrough
|
|
302
|
+
tags:
|
|
303
|
+
- log
|
|
304
|
+
- parsing
|
|
305
|
+
- multiline
|
|
306
|
+
- signature
|
|
307
|
+
- gotcha
|
|
308
|
+
detail: A ModWright implementation must do the reassembly before any signature runs. Without it, the
|
|
309
|
+
contents of a stack trace get scanned as if they were log lines, and a signature anchored on a
|
|
310
|
+
substring will fire on the wrong thing. What the continuation lines look like exactly —
|
|
311
|
+
indented, blank-separated or bare — was not established without a real log.
|
|
312
|
+
- id: stardewvalley.smapi.logs.no-real-sample-exists-here
|
|
313
|
+
claim: "No real Stardew Valley log was available when these facts were written: the game is not
|
|
314
|
+
installed on the research machine, `%APPDATA%\\StardewValley` does not exist, and every line
|
|
315
|
+
shape recorded here comes from source or from the wiki's constructed examples. Every derived
|
|
316
|
+
log signature is pending a real sample."
|
|
317
|
+
status: inferred
|
|
318
|
+
source: "Direct observation 2026-09-11: no `appmanifest_413150.acf` and no `steamapps/common/Stardew
|
|
319
|
+
Valley` under the machine's one Steam library, and no `%APPDATA%\\StardewValley` directory"
|
|
320
|
+
tags:
|
|
321
|
+
- log
|
|
322
|
+
- provenance
|
|
323
|
+
- unverified
|
|
324
|
+
- testing
|
|
325
|
+
- fixture
|
|
326
|
+
detail: The corroboration that does exist is strong — the wiki's five example lines agree exactly
|
|
327
|
+
with the source's format string, and SMAPI's own parser regexes agree with both — but no line
|
|
328
|
+
from a real run has been matched. The cheapest useful first step in a real run is capturing
|
|
329
|
+
one title-screen launch's `SMAPI-latest.txt` as a fixture.
|