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,264 @@
|
|
|
1
|
+
# new-item (BG3, armor/weapon). Writes the stat -> RootTemplate -> VisualBank
|
|
2
|
+
# triangle: a stats entry that `using`s a
|
|
3
|
+
# vanilla parent, a RootTemplate GameObjects node with a fresh MapKey, a
|
|
4
|
+
# TreasureTable row, and DisplayName/Description loca rows.
|
|
5
|
+
#
|
|
6
|
+
# Design note: this
|
|
7
|
+
# scaffold REUSES an existing (project or vanilla) VisualBank Resource id
|
|
8
|
+
# directly — RootTemplate's VisualTemplate points straight at the id the
|
|
9
|
+
# author names — rather than writing a *new* VisualBank/MaterialBank/
|
|
10
|
+
# TextureBank Resource chain of its own. Two reasons: the vanilla index's `guid` query
|
|
11
|
+
# answers only a Resource node's own top-level attributes (`ID`, `Name`),
|
|
12
|
+
# never its `Objects`/`Texture2DParameters` children (those node ids are not
|
|
13
|
+
# in `INDEXED_NODE_IDS` — see build.ts), so a chosen visual's own MaterialID
|
|
14
|
+
# cannot be read back through the index to build a faithful copy; and LSX has
|
|
15
|
+
# no "insert a child node into an existing region's children" emit op in this
|
|
16
|
+
# engine (only line-oriented text, loca and CR2W-json have dedicated insert
|
|
17
|
+
# ops). Recoloring — writing a mod-owned bank chain and repointing
|
|
18
|
+
# VisualTemplate at it — is the manual, optional creative step ("recolor art, optional").
|
|
19
|
+
#
|
|
20
|
+
# Observed in game: a loose `.lsx` under `Public/<Mod>/RootTemplates` is never
|
|
21
|
+
# loaded by the game — `Ext.Template.GetTemplate` and `Osi.CreateAt` both
|
|
22
|
+
# returned nothing for it live, while the identical node converted to a
|
|
23
|
+
# `.lsf` of its own name (beside `_merged.lsf`, not merged into it) loaded,
|
|
24
|
+
# resolved and spawned (knowledge fact
|
|
25
|
+
# bg3.items.roottemplates.loose-lsx-in-roottemplates-is-not-loaded-a-separate-lsf-is).
|
|
26
|
+
# The one-RootTemplate-per-file choice above still stands — only the file
|
|
27
|
+
# *type* this scaffold shipped was wrong. Fixed by the `patch-project` emit
|
|
28
|
+
# below, which ensures a `divine-lsx-to-lsf` build step exists (idempotent —
|
|
29
|
+
# reapplying this scaffold never adds a second one) covering
|
|
30
|
+
# `Public/**/RootTemplates/*.lsx`, with `deleteSource: true` and positioned
|
|
31
|
+
# before `divine-create-package` (`engine.ts`'s `before:` convention) so the
|
|
32
|
+
# item's own written `.lsx` reaches the pak as a `.lsf` and the stale `.lsx`
|
|
33
|
+
# does not reach it at all. The narrow glob matters: only `RootTemplates` is
|
|
34
|
+
# affected, and the rest of `Public/<Mod>` (Lists, Progressions,
|
|
35
|
+
# ClassDescriptions, GUI atlases) keeps shipping as the `.lsx` the game
|
|
36
|
+
# reads.
|
|
37
|
+
id: baldursgate3.new-item
|
|
38
|
+
game: baldursgate3
|
|
39
|
+
title: New BG3 item (armor/weapon with a visual bank)
|
|
40
|
+
summary: Append an Armor/Weapon stats entry with a vanilla `using` parent, a RootTemplate reusing an existing VisualBank visual, a TreasureTable row, and loca rows.
|
|
41
|
+
modTypes: [armor, weapon, accessory]
|
|
42
|
+
needs: { index: true }
|
|
43
|
+
inputs:
|
|
44
|
+
- type: string
|
|
45
|
+
name: itemName
|
|
46
|
+
prompt: "Full stats entry name, e.g. HWV_TestBreastplate."
|
|
47
|
+
pattern: "^[A-Za-z][A-Za-z0-9_]*$"
|
|
48
|
+
- type: enum
|
|
49
|
+
name: entryKind
|
|
50
|
+
prompt: "Stats file this entry belongs in (also its `type`)."
|
|
51
|
+
values: [Armor, Weapon]
|
|
52
|
+
- type: string
|
|
53
|
+
name: slot
|
|
54
|
+
prompt: "data \"Slot\" value, e.g. Breast, Shield, Melee Main Weapon."
|
|
55
|
+
- type: index-ref
|
|
56
|
+
name: parentStat
|
|
57
|
+
prompt: "Vanilla (or project) Armor/Weapon entry to `using`."
|
|
58
|
+
lookup: { kind: stat, params: { name: "${input.parentStat}" } }
|
|
59
|
+
requires:
|
|
60
|
+
- path: type
|
|
61
|
+
matches: "^(Armor|Weapon)$"
|
|
62
|
+
reason: "the parent must be an Armor or Weapon entry, or `using` inherits fields from the wrong stat family."
|
|
63
|
+
# Observed in game (2026-09-11): a GameObjects node carrying
|
|
64
|
+
# only MapKey/Name/VisualTemplate reached the pak as an .lsf and the
|
|
65
|
+
# engine still did not load it (`Ext.Template.GetTemplate` nil,
|
|
66
|
+
# `bg3.template.exists` fail), while every template the engine has been
|
|
67
|
+
# seen to load — the vanilla dagger, the 2026-09-10 chest repro, the
|
|
68
|
+
# summoned-weapon recipe — carries Type, Stats and a ParentTemplateId.
|
|
69
|
+
# The parent stat's own RootTemplate becomes this template's
|
|
70
|
+
# ParentTemplateId, so the item inherits physics, equipment type and
|
|
71
|
+
# icon handling from the vanilla template its stats already `using`.
|
|
72
|
+
- path: fields.RootTemplate
|
|
73
|
+
matches: "^[0-9a-fA-F-]{36}$"
|
|
74
|
+
reason: "the parent must carry its own RootTemplate (a UUID) — it becomes the new template's ParentTemplateId, which the engine needs to load the node at all."
|
|
75
|
+
expose: parentRootTemplate
|
|
76
|
+
- type: index-ref
|
|
77
|
+
name: visualBankId
|
|
78
|
+
prompt: "Existing (project or vanilla) VisualBank Resource ID this item's RootTemplate should reuse."
|
|
79
|
+
lookup: { kind: guid, params: { uuid: "${input.visualBankId}" } }
|
|
80
|
+
requires:
|
|
81
|
+
- path: kind
|
|
82
|
+
matches: "^Resource$"
|
|
83
|
+
reason: "the given UUID must resolve to a Resource node, or the RootTemplate's VisualTemplate would point at a non-visual LSX node."
|
|
84
|
+
- path: region
|
|
85
|
+
matches: "^VisualBank$"
|
|
86
|
+
reason: "the given UUID must be a VisualBank Resource (region VisualBank), not a MaterialBank/TextureBank one, or the RootTemplate's VisualTemplate would point at the wrong bank kind."
|
|
87
|
+
- type: string
|
|
88
|
+
name: displayName
|
|
89
|
+
prompt: "Player-facing item name."
|
|
90
|
+
- type: string
|
|
91
|
+
name: description
|
|
92
|
+
prompt: "Tooltip description text."
|
|
93
|
+
ids:
|
|
94
|
+
- name: rootTemplateUuid
|
|
95
|
+
slot: "roottemplate:${input.itemName}"
|
|
96
|
+
form: uuid
|
|
97
|
+
collision:
|
|
98
|
+
project: true
|
|
99
|
+
index: { kind: guid, param: uuid }
|
|
100
|
+
- name: display
|
|
101
|
+
slot: "display:${input.itemName}"
|
|
102
|
+
form: bg3-handle
|
|
103
|
+
- name: description
|
|
104
|
+
slot: "description:${input.itemName}"
|
|
105
|
+
form: bg3-handle
|
|
106
|
+
# The same two handles without the `;1` suffix, for the RootTemplate's
|
|
107
|
+
# TranslatedString attributes (same slot => same digest => same loca row).
|
|
108
|
+
- name: displayHandle
|
|
109
|
+
slot: "display:${input.itemName}"
|
|
110
|
+
form: bg3-handle-bare
|
|
111
|
+
- name: descriptionHandle
|
|
112
|
+
slot: "description:${input.itemName}"
|
|
113
|
+
form: bg3-handle-bare
|
|
114
|
+
emits:
|
|
115
|
+
- op: ensure-dir
|
|
116
|
+
path: "Public/${project.identity.folder}/Stats/Generated/Data"
|
|
117
|
+
- op: ensure-dir
|
|
118
|
+
path: "Public/${project.identity.folder}/RootTemplates"
|
|
119
|
+
- op: insert-block
|
|
120
|
+
path: "Public/${project.identity.folder}/Stats/Generated/Data/${input.entryKind}.txt"
|
|
121
|
+
createIfMissing: "// ModWright-scaffolded ${input.entryKind} file.\n"
|
|
122
|
+
anchor: append
|
|
123
|
+
body: |
|
|
124
|
+
// ${project.today} - ModWright scaffold: ${input.itemName}, using parent ${input.parentStat}.
|
|
125
|
+
new entry "${input.itemName}"
|
|
126
|
+
type "${input.entryKind}"
|
|
127
|
+
using "${input.parentStat}"
|
|
128
|
+
data "RootTemplate" "${ids.rootTemplateUuid}"
|
|
129
|
+
data "Slot" "${input.slot}"
|
|
130
|
+
# One RootTemplate per file (not a shared _merged.lsx) sidesteps the
|
|
131
|
+
# missing "insert into an existing LSX region" op — see this file's header.
|
|
132
|
+
- op: write-text
|
|
133
|
+
path: "Public/${project.identity.folder}/RootTemplates/${input.itemName}.lsx"
|
|
134
|
+
body: |
|
|
135
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
136
|
+
<save>
|
|
137
|
+
<version major="4" minor="8" revision="0" build="10"/>
|
|
138
|
+
<region id="Templates">
|
|
139
|
+
<node id="Templates">
|
|
140
|
+
<children>
|
|
141
|
+
<node id="GameObjects">
|
|
142
|
+
<attribute id="MapKey" type="FixedString" value="${ids.rootTemplateUuid}"/>
|
|
143
|
+
<attribute id="Name" type="LSString" value="${input.itemName}"/>
|
|
144
|
+
<attribute id="Type" type="FixedString" value="item"/>
|
|
145
|
+
<attribute id="ParentTemplateId" type="FixedString" value="${template.parentRootTemplate}"/>
|
|
146
|
+
<attribute id="Stats" type="FixedString" value="${input.itemName}"/>
|
|
147
|
+
<attribute id="VisualTemplate" type="FixedString" value="${input.visualBankId}"/>
|
|
148
|
+
<attribute id="Icon" type="FixedString" value="${input.itemName}_Icon"/>
|
|
149
|
+
<attribute id="DisplayName" type="TranslatedString" handle="${ids.displayHandle}" version="1"/>
|
|
150
|
+
<attribute id="Description" type="TranslatedString" handle="${ids.descriptionHandle}" version="1"/>
|
|
151
|
+
</node>
|
|
152
|
+
</children>
|
|
153
|
+
</node>
|
|
154
|
+
</region>
|
|
155
|
+
</save>
|
|
156
|
+
# Ensures the pak's build actually converts RootTemplates .lsx -> .lsf
|
|
157
|
+
# (this file's header note above); idempotent (`engine.ts`'s
|
|
158
|
+
# `mergeBuildSteps`), so scaffolding a second item never adds a second
|
|
159
|
+
# copy of this step, and `before` lands it ahead of
|
|
160
|
+
# `divine-create-package` (or a bare-string shorthand that expands to it,
|
|
161
|
+
# e.g. "pack-pak") whichever form the project's build
|
|
162
|
+
# already uses.
|
|
163
|
+
#
|
|
164
|
+
# `in: "${stage}"` is the *whole* stage root, not one stage id's own
|
|
165
|
+
# subtree (core/build/paths.ts's own header comment: `in` on this step
|
|
166
|
+
# normally names a bare stage id, resolved as `${stage}/<id>`; the bare
|
|
167
|
+
# `${stage}` token alone resolves to the stage root with no id segment at
|
|
168
|
+
# all) — deliberate, because a `patch-project` addition is static YAML and
|
|
169
|
+
# cannot know which id the project's own `stage` step happens to use
|
|
170
|
+
# (a real project may use "pack"; the schemaVersion-1 shorthand
|
|
171
|
+
# uses "stage"). `walk()` (core/fsutil.ts) recurses the whole tree either
|
|
172
|
+
# way, so the glob below is written `**/Public/**/...` — tolerant of
|
|
173
|
+
# whatever stage-id segment precedes `Public/` in the staged copy — rather
|
|
174
|
+
# than anchored to `Public/` the way a per-id `in` value could afford to
|
|
175
|
+
# be.
|
|
176
|
+
#
|
|
177
|
+
# `deleteSource: true` is set here and nowhere else. The step's own default
|
|
178
|
+
# is false (it converts in place, as it always has), because its default
|
|
179
|
+
# glob is the whole-stage `**/*.lsx` and every other `Public/<Mod>` folder's
|
|
180
|
+
# `.lsx` — Lists, Progressions, ClassDescriptions, GUI atlases — is read by
|
|
181
|
+
# the game as `.lsx`. This step's glob is narrowed to `RootTemplates`, the
|
|
182
|
+
# one folder where the loose `.lsx` is dead weight, so removing the staged
|
|
183
|
+
# copy matches exactly the configuration verified in game (convert,
|
|
184
|
+
# remove the `.lsx`, rebuild) and keeps the stale copy out of the pak.
|
|
185
|
+
- op: patch-project
|
|
186
|
+
add:
|
|
187
|
+
steps:
|
|
188
|
+
- step: divine-lsx-to-lsf
|
|
189
|
+
id: roottemplates-lsx-to-lsf
|
|
190
|
+
in: "${stage}"
|
|
191
|
+
glob: "**/Public/**/RootTemplates/*.lsx"
|
|
192
|
+
deleteSource: true
|
|
193
|
+
before: divine-create-package
|
|
194
|
+
- op: insert-block
|
|
195
|
+
path: "Public/${project.identity.folder}/Stats/Generated/TreasureTable.txt"
|
|
196
|
+
createIfMissing: "// ModWright TreasureTable, ModWright-scaffolded.\n"
|
|
197
|
+
anchor: append
|
|
198
|
+
body: |
|
|
199
|
+
new treasuretable "${project.identity.folder}_Treasure"
|
|
200
|
+
CanMerge 1
|
|
201
|
+
object category "I_${input.itemName}",1,0,0,0,0,0,0,0
|
|
202
|
+
- op: insert-loca-row
|
|
203
|
+
path: "Mods/${project.identity.folder}/Localization/English/${project.identity.folder}.xml"
|
|
204
|
+
handle: "${ids.display}"
|
|
205
|
+
text: "${input.displayName}"
|
|
206
|
+
- op: insert-loca-row
|
|
207
|
+
path: "Mods/${project.identity.folder}/Localization/English/${project.identity.folder}.xml"
|
|
208
|
+
handle: "${ids.description}"
|
|
209
|
+
text: "${input.description}"
|
|
210
|
+
templates: []
|
|
211
|
+
satisfies:
|
|
212
|
+
- bg3.items.stats-roottemplate-link
|
|
213
|
+
- bg3.items.roottemplate-visual-link
|
|
214
|
+
- bg3.items.visual-material-texture-chain
|
|
215
|
+
- bg3.items.parenttemplateid-type-match
|
|
216
|
+
- bg3.items.armor-weapon-fields
|
|
217
|
+
- bg3.items.treasuretable-i-prefix
|
|
218
|
+
- bg3.items.icon-mapkey-resolves
|
|
219
|
+
- bg3.items.dds-extension-case
|
|
220
|
+
- bg3.items.texturebank-srgb
|
|
221
|
+
- bg3.items.roottemplate-guid-attribute-type
|
|
222
|
+
- bg3.history.handle-form-per-field
|
|
223
|
+
- bg3.history.handle-defined-in-loca
|
|
224
|
+
manual:
|
|
225
|
+
- title: Icon, visual and (for a Weapon) proficiency fields
|
|
226
|
+
steps:
|
|
227
|
+
- "Draw the ${input.itemName}_Icon art and register it in the item atlas (bg3.items.icon-mapkey-resolves warns until then)."
|
|
228
|
+
- "For a Weapon entry (this one is ${input.entryKind}), also add data \"Proficiency Group\" and data \"Weapon Properties\" to the new entry (bg3.items.armor-weapon-fields warns without them; there is no new base weapon type, so fake one by combining an existing group with Weapon Properties)."
|
|
229
|
+
- "To give ${input.itemName} its own recolor instead of reusing VisualBank ${input.visualBankId}'s appearance, add a mod-owned VisualBank/MaterialBank/TextureBank Resource chain under Content/Assets/Characters and repoint this RootTemplate's VisualTemplate at your new VisualBank ID."
|
|
230
|
+
expected: "The item spawns with a real icon, its own visual (recolored or reused), and (if a Weapon) a valid proficiency/properties pair."
|
|
231
|
+
claim:
|
|
232
|
+
idSuffix: spawns-with-stats
|
|
233
|
+
claim: "${input.itemName} (using parent ${input.parentStat}) spawns with stats from its RootTemplate, a visible visual reused from VisualBank ${input.visualBankId}, and a treasure-table entry."
|
|
234
|
+
testRows:
|
|
235
|
+
- gate: S-1
|
|
236
|
+
title: "Stat entry loads with expected fields"
|
|
237
|
+
expected: "bg3.stat.exists finds ${input.itemName}; bg3.stat.fields confirms RootTemplate/Slot match this scaffold's output (an Armor/Weapon stats object has no DisplayName/Description attribute — observed in game 2026-09-11; those live on the RootTemplate)."
|
|
238
|
+
manual: false
|
|
239
|
+
probes:
|
|
240
|
+
- kind: bg3.stat.exists
|
|
241
|
+
params: { name: "${input.itemName}" }
|
|
242
|
+
- kind: bg3.stat.fields
|
|
243
|
+
params: { name: "${input.itemName}", fields: [RootTemplate, Slot] }
|
|
244
|
+
# A separate row, not a third probe on S-1. The kind is attested (its own
|
|
245
|
+
# bridge run, 2026-09-10), so the row is automated, but
|
|
246
|
+
# it stays its own row because bg3.stat.exists alone cannot tell a real
|
|
247
|
+
# RootTemplate from a loose, engine-ignored `.lsx` (this file's header
|
|
248
|
+
# note) and a template verdict should not drag the stats verdict down with
|
|
249
|
+
# it — exactly what was observed in game (2026-09-11): this row failed
|
|
250
|
+
# (`present: false`) while bg3.stat.exists passed on the same item.
|
|
251
|
+
- gate: S-1.1
|
|
252
|
+
title: "RootTemplate resolves in the engine"
|
|
253
|
+
expected: "bg3.template.exists confirms Ext.Template.GetTemplate(\"${ids.rootTemplateUuid}\") returns the template (present: true, name ${input.itemName}), not nil — a bg3.stat.exists pass alone does not prove the template this scaffold wrote actually reached the engine (it does not, unless the divine-lsx-to-lsf step this scaffold adds converts it)."
|
|
254
|
+
manual: false
|
|
255
|
+
probes:
|
|
256
|
+
- kind: bg3.template.exists
|
|
257
|
+
params:
|
|
258
|
+
mapKey: "${ids.rootTemplateUuid}"
|
|
259
|
+
- gate: S-2
|
|
260
|
+
title: "Visual renders, not the default fallback"
|
|
261
|
+
expected: "A human confirms TemplateAddTo/spawn shows the reused VisualBank ${input.visualBankId} visual, not the invisible/default fallback, and the icon/tooltip render."
|
|
262
|
+
manual: true
|
|
263
|
+
probeKinds: []
|
|
264
|
+
evidence: ["ModWright research"]
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# new-mod (BG3). Writes the
|
|
2
|
+
# standard skeleton: meta.lsx, ScriptExtender/Config.json,
|
|
3
|
+
# Localization/English/<Mod>.xml, and the Public/<Mod> subtree every stats/
|
|
4
|
+
# progression/item scaffold expects to already exist. Version64 is derived
|
|
5
|
+
# from the project's own declared version (project.version64, computed by
|
|
6
|
+
# the engine — see engine.ts's computeVersion64), not re-specified here, so
|
|
7
|
+
# meta.lsx and modwright.json never disagree on major/minor/revision.
|
|
8
|
+
id: baldursgate3.new-mod
|
|
9
|
+
game: baldursgate3
|
|
10
|
+
title: New BG3 mod (meta.lsx, Config.json, Localization)
|
|
11
|
+
summary: Write meta.lsx, ScriptExtender/Config.json and an empty Localization/English/<Mod>.xml, plus the Public/<Mod> subtree, and declare the BG3 Script Extender dependency.
|
|
12
|
+
modTypes: [packaging]
|
|
13
|
+
needs: {}
|
|
14
|
+
inputs:
|
|
15
|
+
- type: string
|
|
16
|
+
name: folder
|
|
17
|
+
prompt: Module folder name (Mods/<folder>, Public/<folder>).
|
|
18
|
+
pattern: "^[A-Za-z][A-Za-z0-9_]*$"
|
|
19
|
+
- type: string
|
|
20
|
+
name: displayName
|
|
21
|
+
prompt: Display name shown in the in-game mod manager.
|
|
22
|
+
- type: string
|
|
23
|
+
name: author
|
|
24
|
+
prompt: Author name.
|
|
25
|
+
default: "Unknown"
|
|
26
|
+
- type: string
|
|
27
|
+
name: description
|
|
28
|
+
prompt: One-line mod description.
|
|
29
|
+
default: ""
|
|
30
|
+
- type: string
|
|
31
|
+
name: tags
|
|
32
|
+
prompt: Comma-separated Larian tag(s), e.g. "Class".
|
|
33
|
+
default: "Adventure"
|
|
34
|
+
ids:
|
|
35
|
+
- name: moduleUuid
|
|
36
|
+
slot: "module-uuid:${input.folder}"
|
|
37
|
+
form: uuid
|
|
38
|
+
collision:
|
|
39
|
+
project: true
|
|
40
|
+
loadOrder: true
|
|
41
|
+
index: { kind: guid, param: uuid }
|
|
42
|
+
emits:
|
|
43
|
+
- op: ensure-dir
|
|
44
|
+
path: "Mods/${input.folder}/ScriptExtender"
|
|
45
|
+
- op: ensure-dir
|
|
46
|
+
path: "Mods/${input.folder}/Localization/English"
|
|
47
|
+
- op: ensure-dir
|
|
48
|
+
path: "Public/${input.folder}/ActionResourceDefinitions"
|
|
49
|
+
- op: ensure-dir
|
|
50
|
+
path: "Public/${input.folder}/ClassDescriptions"
|
|
51
|
+
- op: ensure-dir
|
|
52
|
+
path: "Public/${input.folder}/Lists"
|
|
53
|
+
- op: ensure-dir
|
|
54
|
+
path: "Public/${input.folder}/Progressions"
|
|
55
|
+
- op: ensure-dir
|
|
56
|
+
path: "Public/${input.folder}/RootTemplates"
|
|
57
|
+
- op: ensure-dir
|
|
58
|
+
path: "Public/${input.folder}/Stats/Generated/Data"
|
|
59
|
+
- op: ensure-dir
|
|
60
|
+
path: "Public/${input.folder}/Tags"
|
|
61
|
+
- op: ensure-dir
|
|
62
|
+
path: "Public/${input.folder}/GUI"
|
|
63
|
+
# meta.lsx: BOM (bg3.history.no-bom exempts it by name — Larian's own
|
|
64
|
+
# Toolkit writes one), Version64 from the project's own declared version.
|
|
65
|
+
- op: write-text
|
|
66
|
+
path: "Mods/${input.folder}/meta.lsx"
|
|
67
|
+
bom: true
|
|
68
|
+
body: |
|
|
69
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
70
|
+
<save>
|
|
71
|
+
<version major="4" minor="8" revision="0" build="500" />
|
|
72
|
+
<region id="Config">
|
|
73
|
+
<node id="root">
|
|
74
|
+
<children>
|
|
75
|
+
<node id="Conflicts" />
|
|
76
|
+
<node id="Dependencies" />
|
|
77
|
+
<node id="ModuleInfo">
|
|
78
|
+
<attribute id="Author" type="LSString" value="${input.author}" />
|
|
79
|
+
<attribute id="CharacterCreationLevelName" type="FixedString" value="" />
|
|
80
|
+
<attribute id="Description" type="LSString" value="${input.description}" />
|
|
81
|
+
<attribute id="FileSize" type="uint64" value="0" />
|
|
82
|
+
<attribute id="Folder" type="LSString" value="${input.folder}" />
|
|
83
|
+
<attribute id="LobbyLevelName" type="FixedString" value="" />
|
|
84
|
+
<attribute id="MD5" type="LSString" value="" />
|
|
85
|
+
<attribute id="MainMenuBackgroundVideo" type="FixedString" value="" />
|
|
86
|
+
<attribute id="MenuLevelName" type="FixedString" value="" />
|
|
87
|
+
<attribute id="Name" type="FixedString" value="${input.displayName}" />
|
|
88
|
+
<attribute id="NumPlayers" type="uint8" value="4" />
|
|
89
|
+
<attribute id="PhotoBooth" type="FixedString" value="" />
|
|
90
|
+
<attribute id="PublishHandle" type="uint64" value="0" />
|
|
91
|
+
<attribute id="StartupLevelName" type="FixedString" value="" />
|
|
92
|
+
<attribute id="Tags" type="LSString" value="${input.tags}" />
|
|
93
|
+
<attribute id="Type" type="FixedString" value="Add-on" />
|
|
94
|
+
<attribute id="UUID" type="FixedString" value="${ids.moduleUuid}" />
|
|
95
|
+
<attribute id="Version64" type="int64" value="${project.version64}" />
|
|
96
|
+
<children>
|
|
97
|
+
<node id="PublishVersion">
|
|
98
|
+
<attribute id="Version64" type="int64" value="${project.version64}" />
|
|
99
|
+
</node>
|
|
100
|
+
<node id="Scripts" />
|
|
101
|
+
<node id="TargetModes">
|
|
102
|
+
<children>
|
|
103
|
+
<node id="Target">
|
|
104
|
+
<attribute id="Object" type="FixedString" value="Story" />
|
|
105
|
+
</node>
|
|
106
|
+
</children>
|
|
107
|
+
</node>
|
|
108
|
+
</children>
|
|
109
|
+
</node>
|
|
110
|
+
</children>
|
|
111
|
+
</node>
|
|
112
|
+
</region>
|
|
113
|
+
</save>
|
|
114
|
+
- op: write-text
|
|
115
|
+
path: "Mods/${input.folder}/ScriptExtender/Config.json"
|
|
116
|
+
body: |
|
|
117
|
+
{
|
|
118
|
+
"RequiredVersion": 21,
|
|
119
|
+
"ModTable": "${input.folder}",
|
|
120
|
+
"FeatureFlags": ["Lua"]
|
|
121
|
+
}
|
|
122
|
+
- op: write-text
|
|
123
|
+
path: "Mods/${input.folder}/Localization/English/${input.folder}.xml"
|
|
124
|
+
body: |
|
|
125
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
126
|
+
<contentList>
|
|
127
|
+
</contentList>
|
|
128
|
+
- op: insert-xl-entry
|
|
129
|
+
path: "modwright.json"
|
|
130
|
+
pointer: identity.uuid
|
|
131
|
+
value: "${ids.moduleUuid}"
|
|
132
|
+
- op: insert-xl-entry
|
|
133
|
+
path: "modwright.json"
|
|
134
|
+
pointer: identity.folder
|
|
135
|
+
value: "${input.folder}"
|
|
136
|
+
- op: patch-project
|
|
137
|
+
add:
|
|
138
|
+
dependencies:
|
|
139
|
+
- id: bg3-script-extender
|
|
140
|
+
kind: loader
|
|
141
|
+
minVersion: "21"
|
|
142
|
+
url: "https://github.com/Norbyte/bg3se"
|
|
143
|
+
notes: "RequiredVersion 21 pinned in ScriptExtender/Config.json."
|
|
144
|
+
templates: []
|
|
145
|
+
satisfies:
|
|
146
|
+
- bg3.progression.meta-version64
|
|
147
|
+
- bg3.history.no-bom
|
|
148
|
+
- bg3.history.se-config-shape
|
|
149
|
+
- bg3.history.stale-same-uuid-pak
|
|
150
|
+
- bg3.history.external-guid-load-order
|
|
151
|
+
- bg3.history.loca-no-xml-comments
|
|
152
|
+
manual:
|
|
153
|
+
- title: Add real content
|
|
154
|
+
steps:
|
|
155
|
+
- "Run new-spell/new-passive/new-status to fill Stats/Generated/Data."
|
|
156
|
+
- "Register the module in the game's modsettings.lsx load order once tested."
|
|
157
|
+
expected: "The module loads in-game and passes validate with no blocking findings."
|
|
158
|
+
claim:
|
|
159
|
+
idSuffix: mod-loads
|
|
160
|
+
claim: "${input.folder} (UUID ${ids.moduleUuid}) is a loadable BG3 module with a valid meta.lsx and Script Extender config."
|
|
161
|
+
testRows:
|
|
162
|
+
- gate: S-1
|
|
163
|
+
title: "Module enumerates and loads"
|
|
164
|
+
expected: "bg3.mod.active reports the module UUID loaded, matching the declared Version64."
|
|
165
|
+
manual: false
|
|
166
|
+
probes:
|
|
167
|
+
- kind: bg3.mod.active
|
|
168
|
+
params: { uuid: "${ids.moduleUuid}" }
|
|
169
|
+
- gate: S-2
|
|
170
|
+
title: "Menu enumeration"
|
|
171
|
+
expected: "The mod appears in the in-game mod manager under its display name."
|
|
172
|
+
manual: true
|
|
173
|
+
probeKinds: [bg3.client.loaded]
|
|
174
|
+
evidence: ["ModWright research"]
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# new-passive (BG3). Same
|
|
2
|
+
# shape as new-spell, but PassiveData carries
|
|
3
|
+
# BoostContext including OnCreate, so the
|
|
4
|
+
# `bg3.history.boostcontext-initial-event` "initial-event" failure mode is
|
|
5
|
+
# a passive-specific concern, unlike SpellData.
|
|
6
|
+
id: baldursgate3.new-passive
|
|
7
|
+
game: baldursgate3
|
|
8
|
+
title: New BG3 passive (PassiveData entry)
|
|
9
|
+
summary: Append a PassiveData entry to Passive.txt with a vanilla `using` parent, BoostContext including OnCreate, and DisplayName/Description loca rows.
|
|
10
|
+
modTypes: [dialogue]
|
|
11
|
+
needs: { index: true }
|
|
12
|
+
inputs:
|
|
13
|
+
- type: string
|
|
14
|
+
name: entryName
|
|
15
|
+
prompt: "Full stats entry name, e.g. MyMod_QuickReflexes."
|
|
16
|
+
pattern: "^[A-Za-z][A-Za-z0-9_]*$"
|
|
17
|
+
- type: index-ref
|
|
18
|
+
name: parent
|
|
19
|
+
prompt: "Vanilla (or project) PassiveData entry to `using`."
|
|
20
|
+
lookup: { kind: stat, params: { name: "${input.parent}" } }
|
|
21
|
+
requires:
|
|
22
|
+
- path: type
|
|
23
|
+
matches: "^PassiveData$"
|
|
24
|
+
reason: "the parent must be a PassiveData entry, or `using` inherits fields from the wrong stat family."
|
|
25
|
+
- type: string
|
|
26
|
+
name: displayName
|
|
27
|
+
prompt: "Player-facing passive name."
|
|
28
|
+
- type: string
|
|
29
|
+
name: description
|
|
30
|
+
prompt: "Tooltip description text."
|
|
31
|
+
- type: string
|
|
32
|
+
name: boosts
|
|
33
|
+
prompt: "Boosts string (semicolon-separated boost functors), or leave blank for a display-only passive."
|
|
34
|
+
default: ""
|
|
35
|
+
ids:
|
|
36
|
+
- name: display
|
|
37
|
+
slot: "display:${input.entryName}"
|
|
38
|
+
form: bg3-handle
|
|
39
|
+
- name: description
|
|
40
|
+
slot: "description:${input.entryName}"
|
|
41
|
+
form: bg3-handle
|
|
42
|
+
emits:
|
|
43
|
+
- op: insert-block
|
|
44
|
+
path: "Public/${project.identity.folder}/Stats/Generated/Data/Passive.txt"
|
|
45
|
+
createIfMissing: "// ModWright-scaffolded passive file.\n"
|
|
46
|
+
anchor: append
|
|
47
|
+
body: |
|
|
48
|
+
// ${project.today} - ModWright scaffold: ${input.entryName}, using parent ${input.parent}.
|
|
49
|
+
new entry "${input.entryName}"
|
|
50
|
+
type "PassiveData"
|
|
51
|
+
using "${input.parent}"
|
|
52
|
+
data "Icon" "${input.entryName}_Icon"
|
|
53
|
+
data "DisplayName" "${ids.display}"
|
|
54
|
+
data "Description" "${ids.description}"
|
|
55
|
+
data "Boosts" "${input.boosts}"
|
|
56
|
+
data "BoostContext" "OnCreate"
|
|
57
|
+
- op: insert-loca-row
|
|
58
|
+
path: "Mods/${project.identity.folder}/Localization/English/${project.identity.folder}.xml"
|
|
59
|
+
handle: "${ids.display}"
|
|
60
|
+
text: "${input.displayName}"
|
|
61
|
+
- op: insert-loca-row
|
|
62
|
+
path: "Mods/${project.identity.folder}/Localization/English/${project.identity.folder}.xml"
|
|
63
|
+
handle: "${ids.description}"
|
|
64
|
+
text: "${input.description}"
|
|
65
|
+
templates: []
|
|
66
|
+
satisfies:
|
|
67
|
+
- bg3.history.spellanimation-present
|
|
68
|
+
- bg3.history.boostcontext-initial-event
|
|
69
|
+
- bg3.history.context-qualifier-validity
|
|
70
|
+
- bg3.history.reference-integrity
|
|
71
|
+
- bg3.history.handle-form-per-field
|
|
72
|
+
- bg3.history.handle-defined-in-loca
|
|
73
|
+
- bg3.history.islinkedspellcontainer-links
|
|
74
|
+
- bg3.history.spellid-enumeration-drift
|
|
75
|
+
- bg3.history.loca-no-xml-comments
|
|
76
|
+
manual:
|
|
77
|
+
- title: Icon and progression
|
|
78
|
+
steps:
|
|
79
|
+
- "Draw the ${input.entryName}_Icon art and register it in the spell atlas."
|
|
80
|
+
- "Grant ${input.entryName} via a Progression's PassivesAdded if it should be automatic."
|
|
81
|
+
expected: "The passive shows a real icon and its boost is observable in-game."
|
|
82
|
+
claim:
|
|
83
|
+
idSuffix: applies
|
|
84
|
+
claim: "${input.entryName} applies its boost(s) once granted, inheriting fields from ${input.parent}."
|
|
85
|
+
testRows:
|
|
86
|
+
- gate: S-1
|
|
87
|
+
title: "Stat entry loads with expected fields"
|
|
88
|
+
expected: "bg3.stat.exists finds ${input.entryName}; bg3.stat.fields confirms BoostContext/Boosts/DisplayName/Description."
|
|
89
|
+
manual: false
|
|
90
|
+
probes:
|
|
91
|
+
- kind: bg3.stat.exists
|
|
92
|
+
params: { name: "${input.entryName}" }
|
|
93
|
+
- kind: bg3.stat.fields
|
|
94
|
+
params: { name: "${input.entryName}", fields: [BoostContext, Boosts, DisplayName, Description] }
|
|
95
|
+
- gate: S-2
|
|
96
|
+
title: "Icon and tooltip render"
|
|
97
|
+
expected: "The passive's card shows the drawn icon and correct tooltip text in-game."
|
|
98
|
+
manual: true
|
|
99
|
+
probeKinds: []
|
|
100
|
+
evidence: ["ModWright research"]
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# new-project (Baldur's Gate 3).
|
|
2
|
+
# The one scaffold that runs before a modwright.json exists: writes the
|
|
3
|
+
# skeleton every other BG3 scaffold assumes (the two source trees, the v2
|
|
4
|
+
# project file, ledger/decisions.yaml). tests/authored.yaml and
|
|
5
|
+
# ledger/claims.yaml are written by the engine's own automatic per-apply
|
|
6
|
+
# steps, not by an emit here.
|
|
7
|
+
id: baldursgate3.new-project
|
|
8
|
+
game: baldursgate3
|
|
9
|
+
title: New BG3 mod project
|
|
10
|
+
summary: Scaffold a fresh ModWright project for a Baldur's Gate 3 mod — modwright.json (schemaVersion 2), the Mods/Public source trees, .gitignore, and ledger/decisions.yaml.
|
|
11
|
+
modTypes: [packaging]
|
|
12
|
+
needs: {}
|
|
13
|
+
inputs:
|
|
14
|
+
- type: string
|
|
15
|
+
name: name
|
|
16
|
+
prompt: Mod name (also used as the Mods/<name> and Public/<name> folder name).
|
|
17
|
+
pattern: "^[A-Za-z][A-Za-z0-9_]*$"
|
|
18
|
+
- type: string
|
|
19
|
+
name: version
|
|
20
|
+
prompt: Initial version (semver-ish, major.minor.revision).
|
|
21
|
+
default: "0.1.0"
|
|
22
|
+
- type: string
|
|
23
|
+
name: author
|
|
24
|
+
prompt: Author name.
|
|
25
|
+
default: "Unknown"
|
|
26
|
+
# A project can keep its
|
|
27
|
+
# LSLib divine path as a toolchain override in modwright.json; a fresh
|
|
28
|
+
# project on the same machine needs the same line or its first build
|
|
29
|
+
# cannot find the tool. Empty means "the locator's own candidates" and
|
|
30
|
+
# writes nothing.
|
|
31
|
+
- type: string
|
|
32
|
+
name: divine
|
|
33
|
+
prompt: "Absolute path to LSLib's Divine.exe when it is not where check_toolchain looks (written as the project's toolchain override; leave empty to rely on the locator)."
|
|
34
|
+
default: ""
|
|
35
|
+
ids:
|
|
36
|
+
- name: moduleUuid
|
|
37
|
+
slot: "module-uuid:${input.name}"
|
|
38
|
+
form: uuid
|
|
39
|
+
collision:
|
|
40
|
+
project: true
|
|
41
|
+
index: { kind: guid, param: uuid }
|
|
42
|
+
emits:
|
|
43
|
+
- op: ensure-dir
|
|
44
|
+
path: "Mods/${input.name}"
|
|
45
|
+
- op: ensure-dir
|
|
46
|
+
path: "Public/${input.name}/Stats/Generated/Data"
|
|
47
|
+
- op: ensure-dir
|
|
48
|
+
path: "Public/${input.name}/Localization/English"
|
|
49
|
+
- op: write-text
|
|
50
|
+
path: ".gitignore"
|
|
51
|
+
ifExists: skip
|
|
52
|
+
# Two files under .modwright are worth tracking, so a reviewer
|
|
53
|
+
# reads them in a clean checkout: suppressions.json and
|
|
54
|
+
# templates/manifest.json. A bare `.modwright/` hides both (a
|
|
55
|
+
# hand-written ignore often un-hides only the first). git cannot re-include
|
|
56
|
+
# a file inside an ignored directory, so the templates folder is
|
|
57
|
+
# re-included and its other contents ignored again.
|
|
58
|
+
body: |
|
|
59
|
+
.modwright/*
|
|
60
|
+
!.modwright/suppressions.json
|
|
61
|
+
!.modwright/templates/
|
|
62
|
+
.modwright/templates/*
|
|
63
|
+
!.modwright/templates/manifest.json
|
|
64
|
+
build/
|
|
65
|
+
*.pak
|
|
66
|
+
.modwright-build-manifest.json
|
|
67
|
+
- op: write-text
|
|
68
|
+
path: "ledger/decisions.yaml"
|
|
69
|
+
body: |
|
|
70
|
+
decisions: []
|
|
71
|
+
- op: write-text
|
|
72
|
+
path: "modwright.json"
|
|
73
|
+
body: |
|
|
74
|
+
{
|
|
75
|
+
"schemaVersion": 2,
|
|
76
|
+
"name": "${input.name}",
|
|
77
|
+
"game": "baldursgate3",
|
|
78
|
+
"version": "${input.version}",
|
|
79
|
+
"authors": ["${input.author}"],
|
|
80
|
+
"identity": {
|
|
81
|
+
"uuid": "${ids.moduleUuid}",
|
|
82
|
+
"folder": "${input.name}"
|
|
83
|
+
},
|
|
84
|
+
"sources": [
|
|
85
|
+
{ "id": "mods", "path": "Mods/${input.name}", "kind": "mods" },
|
|
86
|
+
{ "id": "public", "path": "Public/${input.name}", "kind": "public" }
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
# The LSLib divine override, written the way a project keeps
|
|
90
|
+
# its own; the engine merges it into the modwright.json written just above, and an
|
|
91
|
+
# empty input adds no key at all.
|
|
92
|
+
- op: patch-project
|
|
93
|
+
add:
|
|
94
|
+
toolchain:
|
|
95
|
+
divine: "${input.divine}"
|
|
96
|
+
templates: []
|
|
97
|
+
# Nothing is satisfied directly: the one real postcondition is that
|
|
98
|
+
# validate reports no *unmet-needs* skip among project-only rules. A
|
|
99
|
+
# project-target rule with needs:{project:true} always evaluates (the
|
|
100
|
+
# {kind:"project"} target always exists), so this trivially "ran" with zero
|
|
101
|
+
# findings against the still-empty source trees.
|
|
102
|
+
satisfies: [bg3.progression.meta-version64]
|
|
103
|
+
manual:
|
|
104
|
+
- title: Populate the mod
|
|
105
|
+
steps:
|
|
106
|
+
- "Add real content under Mods/<name> (meta.lsx, ScriptExtender, Localization) and Public/<name> (Stats, RootTemplates)."
|
|
107
|
+
- "Run the new-mod scaffold next to fill in meta.lsx and ScriptExtender/Config.json."
|
|
108
|
+
expected: "validate reports the project's own structural rules clean once real content exists."
|
|
109
|
+
claim:
|
|
110
|
+
idSuffix: scaffolded
|
|
111
|
+
claim: "${input.name} is scaffolded as a ModWright project with a schemaVersion 2 modwright.json and a fresh module UUID."
|
|
112
|
+
testRows:
|
|
113
|
+
- gate: S-0
|
|
114
|
+
title: "Project loads"
|
|
115
|
+
expected: "validate loads modwright.json with no schema errors and no unmet-needs skip among project-only rules."
|
|
116
|
+
manual: true
|
|
117
|
+
probeKinds: []
|
|
118
|
+
evidence: ["ModWright research"]
|