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,157 @@
|
|
|
1
|
+
# new-project (Cyberpunk 2077). Mirrors the BG3 new-project scaffold: writes
|
|
2
|
+
# the skeleton every other CP2077 scaffold assumes. tests/authored.yaml and
|
|
3
|
+
# ledger/claims.yaml come from the engine's own automatic per-apply steps,
|
|
4
|
+
# not an emit here.
|
|
5
|
+
#
|
|
6
|
+
# It also writes the build and deploy configuration a working project
|
|
7
|
+
# needs (2026-09-11: scratch projects had to be configured by hand while
|
|
8
|
+
# this scaffold wrote sources only): stage the archive-staging source under
|
|
9
|
+
# the mod's name, pack it with WolvenKit, verify no CR2W JSON leaked into
|
|
10
|
+
# the archive, and deploy the archive, the tweaks folder and the scripts
|
|
11
|
+
# folder. The content scaffolds (new-item-chain, new-garment-refit,
|
|
12
|
+
# new-sector-node) put their deserialize steps ahead of the stage step and
|
|
13
|
+
# register the manifests they write as a project source and a deploy
|
|
14
|
+
# target. A build on a project with nothing staged yet fails at the stage
|
|
15
|
+
# step ("staged zero files"), which is the honest result until a content
|
|
16
|
+
# scaffold has run.
|
|
17
|
+
id: cyberpunk2077.new-project
|
|
18
|
+
game: cyberpunk2077
|
|
19
|
+
title: New Cyberpunk 2077 mod project
|
|
20
|
+
summary: Scaffold a fresh ModWright project for a Cyberpunk 2077 mod — modwright.json (schemaVersion 2), the tweaks/scripts source trees, .gitignore, and ledger/decisions.yaml.
|
|
21
|
+
modTypes: [packaging]
|
|
22
|
+
needs: {}
|
|
23
|
+
inputs:
|
|
24
|
+
- type: string
|
|
25
|
+
name: name
|
|
26
|
+
prompt: Mod name (also used as the r6/tweaks/<name> and scripts/<name> folder name).
|
|
27
|
+
pattern: "^[A-Za-z][A-Za-z0-9_]*$"
|
|
28
|
+
- type: string
|
|
29
|
+
name: version
|
|
30
|
+
prompt: Initial version (semver-ish, major.minor.revision).
|
|
31
|
+
default: "0.1.0"
|
|
32
|
+
- type: string
|
|
33
|
+
name: author
|
|
34
|
+
prompt: Author name.
|
|
35
|
+
default: "Unknown"
|
|
36
|
+
# Observed in practice (2026-09-12): the WolvenKit CLI override had to be
|
|
37
|
+
# added to a fresh project by hand because the locator does not find a CLI
|
|
38
|
+
# installed outside the usual places. The path is machine-specific and
|
|
39
|
+
# lives in modwright.json's `toolchain` block; empty means "the locator's
|
|
40
|
+
# own candidates" and writes nothing.
|
|
41
|
+
- type: string
|
|
42
|
+
name: wolvenkitCli
|
|
43
|
+
prompt: "Absolute path to WolvenKit.CLI.exe when it is not where check_toolchain looks (written as the project's toolchain override; leave empty to rely on the locator)."
|
|
44
|
+
default: ""
|
|
45
|
+
ids: []
|
|
46
|
+
emits:
|
|
47
|
+
- op: ensure-dir
|
|
48
|
+
path: "r6/tweaks/${input.name}"
|
|
49
|
+
- op: ensure-dir
|
|
50
|
+
path: "scripts/${input.name}"
|
|
51
|
+
- op: ensure-dir
|
|
52
|
+
path: "archive-staging/${input.name}"
|
|
53
|
+
# Every other Cyberpunk scaffold that writes an editable JSON source
|
|
54
|
+
# (new-item-chain's .ent.json/localization, new-sector-node's
|
|
55
|
+
# .streamingsector.json, new-vehicle-livery's .mlsetup.json) writes it
|
|
56
|
+
# under "sources/...", and a working project declares exactly this as a
|
|
57
|
+
# project source of kind "sources". Without it here, those files sit
|
|
58
|
+
# outside every declared project source, so `core/validate/context.ts`'s
|
|
59
|
+
# `listFiles()` (which walks `project.sources`, not the whole tree) never
|
|
60
|
+
# lists them: the reason `cp2077.vehicles.cr2w-unique-ids`/
|
|
61
|
+
# `cr2w-enums-are-strings`/`cr2w-resource-path-shape` skipped "no file
|
|
62
|
+
# matched" against a scaffold that plainly does write a JSON
|
|
63
|
+
# `.mlsetup`/`.ent`/`.streamingsector` source, confirmed against a fresh
|
|
64
|
+
# project. Declaring it here is the root-cause fix: it makes those rules
|
|
65
|
+
# genuinely run (and check real content) instead of quietly moving them to
|
|
66
|
+
# `manual` for every scaffold that writes under sources/.
|
|
67
|
+
- op: ensure-dir
|
|
68
|
+
path: "sources"
|
|
69
|
+
- op: write-text
|
|
70
|
+
path: ".gitignore"
|
|
71
|
+
ifExists: skip
|
|
72
|
+
# Two files under .modwright should be tracked, so a reviewer reads them
|
|
73
|
+
# in a clean checkout: suppressions.json and templates/manifest.json. A
|
|
74
|
+
# bare `.modwright/` hides both (observed 2026-09-12). git cannot
|
|
75
|
+
# re-include a file inside an ignored directory, so the templates folder
|
|
76
|
+
# is re-included and its other contents ignored again.
|
|
77
|
+
body: |
|
|
78
|
+
.modwright/*
|
|
79
|
+
!.modwright/suppressions.json
|
|
80
|
+
!.modwright/templates/
|
|
81
|
+
.modwright/templates/*
|
|
82
|
+
!.modwright/templates/manifest.json
|
|
83
|
+
build/
|
|
84
|
+
*.archive
|
|
85
|
+
.modwright-build-manifest.json
|
|
86
|
+
- op: write-text
|
|
87
|
+
path: "ledger/decisions.yaml"
|
|
88
|
+
body: |
|
|
89
|
+
decisions: []
|
|
90
|
+
- op: write-text
|
|
91
|
+
path: "modwright.json"
|
|
92
|
+
body: |
|
|
93
|
+
{
|
|
94
|
+
"schemaVersion": 2,
|
|
95
|
+
"name": "${input.name}",
|
|
96
|
+
"game": "cyberpunk2077",
|
|
97
|
+
"version": "${input.version}",
|
|
98
|
+
"authors": ["${input.author}"],
|
|
99
|
+
"identity": {
|
|
100
|
+
"name": "${input.name}"
|
|
101
|
+
},
|
|
102
|
+
"sources": [
|
|
103
|
+
{ "id": "tweaks", "path": "r6/tweaks/${input.name}", "kind": "tweaks" },
|
|
104
|
+
{ "id": "scripts", "path": "scripts/${input.name}", "kind": "scripts" },
|
|
105
|
+
{ "id": "archive-staging", "path": "archive-staging/${input.name}", "kind": "archive-staging" },
|
|
106
|
+
{ "id": "sources", "path": "sources", "kind": "sources" }
|
|
107
|
+
],
|
|
108
|
+
"build": {
|
|
109
|
+
"outDir": "archive-staging",
|
|
110
|
+
"steps": [
|
|
111
|
+
{ "step": "stage", "id": "pack", "sources": ["archive-staging"], "into": "${input.name}" },
|
|
112
|
+
{ "step": "wolvenkit-pack", "from": "${stage}/pack/${input.name}", "out": "${input.name}.archive" },
|
|
113
|
+
{ "step": "verify-listing", "of": "${input.name}.archive", "forbid": ["**/*.json", "!**/en-us.json"] }
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
"deploy": {
|
|
117
|
+
"waitMinutes": 0,
|
|
118
|
+
"targets": [
|
|
119
|
+
{ "rootId": "archive", "from": "${input.name}.archive", "locked": true, "backup": true },
|
|
120
|
+
{ "rootId": "tweaks", "from": "tweaks", "into": "${input.name}", "locked": false, "backup": true },
|
|
121
|
+
{ "rootId": "redscript", "from": "scripts", "into": "${input.name}", "locked": false, "backup": true }
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
"dependencies": [
|
|
125
|
+
{ "id": "red4ext", "kind": "loader", "url": "https://www.nexusmods.com/cyberpunk2077/mods/2380" },
|
|
126
|
+
{ "id": "archivexl", "kind": "framework", "url": "https://www.nexusmods.com/cyberpunk2077/mods/4198" },
|
|
127
|
+
{ "id": "tweakxl", "kind": "framework", "url": "https://www.nexusmods.com/cyberpunk2077/mods/4197" },
|
|
128
|
+
{ "id": "wolvenkit-cli", "kind": "tool", "minVersion": "8.20", "notes": "Packs archive-staging/${input.name} into ${input.name}.archive and deserializes the CR2W JSON sources the content scaffolds write." }
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
# The override merges into the modwright.json written just above (the
|
|
132
|
+
# engine patches the pending copy); an empty input adds no key at all.
|
|
133
|
+
- op: patch-project
|
|
134
|
+
add:
|
|
135
|
+
toolchain:
|
|
136
|
+
wolvenkit-cli: "${input.wolvenkitCli}"
|
|
137
|
+
templates: []
|
|
138
|
+
# No rule applies directly, same reasoning as the BG3 twin: pick a
|
|
139
|
+
# project-target, project-only-needs rule so the postcondition is "ran,
|
|
140
|
+
# clean" against the still-empty tree rather than "skipped".
|
|
141
|
+
satisfies: [cp2077.tweaks.dotted-path-same-file]
|
|
142
|
+
manual:
|
|
143
|
+
- title: Populate the mod
|
|
144
|
+
steps:
|
|
145
|
+
- "Add tweak YAML under r6/tweaks/<name>, redscript under scripts/<name>."
|
|
146
|
+
- "Run the new-tweak scaffold next to add the first TweakDB record."
|
|
147
|
+
expected: "validate reports the project's own structural rules clean once real content exists."
|
|
148
|
+
claim:
|
|
149
|
+
idSuffix: scaffolded
|
|
150
|
+
claim: "${input.name} is scaffolded as a ModWright project with a schemaVersion 2 modwright.json."
|
|
151
|
+
testRows:
|
|
152
|
+
- gate: S-0
|
|
153
|
+
title: "Project loads"
|
|
154
|
+
expected: "validate loads modwright.json with no schema errors and no unmet-needs skip among project-only rules."
|
|
155
|
+
manual: true
|
|
156
|
+
probeKinds: []
|
|
157
|
+
evidence: ["ModWright research"]
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# new-sector-node (Cyberpunk 2077) — the scaffold writes the JSON source and
|
|
2
|
+
# appends a `convert deserialize` build step (via patch-project) rather than
|
|
3
|
+
# invoking WolvenKit itself. HandleId/BufferId are renumbered into document-
|
|
4
|
+
# encounter order automatically by the engine's `insert-xl-entry` handling —
|
|
5
|
+
# the literal placeholder below is arbitrary on purpose.
|
|
6
|
+
#
|
|
7
|
+
# Deviations observed in game (2026-09):
|
|
8
|
+
# - this scaffold's own patch-project op now supplies
|
|
9
|
+
# `add.outDir: "archive-staging"` — the convention a working project
|
|
10
|
+
# ships (`build.outDir: "archive-staging"` holding
|
|
11
|
+
# `archive-staging/<ModName>`) — so a project with no `build` block yet
|
|
12
|
+
# (fresh off `new-project`) does not end up with one missing `outDir`.
|
|
13
|
+
# It only fills the gap: a project that already has `build.outDir` set
|
|
14
|
+
# keeps its own value (engine.ts's own merge). Fixed at the engine level
|
|
15
|
+
# too: a patch-project op that would leave modwright.json invalid now
|
|
16
|
+
# refuses instead of writing (engine.ts).
|
|
17
|
+
# - the emitted build step used `wolvenkit-cli convert deserialize
|
|
18
|
+
# -i <src> -o <dst>`, but WolvenKit.CLI's `convert` subcommands take the
|
|
19
|
+
# input path positionally and `-o` names an output *directory*, not a
|
|
20
|
+
# file (`-i` is silently swallowed as noise and the run exits 161 —
|
|
21
|
+
# confirmed by hand in game). Fixed to `convert deserialize
|
|
22
|
+
# <input file> -o <output directory>` via a new `outputDir` input
|
|
23
|
+
# (smaller than teaching the engine a "directory of this path" derived
|
|
24
|
+
# value for the one caller that needs it — see new-item-chain.yaml's
|
|
25
|
+
# matching note). `expectOutputs` still names `outputPath`, the file
|
|
26
|
+
# WolvenKit is expected to actually write there — inferred from the
|
|
27
|
+
# serialize direction (it strips the trailing `.json` off the source
|
|
28
|
+
# file's own name) and NOT yet confirmed against a real `deserialize`
|
|
29
|
+
# run; `outputPath` and `outputDir` are both given by the caller and
|
|
30
|
+
# must agree (outputPath's directory should equal outputDir) — nothing
|
|
31
|
+
# here derives one from the other.
|
|
32
|
+
# - `satisfies` is trimmed to the rules that genuinely run against
|
|
33
|
+
# the `.streamingsector` JSON this scaffold writes (checked with a
|
|
34
|
+
# `ran`-membership assertion in the scaffold's tests) — `cp2077.history.
|
|
35
|
+
# xl-manifest-lint` only applies to `.xl` files and never matches a bare
|
|
36
|
+
# sector JSON, so it is dropped.
|
|
37
|
+
#
|
|
38
|
+
# Re-audited against a truly fresh new-project output, not a hand-built
|
|
39
|
+
# fixture (observed 2026-09): `${input.file}` typically lands under
|
|
40
|
+
# `sources/sector/...`, which only resolves to a file the validation context
|
|
41
|
+
# can see because `cyberpunk2077.new-project`
|
|
42
|
+
# now declares a `sources`-kind project source (fixed there, at the root,
|
|
43
|
+
# once for every scaffold that writes under `sources/...`). No change to
|
|
44
|
+
# this file's own satisfies[] was needed once that fix landed.
|
|
45
|
+
id: cyberpunk2077.new-sector-node
|
|
46
|
+
game: cyberpunk2077
|
|
47
|
+
title: New Cyberpunk 2077 sector node
|
|
48
|
+
summary: Append a worldEntityNode to an existing .streamingsector JSON source at a given position, and add the convert-deserialize build step for it.
|
|
49
|
+
modTypes: [world-sector]
|
|
50
|
+
needs: {}
|
|
51
|
+
inputs:
|
|
52
|
+
- type: path
|
|
53
|
+
name: file
|
|
54
|
+
prompt: "The mod's own .streamingsector JSON source to append the node to (must already exist)."
|
|
55
|
+
mustExist: true
|
|
56
|
+
- type: path
|
|
57
|
+
name: outputPath
|
|
58
|
+
prompt: "Where the compiled .streamingsector binary should land (project-relative), for the build step this scaffold appends. Its directory must equal outputDir."
|
|
59
|
+
mustExist: false
|
|
60
|
+
- type: path
|
|
61
|
+
name: outputDir
|
|
62
|
+
prompt: "Directory the compiled .streamingsector binary should land in (project-relative) — passed to WolvenKit.CLI's convert deserialize -o, which takes a directory, not a file. Must be outputPath's own directory."
|
|
63
|
+
mustExist: false
|
|
64
|
+
- type: string
|
|
65
|
+
name: entityTemplatePath
|
|
66
|
+
prompt: "Depot path (backslash, lowercase) to the .ent this node spawns, e.g. mod\\\\mymod\\\\newprop.ent."
|
|
67
|
+
pattern: "^[a-z0-9_]+(\\\\[a-z0-9_]+)*\\.ent$"
|
|
68
|
+
- type: string
|
|
69
|
+
name: appearanceName
|
|
70
|
+
prompt: "Appearance name to use (must be one the .ent actually declares, once staged)."
|
|
71
|
+
default: "default"
|
|
72
|
+
- type: number
|
|
73
|
+
name: positionX
|
|
74
|
+
prompt: "World position X."
|
|
75
|
+
- type: number
|
|
76
|
+
name: positionY
|
|
77
|
+
prompt: "World position Y."
|
|
78
|
+
- type: number
|
|
79
|
+
name: positionZ
|
|
80
|
+
prompt: "World position Z."
|
|
81
|
+
ids: []
|
|
82
|
+
emits:
|
|
83
|
+
- op: insert-xl-entry
|
|
84
|
+
path: "${input.file}"
|
|
85
|
+
pointer: Data.RootChunk.nodes.-
|
|
86
|
+
value:
|
|
87
|
+
HandleId: "new-node"
|
|
88
|
+
Data:
|
|
89
|
+
$type: worldEntityNode
|
|
90
|
+
appearanceName: { $type: CName, $storage: string, $value: "${input.appearanceName}" }
|
|
91
|
+
debugName: { $type: CName, $storage: string, $value: "[ModWright] ${input.entityTemplatePath}" }
|
|
92
|
+
entityLod: 0
|
|
93
|
+
entityTemplate:
|
|
94
|
+
DepotPath: { $type: ResourcePath, $storage: string, $value: "${input.entityTemplatePath}" }
|
|
95
|
+
Flags: Soft
|
|
96
|
+
ioPriority: Immediate
|
|
97
|
+
isHostOnly: 0
|
|
98
|
+
isVisibleInGame: 1
|
|
99
|
+
sourcePrefabHash: "0"
|
|
100
|
+
tag: None
|
|
101
|
+
tagExt: None
|
|
102
|
+
- op: insert-xl-entry
|
|
103
|
+
path: "${input.file}"
|
|
104
|
+
pointer: Data.RootChunk.nodeData.Data.-
|
|
105
|
+
value:
|
|
106
|
+
Id: "1"
|
|
107
|
+
NodeIndex: 1
|
|
108
|
+
Position: { $type: Vector4, W: 0, X: "${input.positionX}", Y: "${input.positionY}", Z: "${input.positionZ}" }
|
|
109
|
+
Orientation: { $type: Quaternion, i: 0.0, j: 0.0, k: 0.0, r: 1.0 }
|
|
110
|
+
Scale: { $type: Vector3, X: 1, Y: 1, Z: 1 }
|
|
111
|
+
- op: patch-project
|
|
112
|
+
add:
|
|
113
|
+
outDir: "archive-staging"
|
|
114
|
+
steps:
|
|
115
|
+
- step: exec
|
|
116
|
+
id: "deserialize-sector"
|
|
117
|
+
command: wolvenkit-cli
|
|
118
|
+
args: ["convert", "deserialize", "${input.file}", "-o", "${input.outputDir}"]
|
|
119
|
+
expectOutputs: ["${input.outputPath}"]
|
|
120
|
+
# Ordering (2026-09-11): ahead of the project's stage step, or
|
|
121
|
+
# the compiled sector lands after the archive was packed.
|
|
122
|
+
before: stage
|
|
123
|
+
templates: []
|
|
124
|
+
satisfies:
|
|
125
|
+
- cp2077.vehicles.cr2w-unique-ids
|
|
126
|
+
- cp2077.vehicles.cr2w-enums-are-strings
|
|
127
|
+
- cp2077.vehicles.cr2w-resource-path-shape
|
|
128
|
+
- cp2077.vehicles.cr2w-gameversion-header
|
|
129
|
+
- cp2077.vehicles.appearance-name-resolution
|
|
130
|
+
manual:
|
|
131
|
+
- title: Confirm placement in-game
|
|
132
|
+
steps:
|
|
133
|
+
- "Stage the referenced .ent (${input.entityTemplatePath}) so appearance-name-resolution can actually check ${input.appearanceName}."
|
|
134
|
+
- "Load a save near the placed coordinates and confirm the entity spawns and renders."
|
|
135
|
+
expected: "The entity is visible at the given position with the expected appearance."
|
|
136
|
+
claim:
|
|
137
|
+
idSuffix: placed
|
|
138
|
+
claim: "A worldEntityNode referencing ${input.entityTemplatePath} (appearance ${input.appearanceName}) is placed at (${input.positionX}, ${input.positionY}, ${input.positionZ})."
|
|
139
|
+
testRows:
|
|
140
|
+
- gate: N-1
|
|
141
|
+
title: "Entity located in-game"
|
|
142
|
+
# cp2077.entity.tagged only finds legacy dev-spawn duplicates, not a
|
|
143
|
+
# sector-placed static prop (observed in game, 2026-09,
|
|
144
|
+
# taggedCount: 0 against a real placed prop) — this scaffold's own node is
|
|
145
|
+
# exactly that case, so the tag mechanism does not apply to it at all. cp2077.entity.transform
|
|
146
|
+
# is itself only `unverified` for a sector-placed prop (same citation).
|
|
147
|
+
# Neither kind is usable here; a human confirms placement by eye instead.
|
|
148
|
+
expected: "A human loads near (${input.positionX}, ${input.positionY}, ${input.positionZ}) and confirms the entity is present at that position — cp2077.entity.tagged/cp2077.entity.transform do not apply to a sector-placed static prop (see this row's own note)."
|
|
149
|
+
manual: true
|
|
150
|
+
probeKinds: [cp2077.entity.tagged, cp2077.entity.transform]
|
|
151
|
+
- gate: N-2
|
|
152
|
+
title: "Visual inspection"
|
|
153
|
+
expected: "A human confirms the entity renders with the correct mesh/appearance from two camera angles."
|
|
154
|
+
manual: true
|
|
155
|
+
probeKinds: []
|
|
156
|
+
evidence: ["ModWright research"]
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# new-tweak (Cyberpunk 2077) — writes one TweakXL record from a vanilla (or
|
|
2
|
+
# project) $base into a .yaml file under a project source of kind "tweaks".
|
|
3
|
+
# `file` is a `path` input rather than a fixed convention, because projects
|
|
4
|
+
# lay their tweaks trees out differently (r6/tweaks/<Mod>/*.yaml in one,
|
|
5
|
+
# tweaks/*.yaml deployed to r6/tweaks/ in another) — the caller (a `lookup`
|
|
6
|
+
# call, or the person running the scaffold) names the destination, this
|
|
7
|
+
# scaffold does not guess it.
|
|
8
|
+
#
|
|
9
|
+
# Observed while authoring a quickhack (2026-09-19): a record either
|
|
10
|
+
# clones a vanilla/project `$base` OR declares a fresh engine `$type` with no
|
|
11
|
+
# base — the quickhack chain's `ObjectActionPrereq` prereq wrapper is the
|
|
12
|
+
# latter, and this scaffold could not write it while `base` was required.
|
|
13
|
+
# `base` and `type` are now a `oneOf` group (exactly one, engine.ts): each is
|
|
14
|
+
# optional, and the two record blocks below gate on which was given
|
|
15
|
+
# (`when.inputDefined`), so `${ids.recordName}` gets exactly one occurrence in
|
|
16
|
+
# the file — the same mutual-exclusion discipline new-item-chain's two record
|
|
17
|
+
# blocks follow. The `$type` path leans on the tweaks validators already
|
|
18
|
+
# handling a base-less record (`base-exists` skips `!rec.base`; `type-known`
|
|
19
|
+
# checks `rec.type`; `flat-name-exists` is out of scope "unless the record
|
|
20
|
+
# declares its own $type").
|
|
21
|
+
id: cyberpunk2077.new-tweak
|
|
22
|
+
game: cyberpunk2077
|
|
23
|
+
title: New Cyberpunk 2077 TweakDB record
|
|
24
|
+
summary: Append one TweakXL record (with a $base and hand-authored flats) into an existing .yaml under a project's "tweaks" source.
|
|
25
|
+
modTypes: [gameplay-tweak, weapon, item, loot]
|
|
26
|
+
needs: { index: true }
|
|
27
|
+
inputs:
|
|
28
|
+
- type: path
|
|
29
|
+
name: file
|
|
30
|
+
prompt: "Destination .yaml under a project source of kind \"tweaks\" (created if it does not yet exist)."
|
|
31
|
+
mustExist: false
|
|
32
|
+
- type: string
|
|
33
|
+
name: recordName
|
|
34
|
+
prompt: "Full TweakDB record name, e.g. Items.Preset_MyGun."
|
|
35
|
+
pattern: "^[A-Za-z][A-Za-z0-9_]*(\\.[A-Za-z0-9_]+)+$"
|
|
36
|
+
- type: index-ref
|
|
37
|
+
name: base
|
|
38
|
+
prompt: "$base record this inherits from (provide this OR type, not both)."
|
|
39
|
+
lookup: { kind: record, params: { name: "${input.base}" } }
|
|
40
|
+
requires: []
|
|
41
|
+
- type: string
|
|
42
|
+
name: type
|
|
43
|
+
prompt: "$type engine record type for a fresh record with no vanilla $base, e.g. ObjectActionPrereq (provide this OR base, not both)."
|
|
44
|
+
pattern: "^[A-Za-z][A-Za-z0-9_]*$"
|
|
45
|
+
- type: string
|
|
46
|
+
name: flats
|
|
47
|
+
prompt: "Hand-authored flat lines as YAML (e.g. \"displayName: LocKey#Foo-Name\\nprice: 500\"). Indentation is normalized to nest under the record, so write it at any consistent base indent — a sequence step can fix this as a natural block scalar."
|
|
48
|
+
default: ""
|
|
49
|
+
reindent: 2
|
|
50
|
+
ids:
|
|
51
|
+
- name: recordName
|
|
52
|
+
slot: "${input.recordName}"
|
|
53
|
+
form: tweak-record
|
|
54
|
+
collision:
|
|
55
|
+
project: true
|
|
56
|
+
index: { kind: record, param: name }
|
|
57
|
+
oneOf:
|
|
58
|
+
- [base, type]
|
|
59
|
+
emits:
|
|
60
|
+
# Exactly one of these two fires (oneOf: [base, type], enforced by the
|
|
61
|
+
# engine): a $base clone, or a fresh $type declaration. Both append the
|
|
62
|
+
# record name once, then the hand-authored flats.
|
|
63
|
+
- op: insert-block
|
|
64
|
+
path: "${input.file}"
|
|
65
|
+
when: { inputDefined: base }
|
|
66
|
+
createIfMissing: ""
|
|
67
|
+
anchor: append
|
|
68
|
+
body: |
|
|
69
|
+
${ids.recordName}:
|
|
70
|
+
$base: ${input.base}
|
|
71
|
+
${input.flats}
|
|
72
|
+
- op: insert-block
|
|
73
|
+
path: "${input.file}"
|
|
74
|
+
when: { inputDefined: type }
|
|
75
|
+
createIfMissing: ""
|
|
76
|
+
anchor: append
|
|
77
|
+
body: |
|
|
78
|
+
${ids.recordName}:
|
|
79
|
+
$type: ${input.type}
|
|
80
|
+
${input.flats}
|
|
81
|
+
templates: []
|
|
82
|
+
satisfies:
|
|
83
|
+
- cp2077.tweaks.yaml-lint
|
|
84
|
+
- cp2077.tweaks.base-exists
|
|
85
|
+
- cp2077.tweaks.type-known
|
|
86
|
+
- cp2077.tweaks.flat-name-exists
|
|
87
|
+
- cp2077.tweaks.record-name-exists
|
|
88
|
+
- cp2077.tweaks.append-on-list-flat
|
|
89
|
+
- cp2077.tweaks.dotted-path-same-file
|
|
90
|
+
- cp2077.tweaks.instances-resolve
|
|
91
|
+
manual:
|
|
92
|
+
- title: Confirm in-game
|
|
93
|
+
steps:
|
|
94
|
+
- "Load a save with the mod active and confirm the TweakXL log shows no error for ${input.file}."
|
|
95
|
+
- "Spawn/inspect ${ids.recordName} and confirm the copied flats read as expected."
|
|
96
|
+
expected: "TweakXL-<timestamp>.log carries no error for this file, and the record's flats match the $base plus overrides."
|
|
97
|
+
claim:
|
|
98
|
+
idSuffix: spawns-with-stats
|
|
99
|
+
# Not "$base ${input.base}": a $type-only record has no base, and an
|
|
100
|
+
# unguarded ${input.base} would fail to interpolate in that mode.
|
|
101
|
+
claim: "${ids.recordName} exists in TweakDB with its declared $base or $type and the hand-authored flat overrides applied."
|
|
102
|
+
testRows:
|
|
103
|
+
- gate: T-1
|
|
104
|
+
title: "Record exists with the right base and flats"
|
|
105
|
+
# cp2077.tweakdb.flat needs one concrete <record>.<flat> id, but
|
|
106
|
+
# ${input.flats} is hand-authored free text (no free-form
|
|
107
|
+
# name is trusted to happen to match) — no flat name is fixed
|
|
108
|
+
# here to probe, so only the record's own existence is automated; the
|
|
109
|
+
# flat values themselves stay on the manual checklist above
|
|
110
|
+
# ("confirm the copied flats read as expected").
|
|
111
|
+
expected: "cp2077.tweakdb.record confirms ${ids.recordName} exists."
|
|
112
|
+
manual: false
|
|
113
|
+
probes:
|
|
114
|
+
- kind: cp2077.tweakdb.record
|
|
115
|
+
params: { id: "${ids.recordName}" }
|
|
116
|
+
- gate: T-2
|
|
117
|
+
title: "TweakXL log clean"
|
|
118
|
+
expected: "TweakXL-<timestamp>.log shows no error for this file after a fresh load."
|
|
119
|
+
manual: true
|
|
120
|
+
probeKinds: []
|
|
121
|
+
evidence: ["ModWright research"]
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# new-vehicle-livery (Cyberpunk 2077) — clones a vehicle's `.mlsetup`
|
|
2
|
+
# material with a renamed base material/texture pair, and a TweakXL vehicle
|
|
3
|
+
# record inheriting the base vehicle's own entityTemplate through its `$base`
|
|
4
|
+
# chain (so no new `.ent` is needed for a pure recolor).
|
|
5
|
+
#
|
|
6
|
+
# Observed in game (2026-09): the `baseVehicle` index-ref's `requires`
|
|
7
|
+
# checked `type` against `^gamedataVehicle`, but `chain`'s own `type` field is
|
|
8
|
+
# the record's bare RTTI-derived type name (queries.ts's `latestPointer`), and
|
|
9
|
+
# for every real vehicle record that name is the literal string `Vehicle` —
|
|
10
|
+
# WolvenKit's own naming rule drops both the `gamedata` prefix and `_Record`
|
|
11
|
+
# suffix (`gamedataVehicle_Record` -> `Vehicle`), confirmed in
|
|
12
|
+
# cp2077.wolvenkit.cli.tweak-type-name-drops-gamedata-and-record-suffix.
|
|
13
|
+
# The requirement matches that literal value.
|
|
14
|
+
#
|
|
15
|
+
# `cp2077.vehicles.tweak-name-from-ent` and `cp2077.vehicles.inkatlas-uv-range`
|
|
16
|
+
# are not in `satisfies`: both are file-extension-gated (`v_*.ent.json`,
|
|
17
|
+
# `*.inkatlas.json` respectively) and this scaffold clones only a `.mlsetup`
|
|
18
|
+
# and a tweak record, never an `.ent` or an `.inkatlas`.
|
|
19
|
+
# `cp2077.vehicles.ent-app-resolution`/`appearance-name-resolution`/
|
|
20
|
+
# `inkatlas-part-resolves` stay: all three are project-scoped
|
|
21
|
+
# (`appliesTo: project`), so they genuinely run every time.
|
|
22
|
+
#
|
|
23
|
+
# Observed in game (2026-09): a fresh project reported `clean: false` with
|
|
24
|
+
# `findings: []` — only benign `(listed in satisfies) skipped` reasons. The
|
|
25
|
+
# real offenders were `cp2077.vehicles.cr2w-unique-ids`/`cr2w-enums-are-strings`/
|
|
26
|
+
# `cr2w-resource-path-shape` skipping "no file matched", because this
|
|
27
|
+
# scaffold's `.mlsetup.json` source landed under `sources/...`, which
|
|
28
|
+
# `cyberpunk2077.new-project` declared no project source for, so the
|
|
29
|
+
# validation context never saw it. `new-project` now declares a
|
|
30
|
+
# `sources`-kind project source; every satisfies rule here concerns a file
|
|
31
|
+
# this scaffold writes, once that file is visible at all.
|
|
32
|
+
#
|
|
33
|
+
# The catalog also lists an "`.xl` substitution entry". There is no
|
|
34
|
+
# confirmed shape for how ArchiveXL wires a recolored `.mlsetup` into a
|
|
35
|
+
# vehicle's paint job (`resource.patch`'s own sub-shape, per
|
|
36
|
+
# `cp2077.history.xl-manifest-lint`, is `.ent`-keyed-to-`.ent` only, which a
|
|
37
|
+
# material swap does not fit). Inventing an unconfirmed manifest shape would
|
|
38
|
+
# be guessing; the manual checklist calls out confirming the real mechanism
|
|
39
|
+
# against current ArchiveXL docs instead of shipping a shape nobody has
|
|
40
|
+
# verified.
|
|
41
|
+
id: cyberpunk2077.new-vehicle-livery
|
|
42
|
+
game: cyberpunk2077
|
|
43
|
+
title: New Cyberpunk 2077 vehicle livery
|
|
44
|
+
summary: Clone a vehicle's .mlsetup material with a renamed base material and texture, plus a TweakXL vehicle record inheriting the base vehicle's own entityTemplate.
|
|
45
|
+
modTypes: [vehicle]
|
|
46
|
+
needs: { index: true }
|
|
47
|
+
inputs:
|
|
48
|
+
- type: string
|
|
49
|
+
name: vehicleName
|
|
50
|
+
prompt: "Suffix for the new TweakDB Vehicle.* record, e.g. TestQuartzRecolor."
|
|
51
|
+
pattern: "^[A-Za-z][A-Za-z0-9_]*$"
|
|
52
|
+
- type: index-ref
|
|
53
|
+
name: baseVehicle
|
|
54
|
+
prompt: "$base Vehicle.* TweakDB record this livery inherits from (its entityTemplate is inherited, not restated)."
|
|
55
|
+
lookup: { kind: chain, params: { name: "${input.baseVehicle}" } }
|
|
56
|
+
requires:
|
|
57
|
+
- path: type
|
|
58
|
+
matches: "^Vehicle$"
|
|
59
|
+
reason: "the base's resolved type must be the literal record type \"Vehicle\" — how RTTI type gamedataVehicle_Record is written in .tweak yaml (cp2077.wolvenkit.cli.tweak-type-name-drops-gamedata-and-record-suffix) and what the chain lookup's own type field actually holds for every real vehicle record — or this livery would inherit fields from the wrong record family."
|
|
60
|
+
- type: string
|
|
61
|
+
name: baseMaterialPath
|
|
62
|
+
prompt: "Depot path (backslash, lowercase) to the vanilla/project base .mt this livery's material inherits, e.g. base\\\\materials\\\\metal_painted.mt."
|
|
63
|
+
pattern: "^[a-z0-9_]+(\\\\[a-z0-9_]+)*\\.mt$"
|
|
64
|
+
- type: string
|
|
65
|
+
name: textureBaseColorPath
|
|
66
|
+
prompt: "Depot path (backslash, lowercase) to this livery's own basecolor texture."
|
|
67
|
+
pattern: "^[a-z0-9_]+(\\\\[a-z0-9_]+)*\\.xbm$"
|
|
68
|
+
- type: path
|
|
69
|
+
name: tweaksFile
|
|
70
|
+
prompt: "Destination .yaml under a project source of kind \"tweaks\" (created if missing)."
|
|
71
|
+
mustExist: false
|
|
72
|
+
- type: path
|
|
73
|
+
name: mlsetupOutputFile
|
|
74
|
+
prompt: "Destination for the cloned .mlsetup JSON source."
|
|
75
|
+
mustExist: false
|
|
76
|
+
- type: template-record
|
|
77
|
+
name: mlsetupTemplate
|
|
78
|
+
prompt: "Cached template-record directory (record.json + content.mlsetup) for the .mlsetup this livery clones."
|
|
79
|
+
ids:
|
|
80
|
+
- name: recordName
|
|
81
|
+
slot: "Vehicle.${project.name}_${input.vehicleName}"
|
|
82
|
+
form: tweak-record
|
|
83
|
+
collision:
|
|
84
|
+
project: true
|
|
85
|
+
index: { kind: record, param: name }
|
|
86
|
+
emits:
|
|
87
|
+
- op: insert-block
|
|
88
|
+
path: "${input.tweaksFile}"
|
|
89
|
+
createIfMissing: ""
|
|
90
|
+
anchor: append
|
|
91
|
+
body: |
|
|
92
|
+
${ids.recordName}:
|
|
93
|
+
$base: ${input.baseVehicle}
|
|
94
|
+
- op: write-json-from-template
|
|
95
|
+
path: "${input.mlsetupOutputFile}"
|
|
96
|
+
template: mlsetupTemplate
|
|
97
|
+
rewrite:
|
|
98
|
+
- path: Data.BaseMaterial.DepotPath.$value
|
|
99
|
+
value: "${input.baseMaterialPath}"
|
|
100
|
+
- path: Data.Values.0.v.DepotPath.$value
|
|
101
|
+
value: "${input.textureBaseColorPath}"
|
|
102
|
+
strip: []
|
|
103
|
+
# .mlsetup carries no HandleId/BufferId at all (unlike .ent/.app) — the
|
|
104
|
+
# renumber pass would be a harmless no-op either way, but disabling it
|
|
105
|
+
# names that explicitly rather than relying on it silently doing nothing.
|
|
106
|
+
renumberHandles: false
|
|
107
|
+
templates:
|
|
108
|
+
- ref: mlsetupTemplate
|
|
109
|
+
from: "${template.mlsetupTemplate.contentPath}"
|
|
110
|
+
provenanceFrom: mlsetupTemplate
|
|
111
|
+
satisfies:
|
|
112
|
+
- cp2077.tweaks.yaml-lint
|
|
113
|
+
- cp2077.tweaks.base-exists
|
|
114
|
+
- cp2077.tweaks.type-known
|
|
115
|
+
- cp2077.tweaks.dotted-path-same-file
|
|
116
|
+
- cp2077.tweaks.instances-resolve
|
|
117
|
+
- cp2077.vehicles.ent-app-resolution
|
|
118
|
+
- cp2077.vehicles.appearance-name-resolution
|
|
119
|
+
- cp2077.vehicles.inkatlas-part-resolves
|
|
120
|
+
- cp2077.vehicles.cr2w-unique-ids
|
|
121
|
+
- cp2077.vehicles.cr2w-enums-are-strings
|
|
122
|
+
- cp2077.vehicles.cr2w-resource-path-shape
|
|
123
|
+
- cp2077.vehicles.cr2w-gameversion-header
|
|
124
|
+
- cp2077.history.xl-manifest-lint
|
|
125
|
+
manual:
|
|
126
|
+
- title: Wire the recolor in and paint the texture
|
|
127
|
+
steps:
|
|
128
|
+
- "Confirm, against ArchiveXL's current docs, the real mechanism for pointing ${input.baseVehicle}'s paint job at ${input.mlsetupOutputFile}'s compiled .mlsetup — this scaffold deliberately does not guess at an .xl manifest shape nobody has confirmed (see this file's own header note)."
|
|
129
|
+
- "Paint the basecolor (and normal/roughness, if this material needs them) texture(s) referenced by ${input.textureBaseColorPath}."
|
|
130
|
+
- "Build and deploy, then confirm the vehicle is drivable and the livery is visible from two camera angles."
|
|
131
|
+
expected: "The vehicle spawns drivable with the new livery visible from at least two camera angles, and the base vehicle's own paint jobs are unaffected."
|
|
132
|
+
claim:
|
|
133
|
+
idSuffix: livery-applied
|
|
134
|
+
claim: "${ids.recordName} (based on ${input.baseVehicle}) renders with the ${input.mlsetupOutputFile}-derived livery."
|
|
135
|
+
testRows:
|
|
136
|
+
- gate: L-1
|
|
137
|
+
title: "Vehicle record exists with the right base"
|
|
138
|
+
expected: "cp2077.tweakdb.record confirms ${ids.recordName} exists with $base ${input.baseVehicle}."
|
|
139
|
+
manual: false
|
|
140
|
+
probes:
|
|
141
|
+
- kind: cp2077.tweakdb.record
|
|
142
|
+
params: { id: "${ids.recordName}" }
|
|
143
|
+
- gate: L-2
|
|
144
|
+
title: "Drivable with the livery visible"
|
|
145
|
+
expected: "CET spawn probe confirms the vehicle is drivable and the livery is visible from two camera angles."
|
|
146
|
+
manual: true
|
|
147
|
+
probeKinds: []
|
|
148
|
+
evidence: ["ModWright research"]
|