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,177 @@
|
|
|
1
|
+
# new-workspot-entity (Cyberpunk 2077) — observed in game (2026-09-19).
|
|
2
|
+
#
|
|
3
|
+
# A spawnable entity whose only job is to carry a workspot, so a script can
|
|
4
|
+
# pose any puppet with it: spawn the entity at the puppet's transform, then
|
|
5
|
+
# WorkspotSystem.PlayInDeviceSimple(entity, puppet, false, n"<componentName>",
|
|
6
|
+
# n"", n"", 0.0, WorkspotSlidingBehaviour.DontPlayAtResourcePosition, null)
|
|
7
|
+
# and, when the workspot's animation set has several entries,
|
|
8
|
+
# WorkspotSystem.SendJumpToAnimEnt(puppet, n"<animation>", true).
|
|
9
|
+
# That is exactly how Appearance Menu Mod poses NPCs and spawned V clones
|
|
10
|
+
# (its `base\amm_workspots\entity\workspot_anim.ent`, one
|
|
11
|
+
# `workWorkspotResourceComponent` named `amm_workspot_base`), and what an
|
|
12
|
+
# in-game test confirmed on a spawned `Character.TPP_Player_Cutscene_Female`:
|
|
13
|
+
# `NPCPuppet.ChangeStanceState(Crouch)` sets the blackboard and poses
|
|
14
|
+
# nothing, the workspot kneels it. The game itself ships no entity that is
|
|
15
|
+
# only a workspot (the 2,607 `.workspot` resources under `base\workspots\`
|
|
16
|
+
# are referenced from sector nodes and device entities), which is why a mod
|
|
17
|
+
# that wants a pose must ship its own — and why this scaffold exists rather
|
|
18
|
+
# than a dependency on AMM.
|
|
19
|
+
#
|
|
20
|
+
# The component block is the `workWorkspotResourceComponent` read off the
|
|
21
|
+
# vanilla `base\gameplay\devices\utilities\netrunner\netrunner_chair.ent`
|
|
22
|
+
# (extracted 2026-09-19): `workspotResource` is the one field that matters,
|
|
23
|
+
# the two `*ResourceSync` paths stay unset (uint64 0, as the chair's own
|
|
24
|
+
# personal-link workspot has them), `syncSlotName` None, `shouldCrouch` 0,
|
|
25
|
+
# `parentTransform` null, identity transform. The root is a `gameObject`,
|
|
26
|
+
# not a bare `entEntity`: `PlayInDeviceSimple` takes the device as a
|
|
27
|
+
# `GameObject`, and a script resolving the spawned entity casts it to one
|
|
28
|
+
# (observed in game, 2026-09-19: an `entEntity` root spawned
|
|
29
|
+
# but never cast, so the clone was never posed). The component `id` is
|
|
30
|
+
# fixed above the vanilla range like `new-entity-patch`'s.
|
|
31
|
+
#
|
|
32
|
+
# `workspotResource` is a plain string, not an `index-ref`: the resource
|
|
33
|
+
# index answers existence (`lookup` kind `resource`, `path`), and the
|
|
34
|
+
# manual step says to ask it, but a scaffold that needs the index cannot
|
|
35
|
+
# run in a project without one, and the pose is chosen by eye in any case.
|
|
36
|
+
id: cyberpunk2077.new-workspot-entity
|
|
37
|
+
game: cyberpunk2077
|
|
38
|
+
title: New Cyberpunk 2077 workspot entity (a spawnable pose holder)
|
|
39
|
+
summary: Write a spawnable entity carrying one workWorkspotResourceComponent that points at a vanilla .workspot, plus its deserialize build step, so a script can pose a puppet with PlayInDeviceSimple.
|
|
40
|
+
modTypes: [quickhack, npc, entity-patch]
|
|
41
|
+
needs: {}
|
|
42
|
+
inputs:
|
|
43
|
+
- type: string
|
|
44
|
+
name: modSlug
|
|
45
|
+
prompt: "Lowercase depot folder name for this mod, e.g. mymod (the entity compiles to mod\\\\<slug>\\\\<entityName>.ent)."
|
|
46
|
+
pattern: "^[a-z][a-z0-9_]*$"
|
|
47
|
+
- type: string
|
|
48
|
+
name: entityName
|
|
49
|
+
prompt: "File stem of the entity, e.g. kneel_workspot (source <entityName>.ent.json, compiled <entityName>.ent)."
|
|
50
|
+
pattern: "^[a-z][a-z0-9_]*$"
|
|
51
|
+
- type: string
|
|
52
|
+
name: componentName
|
|
53
|
+
prompt: "Name of the workspot component (what a script passes as actorDataCompName to PlayInDeviceSimple)."
|
|
54
|
+
pattern: "^[A-Za-z][A-Za-z0-9_]*$"
|
|
55
|
+
default: "workspot"
|
|
56
|
+
- type: string
|
|
57
|
+
name: workspotResource
|
|
58
|
+
prompt: "Depot path of the vanilla .workspot the entity plays, backslashes, lowercase, e.g. base\\\\workspots\\\\common\\\\ground\\\\generic__kneel_ground__cover__01.workspot. Confirm it exists with lookup kind resource (path) first."
|
|
59
|
+
pattern: "^[a-z0-9_]+(\\\\[a-z0-9_.]+)+\\.workspot$"
|
|
60
|
+
- type: path
|
|
61
|
+
name: sourceDir
|
|
62
|
+
prompt: "Directory the entity's JSON source is written to, typically sources/<modSlug>."
|
|
63
|
+
mustExist: false
|
|
64
|
+
- type: path
|
|
65
|
+
name: compiledDir
|
|
66
|
+
prompt: "Directory the compiled <entityName>.ent lands in, typically <archive-staging>/<Project>/mod/<modSlug> — the folder the script's ResRef names (mod\\\\<modSlug>\\\\<entityName>.ent)."
|
|
67
|
+
mustExist: false
|
|
68
|
+
ids: []
|
|
69
|
+
emits:
|
|
70
|
+
# One write-text with ifExists: skip, idempotent, for the same reason
|
|
71
|
+
# new-entity-patch gives: an append at `components.-` would grow a second
|
|
72
|
+
# component with the same name and id on a re-run. The depot path does
|
|
73
|
+
# NOT land inside this JSON text: a backslash substituted raw into JSON
|
|
74
|
+
# is an invalid escape (`\w`), and the engine's string context does not
|
|
75
|
+
# JSON-escape. So the body carries an empty `$value` and the structured
|
|
76
|
+
# `insert-xl-entry` below sets the leaf by pointer (a numeric segment
|
|
77
|
+
# indexes the components array), which is also a plain set on a re-run.
|
|
78
|
+
- op: write-text
|
|
79
|
+
path: "${input.sourceDir}/${input.entityName}.ent.json"
|
|
80
|
+
ifExists: skip
|
|
81
|
+
body: |
|
|
82
|
+
{
|
|
83
|
+
"Header": {
|
|
84
|
+
"WolvenKitVersion": "8.20.0",
|
|
85
|
+
"WKitJsonVersion": "0.0.9",
|
|
86
|
+
"GameVersion": 2310,
|
|
87
|
+
"DataType": "CR2W",
|
|
88
|
+
"ArchiveFileName": "${input.entityName}.ent"
|
|
89
|
+
},
|
|
90
|
+
"Data": {
|
|
91
|
+
"Version": 195,
|
|
92
|
+
"BuildVersion": 0,
|
|
93
|
+
"RootChunk": {
|
|
94
|
+
"$type": "entEntityTemplate",
|
|
95
|
+
"appearances": [],
|
|
96
|
+
"components": [
|
|
97
|
+
{
|
|
98
|
+
"$type": "workWorkspotResourceComponent",
|
|
99
|
+
"deviceWorkspotResourceSync": {
|
|
100
|
+
"DepotPath": { "$type": "ResourcePath", "$storage": "uint64", "$value": "0" },
|
|
101
|
+
"Flags": "Default"
|
|
102
|
+
},
|
|
103
|
+
"id": "9020000000000000001",
|
|
104
|
+
"isReplicable": 0,
|
|
105
|
+
"localTransform": {
|
|
106
|
+
"$type": "WorldTransform",
|
|
107
|
+
"Orientation": { "$type": "Quaternion", "i": 0, "j": 0, "k": 0, "r": 1 },
|
|
108
|
+
"Position": {
|
|
109
|
+
"$type": "WorldPosition",
|
|
110
|
+
"x": { "$type": "FixedPoint", "Bits": 0 },
|
|
111
|
+
"y": { "$type": "FixedPoint", "Bits": 0 },
|
|
112
|
+
"z": { "$type": "FixedPoint", "Bits": 0 }
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"name": { "$type": "CName", "$storage": "string", "$value": "${input.componentName}" },
|
|
116
|
+
"npcWorkspotResourceSync": {
|
|
117
|
+
"DepotPath": { "$type": "ResourcePath", "$storage": "uint64", "$value": "0" },
|
|
118
|
+
"Flags": "Default"
|
|
119
|
+
},
|
|
120
|
+
"parentTransform": null,
|
|
121
|
+
"shouldCrouch": 0,
|
|
122
|
+
"syncSlotName": { "$type": "CName", "$storage": "string", "$value": "None" },
|
|
123
|
+
"workspotResource": {
|
|
124
|
+
"DepotPath": { "$type": "ResourcePath", "$storage": "string", "$value": "" },
|
|
125
|
+
"Flags": "Default"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
"cookingPlatform": "PLATFORM_None",
|
|
130
|
+
"defaultAppearance": { "$type": "CName", "$storage": "string", "$value": "default" },
|
|
131
|
+
"entity": {
|
|
132
|
+
"HandleId": "0",
|
|
133
|
+
"Data": { "$type": "gameObject" }
|
|
134
|
+
},
|
|
135
|
+
"includes": [],
|
|
136
|
+
"resolvedDependencies": []
|
|
137
|
+
},
|
|
138
|
+
"EmbeddedFiles": []
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
- op: insert-xl-entry
|
|
142
|
+
path: "${input.sourceDir}/${input.entityName}.ent.json"
|
|
143
|
+
pointer: "Data.RootChunk.components.0.workspotResource.DepotPath.$value"
|
|
144
|
+
value: "${input.workspotResource}"
|
|
145
|
+
- op: patch-project
|
|
146
|
+
add:
|
|
147
|
+
outDir: "archive-staging"
|
|
148
|
+
steps:
|
|
149
|
+
- step: exec
|
|
150
|
+
id: "deserialize-${input.modSlug}-${input.entityName}"
|
|
151
|
+
command: wolvenkit-cli
|
|
152
|
+
args: ["convert", "deserialize", "${input.sourceDir}/${input.entityName}.ent.json", "-o", "${input.compiledDir}"]
|
|
153
|
+
expectOutputs: ["${input.compiledDir}/${input.entityName}.ent"]
|
|
154
|
+
before: stage
|
|
155
|
+
templates: []
|
|
156
|
+
satisfies:
|
|
157
|
+
- cp2077.vehicles.cr2w-unique-ids
|
|
158
|
+
- cp2077.vehicles.cr2w-resource-path-shape
|
|
159
|
+
- cp2077.vehicles.cr2w-gameversion-header
|
|
160
|
+
manual:
|
|
161
|
+
- title: Spawn it and pose a puppet
|
|
162
|
+
steps:
|
|
163
|
+
- "Confirm the workspot exists in the install: lookup kind resource, path ${input.workspotResource}; a count of 0 means the pose will silently not play."
|
|
164
|
+
- "Build, then from a script (Codeware's DynamicEntitySystem, or exEntitySpawner.Spawn from the CET console) spawn mod\\\\${input.modSlug}\\\\${input.entityName}.ent at the puppet's transform, wait for the entity to resolve (one frame; two armed bridge requests), then WorkspotSystem.PlayInDeviceSimple(entity, puppet, false, n\"${input.componentName}\", n\"\", n\"\", 0.0, WorkspotSlidingBehaviour.DontPlayAtResourcePosition, null)."
|
|
165
|
+
- "IsActorInWorkspot(puppet) reads true only a frame after PlayInDeviceSimple, not in the same call; if the puppet stays standing with it true, the workspot's animation does not fit the puppet's rig (observed in game: a player-rig animation did nothing on the cutscene V, the woman-average one posed it) — pick a workspot authored for that rig, or SendJumpToAnimEnt a named animation from the set."
|
|
166
|
+
- "Release with WorkspotSystem.StopInDevice(puppet) before despawning the entity; a puppet left in a workspot whose device vanished keeps the pose."
|
|
167
|
+
expected: "The puppet holds the workspot's pose from the entity's position and facing, and StopInDevice returns it to its own animation."
|
|
168
|
+
claim:
|
|
169
|
+
idSuffix: "${input.entityName}.poses"
|
|
170
|
+
claim: "mod\\${input.modSlug}\\${input.entityName}.ent spawns, and PlayInDeviceSimple on it with actorDataCompName ${input.componentName} puts a puppet into ${input.workspotResource}."
|
|
171
|
+
testRows:
|
|
172
|
+
- gate: P-1
|
|
173
|
+
title: "Spawned workspot entity poses a puppet"
|
|
174
|
+
expected: "Through the bridge, spawn the entity at a spawned puppet, PlayInDeviceSimple, and read IsActorInWorkspot(puppet) true a request later; the pose is visible in game."
|
|
175
|
+
manual: true
|
|
176
|
+
probeKinds: []
|
|
177
|
+
evidence: ["ModWright research"]
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# iconic-weapon (Cyberpunk 2077) — the authoring sequence for a weapon mod:
|
|
2
|
+
# a project, the kitbashed mesh, the item chain, and the world placement of
|
|
3
|
+
# the prop that holds the acquisition. Each step names the asset it needs from the
|
|
4
|
+
# modder at the point it needs it; `scaffold action=plan` asks for exactly
|
|
5
|
+
# those and nothing is guessed. Applying a step is still `scaffold run`.
|
|
6
|
+
id: cyberpunk2077.iconic-weapon
|
|
7
|
+
game: cyberpunk2077
|
|
8
|
+
title: Iconic weapon from nothing
|
|
9
|
+
summary: Project, kitbashed mesh export, TweakXL item chain with its own blueprint and localization, and a world-placed prop for the acquisition.
|
|
10
|
+
modType: weapon
|
|
11
|
+
inputs:
|
|
12
|
+
- name: modName
|
|
13
|
+
prompt: "Mod name, used for the project and its r6/tweaks/<name> and scripts/<name> folders, e.g. MyWeapon."
|
|
14
|
+
- name: modSlug
|
|
15
|
+
prompt: "Lowercase depot folder name, used in every mod\\<slug>\\... path, e.g. myweapon."
|
|
16
|
+
- name: itemName
|
|
17
|
+
prompt: "Item name, used for the TweakDB record and LocKey namespace, e.g. MyWeapon."
|
|
18
|
+
steps:
|
|
19
|
+
- id: project
|
|
20
|
+
scaffold: cyberpunk2077.new-project
|
|
21
|
+
title: The project file and source trees
|
|
22
|
+
skipIf: project-exists
|
|
23
|
+
inputs:
|
|
24
|
+
name: "${sequence.modName}"
|
|
25
|
+
- id: mesh
|
|
26
|
+
scaffold: cyberpunk2077.mesh-export-preset
|
|
27
|
+
title: The mesh export preset (Blender join-by-material export, WolvenKit import over a donor mesh)
|
|
28
|
+
inputs:
|
|
29
|
+
presetId: "${sequence.modSlug}"
|
|
30
|
+
exportScriptFile: "blender/export_${sequence.modSlug}.py"
|
|
31
|
+
glbOutputPath: "${stage}/${sequence.modSlug}.glb"
|
|
32
|
+
outputMeshDir: "archive-staging/${sequence.modName}/mod/${sequence.modSlug}/meshes"
|
|
33
|
+
assets:
|
|
34
|
+
- name: blend
|
|
35
|
+
prompt: "The editable .blend of the kitbash, parts kept as separate objects (e.g. blender/myweapon_kitbash_edit.blend). Path relative to the project."
|
|
36
|
+
inputs: [blendFile]
|
|
37
|
+
- name: donorMesh
|
|
38
|
+
prompt: "The staged vanilla .mesh WolvenKit imports the exported glb over, for its chunkMaterials and skinning (extract it from the base weapon's own archive; keep it under 65,535 vertices per submesh). Path relative to the project."
|
|
39
|
+
inputs: [baseMeshPath]
|
|
40
|
+
- id: chain
|
|
41
|
+
scaffold: cyberpunk2077.new-item-chain
|
|
42
|
+
title: The item chain (TweakXL record, its own blueprint with the iconic slot, factory row, localization, cloned .app)
|
|
43
|
+
inputs:
|
|
44
|
+
itemName: "${sequence.itemName}"
|
|
45
|
+
modSlug: "${sequence.modSlug}"
|
|
46
|
+
tweaksFile: "r6/tweaks/${sequence.modName}/${sequence.modSlug}.yaml"
|
|
47
|
+
xlFile: "archive-staging/${sequence.modName}.archive.xl"
|
|
48
|
+
factoryCsvFile: "archive-staging/${sequence.modName}/mod/${sequence.modSlug}/factory_parts.csv"
|
|
49
|
+
enUsSourceDir: "sources/${sequence.modSlug}"
|
|
50
|
+
entSourceDir: "sources/entities/${sequence.modSlug}"
|
|
51
|
+
entCompiledDir: "archive-staging/${sequence.modName}/mod/${sequence.modSlug}"
|
|
52
|
+
assets:
|
|
53
|
+
- name: appTemplate
|
|
54
|
+
prompt: "The cached template-record directory of the base weapon's own .app (template extract of the .app that weapons_appearances.csv maps the base's appearanceResourceName to, kind weapon-app; it must be the base's kind, or the game hangs on equip). The record.json + content.json directory path."
|
|
55
|
+
inputs: [entTemplate]
|
|
56
|
+
- name: icon
|
|
57
|
+
prompt: "The inventory icon: a PNG authored dark (the png→xbm import lifts gamma in game; power-curve the pixels, ~3.0) and the .inkatlas rectangle it occupies. Not a scaffold input; say where both went."
|
|
58
|
+
- id: place
|
|
59
|
+
scaffold: cyberpunk2077.new-sector-node
|
|
60
|
+
title: The world-placed prop that holds the acquisition (a case, a spec)
|
|
61
|
+
inputs:
|
|
62
|
+
outputDir: "archive-staging/${sequence.modName}/mod/${sequence.modSlug}/sectors"
|
|
63
|
+
outputPath: "archive-staging/${sequence.modName}/mod/${sequence.modSlug}/sectors/${sequence.modSlug}.streamingsector"
|
|
64
|
+
assets:
|
|
65
|
+
- name: sectorSource
|
|
66
|
+
prompt: "The mod's own .streamingsector JSON source (an entSpawner export run through WolvenKit's import script; category Exterior, level 1). Path relative to the project; it must already exist."
|
|
67
|
+
inputs: [file]
|
|
68
|
+
- name: propEntity
|
|
69
|
+
prompt: "Depot path of the .ent the node spawns (backslashes, lowercase), e.g. mod\\myweapon\\cache_case.ent, with an appearanceName the .ent actually declares (a wrong name spawns an invisible entity)."
|
|
70
|
+
inputs: [entityTemplatePath]
|
|
71
|
+
evidence:
|
|
72
|
+
- cp2077.tweakdb.iconic-blueprint-required-for-mod-slot
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# quickhack-takeover (Cyberpunk 2077) — the authoring sequence for a mod that
|
|
2
|
+
# takes an NPC over through a quickhack: a camera patched into NPC archetypes,
|
|
3
|
+
# the control system's quickhack records, and its Mod Settings page.
|
|
4
|
+
#
|
|
5
|
+
# The `hack` step is FIVE `new-tweak` runs, because a quickhack is five records
|
|
6
|
+
# and the plan runs `scaffold run` once per step (a step cannot be several
|
|
7
|
+
# records). Four clone a vanilla `$base` — the objectActionUI interaction, the
|
|
8
|
+
# status effect (the only bridge to script), the cyberdeck program, and the
|
|
9
|
+
# hack itself — and the eligibility wrapper is a `$type: ObjectActionPrereq`
|
|
10
|
+
# record with no base, written through new-tweak's `type` mode.
|
|
11
|
+
#
|
|
12
|
+
# The flats are FIXED here: this sequence records the shape of a working
|
|
13
|
+
# takeover mod, so it encodes the takeover wiring rather than leaving the modder to
|
|
14
|
+
# rediscover it. The four dependent records cross-link by
|
|
15
|
+
# `${steps.<id>.ids.recordName}`, so each names exactly the record the earlier
|
|
16
|
+
# step allocated. Values are that mod's own (memory cost 6, 30 s status duration,
|
|
17
|
+
# Rare program) — a sensible takeover default; the modder edits the produced
|
|
18
|
+
# yaml or tunes at runtime through the Mod Settings page. The flats are written
|
|
19
|
+
# as natural block scalars and normalized to nest under the record by
|
|
20
|
+
# new-tweak's `flats` `reindent`.
|
|
21
|
+
#
|
|
22
|
+
# Target-side registration: the hack only
|
|
23
|
+
# appears on an NPC whose `objectActions` list names it (matched by actionName),
|
|
24
|
+
# so the two `register-*` steps edit `Character.Interactable_NPC_Base` (humans)
|
|
25
|
+
# and `Character.Mechanical_NPC_Base` (mechanicals) — the bases most NPCs
|
|
26
|
+
# inherit their hack list from — with `objectActions: [!append <hack>]` through
|
|
27
|
+
# `edit-tweak`. A handful of NPC families (arasaka, Cerberus,
|
|
28
|
+
# drones, exos in the working mod's own tree) RE-DECLARE their own hack list
|
|
29
|
+
# rather than inheriting; which ones is install-version-specific (found by
|
|
30
|
+
# indexing the install), so registering the hack on those is left to the modder
|
|
31
|
+
# as extra `edit-tweak` runs rather than hardcoded here.
|
|
32
|
+
#
|
|
33
|
+
# Localization: the three `loca-*` steps define the
|
|
34
|
+
# `LocKey#${modName}-Name/-Description/-Ineligible` handles the records
|
|
35
|
+
# reference, each through `new-localization` (one en-us on-screen entry, sharing
|
|
36
|
+
# one source and one deserialize step across the three runs).
|
|
37
|
+
#
|
|
38
|
+
# ONE thing this sequence still does NOT do: the
|
|
39
|
+
# scripted eligibility class `${modName}.${modName}TargetPrereq` is redscript
|
|
40
|
+
# the modder writes; this sequence assumes that name in the wrapper's
|
|
41
|
+
# prereqClassName (ModWright has no redscript scaffold yet).
|
|
42
|
+
id: cyberpunk2077.quickhack-takeover
|
|
43
|
+
game: cyberpunk2077
|
|
44
|
+
title: Quickhack that takes an NPC over
|
|
45
|
+
summary: A camera patched into NPC archetypes, the five-record quickhack chain (interaction, status effect, eligibility wrapper, the hack, the cyberdeck program), and a Mod Settings page.
|
|
46
|
+
modType: quickhack
|
|
47
|
+
inputs:
|
|
48
|
+
- name: modName
|
|
49
|
+
prompt: "Mod name, used for the project and its r6/tweaks/<name> and scripts/<name> folders, e.g. MyTakeover."
|
|
50
|
+
- name: modSlug
|
|
51
|
+
prompt: "Lowercase depot folder name, e.g. mytakeover."
|
|
52
|
+
- name: patchName
|
|
53
|
+
prompt: "File stem of the patch entity, e.g. npc_camera_patch."
|
|
54
|
+
steps:
|
|
55
|
+
- id: project
|
|
56
|
+
scaffold: cyberpunk2077.new-project
|
|
57
|
+
title: The project file and source trees
|
|
58
|
+
skipIf: project-exists
|
|
59
|
+
inputs:
|
|
60
|
+
name: "${sequence.modName}"
|
|
61
|
+
- id: patch
|
|
62
|
+
scaffold: cyberpunk2077.new-entity-patch
|
|
63
|
+
title: The camera patched into the target archetypes
|
|
64
|
+
inputs:
|
|
65
|
+
modSlug: "${sequence.modSlug}"
|
|
66
|
+
patchName: "${sequence.patchName}"
|
|
67
|
+
component: camera
|
|
68
|
+
xlFile: "archive-staging/${sequence.modName}.archive.xl"
|
|
69
|
+
patchSourceDir: "sources/${sequence.modSlug}"
|
|
70
|
+
patchCompiledDir: "archive-staging/${sequence.modName}/mod/${sequence.modSlug}"
|
|
71
|
+
assets:
|
|
72
|
+
- name: targets
|
|
73
|
+
prompt: "The vanilla entity templates to patch, one depot path per line (backslashes, no leading slash, lowercase, .ent) — list them from the install's own archives, not from memory; a working takeover mod patched 426 human NPC archetypes."
|
|
74
|
+
inputs: [targets]
|
|
75
|
+
- id: interaction
|
|
76
|
+
scaffold: cyberpunk2077.new-tweak
|
|
77
|
+
title: The objectActionUI interaction (the hack's on-screen entry)
|
|
78
|
+
inputs:
|
|
79
|
+
file: "r6/tweaks/${sequence.modName}/${sequence.modSlug}.yaml"
|
|
80
|
+
recordName: "Interactions.${sequence.modName}Hack"
|
|
81
|
+
base: Interactions.BlindHack
|
|
82
|
+
flats: |
|
|
83
|
+
name: ${sequence.modName}Hack
|
|
84
|
+
caption: LocKey#${sequence.modName}-Name
|
|
85
|
+
description: LocKey#${sequence.modName}-Description
|
|
86
|
+
captionIcon: ChoiceCaptionParts.CyberwareMalfunctionIcon
|
|
87
|
+
- id: status-effect
|
|
88
|
+
scaffold: cyberpunk2077.new-tweak
|
|
89
|
+
title: The status effect the hack applies (the only bridge to script)
|
|
90
|
+
inputs:
|
|
91
|
+
file: "r6/tweaks/${sequence.modName}/${sequence.modSlug}.yaml"
|
|
92
|
+
recordName: "BaseStatusEffect.${sequence.modName}Takeover"
|
|
93
|
+
base: BaseStatusEffect.WasQuickHacked
|
|
94
|
+
flats: |
|
|
95
|
+
gameplayTags: [Debuff, Quickhack, ${sequence.modName}]
|
|
96
|
+
duration:
|
|
97
|
+
statModifiers:
|
|
98
|
+
- $type: ConstantStatModifier
|
|
99
|
+
statType: BaseStats.MaxDuration
|
|
100
|
+
modifierType: Additive
|
|
101
|
+
value: 30
|
|
102
|
+
- id: wrapper
|
|
103
|
+
scaffold: cyberpunk2077.new-tweak
|
|
104
|
+
title: The eligibility prereq wrapper ($type-only, no vanilla base)
|
|
105
|
+
inputs:
|
|
106
|
+
file: "r6/tweaks/${sequence.modName}/${sequence.modSlug}.yaml"
|
|
107
|
+
recordName: "Prereqs.${sequence.modName}TargetPrereq"
|
|
108
|
+
type: ObjectActionPrereq
|
|
109
|
+
flats: |
|
|
110
|
+
failureConditionPrereq:
|
|
111
|
+
- $type: IPrereq
|
|
112
|
+
prereqClassName: ${sequence.modName}.${sequence.modName}TargetPrereq
|
|
113
|
+
failureExplanation: LocKey#${sequence.modName}-Ineligible
|
|
114
|
+
- id: hack
|
|
115
|
+
scaffold: cyberpunk2077.new-tweak
|
|
116
|
+
title: The quickhack record (QuickHack.BaseBlindHack family), wiring the interaction, status effect and prereq
|
|
117
|
+
inputs:
|
|
118
|
+
file: "r6/tweaks/${sequence.modName}/${sequence.modSlug}.yaml"
|
|
119
|
+
recordName: "QuickHack.${sequence.modName}Hack"
|
|
120
|
+
base: QuickHack.BaseBlindHack
|
|
121
|
+
flats: |
|
|
122
|
+
actionName: ${sequence.modName}
|
|
123
|
+
priority: 1
|
|
124
|
+
objectActionUI: ${steps.interaction.ids.recordName}
|
|
125
|
+
costs:
|
|
126
|
+
- $base: QuickHack.MemoryCostControl
|
|
127
|
+
costMods:
|
|
128
|
+
- $base: QuickHack.MemoryMod
|
|
129
|
+
value: 6
|
|
130
|
+
completionEffects:
|
|
131
|
+
- !append
|
|
132
|
+
statusEffect: ${steps.status-effect.ids.recordName}
|
|
133
|
+
recipient: ObjectActionReference.Target
|
|
134
|
+
targetActivePrereqs:
|
|
135
|
+
- !append ${steps.wrapper.ids.recordName}
|
|
136
|
+
- id: program
|
|
137
|
+
scaffold: cyberpunk2077.new-tweak
|
|
138
|
+
title: The cyberdeck program item that carries the hack
|
|
139
|
+
inputs:
|
|
140
|
+
file: "r6/tweaks/${sequence.modName}/${sequence.modSlug}.yaml"
|
|
141
|
+
recordName: "Items.${sequence.modName}Program"
|
|
142
|
+
base: Items.BlindLvl1Program
|
|
143
|
+
flats: |
|
|
144
|
+
displayName: LocKey#${sequence.modName}-Name
|
|
145
|
+
localizedDescription: LocKey#${sequence.modName}-Description
|
|
146
|
+
quality: Quality.Rare
|
|
147
|
+
objectActions:
|
|
148
|
+
- ItemAction.ProgramDisassemble
|
|
149
|
+
- ${steps.hack.ids.recordName}
|
|
150
|
+
OnAttach:
|
|
151
|
+
- $type: GameplayLogicPackage
|
|
152
|
+
UIData:
|
|
153
|
+
iconPath: ability_utility
|
|
154
|
+
localizedName: LocKey#${sequence.modName}-Name
|
|
155
|
+
localizedDescription: LocKey#${sequence.modName}-Description
|
|
156
|
+
- id: register-humans
|
|
157
|
+
scaffold: cyberpunk2077.edit-tweak
|
|
158
|
+
title: Register the hack on human NPC hack lists (edits Character.Interactable_NPC_Base)
|
|
159
|
+
inputs:
|
|
160
|
+
file: "r6/tweaks/${sequence.modName}/${sequence.modSlug}.yaml"
|
|
161
|
+
recordName: Character.Interactable_NPC_Base
|
|
162
|
+
flats: |
|
|
163
|
+
objectActions:
|
|
164
|
+
- !append ${steps.hack.ids.recordName}
|
|
165
|
+
- id: register-mechanical
|
|
166
|
+
scaffold: cyberpunk2077.edit-tweak
|
|
167
|
+
title: Register the hack on mechanical NPC hack lists (edits Character.Mechanical_NPC_Base)
|
|
168
|
+
inputs:
|
|
169
|
+
file: "r6/tweaks/${sequence.modName}/${sequence.modSlug}.yaml"
|
|
170
|
+
recordName: Character.Mechanical_NPC_Base
|
|
171
|
+
flats: |
|
|
172
|
+
objectActions:
|
|
173
|
+
- !append ${steps.hack.ids.recordName}
|
|
174
|
+
- id: loca-name
|
|
175
|
+
scaffold: cyberpunk2077.new-localization
|
|
176
|
+
title: The player-facing name text (LocKey#<mod>-Name)
|
|
177
|
+
inputs:
|
|
178
|
+
modSlug: "${sequence.modSlug}"
|
|
179
|
+
xlFile: "archive-staging/${sequence.modName}.archive.xl"
|
|
180
|
+
enUsSourceDir: "sources/${sequence.modSlug}"
|
|
181
|
+
entCompiledDir: "archive-staging/${sequence.modName}/mod/${sequence.modSlug}"
|
|
182
|
+
secondaryKey: "${sequence.modName}-Name"
|
|
183
|
+
- id: loca-description
|
|
184
|
+
scaffold: cyberpunk2077.new-localization
|
|
185
|
+
title: The description text (LocKey#<mod>-Description)
|
|
186
|
+
inputs:
|
|
187
|
+
modSlug: "${sequence.modSlug}"
|
|
188
|
+
xlFile: "archive-staging/${sequence.modName}.archive.xl"
|
|
189
|
+
enUsSourceDir: "sources/${sequence.modSlug}"
|
|
190
|
+
entCompiledDir: "archive-staging/${sequence.modName}/mod/${sequence.modSlug}"
|
|
191
|
+
secondaryKey: "${sequence.modName}-Description"
|
|
192
|
+
- id: loca-ineligible
|
|
193
|
+
scaffold: cyberpunk2077.new-localization
|
|
194
|
+
title: The "ineligible target" text (LocKey#<mod>-Ineligible)
|
|
195
|
+
inputs:
|
|
196
|
+
modSlug: "${sequence.modSlug}"
|
|
197
|
+
xlFile: "archive-staging/${sequence.modName}.archive.xl"
|
|
198
|
+
enUsSourceDir: "sources/${sequence.modSlug}"
|
|
199
|
+
entCompiledDir: "archive-staging/${sequence.modName}/mod/${sequence.modSlug}"
|
|
200
|
+
secondaryKey: "${sequence.modName}-Ineligible"
|
|
201
|
+
- id: settings-trigger
|
|
202
|
+
scaffold: cyberpunk2077.new-mod-settings
|
|
203
|
+
title: The Mod Settings page — first setting (a trigger)
|
|
204
|
+
inputs:
|
|
205
|
+
file: "scripts/${sequence.modName}/${sequence.modSlug}_settings.reds"
|
|
206
|
+
className: "${sequence.modName}Settings"
|
|
207
|
+
- id: settings-multiplier
|
|
208
|
+
scaffold: cyberpunk2077.new-mod-settings
|
|
209
|
+
title: The Mod Settings page — second setting (a multiplier), added to the same class
|
|
210
|
+
inputs:
|
|
211
|
+
file: "scripts/${sequence.modName}/${sequence.modSlug}_settings.reds"
|
|
212
|
+
className: "${sequence.modName}Settings"
|
|
213
|
+
evidence: ["ModWright research"]
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# new-cp-patch (Stardew Valley). Appends one
|
|
2
|
+
# patch to an existing pack's content.json, with LogName set, because
|
|
3
|
+
# Content Patcher's troubleshooting guide says to "make sure you set a
|
|
4
|
+
# LogName field ... and then search the SMAPI log file for that name".
|
|
5
|
+
# Limited to the two file-backed actions (Load, EditImage): their required
|
|
6
|
+
# fields are the same three (Target, FromFile, plus the action), every
|
|
7
|
+
# other action needs a body this scaffold cannot author honestly without
|
|
8
|
+
# the data index, and an Include is
|
|
9
|
+
# one line by hand.
|
|
10
|
+
#
|
|
11
|
+
# The asset FromFile names is the author's to supply: this scaffold writes
|
|
12
|
+
# no image. Until it exists, `stardewvalley.content.fromfile-exists` blocks
|
|
13
|
+
# with the file's exact path, which is the scaffold's own next step
|
|
14
|
+
# reported by the postcondition validate rather than a failure of it.
|
|
15
|
+
id: stardewvalley.new-cp-patch
|
|
16
|
+
game: stardewvalley
|
|
17
|
+
title: New Content Patcher patch (Load or EditImage)
|
|
18
|
+
summary: Append one Load or EditImage patch, with a LogName, to an existing pack's content.json; the FromFile asset is the author's to add under the pack.
|
|
19
|
+
modTypes: [content-pack]
|
|
20
|
+
needs: {}
|
|
21
|
+
inputs:
|
|
22
|
+
# A `path`, not a `string`, for the same two reasons every other
|
|
23
|
+
# append-into-an-existing-file scaffold makes its destination one
|
|
24
|
+
# (cyberpunk2077 new-tweak's `file`, new-mod-settings' `file`): the folder
|
|
25
|
+
# has to be there already — `mustExist` refuses a typo before the
|
|
26
|
+
# insert-xl-entry op creates a stray content.json under it, outside every
|
|
27
|
+
# project source where no rule would ever see it — and the engine builds
|
|
28
|
+
# the ledger claim id from the first `string`/`index-ref` input, so leaving
|
|
29
|
+
# the pack folder first would give every patch in one pack the same claim
|
|
30
|
+
# id (a second run is then an idempotent authored→authored no-op that keeps
|
|
31
|
+
# the *first* patch's claim text; `core/ledger/status.ts`). `logName` is the
|
|
32
|
+
# input that actually distinguishes one run from the next.
|
|
33
|
+
- type: path
|
|
34
|
+
name: folder
|
|
35
|
+
mustExist: true
|
|
36
|
+
prompt: The pack folder holding content.json, relative to the project (e.g. "[CP] YourModName"); it must already exist.
|
|
37
|
+
- type: string
|
|
38
|
+
name: logName
|
|
39
|
+
prompt: LogName for the patch — the name to search the SMAPI log for.
|
|
40
|
+
pattern: "^[^\\r\\n]+$"
|
|
41
|
+
- type: enum
|
|
42
|
+
name: action
|
|
43
|
+
prompt: Load replaces the whole asset with FromFile; EditImage edits or overlays part of it.
|
|
44
|
+
values: [Load, EditImage]
|
|
45
|
+
- type: string
|
|
46
|
+
name: target
|
|
47
|
+
prompt: The asset name (no Content/ prefix, no extension, no language code), e.g. "Portraits/Abigail".
|
|
48
|
+
pattern: "^(?!Content/)[^\\\\]+(?<!\\.xnb|\\.png|\\.json|\\.tbin|\\.tmx)$"
|
|
49
|
+
- type: string
|
|
50
|
+
name: fromFile
|
|
51
|
+
prompt: The file to load, relative to the pack folder (the assets/ subfolder by convention), e.g. "assets/abigail.png".
|
|
52
|
+
default: "assets/example.png"
|
|
53
|
+
ids: []
|
|
54
|
+
emits:
|
|
55
|
+
# content.json must already exist (new-project writes it); a missing file
|
|
56
|
+
# would come back as a Changes-only document with no Format, which the
|
|
57
|
+
# format rule then blocks — the report says so rather than guessing one.
|
|
58
|
+
# The append re-serializes the whole document (`emit.ts`), so it parses the
|
|
59
|
+
# file as strict JSON: a content.json carrying the `//` comments or
|
|
60
|
+
# trailing commas Content Patcher's own reader tolerates (and the author
|
|
61
|
+
# guide's examples use) fails the run with a named parse error rather than
|
|
62
|
+
# being silently rewritten without them. Add that patch by hand.
|
|
63
|
+
- op: insert-xl-entry
|
|
64
|
+
path: "${input.folder}/content.json"
|
|
65
|
+
pointer: "Changes.-"
|
|
66
|
+
value:
|
|
67
|
+
LogName: "${input.logName}"
|
|
68
|
+
Action: "${input.action}"
|
|
69
|
+
Target: "${input.target}"
|
|
70
|
+
FromFile: "${input.fromFile}"
|
|
71
|
+
templates: []
|
|
72
|
+
# The rules the appended patch itself must pass. fromfile-exists is
|
|
73
|
+
# deliberately not listed: it is expected to block until the asset is in
|
|
74
|
+
# place (header comment), and a satisfies rule must come back clean.
|
|
75
|
+
satisfies:
|
|
76
|
+
- stardewvalley.content.parses
|
|
77
|
+
- stardewvalley.content.format
|
|
78
|
+
- stardewvalley.content.changes-present
|
|
79
|
+
- stardewvalley.content.patch-action
|
|
80
|
+
- stardewvalley.content.patch-target
|
|
81
|
+
- stardewvalley.content.patch-fields
|
|
82
|
+
- stardewvalley.content.when-tokens
|
|
83
|
+
manual:
|
|
84
|
+
- title: Add the asset
|
|
85
|
+
steps:
|
|
86
|
+
- "Put the image at <folder>/<fromFile>; for a Load it replaces the whole asset, so unpack the original with StardewXnbHack first to match its size."
|
|
87
|
+
- "Re-run validate: stardewvalley.content.fromfile-exists must no longer report the file."
|
|
88
|
+
expected: "validate is clean for the pack."
|
|
89
|
+
- title: Check in game
|
|
90
|
+
steps:
|
|
91
|
+
- "Launch through SMAPI, run `patch summary` in the console, and find the LogName in the table with applied = X."
|
|
92
|
+
- "If it is loaded but not applied, run `patch export \"<target>\"` to see what the game currently has for that asset."
|
|
93
|
+
expected: "The patch shows as loaded and applied under its LogName; the asset in game is the one from FromFile."
|
|
94
|
+
claim:
|
|
95
|
+
idSuffix: patch
|
|
96
|
+
claim: "content.json in ${input.folder} carries a ${input.action} patch \"${input.logName}\" on ${input.target} from ${input.fromFile}."
|
|
97
|
+
testRows:
|
|
98
|
+
- gate: S-1
|
|
99
|
+
title: "Patch applies"
|
|
100
|
+
expected: "`patch summary` lists the LogName with applied = X and the asset in game is the FromFile image."
|
|
101
|
+
manual: true
|
|
102
|
+
probeKinds: []
|
|
103
|
+
evidence:
|
|
104
|
+
- "stardewvalley.contentpatcher.format.five-actions"
|
|
105
|
+
- "stardewvalley.contentpatcher.format.patch-fields"
|
|
106
|
+
- "stardewvalley.contentpatcher.format.patch-console-commands"
|