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,190 @@
|
|
|
1
|
+
export const WIKI_BASE = "https://stardewvalleywiki.com/Modding:";
|
|
2
|
+
export const WIKI_PAGES = [
|
|
3
|
+
{ page: "Object_data", asset: "Data/Objects", shape: "model" },
|
|
4
|
+
{ page: "Big_craftables", asset: "Data/BigCraftables", shape: "model" },
|
|
5
|
+
{ page: "Pants", asset: "Data/Pants", shape: "model" },
|
|
6
|
+
{ page: "Shirts", asset: "Data/Shirts", shape: "model" },
|
|
7
|
+
{ page: "Tools", asset: "Data/Tools", shape: "model" },
|
|
8
|
+
{ page: "Trinkets", asset: "Data/Trinkets", shape: "model" },
|
|
9
|
+
{ page: "Mannequins", asset: "Data/Mannequins", shape: "model" },
|
|
10
|
+
{ page: "Weapons", asset: "Data/Weapons", shape: "model" },
|
|
11
|
+
{ page: "Wallpaper_and_flooring", asset: "Data/AdditionalWallpaperFlooring", shape: "model" },
|
|
12
|
+
{ page: "Boots", asset: "Data/Boots", shape: "delimited" },
|
|
13
|
+
{ page: "Hats", asset: "Data/Hats", shape: "delimited" },
|
|
14
|
+
{ page: "Furniture", asset: "Data/Furniture", shape: "delimited" },
|
|
15
|
+
{ page: "Crop_data", asset: "Data/Crops", shape: "model" },
|
|
16
|
+
{ page: "Fruit_trees", asset: "Data/FruitTrees", shape: "model" },
|
|
17
|
+
{ page: "Giant_crops", asset: "Data/GiantCrops", shape: "model" },
|
|
18
|
+
{ page: "Wild_trees", asset: "Data/WildTrees", shape: "model" },
|
|
19
|
+
{ page: "Machines", asset: "Data/Machines", shape: "model" },
|
|
20
|
+
{ page: "Farm_data", asset: "Data/AdditionalFarms", shape: "model" },
|
|
21
|
+
{ page: "Location_contexts", asset: "Data/LocationContexts", shape: "model" },
|
|
22
|
+
{ page: "Location_data", asset: "Data/Locations", shape: "model" },
|
|
23
|
+
{ page: "Museum", asset: "Data/MuseumRewards", shape: "model" },
|
|
24
|
+
{ page: "Passive_Festival_data", asset: "Data/PassiveFestivals", shape: "model" },
|
|
25
|
+
{ page: "Buffs", asset: "Data/Buffs", shape: "model" },
|
|
26
|
+
{ page: "Buildings", asset: "Data/Buildings", shape: "model" },
|
|
27
|
+
{ page: "Bundles", asset: "Data/Bundles", shape: "delimited" },
|
|
28
|
+
{ page: "Fences", asset: "Data/Fences", shape: "model" },
|
|
29
|
+
{ page: "Floors_and_Paths", asset: "Data/FloorsAndPaths", shape: "model" },
|
|
30
|
+
{ page: "Fish_ponds", asset: "Data/FishPondData", shape: "model" },
|
|
31
|
+
{ page: "Garbage_cans", asset: "Data/GarbageCans", shape: "model" },
|
|
32
|
+
{ page: "Jukebox_tracks", asset: "Data/JukeboxTracks", shape: "model" },
|
|
33
|
+
{ page: "Lost_items_shop", asset: "Data/LostItemsShop", shape: "model" },
|
|
34
|
+
{ page: "Minecarts", asset: "Data/Minecarts", shape: "model" },
|
|
35
|
+
{ page: "Monster_eradication_goals", asset: "Data/MonsterSlayerQuests", shape: "model" },
|
|
36
|
+
{ page: "Phone_calls", asset: "Data/IncomingPhoneCalls", shape: "model" },
|
|
37
|
+
{ page: "Shops", asset: "Data/Shops", shape: "model" },
|
|
38
|
+
{ page: "Powers", asset: "Data/Powers", shape: "model" },
|
|
39
|
+
{ page: "Special_orders", asset: "Data/SpecialOrders", shape: "model" },
|
|
40
|
+
{ page: "Tailoring", asset: "Data/TailoringRecipes", shape: "model" },
|
|
41
|
+
{ page: "Animal_data", asset: "Data/FarmAnimals", shape: "model" },
|
|
42
|
+
{ page: "Monster_data", asset: "Data/Monsters", shape: "delimited" },
|
|
43
|
+
{ page: "Pets", asset: "Data/Pets", shape: "model" },
|
|
44
|
+
{ page: "NPC_data", asset: "Data/Characters", shape: "model" },
|
|
45
|
+
{ page: "Achievement_data", asset: "Data/Achievements", shape: "delimited" },
|
|
46
|
+
];
|
|
47
|
+
export const WIKI_FETCH = {
|
|
48
|
+
source: "the Stardew Valley Wiki's Modding: data pages (stardewvalleywiki.com)",
|
|
49
|
+
license: "The wiki's text is CC BY-NC-SA. The pages are saved on your machine for build_index to read, and ModWright never redistributes them.",
|
|
50
|
+
files: WIKI_PAGES.map((p) => ({ url: pageUrl(p.page), file: pageFileName(p.page) })),
|
|
51
|
+
delayMs: 1000,
|
|
52
|
+
userAgent: "Mozilla/5.0 (compatible; ModWright wiki fetch; +https://www.npmjs.com/package/modwright)",
|
|
53
|
+
robotsToken: "ModWright",
|
|
54
|
+
};
|
|
55
|
+
export function pageFileName(page) {
|
|
56
|
+
return `${page}.html`;
|
|
57
|
+
}
|
|
58
|
+
export function pageUrl(page) {
|
|
59
|
+
return `${WIKI_BASE}${page}`;
|
|
60
|
+
}
|
|
61
|
+
const ENTITIES = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'", nbsp: " ", "#39": "'", "#160": " " };
|
|
62
|
+
export function plainText(html) {
|
|
63
|
+
return html
|
|
64
|
+
.replace(/<br\s*\/?>/gi, " ")
|
|
65
|
+
.replace(/<[^>]+>/g, "")
|
|
66
|
+
.replace(/&(#\d+|#x[0-9a-f]+|[a-z]+);/gi, (m, e) => {
|
|
67
|
+
const key = e.toLowerCase();
|
|
68
|
+
if (key in ENTITIES)
|
|
69
|
+
return ENTITIES[key];
|
|
70
|
+
if (key.startsWith("#x"))
|
|
71
|
+
return String.fromCodePoint(parseInt(key.slice(2), 16));
|
|
72
|
+
if (key.startsWith("#"))
|
|
73
|
+
return String.fromCodePoint(parseInt(key.slice(1), 10));
|
|
74
|
+
return m;
|
|
75
|
+
})
|
|
76
|
+
.replace(/\s+/g, " ")
|
|
77
|
+
.trim();
|
|
78
|
+
}
|
|
79
|
+
const TOKEN_RE = /<span class="mw-headline" id="[^"]*">([\s\S]*?)<\/span>|<table[^>]*class="[^"]*\bwikitable\b[^"]*"[^>]*>/g;
|
|
80
|
+
const ANY_TABLE_RE = /<table[^>]*>|<\/table>/g;
|
|
81
|
+
const OPEN_TABLE_RE = /<table[^>]*>/g;
|
|
82
|
+
const ROW_RE = /<tr[^>]*>([\s\S]*?)<\/tr>/g;
|
|
83
|
+
const CELL_RE = /<(t[hd])[^>]*>([\s\S]*?)<\/\1>/g;
|
|
84
|
+
function tableAt(html, from) {
|
|
85
|
+
ANY_TABLE_RE.lastIndex = from;
|
|
86
|
+
let depth = 1;
|
|
87
|
+
let m;
|
|
88
|
+
while ((m = ANY_TABLE_RE.exec(html)) !== null) {
|
|
89
|
+
if (m[0].startsWith("</")) {
|
|
90
|
+
depth--;
|
|
91
|
+
if (depth === 0)
|
|
92
|
+
return { inner: html.slice(from, m.index), after: m.index + m[0].length };
|
|
93
|
+
}
|
|
94
|
+
else
|
|
95
|
+
depth++;
|
|
96
|
+
}
|
|
97
|
+
return { inner: html.slice(from), after: html.length };
|
|
98
|
+
}
|
|
99
|
+
function withoutNestedTables(inner) {
|
|
100
|
+
let out = "";
|
|
101
|
+
let i = 0;
|
|
102
|
+
let m;
|
|
103
|
+
OPEN_TABLE_RE.lastIndex = 0;
|
|
104
|
+
while ((m = OPEN_TABLE_RE.exec(inner)) !== null) {
|
|
105
|
+
out += inner.slice(i, m.index) + " ";
|
|
106
|
+
const { after } = tableAt(inner, m.index + m[0].length);
|
|
107
|
+
i = after;
|
|
108
|
+
OPEN_TABLE_RE.lastIndex = after;
|
|
109
|
+
}
|
|
110
|
+
return out + inner.slice(i);
|
|
111
|
+
}
|
|
112
|
+
export function parseWikiPage(html) {
|
|
113
|
+
const bodyStart = html.indexOf('id="mw-content-text"');
|
|
114
|
+
const body = bodyStart >= 0 ? html.slice(bodyStart) : html;
|
|
115
|
+
const titleMatch = /<h1[^>]*id="firstHeading"[^>]*>([\s\S]*?)<\/h1>/.exec(html);
|
|
116
|
+
const modMatch = /id="footer-info-lastmod">([^<]+)</.exec(html);
|
|
117
|
+
const page = { tables: [], text: plainText(body), ...(titleMatch ? { title: plainText(titleMatch[1]) } : {}), ...(modMatch ? { lastModified: plainText(modMatch[1]) } : {}) };
|
|
118
|
+
let section;
|
|
119
|
+
let m;
|
|
120
|
+
TOKEN_RE.lastIndex = 0;
|
|
121
|
+
while ((m = TOKEN_RE.exec(body)) !== null) {
|
|
122
|
+
if (m[1] !== undefined) {
|
|
123
|
+
section = plainText(m[1]);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const { inner } = tableAt(body, m.index + m[0].length);
|
|
127
|
+
const rows = [];
|
|
128
|
+
let columns = [];
|
|
129
|
+
for (const r of withoutNestedTables(inner).matchAll(ROW_RE)) {
|
|
130
|
+
const cells = [];
|
|
131
|
+
for (const c of r[1].matchAll(CELL_RE))
|
|
132
|
+
cells.push({ tag: c[1], html: c[2] });
|
|
133
|
+
if (cells.length === 0)
|
|
134
|
+
continue;
|
|
135
|
+
if (cells.every((c) => c.tag === "th")) {
|
|
136
|
+
if (columns.length === 0)
|
|
137
|
+
columns = cells.map((c) => plainText(c.html).toLowerCase());
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
rows.push(cells.map((c) => c.html));
|
|
141
|
+
}
|
|
142
|
+
page.tables.push({ ...(section !== undefined ? { section } : {}), columns, rows });
|
|
143
|
+
}
|
|
144
|
+
return page;
|
|
145
|
+
}
|
|
146
|
+
const FIELD_COLUMNS = new Set(["field", "field name", "field key"]);
|
|
147
|
+
const DELIMITED_NAME_COLUMNS = new Set([...FIELD_COLUMNS, "syntax"]);
|
|
148
|
+
const NAME_RE = /^[A-Za-z][A-Za-z0-9_.]*$/;
|
|
149
|
+
const OPTIONAL_SUFFIX_RE = /\s*\(optional\)\s*$/i;
|
|
150
|
+
const LABEL_MAX = 60;
|
|
151
|
+
function isName(name, shape) {
|
|
152
|
+
if (name.length === 0)
|
|
153
|
+
return false;
|
|
154
|
+
return shape === "model" ? NAME_RE.test(name) : name.length <= LABEL_MAX && !name.endsWith(".");
|
|
155
|
+
}
|
|
156
|
+
export function fieldNames(cellHtml, shape = "model") {
|
|
157
|
+
return cellHtml
|
|
158
|
+
.split(/<br\s*\/?>/i)
|
|
159
|
+
.map((part) => plainText(part).replace(OPTIONAL_SUFFIX_RE, ""))
|
|
160
|
+
.filter((name) => isName(name, shape));
|
|
161
|
+
}
|
|
162
|
+
export function documentedFields(page, shape) {
|
|
163
|
+
const out = [];
|
|
164
|
+
for (const table of page.tables) {
|
|
165
|
+
if (shape === "model") {
|
|
166
|
+
if (table.columns.length < 2 || !FIELD_COLUMNS.has(table.columns[0]))
|
|
167
|
+
continue;
|
|
168
|
+
for (const row of table.rows) {
|
|
169
|
+
const purpose = plainText(row[1] ?? "");
|
|
170
|
+
const optional = /^\(optional\)/i.test(purpose) || OPTIONAL_SUFFIX_RE.test(plainText(row[0] ?? ""));
|
|
171
|
+
for (const name of fieldNames(row[0] ?? "", "model"))
|
|
172
|
+
out.push({ name, ...(table.section !== undefined ? { section: table.section } : {}), optional, purpose });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
if (table.columns.length < 2 || table.columns[0] !== "index" || !DELIMITED_NAME_COLUMNS.has(table.columns[1]))
|
|
177
|
+
continue;
|
|
178
|
+
for (const row of table.rows) {
|
|
179
|
+
const position = /^\d+/.exec(plainText(row[0] ?? ""));
|
|
180
|
+
if (!position)
|
|
181
|
+
continue;
|
|
182
|
+
const purpose = plainText(row[2] ?? "");
|
|
183
|
+
const optional = /^\(optional\)/i.test(purpose) || OPTIONAL_SUFFIX_RE.test(plainText(row[1] ?? ""));
|
|
184
|
+
for (const name of fieldNames(row[1] ?? "", "delimited"))
|
|
185
|
+
out.push({ name, ...(table.section !== undefined ? { section: table.section } : {}), optional, position: Number(position[0]), purpose });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return out;
|
|
190
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { stardewvalley, gameFolderType, targetsFileGamePath, readLoadOrderOverrides, configCandidates, scanInstallMods, dataDir, STEAM_APP_ID } from "./surface.js";
|
|
2
|
+
export { SIGNATURES, PREFIX } from "./logs.js";
|
|
3
|
+
export { parseManifest, relaxJson, manifestType, scanMods, displayName, SLUG_RE, SEMANTIC_VERSION_RE, ENTRY_DLL_RE, UPDATE_KEY_RE, MANIFEST_FIELDS } from "./mods.js";
|
|
4
|
+
export { MANIFEST_VALIDATORS } from "./validators/manifest.js";
|
|
5
|
+
export { CONTENT_VALIDATORS } from "./validators/content.js";
|
|
6
|
+
export { LOADORDER_VALIDATORS } from "./validators/loadorder.js";
|
|
7
|
+
export { stardewvalleyCompat, detectComponents, RULES as COMPAT_RULES, readModMetadata, metadataFor } from "./compat.js";
|
|
8
|
+
export { readSmapiConfig, smapiConfigFiles, stringList, boolSetting } from "./config.js";
|
|
9
|
+
export { parseContentJson, patchesOf, formatState, splitLexically, tokenNames, conditionTokenName, isKnownToken, tokenPathToRegExp, CURRENT_FORMAT, ACTIONS, BUILTIN_TOKENS } from "./contentpatcher.js";
|
|
10
|
+
export { FIELDS_VALIDATORS } from "./validators/fields.js";
|
|
11
|
+
export { stardewvalleyIndex, buildIndex as buildStardewIndex, query as queryStardewIndex, queryKinds as stardewQueryKinds, importWikiPage, normalizeAsset, WIKI_DATA_ENV, WIKI_DATA_ID } from "./index/index.js";
|
|
12
|
+
export { WIKI_PAGES, WIKI_BASE, parseWikiPage, documentedFields, fieldNames, pageFileName, pageUrl } from "./index/wiki.js";
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
const PARSER = "SMAPI src/SMAPI.Web/Framework/LogParsing/LogParser.cs";
|
|
2
|
+
const RESOLVER = "SMAPI src/SMAPI/Framework/ModLoading/ModResolver.cs";
|
|
3
|
+
const SCORE = "SMAPI src/SMAPI/Framework/SCore.cs";
|
|
4
|
+
const LOGMANAGER = "SMAPI src/SMAPI/Framework/Logging/LogManager.cs";
|
|
5
|
+
const CP = "Content Patcher ContentPatcher/ModEntry.cs and Framework/PatchLoader.cs";
|
|
6
|
+
const PENDING = "pending a real sample";
|
|
7
|
+
export const PREFIX = String.raw `^\[(?<time>\d\d[:.]\d\d[:.]\d\d) (?<level>[A-Za-z]+)(?: +screen_(?<screen>\d+))? +(?<source>[^\]]+)\] `;
|
|
8
|
+
function re(body) {
|
|
9
|
+
return new RegExp(PREFIX + body);
|
|
10
|
+
}
|
|
11
|
+
const smapi = (id, rest) => ({ id: `stardewvalley.smapi.${id}`, game: "stardewvalley", sources: ["smapi", "smapi-crash"], ...rest });
|
|
12
|
+
const cp = (id, rest) => ({ id: `stardewvalley.contentpatcher.${id}`, game: "stardewvalley", sources: ["smapi"], systemImpact: false, ...rest });
|
|
13
|
+
export const SIGNATURES = [
|
|
14
|
+
smapi("banner", {
|
|
15
|
+
severity: "info",
|
|
16
|
+
category: "version",
|
|
17
|
+
pattern: re(String.raw `SMAPI (?<apiVersion>.+) with Stardew Valley (?<gameVersion>.+) on (?<os>.+)$`),
|
|
18
|
+
explain: "SMAPI started and named its own version, the game's and the platform; the anchor for the run.",
|
|
19
|
+
seenIn: [`${PARSER} InfoLinePattern`, PENDING],
|
|
20
|
+
extract: ["apiVersion", "gameVersion", "os"],
|
|
21
|
+
}),
|
|
22
|
+
smapi("mods-path", {
|
|
23
|
+
severity: "info",
|
|
24
|
+
category: "load",
|
|
25
|
+
pattern: re(String.raw `Mods go here: (?<path>.+)$`),
|
|
26
|
+
explain: "The Mods folder this run scanned; with --mods-path it is not the game's own.",
|
|
27
|
+
seenIn: [`${PARSER} ModPathPattern`, PENDING],
|
|
28
|
+
extract: ["path"],
|
|
29
|
+
}),
|
|
30
|
+
smapi("custom-mods-path", {
|
|
31
|
+
severity: "info",
|
|
32
|
+
category: "load",
|
|
33
|
+
pattern: re(String.raw `\(Using custom --mods-path argument\. Game folder: (?<path>.+)\.\)$`),
|
|
34
|
+
explain: "SMAPI was launched with --mods-path, so the mods it loaded are not the ones under the game folder's Mods/.",
|
|
35
|
+
seenIn: [`${PARSER} GamePathPattern`, PENDING],
|
|
36
|
+
extract: ["path"],
|
|
37
|
+
}),
|
|
38
|
+
smapi("log-started", {
|
|
39
|
+
severity: "info",
|
|
40
|
+
category: "version",
|
|
41
|
+
pattern: re(String.raw `Log started at (?<timestamp>.+) UTC$`),
|
|
42
|
+
explain: "The one absolute timestamp in the file; every other line carries only HH:mm:ss.",
|
|
43
|
+
seenIn: [`${PARSER} LogStartedAtPattern`, PENDING],
|
|
44
|
+
extract: ["timestamp"],
|
|
45
|
+
}),
|
|
46
|
+
smapi("loose-files-in-mods", {
|
|
47
|
+
severity: "error",
|
|
48
|
+
category: "load",
|
|
49
|
+
pattern: re(String.raw `Detected mod files directly inside the '(?<folder>[^']+)' folder\. These will be ignored\.`),
|
|
50
|
+
explain: "Files sit directly in Mods/ instead of in a mod's own subfolder; SMAPI ignores them, so that mod is not loaded.",
|
|
51
|
+
hint: "Each mod must have its own subfolder under Mods/ holding its manifest.json.",
|
|
52
|
+
seenIn: [`${SCORE}`, PENDING],
|
|
53
|
+
extract: ["folder"],
|
|
54
|
+
}),
|
|
55
|
+
smapi("load-order-override-missing", {
|
|
56
|
+
severity: "warn",
|
|
57
|
+
category: "order",
|
|
58
|
+
pattern: re(String.raw ` *The '(?<file>[^']+)' file lists mod IDs in (?<list>ModsToLoadEarly|ModsToLoadLate) which aren't installed: (?<ids>.+)$`),
|
|
59
|
+
explain: "smapi-internal/config.json's load-order override names a mod that is not installed; the entry does nothing.",
|
|
60
|
+
hint: "Remove the id from ModsToLoadEarly/ModsToLoadLate, or install the mod.",
|
|
61
|
+
seenIn: [`${SCORE}`, PENDING],
|
|
62
|
+
extract: ["file", "list", "ids"],
|
|
63
|
+
}),
|
|
64
|
+
smapi("mods-loaded", {
|
|
65
|
+
severity: "info",
|
|
66
|
+
category: "success",
|
|
67
|
+
pattern: re(String.raw `Loaded (?<count>\d+) mods[:.]$`),
|
|
68
|
+
explain: "The count of C# mods that loaded; the lines that follow list them alphabetically by display name, which is not the load order.",
|
|
69
|
+
seenIn: [`${PARSER} ModListStartPattern`, PENDING],
|
|
70
|
+
extract: ["count"],
|
|
71
|
+
}),
|
|
72
|
+
smapi("mod-entry", {
|
|
73
|
+
severity: "info",
|
|
74
|
+
category: "load",
|
|
75
|
+
pattern: re(String.raw ` (?<name>.+?) (?<version>[^\s]+)(?: by (?<author>[^|]+))?(?: \| (?<description>.+))?$`),
|
|
76
|
+
explain: "One loaded mod, by display name (not UniqueID), with its version and author.",
|
|
77
|
+
seenIn: [`${PARSER} ModListEntryPattern`, PENDING],
|
|
78
|
+
extract: ["name", "version", "author"],
|
|
79
|
+
}),
|
|
80
|
+
smapi("content-packs-loaded", {
|
|
81
|
+
severity: "info",
|
|
82
|
+
category: "success",
|
|
83
|
+
pattern: re(String.raw `Loaded (?<count>\d+) content packs:$`),
|
|
84
|
+
explain: "The count of content packs that loaded.",
|
|
85
|
+
seenIn: [`${PARSER} ContentPackListStartPattern`, PENDING],
|
|
86
|
+
extract: ["count"],
|
|
87
|
+
}),
|
|
88
|
+
smapi("content-pack-entry", {
|
|
89
|
+
severity: "info",
|
|
90
|
+
category: "load",
|
|
91
|
+
pattern: re(String.raw ` (?<name>.+?) (?<version>[^\s]+)(?: by (?<author>[^|]+))? \| for (?<for>[^|]*)(?: \| (?<description>.+))?$`),
|
|
92
|
+
explain: "One loaded content pack, by display name, with the mod it is for.",
|
|
93
|
+
seenIn: [`${PARSER} ContentPackListEntryPattern`, PENDING],
|
|
94
|
+
extract: ["name", "version", "for"],
|
|
95
|
+
}),
|
|
96
|
+
smapi("skipped-mods-header", {
|
|
97
|
+
severity: "error",
|
|
98
|
+
category: "order",
|
|
99
|
+
pattern: re(String.raw ` Skipped mods$`),
|
|
100
|
+
explain: "At least one mod could not be added to the game; the lines below name each with SMAPI's reason.",
|
|
101
|
+
seenIn: [`${PARSER} SkippedModListStartPattern`, PENDING],
|
|
102
|
+
}),
|
|
103
|
+
smapi("skipped-mod", {
|
|
104
|
+
severity: "error",
|
|
105
|
+
category: "order",
|
|
106
|
+
pattern: re(String.raw ` - (?<name>.+?) ?(?<version>[^\s]*) because (?<reason>.+)$`),
|
|
107
|
+
explain: "One skipped mod and SMAPI's reason, phrased as the tail of 'failed loading <mod> because ...'.",
|
|
108
|
+
seenIn: [`${LOGMANAGER} LogModWarnings`, PENDING],
|
|
109
|
+
extract: ["name", "version", "reason"],
|
|
110
|
+
}),
|
|
111
|
+
smapi("missing-dependencies", {
|
|
112
|
+
severity: "error",
|
|
113
|
+
category: "order",
|
|
114
|
+
pattern: re(String.raw ` - (?<name>.+?) (?<version>[^\s]+) because it requires mods which aren't installed \((?<mods>[^)]*)\)`),
|
|
115
|
+
explain: "The mod declares a required dependency that is not installed; the root cause of a dependency cascade.",
|
|
116
|
+
hint: "Install the named mod(s); the mod's manifest lists them under Dependencies.",
|
|
117
|
+
seenIn: [`${RESOLVER}`, PENDING],
|
|
118
|
+
extract: ["name", "mods"],
|
|
119
|
+
}),
|
|
120
|
+
smapi("dependency-cascade", {
|
|
121
|
+
severity: "error",
|
|
122
|
+
category: "order",
|
|
123
|
+
pattern: re(String.raw ` - (?<name>.+?) (?<version>[^\s]+) because it needs the '(?<dep>[^']+)' mod, which couldn't be loaded`),
|
|
124
|
+
explain: "Collateral of another mod's failure: this mod's dependency was installed but did not load.",
|
|
125
|
+
hint: "Fix the named dependency first; this line clears with it.",
|
|
126
|
+
seenIn: [`${RESOLVER}`, PENDING],
|
|
127
|
+
extract: ["name", "dep"],
|
|
128
|
+
}),
|
|
129
|
+
smapi("dependency-too-old", {
|
|
130
|
+
severity: "error",
|
|
131
|
+
category: "version",
|
|
132
|
+
pattern: re(String.raw ` - (?<name>.+?) (?<version>[^\s]+) because it needs newer versions of some mods: (?<detail>.+)$`),
|
|
133
|
+
explain: "A dependency is installed but older than the MinimumVersion the mod declares.",
|
|
134
|
+
hint: "Update the named dependency.",
|
|
135
|
+
seenIn: [`${RESOLVER}`, PENDING],
|
|
136
|
+
extract: ["name", "detail"],
|
|
137
|
+
}),
|
|
138
|
+
smapi("circular-dependency", {
|
|
139
|
+
severity: "error",
|
|
140
|
+
category: "order",
|
|
141
|
+
pattern: re(String.raw ` - (?<name>.+?) (?<version>[^\s]+) because its dependencies have a circular reference: (?<chain>.+)$`),
|
|
142
|
+
explain: "Two or more mods require each other; SMAPI cannot order them and loads none of the cycle.",
|
|
143
|
+
seenIn: [`${RESOLVER}`, PENDING],
|
|
144
|
+
extract: ["name", "chain"],
|
|
145
|
+
}),
|
|
146
|
+
smapi("needs-newer-smapi", {
|
|
147
|
+
severity: "error",
|
|
148
|
+
category: "version",
|
|
149
|
+
pattern: re(String.raw ` - (?<name>.+?) (?<version>[^\s]+) because it needs SMAPI (?<needed>\S+) or later`),
|
|
150
|
+
explain: "The mod's MinimumApiVersion is above the running SMAPI.",
|
|
151
|
+
hint: "Update SMAPI.",
|
|
152
|
+
seenIn: [`${RESOLVER}`, PENDING],
|
|
153
|
+
extract: ["name", "needed"],
|
|
154
|
+
}),
|
|
155
|
+
smapi("needs-newer-game", {
|
|
156
|
+
severity: "error",
|
|
157
|
+
category: "version",
|
|
158
|
+
pattern: re(String.raw ` - (?<name>.+?) (?<version>[^\s]+) because it needs Stardew Valley (?<needed>\S+) or later`),
|
|
159
|
+
explain: "The mod's MinimumGameVersion is above the installed game.",
|
|
160
|
+
hint: "Update the game.",
|
|
161
|
+
seenIn: [`${RESOLVER}`, PENDING],
|
|
162
|
+
extract: ["name", "needed"],
|
|
163
|
+
}),
|
|
164
|
+
smapi("missing-entry-dll", {
|
|
165
|
+
severity: "error",
|
|
166
|
+
category: "load",
|
|
167
|
+
pattern: re(String.raw ` - (?<name>.+?) (?<version>[^\s]+) because its DLL '(?<dll>[^']+)' doesn't exist`),
|
|
168
|
+
explain: "The manifest's EntryDll names a file that is not in the mod folder.",
|
|
169
|
+
hint: "The build did not copy the DLL, or the manifest's EntryDll is misspelt.",
|
|
170
|
+
seenIn: [`${RESOLVER}`, PENDING],
|
|
171
|
+
extract: ["name", "dll"],
|
|
172
|
+
}),
|
|
173
|
+
smapi("duplicate-mod", {
|
|
174
|
+
severity: "error",
|
|
175
|
+
category: "order",
|
|
176
|
+
pattern: re(String.raw ` - (?<name>.+?) because you have multiple copies of this mod installed`),
|
|
177
|
+
explain: "Two folders carry the same UniqueID; SMAPI loads neither.",
|
|
178
|
+
hint: "Delete the duplicate folders and reinstall the mod once.",
|
|
179
|
+
seenIn: [`${RESOLVER}`, PENDING],
|
|
180
|
+
extract: ["name"],
|
|
181
|
+
}),
|
|
182
|
+
smapi("known-broken", {
|
|
183
|
+
severity: "error",
|
|
184
|
+
category: "version",
|
|
185
|
+
pattern: re(String.raw ` - (?<name>.+?) (?<version>[^\s]+) because .*\. Please check for a (?:newer version|version newer than \S+) at `),
|
|
186
|
+
explain: "SMAPI's internal mod database (smapi-internal/metadata.json) marks this version as broken.",
|
|
187
|
+
hint: "Update the mod from the linked page.",
|
|
188
|
+
seenIn: [`${RESOLVER}`, PENDING],
|
|
189
|
+
extract: ["name"],
|
|
190
|
+
}),
|
|
191
|
+
smapi("obsolete-mod", {
|
|
192
|
+
severity: "error",
|
|
193
|
+
category: "version",
|
|
194
|
+
pattern: re(String.raw ` - (?<name>.+?) (?<version>[^\s]+) because it's obsolete: (?<why>.+)$`),
|
|
195
|
+
explain: "SMAPI's internal mod database marks this mod obsolete.",
|
|
196
|
+
seenIn: [`${RESOLVER}`, PENDING],
|
|
197
|
+
extract: ["name", "why"],
|
|
198
|
+
}),
|
|
199
|
+
smapi("broken-mods-warning", {
|
|
200
|
+
severity: "error",
|
|
201
|
+
category: "load",
|
|
202
|
+
pattern: re(String.raw ` Broken mods$`),
|
|
203
|
+
explain: "SMAPI's 'Broken mods' warning group follows: mods that loaded but reference game code that no longer exists.",
|
|
204
|
+
seenIn: [`${LOGMANAGER} LogModWarningGroup`, PENDING],
|
|
205
|
+
}),
|
|
206
|
+
smapi("patches-game", {
|
|
207
|
+
severity: "info",
|
|
208
|
+
category: "script",
|
|
209
|
+
pattern: re(String.raw ` Patched game code$`),
|
|
210
|
+
explain: "The mods listed below patch game code with Harmony; SMAPI notes it, it is not an error.",
|
|
211
|
+
seenIn: [`${LOGMANAGER} LogModWarningGroup`, PENDING],
|
|
212
|
+
}),
|
|
213
|
+
smapi("patches-game-unfixed-harmony", {
|
|
214
|
+
severity: "warn",
|
|
215
|
+
category: "script",
|
|
216
|
+
pattern: re(String.raw ` Patched game code without Harmony fix$`),
|
|
217
|
+
explain: "The mods listed below patch game code through a Harmony SMAPI did not rewrite, which its own documentation calls a stability risk.",
|
|
218
|
+
seenIn: [`${LOGMANAGER} LogModWarningGroup`, PENDING],
|
|
219
|
+
}),
|
|
220
|
+
smapi("changes-save-serializer", {
|
|
221
|
+
severity: "warn",
|
|
222
|
+
category: "script",
|
|
223
|
+
pattern: re(String.raw ` Changed save serializer$`),
|
|
224
|
+
explain: "The mods listed below change how saves are serialized; a save written with them may not load without them.",
|
|
225
|
+
seenIn: [`${LOGMANAGER} LogModWarningGroup`, PENDING],
|
|
226
|
+
}),
|
|
227
|
+
smapi("malicious-mod", {
|
|
228
|
+
severity: "error",
|
|
229
|
+
category: "crash",
|
|
230
|
+
pattern: re(String.raw `Malicious mod detected\.$`),
|
|
231
|
+
explain: "SMAPI's blacklist matched an installed mod (logged at CRITICAL, whose level column overflows the usual width).",
|
|
232
|
+
hint: "Remove the mod SMAPI names; see https://smapi.io.",
|
|
233
|
+
seenIn: [`${LOGMANAGER} LogFatal`, PENDING],
|
|
234
|
+
}),
|
|
235
|
+
smapi("crashed-last-time", {
|
|
236
|
+
severity: "error",
|
|
237
|
+
category: "crash",
|
|
238
|
+
pattern: re(String.raw `The game crashed last time you played\.`),
|
|
239
|
+
explain: "SMAPI found its crash marker from the previous run; the previous SMAPI-crash.txt holds the details.",
|
|
240
|
+
seenIn: [`${LOGMANAGER} HandleMarkerFiles`, PENDING],
|
|
241
|
+
}),
|
|
242
|
+
smapi("failed-to-launch", {
|
|
243
|
+
severity: "error",
|
|
244
|
+
category: "crash",
|
|
245
|
+
pattern: re(String.raw `The game failed to launch: (?<summary>.+)$`),
|
|
246
|
+
explain: "The game threw during startup; the summary and the continuation lines carry the exception.",
|
|
247
|
+
seenIn: [`${SCORE}`, PENDING],
|
|
248
|
+
extract: ["summary"],
|
|
249
|
+
}),
|
|
250
|
+
smapi("init-failed", {
|
|
251
|
+
severity: "error",
|
|
252
|
+
category: "crash",
|
|
253
|
+
pattern: re(String.raw `SMAPI failed to initialize: (?<summary>.+)$`),
|
|
254
|
+
explain: "SMAPI itself failed before loading mods.",
|
|
255
|
+
seenIn: [`${SCORE}`, PENDING],
|
|
256
|
+
extract: ["summary"],
|
|
257
|
+
}),
|
|
258
|
+
smapi("update-available", {
|
|
259
|
+
severity: "info",
|
|
260
|
+
category: "version",
|
|
261
|
+
pattern: re(String.raw `You can update SMAPI to (?<version>\S+): (?<link>.+)$`),
|
|
262
|
+
explain: "A newer SMAPI exists.",
|
|
263
|
+
seenIn: [`${PARSER} SmapiUpdatePattern`, PENDING],
|
|
264
|
+
extract: ["version", "link"],
|
|
265
|
+
}),
|
|
266
|
+
smapi("mod-updates-available", {
|
|
267
|
+
severity: "info",
|
|
268
|
+
category: "version",
|
|
269
|
+
pattern: re(String.raw `You can update (?<count>\d+) mods?:$`),
|
|
270
|
+
explain: "Newer versions exist for the mods listed below.",
|
|
271
|
+
seenIn: [`${PARSER} ModUpdateListStartPattern`, PENDING],
|
|
272
|
+
extract: ["count"],
|
|
273
|
+
}),
|
|
274
|
+
smapi("ready", {
|
|
275
|
+
severity: "info",
|
|
276
|
+
category: "success",
|
|
277
|
+
pattern: re(String.raw `Mods loaded and ready!$`),
|
|
278
|
+
explain: "Every mod that was going to load has loaded; what follows is the game.",
|
|
279
|
+
seenIn: [`${SCORE}`, PENDING],
|
|
280
|
+
}),
|
|
281
|
+
cp("pack-rejected", {
|
|
282
|
+
severity: "error",
|
|
283
|
+
category: "resource",
|
|
284
|
+
pattern: re(String.raw `Could not load content pack '(?<pack>[^']+)': (?<reason>.+)\.$`),
|
|
285
|
+
explain: "Content Patcher refused a whole pack: no content.json, no Format field, or neither Changes nor CustomLocations.",
|
|
286
|
+
hint: "Fix the pack's content.json; the reason is Content Patcher's own sentence.",
|
|
287
|
+
seenIn: [`${CP}`, PENDING],
|
|
288
|
+
extract: ["pack", "reason"],
|
|
289
|
+
}),
|
|
290
|
+
cp("patch-ignored", {
|
|
291
|
+
severity: "warn",
|
|
292
|
+
category: "resource",
|
|
293
|
+
pattern: re(String.raw `Ignored (?<pack>.+?) > (?<label>.+?): (?<reason>.+)$`),
|
|
294
|
+
explain: "Content Patcher skipped one patch (`Ignored <pack> > <patch>: <reason>`, PatchLoader's TrackSkip sentence: a missing Action or Target, a FromFile with Entries, an invalid When) or rejected a config.json value against the pack's ConfigSchema (ConfigFileHandler's `Ignored <pack> > <field>: <reason>`); the two share a shape and the reason tells them apart.",
|
|
295
|
+
hint: "Fix the named field in content.json (or config.json); the pack still loads, the one patch or value is dropped.",
|
|
296
|
+
seenIn: [`${CP}`, PENDING],
|
|
297
|
+
extract: ["pack", "label", "reason"],
|
|
298
|
+
}),
|
|
299
|
+
cp("error-preloading", {
|
|
300
|
+
severity: "error",
|
|
301
|
+
category: "resource",
|
|
302
|
+
pattern: re(String.raw `Error (?:preloading|loading configuration for) content pack '(?<pack>[^']+)'\.`),
|
|
303
|
+
explain: "Content Patcher threw while reading a pack; the continuation lines carry the exception.",
|
|
304
|
+
seenIn: [`${CP}`, PENDING],
|
|
305
|
+
extract: ["pack"],
|
|
306
|
+
}),
|
|
307
|
+
];
|