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.
Files changed (455) hide show
  1. package/LICENSE +35 -0
  2. package/README.md +212 -0
  3. package/assets/claude/agents/mw-explore.md +46 -0
  4. package/assets/claude/agents/mw-fixture.md +33 -0
  5. package/assets/claude/agents/mw-rule-author.md +51 -0
  6. package/assets/claude/agents/mw-scaffold-author.md +48 -0
  7. package/assets/claude/skills/mw-author.md +59 -0
  8. package/assets/claude/skills/mw-new-item.md +51 -0
  9. package/assets/claude/skills/mw-new-spell.md +50 -0
  10. package/assets/claude/skills/mw-scaffold.md +59 -0
  11. package/assets/claude/skills/mw-ship.md +57 -0
  12. package/assets/claude/skills/mw-validate.md +51 -0
  13. package/assets/claude/skills/mw-verify.md +59 -0
  14. package/assets/nivalisnights/extract_resources.py +177 -0
  15. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Config.json +5 -0
  16. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/BootstrapClient.lua +55 -0
  17. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/BootstrapServer.lua +81 -0
  18. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Log.lua +96 -0
  19. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Probes.lua +1038 -0
  20. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/ProbesClient.lua +74 -0
  21. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Protocol.lua +985 -0
  22. package/bridges/bg3-se/Mods/ModWrightBridge/ScriptExtender/Lua/ModWrightBridge/Watch.lua +175 -0
  23. package/bridges/bg3-se/Mods/ModWrightBridge/meta.lsx +45 -0
  24. package/bridges/bg3-se/README.md +99 -0
  25. package/bridges/bg3-se/bridge.json +68 -0
  26. package/bridges/cp2077-cet/ModWrightBridge/init.lua +375 -0
  27. package/bridges/cp2077-cet/ModWrightBridge/probes.lua +1104 -0
  28. package/bridges/cp2077-cet/ModWrightBridge/protocol.lua +1306 -0
  29. package/bridges/cp2077-cet/README.md +165 -0
  30. package/bridges/cp2077-cet/bridge.json +53 -0
  31. package/dist/core/bridge/arm.js +175 -0
  32. package/dist/core/bridge/cet-console.js +26 -0
  33. package/dist/core/bridge/cet-log.js +362 -0
  34. package/dist/core/bridge/index.js +11 -0
  35. package/dist/core/bridge/locate.js +35 -0
  36. package/dist/core/bridge/paths.js +34 -0
  37. package/dist/core/bridge/pending.js +89 -0
  38. package/dist/core/bridge/poll.js +155 -0
  39. package/dist/core/bridge/stage.js +100 -0
  40. package/dist/core/bridge/status.js +97 -0
  41. package/dist/core/bridge/types.js +145 -0
  42. package/dist/core/bridge/validate.js +107 -0
  43. package/dist/core/build/index.js +6 -0
  44. package/dist/core/build/manifest.js +47 -0
  45. package/dist/core/build/paths.js +32 -0
  46. package/dist/core/build/run.js +342 -0
  47. package/dist/core/build/stage.js +265 -0
  48. package/dist/core/build/steps/bg3.js +129 -0
  49. package/dist/core/build/steps/core.js +195 -0
  50. package/dist/core/build/steps/cyberpunk.js +95 -0
  51. package/dist/core/build/steps/listing.js +35 -0
  52. package/dist/core/build/types.js +13 -0
  53. package/dist/core/build/zip.js +148 -0
  54. package/dist/core/compat/check.js +113 -0
  55. package/dist/core/compat/pe.js +220 -0
  56. package/dist/core/compat/types.js +1 -0
  57. package/dist/core/compat/version.js +70 -0
  58. package/dist/core/deploy/guards.js +292 -0
  59. package/dist/core/deploy/index.js +5 -0
  60. package/dist/core/deploy/plan.js +696 -0
  61. package/dist/core/deploy/reload-apply.js +361 -0
  62. package/dist/core/deploy/reload.js +358 -0
  63. package/dist/core/deploy/sources.js +169 -0
  64. package/dist/core/deploy/types.js +1 -0
  65. package/dist/core/epic.js +54 -0
  66. package/dist/core/fsutil.js +191 -0
  67. package/dist/core/home.js +70 -0
  68. package/dist/core/knowledge/facts.js +229 -0
  69. package/dist/core/knowledge/index.js +4 -0
  70. package/dist/core/knowledge/search.js +112 -0
  71. package/dist/core/knowledge/store.js +123 -0
  72. package/dist/core/knowledge/types.js +1 -0
  73. package/dist/core/ledger/check.js +42 -0
  74. package/dist/core/ledger/hooks.js +80 -0
  75. package/dist/core/ledger/index.js +7 -0
  76. package/dist/core/ledger/query.js +17 -0
  77. package/dist/core/ledger/record.js +84 -0
  78. package/dist/core/ledger/status.js +53 -0
  79. package/dist/core/ledger/store.js +98 -0
  80. package/dist/core/ledger/types.js +108 -0
  81. package/dist/core/logs/index.js +4 -0
  82. package/dist/core/logs/registry.js +50 -0
  83. package/dist/core/logs/scan.js +195 -0
  84. package/dist/core/logs/triage.js +160 -0
  85. package/dist/core/logs/types.js +1 -0
  86. package/dist/core/lsx.js +10 -0
  87. package/dist/core/lz4.js +66 -0
  88. package/dist/core/mods.js +229 -0
  89. package/dist/core/process.js +49 -0
  90. package/dist/core/project/build-steps.js +83 -0
  91. package/dist/core/project/describe.js +74 -0
  92. package/dist/core/project/index.js +5 -0
  93. package/dist/core/project/load.js +146 -0
  94. package/dist/core/project/schema.js +264 -0
  95. package/dist/core/project/types.js +3 -0
  96. package/dist/core/prompts.js +72 -0
  97. package/dist/core/registry.js +35 -0
  98. package/dist/core/safety/backup.js +206 -0
  99. package/dist/core/safety/execute.js +188 -0
  100. package/dist/core/safety/index.js +5 -0
  101. package/dist/core/safety/plan.js +122 -0
  102. package/dist/core/safety/restore.js +172 -0
  103. package/dist/core/safety/types.js +1 -0
  104. package/dist/core/scaffold/bootstrap.js +7 -0
  105. package/dist/core/scaffold/catalog.js +28 -0
  106. package/dist/core/scaffold/claude-assets.js +271 -0
  107. package/dist/core/scaffold/collisions.js +64 -0
  108. package/dist/core/scaffold/emit.js +356 -0
  109. package/dist/core/scaffold/engine.js +680 -0
  110. package/dist/core/scaffold/ids.js +78 -0
  111. package/dist/core/scaffold/index.js +10 -0
  112. package/dist/core/scaffold/jsonpath.js +121 -0
  113. package/dist/core/scaffold/load.js +81 -0
  114. package/dist/core/scaffold/render.js +85 -0
  115. package/dist/core/scaffold/sequence.js +396 -0
  116. package/dist/core/scaffold/types.js +309 -0
  117. package/dist/core/steam.js +63 -0
  118. package/dist/core/surfaceutil.js +36 -0
  119. package/dist/core/testplan/check.js +67 -0
  120. package/dist/core/testplan/index.js +5 -0
  121. package/dist/core/testplan/load.js +100 -0
  122. package/dist/core/testplan/registry.js +317 -0
  123. package/dist/core/testplan/run.js +389 -0
  124. package/dist/core/testplan/types.js +82 -0
  125. package/dist/core/text/converters/bg3.js +50 -0
  126. package/dist/core/text/converters/cyberpunk.js +36 -0
  127. package/dist/core/text/converters/index.js +261 -0
  128. package/dist/core/text/diff/cr2w.js +180 -0
  129. package/dist/core/text/diff/index.js +16 -0
  130. package/dist/core/text/diff/loca.js +43 -0
  131. package/dist/core/text/diff/lsx.js +126 -0
  132. package/dist/core/text/handles.js +86 -0
  133. package/dist/core/text/index.js +6 -0
  134. package/dist/core/text/json.js +46 -0
  135. package/dist/core/text/templates/cache.js +71 -0
  136. package/dist/core/text/templates/index.js +3 -0
  137. package/dist/core/text/templates/library.js +245 -0
  138. package/dist/core/text/templates/types.js +51 -0
  139. package/dist/core/text/toolchain.js +16 -0
  140. package/dist/core/text/types.js +1 -0
  141. package/dist/core/text/validate.js +149 -0
  142. package/dist/core/text/xml.js +58 -0
  143. package/dist/core/toolchain/datafetch.js +151 -0
  144. package/dist/core/toolchain/env.js +63 -0
  145. package/dist/core/toolchain/features.js +170 -0
  146. package/dist/core/toolchain/index.js +8 -0
  147. package/dist/core/toolchain/install.js +191 -0
  148. package/dist/core/toolchain/locate.js +275 -0
  149. package/dist/core/toolchain/remember.js +84 -0
  150. package/dist/core/toolchain/run.js +318 -0
  151. package/dist/core/toolchain/specs.js +351 -0
  152. package/dist/core/toolchain/types.js +1 -0
  153. package/dist/core/types.js +1 -0
  154. package/dist/core/userconfig.js +66 -0
  155. package/dist/core/validate/context.js +139 -0
  156. package/dist/core/validate/index.js +5 -0
  157. package/dist/core/validate/registry.js +58 -0
  158. package/dist/core/validate/run.js +131 -0
  159. package/dist/core/validate/suppressions.js +91 -0
  160. package/dist/core/validate/types.js +2 -0
  161. package/dist/core/yamledit.js +51 -0
  162. package/dist/index.js +389 -0
  163. package/dist/server.js +1914 -0
  164. package/dist/surfaces/baldursgate3/compat.js +164 -0
  165. package/dist/surfaces/baldursgate3/identity.js +110 -0
  166. package/dist/surfaces/baldursgate3/index/build.js +331 -0
  167. package/dist/surfaces/baldursgate3/index/index.js +17 -0
  168. package/dist/surfaces/baldursgate3/index/info.js +40 -0
  169. package/dist/surfaces/baldursgate3/index/parsers/loca.js +41 -0
  170. package/dist/surfaces/baldursgate3/index/parsers/lsx.js +137 -0
  171. package/dist/surfaces/baldursgate3/index/parsers/stats.js +45 -0
  172. package/dist/surfaces/baldursgate3/index/parsers/treasuretable.js +57 -0
  173. package/dist/surfaces/baldursgate3/index/parsers/xmlutil.js +142 -0
  174. package/dist/surfaces/baldursgate3/index/queries.js +327 -0
  175. package/dist/surfaces/baldursgate3/index/schema.js +62 -0
  176. package/dist/surfaces/baldursgate3/index.js +3 -0
  177. package/dist/surfaces/baldursgate3/logs.js +278 -0
  178. package/dist/surfaces/baldursgate3/modsettings.js +115 -0
  179. package/dist/surfaces/baldursgate3/pak.js +153 -0
  180. package/dist/surfaces/baldursgate3/settings.js +49 -0
  181. package/dist/surfaces/baldursgate3/surface.js +232 -0
  182. package/dist/surfaces/baldursgate3/validators/bridge.js +7 -0
  183. package/dist/surfaces/baldursgate3/validators/files.js +476 -0
  184. package/dist/surfaces/baldursgate3/validators/items.js +1001 -0
  185. package/dist/surfaces/baldursgate3/validators/progression.js +734 -0
  186. package/dist/surfaces/baldursgate3/validators/stats.js +1076 -0
  187. package/dist/surfaces/baldursgate3/validators/story.js +790 -0
  188. package/dist/surfaces/baldursgate3/validators/templates.js +7 -0
  189. package/dist/surfaces/cyberpunk2077/compat.js +223 -0
  190. package/dist/surfaces/cyberpunk2077/index/build.js +231 -0
  191. package/dist/surfaces/cyberpunk2077/index/index.js +17 -0
  192. package/dist/surfaces/cyberpunk2077/index/info.js +51 -0
  193. package/dist/surfaces/cyberpunk2077/index/model.js +52 -0
  194. package/dist/surfaces/cyberpunk2077/index/parsers/tweak.js +483 -0
  195. package/dist/surfaces/cyberpunk2077/index/parsers/tweakxl-yaml.js +183 -0
  196. package/dist/surfaces/cyberpunk2077/index/queries.js +504 -0
  197. package/dist/surfaces/cyberpunk2077/index/resource.js +135 -0
  198. package/dist/surfaces/cyberpunk2077/index/schema.js +90 -0
  199. package/dist/surfaces/cyberpunk2077/index.js +3 -0
  200. package/dist/surfaces/cyberpunk2077/logs.js +742 -0
  201. package/dist/surfaces/cyberpunk2077/paths.js +12 -0
  202. package/dist/surfaces/cyberpunk2077/surface.js +218 -0
  203. package/dist/surfaces/cyberpunk2077/validators/bridge.js +7 -0
  204. package/dist/surfaces/cyberpunk2077/validators/cr2w.js +349 -0
  205. package/dist/surfaces/cyberpunk2077/validators/garments.js +1181 -0
  206. package/dist/surfaces/cyberpunk2077/validators/mesh.js +338 -0
  207. package/dist/surfaces/cyberpunk2077/validators/modsettings.js +120 -0
  208. package/dist/surfaces/cyberpunk2077/validators/packaging.js +463 -0
  209. package/dist/surfaces/cyberpunk2077/validators/red4ext.js +318 -0
  210. package/dist/surfaces/cyberpunk2077/validators/redscript.js +193 -0
  211. package/dist/surfaces/cyberpunk2077/validators/templates.js +7 -0
  212. package/dist/surfaces/cyberpunk2077/validators/tweaks.js +768 -0
  213. package/dist/surfaces/cyberpunk2077/validators/vehicles.js +531 -0
  214. package/dist/surfaces/cyberpunk2077/validators/xl.js +308 -0
  215. package/dist/surfaces/eldenring/binders.js +111 -0
  216. package/dist/surfaces/eldenring/compat.js +166 -0
  217. package/dist/surfaces/eldenring/dcx.js +49 -0
  218. package/dist/surfaces/eldenring/index.js +13 -0
  219. package/dist/surfaces/eldenring/loaders.js +132 -0
  220. package/dist/surfaces/eldenring/logs.js +67 -0
  221. package/dist/surfaces/eldenring/paramdef.js +256 -0
  222. package/dist/surfaces/eldenring/params.js +129 -0
  223. package/dist/surfaces/eldenring/surface.js +121 -0
  224. package/dist/surfaces/eldenring/tools.js +52 -0
  225. package/dist/surfaces/eldenring/validators/binders.js +193 -0
  226. package/dist/surfaces/eldenring/validators/packages.js +159 -0
  227. package/dist/surfaces/eldenring/validators/params.js +334 -0
  228. package/dist/surfaces/eldenring/validators/profiles.js +287 -0
  229. package/dist/surfaces/index.js +34 -0
  230. package/dist/surfaces/nivalisnights/compat.js +229 -0
  231. package/dist/surfaces/nivalisnights/index/build.js +310 -0
  232. package/dist/surfaces/nivalisnights/index/index.js +5 -0
  233. package/dist/surfaces/nivalisnights/index/queries.js +231 -0
  234. package/dist/surfaces/nivalisnights/index.js +4 -0
  235. package/dist/surfaces/nivalisnights/logs.js +473 -0
  236. package/dist/surfaces/nivalisnights/surface.js +195 -0
  237. package/dist/surfaces/skyrimse/archives.js +229 -0
  238. package/dist/surfaces/skyrimse/compat.js +163 -0
  239. package/dist/surfaces/skyrimse/index.js +12 -0
  240. package/dist/surfaces/skyrimse/loadorder.js +174 -0
  241. package/dist/surfaces/skyrimse/logs.js +241 -0
  242. package/dist/surfaces/skyrimse/plugins.js +149 -0
  243. package/dist/surfaces/skyrimse/records.js +94 -0
  244. package/dist/surfaces/skyrimse/surface.js +240 -0
  245. package/dist/surfaces/skyrimse/validators/archive-records.js +165 -0
  246. package/dist/surfaces/skyrimse/validators/archives.js +110 -0
  247. package/dist/surfaces/skyrimse/validators/plugins.js +374 -0
  248. package/dist/surfaces/skyrimse/validators/records.js +117 -0
  249. package/dist/surfaces/stardewvalley/compat.js +190 -0
  250. package/dist/surfaces/stardewvalley/config.js +42 -0
  251. package/dist/surfaces/stardewvalley/contentpatcher.js +203 -0
  252. package/dist/surfaces/stardewvalley/index/index.js +229 -0
  253. package/dist/surfaces/stardewvalley/index/wiki.js +190 -0
  254. package/dist/surfaces/stardewvalley/index.js +12 -0
  255. package/dist/surfaces/stardewvalley/logs.js +307 -0
  256. package/dist/surfaces/stardewvalley/mods.js +182 -0
  257. package/dist/surfaces/stardewvalley/surface.js +244 -0
  258. package/dist/surfaces/stardewvalley/validators/content.js +321 -0
  259. package/dist/surfaces/stardewvalley/validators/fields.js +147 -0
  260. package/dist/surfaces/stardewvalley/validators/loadorder.js +69 -0
  261. package/dist/surfaces/stardewvalley/validators/manifest.js +221 -0
  262. package/dist/surfaces/subnautica2/compat.js +138 -0
  263. package/dist/surfaces/subnautica2/index.js +5 -0
  264. package/dist/surfaces/subnautica2/logs.js +129 -0
  265. package/dist/surfaces/subnautica2/paks.js +173 -0
  266. package/dist/surfaces/subnautica2/surface.js +151 -0
  267. package/dist/surfaces/subnautica2/validators/packaging.js +298 -0
  268. package/dist/surfaces/valheim/compat.js +171 -0
  269. package/dist/surfaces/valheim/index/index.js +301 -0
  270. package/dist/surfaces/valheim/index/tables.js +103 -0
  271. package/dist/surfaces/valheim/index.js +11 -0
  272. package/dist/surfaces/valheim/logs.js +197 -0
  273. package/dist/surfaces/valheim/packaging.js +131 -0
  274. package/dist/surfaces/valheim/plugins.js +270 -0
  275. package/dist/surfaces/valheim/references.js +121 -0
  276. package/dist/surfaces/valheim/surface.js +223 -0
  277. package/dist/surfaces/valheim/validators/packaging.js +218 -0
  278. package/dist/surfaces/valheim/validators/plugins.js +287 -0
  279. package/dist/surfaces/valheim/validators/references.js +169 -0
  280. package/knowledge/baldursgate3/animations.gr2.yaml +166 -0
  281. package/knowledge/baldursgate3/audio.voice.yaml +182 -0
  282. package/knowledge/baldursgate3/audio.wwise.yaml +104 -0
  283. package/knowledge/baldursgate3/charactercreation.heads-hair.yaml +193 -0
  284. package/knowledge/baldursgate3/communitylibrary.shared-content.yaml +129 -0
  285. package/knowledge/baldursgate3/compatibilityframework.api.yaml +176 -0
  286. package/knowledge/baldursgate3/crash.causes.yaml +90 -0
  287. package/knowledge/baldursgate3/dialogue.dialogbank.yaml +120 -0
  288. package/knowledge/baldursgate3/dialogue.files.yaml +236 -0
  289. package/knowledge/baldursgate3/dialogue.osiris-goals.yaml +386 -0
  290. package/knowledge/baldursgate3/dialogue.yaml +122 -0
  291. package/knowledge/baldursgate3/feats.classes.yaml +164 -0
  292. package/knowledge/baldursgate3/items.cloth-physics.yaml +167 -0
  293. package/knowledge/baldursgate3/items.roottemplates.yaml +320 -0
  294. package/knowledge/baldursgate3/items.visualbank.yaml +628 -0
  295. package/knowledge/baldursgate3/journal.quests.yaml +214 -0
  296. package/knowledge/baldursgate3/loadorder.modsettings.yaml +128 -0
  297. package/knowledge/baldursgate3/localization.handles.yaml +92 -0
  298. package/knowledge/baldursgate3/misc.encoding-and-practice.yaml +111 -0
  299. package/knowledge/baldursgate3/origins.companions.yaml +144 -0
  300. package/knowledge/baldursgate3/osiris.signatures.yaml +211 -0
  301. package/knowledge/baldursgate3/packaging.meta.yaml +155 -0
  302. package/knowledge/baldursgate3/packaging.paks.yaml +79 -0
  303. package/knowledge/baldursgate3/process.launch.yaml +34 -0
  304. package/knowledge/baldursgate3/progressions.yaml +92 -0
  305. package/knowledge/baldursgate3/publishing.modio-nexus.yaml +170 -0
  306. package/knowledge/baldursgate3/publishing.toolkit-modio.yaml +135 -0
  307. package/knowledge/baldursgate3/races.progression.yaml +228 -0
  308. package/knowledge/baldursgate3/scriptextender.console.yaml +257 -0
  309. package/knowledge/baldursgate3/scriptextender.yaml +252 -0
  310. package/knowledge/baldursgate3/stats.boosts.yaml +293 -0
  311. package/knowledge/baldursgate3/stats.equipment-kits.yaml +69 -0
  312. package/knowledge/baldursgate3/stats.interrupts.yaml +45 -0
  313. package/knowledge/baldursgate3/stats.itemcombos.yaml +65 -0
  314. package/knowledge/baldursgate3/stats.spells.yaml +293 -0
  315. package/knowledge/baldursgate3/stats.weapons.yaml +210 -0
  316. package/knowledge/baldursgate3/toolchain.divine.yaml +179 -0
  317. package/knowledge/baldursgate3/toolchain.lslib-formats.yaml +242 -0
  318. package/knowledge/baldursgate3/toolkit.levels.yaml +177 -0
  319. package/knowledge/baldursgate3/ui.icons-atlas.yaml +78 -0
  320. package/knowledge/baldursgate3/ui.icons.yaml +412 -0
  321. package/knowledge/baldursgate3/ui.mcm.yaml +161 -0
  322. package/knowledge/baldursgate3/vfx.materials.yaml +174 -0
  323. package/knowledge/baldursgate3/visuals.characterfix.yaml +73 -0
  324. package/knowledge/cyberpunk2077/animations.anims.yaml +118 -0
  325. package/knowledge/cyberpunk2077/anims.archivexl.yaml +163 -0
  326. package/knowledge/cyberpunk2077/anims.authoring.yaml +579 -0
  327. package/knowledge/cyberpunk2077/anims.encoder.yaml +156 -0
  328. package/knowledge/cyberpunk2077/anims.graph.yaml +629 -0
  329. package/knowledge/cyberpunk2077/anims.method.yaml +360 -0
  330. package/knowledge/cyberpunk2077/anims.pipeline.yaml +352 -0
  331. package/knowledge/cyberpunk2077/anims.roundtrip.yaml +222 -0
  332. package/knowledge/cyberpunk2077/anims.sets.yaml +176 -0
  333. package/knowledge/cyberpunk2077/archivexl.bodytypes.yaml +149 -0
  334. package/knowledge/cyberpunk2077/archivexl.dynamic-appearances.yaml +218 -0
  335. package/knowledge/cyberpunk2077/archivexl.manifest.yaml +214 -0
  336. package/knowledge/cyberpunk2077/audio.events.yaml +168 -0
  337. package/knowledge/cyberpunk2077/audio.sounds.yaml +164 -0
  338. package/knowledge/cyberpunk2077/audio.voicesets.yaml +146 -0
  339. package/knowledge/cyberpunk2077/cet.sandbox.yaml +219 -0
  340. package/knowledge/cyberpunk2077/clothing.garments.yaml +283 -0
  341. package/knowledge/cyberpunk2077/clothing.refits.yaml +215 -0
  342. package/knowledge/cyberpunk2077/codeware.overview.yaml +111 -0
  343. package/knowledge/cyberpunk2077/codeware.systems.yaml +192 -0
  344. package/knowledge/cyberpunk2077/drones.combat.yaml +416 -0
  345. package/knowledge/cyberpunk2077/drones.control.yaml +552 -0
  346. package/knowledge/cyberpunk2077/entities.appearance.yaml +166 -0
  347. package/knowledge/cyberpunk2077/equipmentex.slots.yaml +151 -0
  348. package/knowledge/cyberpunk2077/fx.effects.yaml +246 -0
  349. package/knowledge/cyberpunk2077/fx.lights.yaml +171 -0
  350. package/knowledge/cyberpunk2077/hair.modding.yaml +145 -0
  351. package/knowledge/cyberpunk2077/items.wiring.yaml +246 -0
  352. package/knowledge/cyberpunk2077/loadorder.archives.yaml +71 -0
  353. package/knowledge/cyberpunk2077/mesh.blender.yaml +209 -0
  354. package/knowledge/cyberpunk2077/nativedb.dump.yaml +98 -0
  355. package/knowledge/cyberpunk2077/npc.appearance.yaml +275 -0
  356. package/knowledge/cyberpunk2077/npc.behaviour.yaml +128 -0
  357. package/knowledge/cyberpunk2077/npc.locomotion.yaml +490 -0
  358. package/knowledge/cyberpunk2077/packaging.deploy.yaml +175 -0
  359. package/knowledge/cyberpunk2077/packaging.variants.yaml +176 -0
  360. package/knowledge/cyberpunk2077/player.control.yaml +918 -0
  361. package/knowledge/cyberpunk2077/process.assetbuild.yaml +154 -0
  362. package/knowledge/cyberpunk2077/process.lessons.yaml +276 -0
  363. package/knowledge/cyberpunk2077/quests.minor.yaml +46 -0
  364. package/knowledge/cyberpunk2077/quests.scenes.yaml +282 -0
  365. package/knowledge/cyberpunk2077/quickhacks.tiers.yaml +41 -0
  366. package/knowledge/cyberpunk2077/red4ext.api.yaml +645 -0
  367. package/knowledge/cyberpunk2077/red4ext.plugins.yaml +124 -0
  368. package/knowledge/cyberpunk2077/redhottools.hotreload.yaml +245 -0
  369. package/knowledge/cyberpunk2077/redscript.compile-log.yaml +76 -0
  370. package/knowledge/cyberpunk2077/redscript.modules.yaml +118 -0
  371. package/knowledge/cyberpunk2077/toolchain.wolvenkit.yaml +163 -0
  372. package/knowledge/cyberpunk2077/tweakdb.loot-recipes.yaml +184 -0
  373. package/knowledge/cyberpunk2077/tweakdb.melee.yaml +352 -0
  374. package/knowledge/cyberpunk2077/tweakdb.weapons.yaml +325 -0
  375. package/knowledge/cyberpunk2077/tweakxl.hotreload.yaml +151 -0
  376. package/knowledge/cyberpunk2077/tweakxl.yaml-syntax.yaml +208 -0
  377. package/knowledge/cyberpunk2077/ui.icons.yaml +259 -0
  378. package/knowledge/cyberpunk2077/ui.inkatlas.yaml +81 -0
  379. package/knowledge/cyberpunk2077/ui.modsettings.yaml +204 -0
  380. package/knowledge/cyberpunk2077/vehicles.control.yaml +475 -0
  381. package/knowledge/cyberpunk2077/vehicles.dashboard-ui.yaml +203 -0
  382. package/knowledge/cyberpunk2077/vehicles.entities.yaml +195 -0
  383. package/knowledge/cyberpunk2077/vehicles.wiring.yaml +137 -0
  384. package/knowledge/cyberpunk2077/wolvenkit.cli.yaml +167 -0
  385. package/knowledge/cyberpunk2077/workspot.system.yaml +55 -0
  386. package/knowledge/cyberpunk2077/world.interactions.yaml +41 -0
  387. package/knowledge/cyberpunk2077/world.loot-container.yaml +167 -0
  388. package/knowledge/cyberpunk2077/world.sectors.yaml +233 -0
  389. package/knowledge/eldenring/formats.binders.yaml +237 -0
  390. package/knowledge/eldenring/launcher.me3.yaml +230 -0
  391. package/knowledge/eldenring/launcher.modengine2.yaml +119 -0
  392. package/knowledge/eldenring/params.paramdef.yaml +149 -0
  393. package/knowledge/eldenring/params.regulation.yaml +142 -0
  394. package/knowledge/eldenring/saves.online.yaml +118 -0
  395. package/knowledge/eldenring/toolchain.cli.yaml +256 -0
  396. package/knowledge/nivalisnights/modding.runtime.yaml +157 -0
  397. package/knowledge/skyrimse/archives.bsa.yaml +212 -0
  398. package/knowledge/skyrimse/install.detection.yaml +41 -0
  399. package/knowledge/skyrimse/loadorder.files.yaml +242 -0
  400. package/knowledge/skyrimse/plugins.esl.yaml +189 -0
  401. package/knowledge/skyrimse/plugins.format.yaml +224 -0
  402. package/knowledge/skyrimse/skse.runtime.yaml +283 -0
  403. package/knowledge/skyrimse/toolchain.xedit-spriggit.yaml +336 -0
  404. package/knowledge/stardewvalley/contentpatcher.format.yaml +338 -0
  405. package/knowledge/stardewvalley/distribution.channels.yaml +236 -0
  406. package/knowledge/stardewvalley/game.versions.yaml +202 -0
  407. package/knowledge/stardewvalley/install.layout.yaml +277 -0
  408. package/knowledge/stardewvalley/smapi.loader.yaml +284 -0
  409. package/knowledge/stardewvalley/smapi.logs.yaml +329 -0
  410. package/knowledge/stardewvalley/smapi.manifest.yaml +293 -0
  411. package/knowledge/stardewvalley/toolchain.build.yaml +261 -0
  412. package/knowledge/stardewvalley/wiki.dataformat.yaml +130 -0
  413. package/knowledge/subnautica2/game.build.yaml +331 -0
  414. package/knowledge/subnautica2/modding.state.yaml +210 -0
  415. package/knowledge/subnautica2/ue5.containers.yaml +72 -0
  416. package/knowledge/subnautica2/ue5.paks.yaml +203 -0
  417. package/knowledge/subnautica2/ue5.tooling.yaml +175 -0
  418. package/knowledge/subnautica2/ue5.ue4ss.yaml +203 -0
  419. package/knowledge/valheim/bepinex.loader.yaml +247 -0
  420. package/knowledge/valheim/bepinex.plugins.yaml +251 -0
  421. package/knowledge/valheim/game.versions.yaml +321 -0
  422. package/knowledge/valheim/install.layout.yaml +216 -0
  423. package/knowledge/valheim/jotunn.library.yaml +334 -0
  424. package/knowledge/valheim/thunderstore.packaging.yaml +217 -0
  425. package/knowledge/valheim/toolchain.build.yaml +111 -0
  426. package/package.json +29 -0
  427. package/scaffolds/baldursgate3/new-class-injection.yaml +148 -0
  428. package/scaffolds/baldursgate3/new-item.yaml +264 -0
  429. package/scaffolds/baldursgate3/new-mod.yaml +174 -0
  430. package/scaffolds/baldursgate3/new-passive.yaml +100 -0
  431. package/scaffolds/baldursgate3/new-project.yaml +118 -0
  432. package/scaffolds/baldursgate3/new-quest-stub.yaml +159 -0
  433. package/scaffolds/baldursgate3/new-spell.yaml +102 -0
  434. package/scaffolds/baldursgate3/new-status.yaml +119 -0
  435. package/scaffolds/baldursgate3/sequences/subclass-kit.yaml +50 -0
  436. package/scaffolds/cyberpunk2077/edit-tweak.yaml +70 -0
  437. package/scaffolds/cyberpunk2077/mesh-export-preset.yaml +170 -0
  438. package/scaffolds/cyberpunk2077/new-entity-patch.yaml +255 -0
  439. package/scaffolds/cyberpunk2077/new-garment-refit.yaml +279 -0
  440. package/scaffolds/cyberpunk2077/new-item-chain.yaml +548 -0
  441. package/scaffolds/cyberpunk2077/new-localization.yaml +130 -0
  442. package/scaffolds/cyberpunk2077/new-mod-settings.yaml +133 -0
  443. package/scaffolds/cyberpunk2077/new-player-replacer.yaml +1003 -0
  444. package/scaffolds/cyberpunk2077/new-project.yaml +157 -0
  445. package/scaffolds/cyberpunk2077/new-sector-node.yaml +156 -0
  446. package/scaffolds/cyberpunk2077/new-tweak.yaml +121 -0
  447. package/scaffolds/cyberpunk2077/new-vehicle-livery.yaml +148 -0
  448. package/scaffolds/cyberpunk2077/new-workspot-entity.yaml +177 -0
  449. package/scaffolds/cyberpunk2077/sequences/iconic-weapon.yaml +72 -0
  450. package/scaffolds/cyberpunk2077/sequences/quickhack-takeover.yaml +213 -0
  451. package/scaffolds/stardewvalley/new-cp-patch.yaml +106 -0
  452. package/scaffolds/stardewvalley/new-csharp-mod.yaml +195 -0
  453. package/scaffolds/stardewvalley/new-project.yaml +184 -0
  454. package/scaffolds/stardewvalley/sequences/content-pack.yaml +31 -0
  455. package/scripts/mw-tool.mjs +184 -0
@@ -0,0 +1,1003 @@
1
+ # new-player-replacer (Cyberpunk 2077), Part A: the body (decided
2
+ # 2026-09-24: the body alone first, the take later).
3
+ #
4
+ # A replacer is a second PlayerPuppet the engine switches the player into:
5
+ # V's own FPP entity template with its `appearances` pointed at another
6
+ # `.app`, spawned from a Character record that derives
7
+ # Character.Player_Replacer_Puppet_Base, and switched to by the quest node
8
+ # questReplacer_NodeType. The node's enable only stores a body the
9
+ # community system spawned (fact
10
+ # cp2077.player.control.replacer-enable-stores-the-body-through-its-entity-stub),
11
+ # so the body comes with the world pieces that spawn it that way. A working
12
+ # android-body mod ships all of this by hand; this scaffold is that work
13
+ # with the mod's names turned into inputs. Every value in the three world
14
+ # resources below is hand-written; nothing is copied from a game file, and
15
+ # the entity comes from the user's install through the template cache at
16
+ # scaffold time, as in new-entity-patch and new-item-chain.
17
+ #
18
+ # What it writes (one run per body):
19
+ # 1. `<body>.ent.json` — the template, rewritten:
20
+ # - `appearances` replaced by one entry wearing `appearanceName` from
21
+ # `targetApp` (the entity-level name is the .app's own), and
22
+ # `defaultAppearance` set to it; plus one entry per `extraLooks` row
23
+ # (optional, empty by default: `entityName|appearanceName|app`), so
24
+ # a mod can switch the body to the look of the target it took over
25
+ # (the 2.0 android templates wear 28 looks from two .apps under
26
+ # entity-level names such as corpo__android_ma_militech_droid__lvl2_01;
27
+ # fact cp2077.npc.appearance.world-androids-use-the-2-0-templates);
28
+ # - the `hud_component` pointed at V's HUD (prototype_hud.inkhud with
29
+ # ui_main_hud.mt), in the component list and in the compiled package.
30
+ # The android replacer loads mq060's showroom proxy HUD
31
+ # (cp2077.player.control.android-replacer-loads-the-showroom-hud);
32
+ # A mod can fix that with an ArchiveXL patch entity on the vanilla
33
+ # template. Here the mod owns the copy, so the change is made in the
34
+ # copy and no patch entity is needed. On V's own template the rewrite
35
+ # restates what is there.
36
+ # The template must be on the rig family's player skeleton (the
37
+ # `require` below): the replacer is V's skeleton, so only same-rig
38
+ # humans and the androids can be worn.
39
+ # 2. A TweakXL record deriving Character.Player_Replacer_Puppet_Base. Its
40
+ # flats follow Character.android_replacer (read from the vanilla index,
41
+ # 2026-09-24): entityTemplatePath and appearanceName; persistentName
42
+ # emptied (the base's "#player_current_object" is V's); savable;
43
+ # priority Quest; no item groups; the android's five attachment slots.
44
+ # The android's own stat modifiers (no RAM or health regen, half
45
+ # visibility) are left out as a showroom choice, and the stat pools
46
+ # are inherited from the player (V's RAM among them).
47
+ # 3. The AlwaysLoaded streaming sector (the community registry with one
48
+ # entry, the compiled community area, one AI spot), its streaming
49
+ # block, and a quest phase ArchiveXL merges into the main quest and
50
+ # the Phantom Liberty standalone quest. The phase runs two loops from
51
+ # its input node, each gated on a fact:
52
+ # <body>_spawn >= 1 -> community Activate; == 0 -> Deactivate
53
+ # <body>_replacer >= 1 -> questReplacer_NodeType enable 1 on the
54
+ # entry; == 0 -> enable 0
55
+ # Handles are named for what they are (`spawnWaitOn.In`,
56
+ # `start.Out->spawnWaitOn.In`) and numbered by the engine in encounter
57
+ # order, which keeps the numbering stable between runs.
58
+ # 4. The .xl entries: `streaming.blocks` and `quest.phases` (appended
59
+ # once each, `unique`), and four deserialize build steps.
60
+ #
61
+ # NodeRefs: the community and the spot are
62
+ # `$/03_night_city/#<nodeRefGroup>/#<body>_community` and `..._spot`; their
63
+ # ids are FNV-1a 64 of the same path with the `#` marks left out
64
+ # (cp2077.quests.scenes.noderef-hash-is-fnv-of-the-path-without-hash-marks),
65
+ # the `fnv1a64` id form over the mark-free slot. The quest names the
66
+ # community by its alias `#<body>_community`, as vanilla does. The spot's
67
+ # persistent position is FixedPoint bits (metres x 2^17), the `fixed-point`
68
+ # id form. The spot's orientation is fixed (yaw 0).
69
+ #
70
+ # Not here (Part B): the take (the lead, the guard, the
71
+ # first-person pass, the carry-in and carry-back, the release), the target
72
+ # hide, and the plugin the switch needs. The `<body>_replacer` loop runs
73
+ # the vanilla node, and on its own that switch crashed at the body's first
74
+ # resize event (observed in game); it held only with a plugin guarding the
75
+ # resize handler. The manual checklist says so.
76
+ id: cyberpunk2077.new-player-replacer
77
+ game: cyberpunk2077
78
+ title: New Cyberpunk 2077 player replacer body (a playable body for a same-rig target)
79
+ summary: Copy a replacer entity template from the install with its appearance pointed at a target's .app and V's HUD, derive a TweakXL record from Character.Player_Replacer_Puppet_Base, and write the community sector, streaming block and fact-gated quest phase that spawn it and run the replacer switch, with the .xl entries and build steps.
80
+ modTypes: [player-replacer, npc, quickhack]
81
+ needs: { index: true }
82
+ inputs:
83
+ - type: string
84
+ name: modSlug
85
+ prompt: "Lowercase depot folder name for this mod, e.g. mymod. The body's files compile to mod\\<modSlug>\\<bodyName>\\."
86
+ pattern: "^[a-z][a-z0-9_]*$"
87
+ - type: string
88
+ name: bodyName
89
+ prompt: "Lowercase name for this body, e.g. my_body. It names the files, the NodeRefs (#<bodyName>_community, #<bodyName>_spot) and the two facts (<bodyName>_spawn, <bodyName>_replacer)."
90
+ pattern: "^[a-z][a-z0-9_]*$"
91
+ - type: string
92
+ name: nodeRefGroup
93
+ prompt: "The NodeRef group the community and the spot sit under, e.g. mymod for $/03_night_city/#mymod/#<bodyName>_community. Keep it unique to the mod."
94
+ pattern: "^[a-z][a-z0-9_]*$"
95
+ - type: string
96
+ name: entryName
97
+ prompt: "The community entry's name, the name a script passes to GetFixedEntityIdsFromSpawnerEntityID to find the body, e.g. android_replacer, or the body name."
98
+ pattern: "^[a-z][a-z0-9_]*$"
99
+ - type: string
100
+ name: recordName
101
+ prompt: "The body's TweakDB record, e.g. Character.my_android_body."
102
+ pattern: "^Character\\.[A-Za-z][A-Za-z0-9_]*$"
103
+ - type: enum
104
+ name: rigFamily
105
+ prompt: "The rig family of the target and of the template: man (the _ma bodies, player_man_skeleton.rig) or woman (the _wa bodies, player_woman_skeleton.rig)."
106
+ values: [man, woman]
107
+ - type: template-record
108
+ name: template
109
+ prompt: "Template cache directory of the replacer entity, extracted from your install with the template tool: base\\quest\\minor_quests\\mq060\\entities\\mq060_android_replacer_v2.ent (the man android; _v2_f.ent for the woman) or base\\characters\\entities\\player\\player_ma_fpp.ent / player_wa_fpp.ent (V herself, for a human target). It must be on the rig family's skeleton."
110
+ - type: string
111
+ name: targetApp
112
+ prompt: "Depot path of the target's .app, e.g. base\\characters\\appearances\\corpo\\corpo__android_ma.app. Backslashes, lowercase, no leading slash."
113
+ pattern: "^[a-z0-9_]+(\\\\[a-z0-9_.]+)+\\.app$"
114
+ - type: string
115
+ name: appearanceName
116
+ prompt: "The appearance in that .app the body wears, e.g. arasaka_droid__lvl2_01. It is also the entity's appearance name, the record's appearanceName and the community phase's appearance."
117
+ pattern: "^[A-Za-z0-9_]+$"
118
+ - type: list
119
+ name: extraLooks
120
+ prompt: "Optional further looks the body can switch to, one per line: entityName|appearanceName|app, e.g. corpo__android_ma_militech_droid__lvl2_01|militech_droid__lvl2_01|base\\characters\\appearances\\corpo\\corpo__android_ma.app. Each becomes an entity appearance named entityName, wearing appearanceName from app. Empty by default (the body wears appearanceName only)."
121
+ itemPattern: "^[A-Za-z0-9_]+\\|[A-Za-z0-9_]+\\|[a-z0-9_]+(\\\\[a-z0-9_.]+)+\\.app$"
122
+ minItems: 0
123
+ default: ""
124
+ - type: number
125
+ name: spotX
126
+ prompt: "World X of the spot where the body waits after it spawns (metres)."
127
+ - type: number
128
+ name: spotY
129
+ prompt: "World Y of the spot."
130
+ - type: number
131
+ name: spotZ
132
+ prompt: "World Z of the spot (the spot snaps to the ground)."
133
+ - type: string
134
+ name: spotWorkspot
135
+ prompt: "The workspot resource the spot carries (the body stands at it)."
136
+ pattern: "^[a-z0-9_]+(\\\\[a-z0-9_.]+)+\\.workspot$"
137
+ default: "base\\workspots\\common\\ground\\generic__stand_ground__guard__01.workspot"
138
+ - type: path
139
+ name: tweaksFile
140
+ prompt: "A TweakXL .yaml of the body's own for the record, under a project source of kind tweaks, e.g. r6/tweaks/<Project>/<bodyName>.yaml. Every apply rewrites it whole, so keep nothing else in it."
141
+ mustExist: false
142
+ - type: path
143
+ name: xlFile
144
+ prompt: "The mod's .archive.xl manifest (created if missing), beside the staged folder, e.g. archive-staging/<Project>.archive.xl."
145
+ mustExist: false
146
+ - type: path
147
+ name: sourceDir
148
+ prompt: "Directory for the four JSON sources, e.g. sources/<modSlug>/<bodyName>."
149
+ mustExist: false
150
+ - type: path
151
+ name: archiveStagingDir
152
+ prompt: "The staged archive folder the deserialized resources go under, e.g. archive-staging/<Project>. They land in <archiveStagingDir>/mod/<modSlug>/<bodyName>/."
153
+ mustExist: false
154
+ ids:
155
+ # The record's name is checked against the vanilla index only: the
156
+ # project check would find the scaffold's own earlier record in
157
+ # tweaksFile and refuse every re-apply.
158
+ - name: recordName
159
+ slot: "${input.recordName}"
160
+ form: tweak-record
161
+ collision:
162
+ project: false
163
+ index: { kind: record, param: name }
164
+ - name: communityId
165
+ slot: "$/03_night_city/${input.nodeRefGroup}/${input.bodyName}_community"
166
+ form: fnv1a64
167
+ - name: spotId
168
+ slot: "$/03_night_city/${input.nodeRefGroup}/${input.bodyName}_spot"
169
+ form: fnv1a64
170
+ - name: spotXBits
171
+ slot: "${input.spotX}"
172
+ form: fixed-point
173
+ - name: spotYBits
174
+ slot: "${input.spotY}"
175
+ form: fixed-point
176
+ - name: spotZBits
177
+ slot: "${input.spotZ}"
178
+ form: fixed-point
179
+ emits:
180
+ # 1. The body's entity.
181
+ - op: write-json-from-template
182
+ path: "${input.sourceDir}/${input.bodyName}.ent.json"
183
+ template: template
184
+ require:
185
+ - match: { $type: ResourcePath, $value: "base\\characters\\entities\\player\\player_${input.rigFamily}_skeleton.rig" }
186
+ reason: "The template is not on player_${input.rigFamily}_skeleton.rig, so it cannot wear a ${input.rigFamily}-rig target. Extract the replacer template for that rig (the _f android or player_wa_fpp.ent for woman; the android or player_ma_fpp.ent for man), or pick the other rig family."
187
+ rewrite:
188
+ - path: Header.ArchiveFileName
189
+ value: "mod\\${input.modSlug}\\${input.bodyName}\\${input.bodyName}.ent"
190
+ - path: Data.RootChunk.appearances
191
+ value:
192
+ - $type: entTemplateAppearance
193
+ appearanceName: { $type: CName, $storage: string, $value: "${input.appearanceName}" }
194
+ appearanceResource:
195
+ DepotPath: { $type: ResourcePath, $storage: string, $value: "${input.targetApp}" }
196
+ Flags: Soft
197
+ name: { $type: CName, $storage: string, $value: "${input.appearanceName}" }
198
+ - $each: "${input.extraLooks}"
199
+ $item:
200
+ $type: entTemplateAppearance
201
+ appearanceName: { $type: CName, $storage: string, $value: "${each.1}" }
202
+ appearanceResource:
203
+ DepotPath: { $type: ResourcePath, $storage: string, $value: "${each.2}" }
204
+ Flags: Soft
205
+ name: { $type: CName, $storage: string, $value: "${each.0}" }
206
+ - path: Data.RootChunk.defaultAppearance
207
+ value: { $type: CName, $storage: string, $value: "${input.appearanceName}" }
208
+ - match: { $type: WidgetHudComponent, name.$value: hud_component }
209
+ path: hudEntriesResource
210
+ value:
211
+ DepotPath: { $type: ResourcePath, $storage: string, $value: "base\\gameplay\\gui\\prototype_hud.inkhud" }
212
+ Flags: Obligatory
213
+ - match: { $type: WidgetHudComponent, name.$value: hud_component }
214
+ path: externalMaterial
215
+ value:
216
+ DepotPath: { $type: ResourcePath, $storage: string, $value: "base\\materials\\ui_main_hud.mt" }
217
+ Flags: Obligatory
218
+ strip:
219
+ - Header.ExportedDateTime
220
+ # 2. The record, in a file of its own that every apply rewrites, so a
221
+ # re-run with a new appearance keeps the record and the entity in step.
222
+ - op: write-text
223
+ path: "${input.tweaksFile}"
224
+ ifExists: overwrite
225
+ body: |
226
+ ${ids.recordName}:
227
+ $base: Character.Player_Replacer_Puppet_Base
228
+ entityTemplatePath: mod\${input.modSlug}\${input.bodyName}\${input.bodyName}.ent
229
+ appearanceName: ${input.appearanceName}
230
+ persistentName: ""
231
+ savable: true
232
+ priority: SpawnableObjectPriority.Quest
233
+ itemGroups: []
234
+ attachmentSlots:
235
+ - AttachmentSlots.WeaponRight
236
+ - AttachmentSlots.WeaponLeft
237
+ - AttachmentSlots.RightArm
238
+ - AttachmentSlots.PersonalLink
239
+ - AttachmentSlots.Consumable
240
+ # 3. The world pieces, regenerated on every apply (they are output).
241
+ - op: write-json
242
+ path: "${input.sourceDir}/${input.bodyName}_always_loaded.streamingsector.json"
243
+ ifExists: overwrite
244
+ value:
245
+ Header: {WolvenKitVersion: 8.20.0, WKitJsonVersion: 0.0.9, GameVersion: 2310, DataType: CR2W}
246
+ Data:
247
+ Version: 195
248
+ BuildVersion: 0
249
+ RootChunk:
250
+ $type: worldStreamingSector
251
+ category: AlwaysLoaded
252
+ cookingPlatform: PLATFORM_PC
253
+ externInplaceResource:
254
+ DepotPath: {$type: ResourcePath, $storage: uint64, $value: '0'}
255
+ Flags: Soft
256
+ level: 0
257
+ localInplaceResource: []
258
+ nodeData:
259
+ BufferId: '0'
260
+ Flags: 4063232
261
+ Type: WolvenKit.RED4.Archive.Buffer.worldNodeDataBuffer, WolvenKit.RED4, Version=8.20.0.0, Culture=neutral, PublicKeyToken=null
262
+ Data:
263
+ - Id: '0'
264
+ NodeIndex: 0
265
+ Position: {$type: Vector4, W: 0, X: 0, Y: 0, Z: 0}
266
+ Orientation: {$type: Quaternion, i: 0, j: 0, k: 0, r: 1}
267
+ Scale: {$type: Vector3, X: 1, Y: 1, Z: 1}
268
+ Pivot: {$type: Vector3, X: 0, Y: 0, Z: 0}
269
+ Bounds:
270
+ $type: Box
271
+ Max: {$type: Vector4, W: 0, X: 0, Y: 0, Z: 0}
272
+ Min: {$type: Vector4, W: 0, X: 0, Y: 0, Z: 0}
273
+ QuestPrefabRefHash: {$type: NodeRef, $storage: uint64, $value: '0'}
274
+ UkHash1: {$type: NodeRef, $storage: uint64, $value: '0'}
275
+ CookedPrefabData:
276
+ DepotPath: {$type: ResourcePath, $storage: uint64, $value: '0'}
277
+ Flags: Default
278
+ MaxStreamingDistance: 20000
279
+ UkFloat1: 17.320507
280
+ Uk10: 32
281
+ Uk11: 512
282
+ Uk12: 0
283
+ Uk13: '0'
284
+ Uk14: '0'
285
+ - Id: '0'
286
+ NodeIndex: 1
287
+ Position: {$type: Vector4, W: 0, X: '${input.spotX}', Y: '${input.spotY}', Z: '${input.spotZ}'}
288
+ Orientation: {$type: Quaternion, i: 0, j: 0, k: 0, r: 1}
289
+ Scale: {$type: Vector3, X: 1, Y: 1, Z: 1}
290
+ Pivot: {$type: Vector3, X: 0, Y: 0, Z: 0}
291
+ Bounds:
292
+ $type: Box
293
+ Max: {$type: Vector4, W: 0, X: 0, Y: 0, Z: 0}
294
+ Min: {$type: Vector4, W: 0, X: 0, Y: 0, Z: 0}
295
+ QuestPrefabRefHash: {$type: NodeRef, $storage: uint64, $value: '0'}
296
+ UkHash1: {$type: NodeRef, $storage: uint64, $value: '0'}
297
+ CookedPrefabData:
298
+ DepotPath: {$type: ResourcePath, $storage: uint64, $value: '0'}
299
+ Flags: Default
300
+ MaxStreamingDistance: 20000
301
+ UkFloat1: 115.0
302
+ Uk10: 32
303
+ Uk11: 512
304
+ Uk12: 0
305
+ Uk13: '0'
306
+ Uk14: '0'
307
+ - Id: '0'
308
+ NodeIndex: 2
309
+ Position: {$type: Vector4, W: 0, X: '${input.spotX}', Y: '${input.spotY}', Z: '${input.spotZ}'}
310
+ Orientation: {$type: Quaternion, i: 0, j: 0, k: 0, r: 1}
311
+ Scale: {$type: Vector3, X: 1, Y: 1, Z: 1}
312
+ Pivot: {$type: Vector3, X: 0, Y: 0, Z: 0}
313
+ Bounds:
314
+ $type: Box
315
+ Max: {$type: Vector4, W: 0, X: 0, Y: 0, Z: 0}
316
+ Min: {$type: Vector4, W: 0, X: 0, Y: 0, Z: 0}
317
+ QuestPrefabRefHash: {$type: NodeRef, $storage: string, $value: '$/03_night_city/#${input.nodeRefGroup}/#${input.bodyName}_spot'}
318
+ UkHash1: {$type: NodeRef, $storage: uint64, $value: '0'}
319
+ CookedPrefabData:
320
+ DepotPath: {$type: ResourcePath, $storage: uint64, $value: '0'}
321
+ Flags: Default
322
+ MaxStreamingDistance: 520
323
+ UkFloat1: 120
324
+ Uk10: 32
325
+ Uk11: 512
326
+ Uk12: 0
327
+ Uk13: '0'
328
+ Uk14: '0'
329
+ nodeRefs:
330
+ - {$type: NodeRef, $storage: string, $value: '$/03_night_city/#${input.nodeRefGroup}/#${input.bodyName}_community'}
331
+ - {$type: NodeRef, $storage: string, $value: '$/03_night_city/#${input.nodeRefGroup}/#${input.bodyName}_spot'}
332
+ nodes:
333
+ - HandleId: registryNode
334
+ Data:
335
+ $type: worldCommunityRegistryNode
336
+ debugName: {$type: CName, $storage: string, $value: '{${input.bodyName}_registry}'}
337
+ isHostOnly: 0
338
+ isVisibleInGame: 1
339
+ proxyScale: null
340
+ sourcePrefabHash: '0'
341
+ tag: None
342
+ tagExt: None
343
+ communitiesData:
344
+ - $type: worldCommunityRegistryItem
345
+ communityAreaType: Regular
346
+ communityId:
347
+ $type: gameCommunityID
348
+ entityId: {$type: entEntityID, hash: '${ids.communityId}'}
349
+ entriesInitialState:
350
+ - $type: worldCommunityEntryInitialState
351
+ entryActiveOnStart: 0
352
+ entryName: {$type: CName, $storage: string, $value: '${input.entryName}'}
353
+ initialPhaseName: {$type: CName, $storage: string, $value: spawn}
354
+ template:
355
+ HandleId: communityTemplate
356
+ Data:
357
+ $type: communityCommunityTemplateData
358
+ crowdEntries: []
359
+ entries:
360
+ - HandleId: spawnEntry
361
+ Data:
362
+ $type: communitySpawnEntry
363
+ characterRecordId: {$type: TweakDBID, $storage: string, $value: '${ids.recordName}'}
364
+ entryName: {$type: CName, $storage: string, $value: '${input.entryName}'}
365
+ initializers: []
366
+ phases:
367
+ - HandleId: spawnPhase
368
+ Data:
369
+ $type: communitySpawnPhase
370
+ alwaysSpawned: true_
371
+ appearances:
372
+ - {$type: CName, $storage: string, $value: '${input.appearanceName}'}
373
+ phaseName: {$type: CName, $storage: string, $value: spawn}
374
+ prefetchAppearance: 0
375
+ timePeriods:
376
+ - $type: communityPhaseTimePeriod
377
+ categories: []
378
+ hour: Day
379
+ isSequence: 0
380
+ markings: []
381
+ quantity: 1
382
+ spotNodeRefs:
383
+ - {$type: NodeRef, $storage: string, $value: '$/03_night_city/#${input.nodeRefGroup}/#${input.bodyName}_spot'}
384
+ spawnInView: default__true_
385
+ spawnSetReference: {$type: CName, $storage: string, $value: None}
386
+ crowdCreationRegistry: null
387
+ representsCrowd: 0
388
+ spawnSetNameToCommunityID:
389
+ $type: gameCommunitySpawnSetNameToID
390
+ entries: []
391
+ workspotsPersistentData:
392
+ - $type: AISpotPersistentData
393
+ globalNodeId: {$type: worldGlobalNodeID, hash: '${ids.spotId}'}
394
+ isEnabled: 1
395
+ worldPosition:
396
+ $type: WorldPosition
397
+ x: {$type: FixedPoint, Bits: '${ids.spotXBits}'}
398
+ y: {$type: FixedPoint, Bits: '${ids.spotYBits}'}
399
+ z: {$type: FixedPoint, Bits: '${ids.spotZBits}'}
400
+ yaw: 0
401
+ - HandleId: areaNode
402
+ Data:
403
+ $type: worldCompiledCommunityAreaNode
404
+ debugName: {$type: CName, $storage: string, $value: '{${input.bodyName}_community}'}
405
+ isHostOnly: 0
406
+ isVisibleInGame: 1
407
+ proxyScale: null
408
+ sourcePrefabHash: '0'
409
+ tag: None
410
+ tagExt: None
411
+ area:
412
+ HandleId: area
413
+ Data:
414
+ $type: communityArea
415
+ entriesData:
416
+ - $type: communityCommunityEntrySpotsData
417
+ entryName: {$type: CName, $storage: string, $value: '${input.entryName}'}
418
+ phasesData:
419
+ - $type: communityCommunityEntryPhaseSpotsData
420
+ entryPhaseName: {$type: CName, $storage: string, $value: spawn}
421
+ timePeriodsData:
422
+ - $type: communityCommunityEntryPhaseTimePeriodData
423
+ isSequence: 0
424
+ periodName: {$type: CName, $storage: string, $value: Day}
425
+ spotNodeIds:
426
+ - {$type: worldGlobalNodeID, hash: '${ids.spotId}'}
427
+ sourceObjectId: {$type: entEntityID, hash: '${ids.communityId}'}
428
+ - HandleId: spotNode
429
+ Data:
430
+ $type: worldAISpotNode
431
+ debugName: {$type: CName, $storage: string, $value: '{${input.bodyName}_spot}'}
432
+ isHostOnly: 0
433
+ isVisibleInGame: 1
434
+ proxyScale: null
435
+ sourcePrefabHash: '0'
436
+ tag: None
437
+ tagExt: None
438
+ crowdBlacklist:
439
+ $type: redTagList
440
+ tags: []
441
+ crowdWhitelist:
442
+ $type: redTagList
443
+ tags: []
444
+ disableBumps: 0
445
+ isWorkspotInfinite: 0
446
+ isWorkspotStatic: 0
447
+ lookAtTarget: {$type: NodeRef, $storage: uint64, $value: '0'}
448
+ markings: []
449
+ spot:
450
+ HandleId: actionSpot
451
+ Data:
452
+ $type: AIActionSpot
453
+ ActorBodytypeE3: Undefined
454
+ clippingSpaceOrientation: 180
455
+ clippingSpaceRange: 120
456
+ enabledWhenMasterOccupied: 0
457
+ masterNodeRef: {$type: NodeRef, $storage: uint64, $value: '0'}
458
+ resource:
459
+ DepotPath: {$type: ResourcePath, $storage: string, $value: '${input.spotWorkspot}'}
460
+ Flags: Soft
461
+ snapToGround: 1
462
+ useClippingSpace: 0
463
+ spotDef: null
464
+ useCrowdBlacklist: 0
465
+ useCrowdWhitelist: 0
466
+ persistentNodeIndex: 0
467
+ persistentNodes: []
468
+ variantIndices: [0]
469
+ variantNodes: []
470
+ version: 62
471
+ EmbeddedFiles: []
472
+ - op: write-json
473
+ path: "${input.sourceDir}/${input.bodyName}.streamingblock.json"
474
+ ifExists: overwrite
475
+ value:
476
+ Header: {WolvenKitVersion: 8.20.0, WKitJsonVersion: 0.0.9, GameVersion: 2310, DataType: CR2W}
477
+ Data:
478
+ Version: 195
479
+ BuildVersion: 0
480
+ RootChunk:
481
+ $type: worldStreamingBlock
482
+ cookingPlatform: PLATFORM_PC
483
+ descriptors:
484
+ - $type: worldStreamingSectorDescriptor
485
+ blockIndex: {$type: worldStreamingBlockIndex, oup: Base, rldGridCell: 0}
486
+ category: AlwaysLoaded
487
+ data:
488
+ DepotPath: {$type: ResourcePath, $storage: string, $value: 'mod\${input.modSlug}\${input.bodyName}\${input.bodyName}_always_loaded.streamingsector'}
489
+ Flags: Soft
490
+ level: 0
491
+ numNodeRanges: 1
492
+ questPrefabNodeRef: {$type: NodeRef, $storage: uint64, $value: '0'}
493
+ streamingBox:
494
+ $type: Box
495
+ Max: {$type: Vector4, W: 1, X: 20000.0, Y: 20000.0, Z: 2000.0}
496
+ Min: {$type: Vector4, W: 1, X: -20000.0, Y: -20000.0, Z: -2000.0}
497
+ variants: []
498
+ EmbeddedFiles: []
499
+ - op: write-json
500
+ path: "${input.sourceDir}/${input.bodyName}.questphase.json"
501
+ ifExists: overwrite
502
+ value:
503
+ Header: {WolvenKitVersion: 8.20.0, WKitJsonVersion: 0.0.9, GameVersion: 2310, DataType: CR2W}
504
+ Data:
505
+ Version: 195
506
+ BuildVersion: 0
507
+ RootChunk:
508
+ $type: questQuestPhaseResource
509
+ cookingPlatform: PLATFORM_PC
510
+ graph:
511
+ HandleId: graph
512
+ Data:
513
+ $type: questGraphDefinition
514
+ nodes:
515
+ - HandleId: start
516
+ Data:
517
+ $type: questInputNodeDefinition
518
+ id: 0
519
+ socketName: {$type: CName, $storage: string, $value: In1}
520
+ sockets:
521
+ - HandleId: start.CutDestination
522
+ Data:
523
+ $type: questSocketDefinition
524
+ connections: []
525
+ name: {$type: CName, $storage: string, $value: CutDestination}
526
+ type: CutDestination
527
+ - HandleId: start.Out
528
+ Data:
529
+ $type: questSocketDefinition
530
+ connections:
531
+ - HandleId: start.Out->spawnWaitOn.In
532
+ Data:
533
+ $type: graphGraphConnectionDefinition
534
+ destination:
535
+ HandleId: spawnWaitOn.In
536
+ Data:
537
+ $type: questSocketDefinition
538
+ connections:
539
+ - {HandleRefId: start.Out->spawnWaitOn.In}
540
+ - HandleId: spawnDeactivate.Out->spawnWaitOn.In
541
+ Data:
542
+ $type: graphGraphConnectionDefinition
543
+ destination: {HandleRefId: spawnWaitOn.In}
544
+ source:
545
+ HandleId: spawnDeactivate.Out
546
+ Data:
547
+ $type: questSocketDefinition
548
+ connections:
549
+ - {HandleRefId: spawnDeactivate.Out->spawnWaitOn.In}
550
+ name: {$type: CName, $storage: string, $value: Out}
551
+ type: Output
552
+ name: {$type: CName, $storage: string, $value: In}
553
+ type: Input
554
+ source: {HandleRefId: start.Out}
555
+ - HandleId: start.Out->replacerWaitOn.In
556
+ Data:
557
+ $type: graphGraphConnectionDefinition
558
+ destination:
559
+ HandleId: replacerWaitOn.In
560
+ Data:
561
+ $type: questSocketDefinition
562
+ connections:
563
+ - {HandleRefId: start.Out->replacerWaitOn.In}
564
+ - HandleId: replacerDisable.Out->replacerWaitOn.In
565
+ Data:
566
+ $type: graphGraphConnectionDefinition
567
+ destination: {HandleRefId: replacerWaitOn.In}
568
+ source:
569
+ HandleId: replacerDisable.Out
570
+ Data:
571
+ $type: questSocketDefinition
572
+ connections:
573
+ - {HandleRefId: replacerDisable.Out->replacerWaitOn.In}
574
+ name: {$type: CName, $storage: string, $value: Out}
575
+ type: Output
576
+ name: {$type: CName, $storage: string, $value: In}
577
+ type: Input
578
+ source: {HandleRefId: start.Out}
579
+ name: {$type: CName, $storage: string, $value: Out}
580
+ type: Output
581
+ - HandleId: end
582
+ Data:
583
+ $type: questOutputNodeDefinition
584
+ id: 1
585
+ socketName: {$type: CName, $storage: string, $value: Out1}
586
+ sockets:
587
+ - HandleId: end.CutDestination
588
+ Data:
589
+ $type: questSocketDefinition
590
+ connections: []
591
+ name: {$type: CName, $storage: string, $value: CutDestination}
592
+ type: CutDestination
593
+ - HandleId: end.In
594
+ Data:
595
+ $type: questSocketDefinition
596
+ connections: []
597
+ name: {$type: CName, $storage: string, $value: In}
598
+ type: Input
599
+ type: Terminating
600
+ - HandleId: spawnWaitOn
601
+ Data:
602
+ $type: questPauseConditionNodeDefinition
603
+ condition:
604
+ HandleId: spawnWaitOn.condition
605
+ Data:
606
+ $type: questFactsDBCondition
607
+ type:
608
+ HandleId: spawnWaitOn.factCheck
609
+ Data: {$type: questVarComparison_ConditionType, comparisonType: GreaterOrEqual, factName: '${input.bodyName}_spawn', value: 1}
610
+ id: 10
611
+ sockets:
612
+ - HandleId: spawnWaitOn.CutDestination
613
+ Data:
614
+ $type: questSocketDefinition
615
+ connections: []
616
+ name: {$type: CName, $storage: string, $value: CutDestination}
617
+ type: CutDestination
618
+ - {HandleRefId: spawnWaitOn.In}
619
+ - HandleId: spawnWaitOn.Out
620
+ Data:
621
+ $type: questSocketDefinition
622
+ connections:
623
+ - HandleId: spawnWaitOn.Out->spawnActivate.In
624
+ Data:
625
+ $type: graphGraphConnectionDefinition
626
+ destination:
627
+ HandleId: spawnActivate.In
628
+ Data:
629
+ $type: questSocketDefinition
630
+ connections:
631
+ - {HandleRefId: spawnWaitOn.Out->spawnActivate.In}
632
+ name: {$type: CName, $storage: string, $value: In}
633
+ type: Input
634
+ source: {HandleRefId: spawnWaitOn.Out}
635
+ name: {$type: CName, $storage: string, $value: Out}
636
+ type: Output
637
+ - HandleId: spawnActivate
638
+ Data:
639
+ $type: questSpawnManagerNodeDefinition
640
+ actions:
641
+ - $type: questSpawnManagerNodeActionEntry
642
+ type:
643
+ HandleId: spawnActivate.action
644
+ Data:
645
+ $type: questCommunityTemplate_NodeType
646
+ action: Activate
647
+ communityEntryName: {$type: CName, $storage: string, $value: '${input.entryName}'}
648
+ communityEntryPhaseName: {$type: CName, $storage: string, $value: spawn}
649
+ spawnerReference: {$type: NodeRef, $storage: string, $value: '#${input.bodyName}_community'}
650
+ id: 11
651
+ sockets:
652
+ - HandleId: spawnActivate.CutDestination
653
+ Data:
654
+ $type: questSocketDefinition
655
+ connections: []
656
+ name: {$type: CName, $storage: string, $value: CutDestination}
657
+ type: CutDestination
658
+ - {HandleRefId: spawnActivate.In}
659
+ - HandleId: spawnActivate.Out
660
+ Data:
661
+ $type: questSocketDefinition
662
+ connections:
663
+ - HandleId: spawnActivate.Out->spawnWaitOff.In
664
+ Data:
665
+ $type: graphGraphConnectionDefinition
666
+ destination:
667
+ HandleId: spawnWaitOff.In
668
+ Data:
669
+ $type: questSocketDefinition
670
+ connections:
671
+ - {HandleRefId: spawnActivate.Out->spawnWaitOff.In}
672
+ name: {$type: CName, $storage: string, $value: In}
673
+ type: Input
674
+ source: {HandleRefId: spawnActivate.Out}
675
+ name: {$type: CName, $storage: string, $value: Out}
676
+ type: Output
677
+ - HandleId: spawnWaitOff
678
+ Data:
679
+ $type: questPauseConditionNodeDefinition
680
+ condition:
681
+ HandleId: spawnWaitOff.condition
682
+ Data:
683
+ $type: questFactsDBCondition
684
+ type:
685
+ HandleId: spawnWaitOff.factCheck
686
+ Data: {$type: questVarComparison_ConditionType, comparisonType: Equal, factName: '${input.bodyName}_spawn', value: 0}
687
+ id: 12
688
+ sockets:
689
+ - HandleId: spawnWaitOff.CutDestination
690
+ Data:
691
+ $type: questSocketDefinition
692
+ connections: []
693
+ name: {$type: CName, $storage: string, $value: CutDestination}
694
+ type: CutDestination
695
+ - {HandleRefId: spawnWaitOff.In}
696
+ - HandleId: spawnWaitOff.Out
697
+ Data:
698
+ $type: questSocketDefinition
699
+ connections:
700
+ - HandleId: spawnWaitOff.Out->spawnDeactivate.In
701
+ Data:
702
+ $type: graphGraphConnectionDefinition
703
+ destination:
704
+ HandleId: spawnDeactivate.In
705
+ Data:
706
+ $type: questSocketDefinition
707
+ connections:
708
+ - {HandleRefId: spawnWaitOff.Out->spawnDeactivate.In}
709
+ name: {$type: CName, $storage: string, $value: In}
710
+ type: Input
711
+ source: {HandleRefId: spawnWaitOff.Out}
712
+ name: {$type: CName, $storage: string, $value: Out}
713
+ type: Output
714
+ - HandleId: spawnDeactivate
715
+ Data:
716
+ $type: questSpawnManagerNodeDefinition
717
+ actions:
718
+ - $type: questSpawnManagerNodeActionEntry
719
+ type:
720
+ HandleId: spawnDeactivate.action
721
+ Data:
722
+ $type: questCommunityTemplate_NodeType
723
+ action: Deactivate
724
+ communityEntryName: {$type: CName, $storage: string, $value: '${input.entryName}'}
725
+ communityEntryPhaseName: {$type: CName, $storage: string, $value: spawn}
726
+ spawnerReference: {$type: NodeRef, $storage: string, $value: '#${input.bodyName}_community'}
727
+ id: 13
728
+ sockets:
729
+ - HandleId: spawnDeactivate.CutDestination
730
+ Data:
731
+ $type: questSocketDefinition
732
+ connections: []
733
+ name: {$type: CName, $storage: string, $value: CutDestination}
734
+ type: CutDestination
735
+ - {HandleRefId: spawnDeactivate.In}
736
+ - {HandleRefId: spawnDeactivate.Out}
737
+ - HandleId: replacerWaitOn
738
+ Data:
739
+ $type: questPauseConditionNodeDefinition
740
+ condition:
741
+ HandleId: replacerWaitOn.condition
742
+ Data:
743
+ $type: questFactsDBCondition
744
+ type:
745
+ HandleId: replacerWaitOn.factCheck
746
+ Data: {$type: questVarComparison_ConditionType, comparisonType: GreaterOrEqual, factName: '${input.bodyName}_replacer', value: 1}
747
+ id: 20
748
+ sockets:
749
+ - HandleId: replacerWaitOn.CutDestination
750
+ Data:
751
+ $type: questSocketDefinition
752
+ connections: []
753
+ name: {$type: CName, $storage: string, $value: CutDestination}
754
+ type: CutDestination
755
+ - {HandleRefId: replacerWaitOn.In}
756
+ - HandleId: replacerWaitOn.Out
757
+ Data:
758
+ $type: questSocketDefinition
759
+ connections:
760
+ - HandleId: replacerWaitOn.Out->replacerEnable.In
761
+ Data:
762
+ $type: graphGraphConnectionDefinition
763
+ destination:
764
+ HandleId: replacerEnable.In
765
+ Data:
766
+ $type: questSocketDefinition
767
+ connections:
768
+ - {HandleRefId: replacerWaitOn.Out->replacerEnable.In}
769
+ name: {$type: CName, $storage: string, $value: In}
770
+ type: Input
771
+ source: {HandleRefId: replacerWaitOn.Out}
772
+ name: {$type: CName, $storage: string, $value: Out}
773
+ type: Output
774
+ - HandleId: replacerEnable
775
+ Data:
776
+ $type: questGameManagerNodeDefinition
777
+ type:
778
+ HandleId: replacerEnable.action
779
+ Data:
780
+ $type: questReplacer_NodeType
781
+ audioOverrideAppearanceName: {$type: CName, $storage: string, $value: None}
782
+ enable: 1
783
+ objectRef:
784
+ $type: gameEntityReference
785
+ dynamicEntityUniqueName: {$type: CName, $storage: string, $value: None}
786
+ names:
787
+ - {$type: CName, $storage: string, $value: '${input.entryName}'}
788
+ reference: {$type: NodeRef, $storage: string, $value: '#${input.bodyName}_community'}
789
+ sceneActorContextName: {$type: CName, $storage: string, $value: None}
790
+ slotName: {$type: CName, $storage: string, $value: None}
791
+ type: EntityRef
792
+ id: 21
793
+ sockets:
794
+ - HandleId: replacerEnable.CutDestination
795
+ Data:
796
+ $type: questSocketDefinition
797
+ connections: []
798
+ name: {$type: CName, $storage: string, $value: CutDestination}
799
+ type: CutDestination
800
+ - {HandleRefId: replacerEnable.In}
801
+ - HandleId: replacerEnable.Out
802
+ Data:
803
+ $type: questSocketDefinition
804
+ connections:
805
+ - HandleId: replacerEnable.Out->replacerWaitOff.In
806
+ Data:
807
+ $type: graphGraphConnectionDefinition
808
+ destination:
809
+ HandleId: replacerWaitOff.In
810
+ Data:
811
+ $type: questSocketDefinition
812
+ connections:
813
+ - {HandleRefId: replacerEnable.Out->replacerWaitOff.In}
814
+ name: {$type: CName, $storage: string, $value: In}
815
+ type: Input
816
+ source: {HandleRefId: replacerEnable.Out}
817
+ name: {$type: CName, $storage: string, $value: Out}
818
+ type: Output
819
+ - HandleId: replacerWaitOff
820
+ Data:
821
+ $type: questPauseConditionNodeDefinition
822
+ condition:
823
+ HandleId: replacerWaitOff.condition
824
+ Data:
825
+ $type: questFactsDBCondition
826
+ type:
827
+ HandleId: replacerWaitOff.factCheck
828
+ Data: {$type: questVarComparison_ConditionType, comparisonType: Equal, factName: '${input.bodyName}_replacer', value: 0}
829
+ id: 22
830
+ sockets:
831
+ - HandleId: replacerWaitOff.CutDestination
832
+ Data:
833
+ $type: questSocketDefinition
834
+ connections: []
835
+ name: {$type: CName, $storage: string, $value: CutDestination}
836
+ type: CutDestination
837
+ - {HandleRefId: replacerWaitOff.In}
838
+ - HandleId: replacerWaitOff.Out
839
+ Data:
840
+ $type: questSocketDefinition
841
+ connections:
842
+ - HandleId: replacerWaitOff.Out->replacerDisable.In
843
+ Data:
844
+ $type: graphGraphConnectionDefinition
845
+ destination:
846
+ HandleId: replacerDisable.In
847
+ Data:
848
+ $type: questSocketDefinition
849
+ connections:
850
+ - {HandleRefId: replacerWaitOff.Out->replacerDisable.In}
851
+ name: {$type: CName, $storage: string, $value: In}
852
+ type: Input
853
+ source: {HandleRefId: replacerWaitOff.Out}
854
+ name: {$type: CName, $storage: string, $value: Out}
855
+ type: Output
856
+ - HandleId: replacerDisable
857
+ Data:
858
+ $type: questGameManagerNodeDefinition
859
+ type:
860
+ HandleId: replacerDisable.action
861
+ Data:
862
+ $type: questReplacer_NodeType
863
+ audioOverrideAppearanceName: {$type: CName, $storage: string, $value: None}
864
+ enable: 0
865
+ objectRef:
866
+ $type: gameEntityReference
867
+ dynamicEntityUniqueName: {$type: CName, $storage: string, $value: None}
868
+ names:
869
+ - {$type: CName, $storage: string, $value: '${input.entryName}'}
870
+ reference: {$type: NodeRef, $storage: string, $value: '#${input.bodyName}_community'}
871
+ sceneActorContextName: {$type: CName, $storage: string, $value: None}
872
+ slotName: {$type: CName, $storage: string, $value: None}
873
+ type: EntityRef
874
+ id: 23
875
+ sockets:
876
+ - HandleId: replacerDisable.CutDestination
877
+ Data:
878
+ $type: questSocketDefinition
879
+ connections: []
880
+ name: {$type: CName, $storage: string, $value: CutDestination}
881
+ type: CutDestination
882
+ - {HandleRefId: replacerDisable.In}
883
+ - {HandleRefId: replacerDisable.Out}
884
+ inplacePhases: []
885
+ phasePrefabs: []
886
+ EmbeddedFiles: []
887
+ # 4. The .xl entries and the build.
888
+ - op: write-text
889
+ path: "${input.xlFile}"
890
+ ifExists: skip
891
+ body: |
892
+ {}
893
+ - op: insert-xl-entry
894
+ path: "${input.xlFile}"
895
+ pointer: streaming.blocks.-
896
+ unique: true
897
+ value: "mod\\${input.modSlug}\\${input.bodyName}\\${input.bodyName}.streamingblock"
898
+ - op: insert-xl-entry
899
+ path: "${input.xlFile}"
900
+ pointer: quest.phases.-
901
+ unique: true
902
+ value:
903
+ path: "mod\\${input.modSlug}\\${input.bodyName}\\${input.bodyName}.questphase"
904
+ parent: "base\\quest\\cyberpunk2077.quest"
905
+ - op: insert-xl-entry
906
+ path: "${input.xlFile}"
907
+ pointer: quest.phases.-
908
+ unique: true
909
+ value:
910
+ path: "mod\\${input.modSlug}\\${input.bodyName}\\${input.bodyName}.questphase"
911
+ parent: "ep1\\quest\\ep1_standalone.quest"
912
+ - op: patch-project
913
+ add:
914
+ outDir: "archive-staging"
915
+ sources:
916
+ - id: "xl-${input.modSlug}"
917
+ path: "${input.xlFile}"
918
+ kind: xl
919
+ steps:
920
+ - step: exec
921
+ id: "deserialize-${input.modSlug}-${input.bodyName}-ent"
922
+ command: wolvenkit-cli
923
+ args: ["convert", "deserialize", "${input.sourceDir}/${input.bodyName}.ent.json", "-o", "${input.archiveStagingDir}/mod/${input.modSlug}/${input.bodyName}"]
924
+ expectOutputs: ["${input.archiveStagingDir}/mod/${input.modSlug}/${input.bodyName}/${input.bodyName}.ent"]
925
+ inputs: ["${input.sourceDir}/${input.bodyName}.ent.json"]
926
+ before: stage
927
+ - step: exec
928
+ id: "deserialize-${input.modSlug}-${input.bodyName}-sector"
929
+ command: wolvenkit-cli
930
+ args: ["convert", "deserialize", "${input.sourceDir}/${input.bodyName}_always_loaded.streamingsector.json", "-o", "${input.archiveStagingDir}/mod/${input.modSlug}/${input.bodyName}"]
931
+ expectOutputs: ["${input.archiveStagingDir}/mod/${input.modSlug}/${input.bodyName}/${input.bodyName}_always_loaded.streamingsector"]
932
+ inputs: ["${input.sourceDir}/${input.bodyName}_always_loaded.streamingsector.json"]
933
+ before: stage
934
+ - step: exec
935
+ id: "deserialize-${input.modSlug}-${input.bodyName}-block"
936
+ command: wolvenkit-cli
937
+ args: ["convert", "deserialize", "${input.sourceDir}/${input.bodyName}.streamingblock.json", "-o", "${input.archiveStagingDir}/mod/${input.modSlug}/${input.bodyName}"]
938
+ expectOutputs: ["${input.archiveStagingDir}/mod/${input.modSlug}/${input.bodyName}/${input.bodyName}.streamingblock"]
939
+ inputs: ["${input.sourceDir}/${input.bodyName}.streamingblock.json"]
940
+ before: stage
941
+ - step: exec
942
+ id: "deserialize-${input.modSlug}-${input.bodyName}-phase"
943
+ command: wolvenkit-cli
944
+ args: ["convert", "deserialize", "${input.sourceDir}/${input.bodyName}.questphase.json", "-o", "${input.archiveStagingDir}/mod/${input.modSlug}/${input.bodyName}"]
945
+ expectOutputs: ["${input.archiveStagingDir}/mod/${input.modSlug}/${input.bodyName}/${input.bodyName}.questphase"]
946
+ inputs: ["${input.sourceDir}/${input.bodyName}.questphase.json"]
947
+ before: stage
948
+ deployTargets:
949
+ - rootId: archive
950
+ from: "${input.xlFile}"
951
+ locked: false
952
+ backup: true
953
+ templates:
954
+ - ref: template
955
+ from: "${template.template.contentPath}"
956
+ provenanceFrom: template
957
+ satisfies:
958
+ - cp2077.tweaks.yaml-lint
959
+ - cp2077.tweaks.base-exists
960
+ - cp2077.tweaks.flat-name-exists
961
+ - cp2077.tweaks.replacer-template-staged
962
+ - cp2077.history.xl-manifest-lint
963
+ - cp2077.vehicles.cr2w-unique-ids
964
+ - cp2077.vehicles.cr2w-enums-are-strings
965
+ - cp2077.vehicles.cr2w-resource-path-shape
966
+ - cp2077.vehicles.cr2w-gameversion-header
967
+ manual:
968
+ - title: Check the target and build
969
+ steps:
970
+ - "Confirm ${input.targetApp} is a ${input.rigFamily}-rig appearance file (an _ma .app for man, _wa for woman) and that it declares ${input.appearanceName}; the scaffold checks the template's skeleton, not the .app, which is not extracted."
971
+ - "Build and deploy, then run validate again: cp2077.garments.xl-entries-resolve and cp2077.tweaks.replacer-template-staged read the staged tree, where the four resources exist only after the deserialize steps."
972
+ expected: "The build writes ${input.bodyName}.ent, the sector, the block and the phase under mod\\${input.modSlug}\\${input.bodyName}\\, and validate is clean."
973
+ - title: The spawn, in one boot (older saves only)
974
+ steps:
975
+ - "Load a save with both facts at 0. ArchiveXL.log should show 'Merged phase \"mod\\${input.modSlug}\\${input.bodyName}\\${input.bodyName}.questphase\"' after the save loads."
976
+ - "Set the fact ${input.bodyName}_spawn to 1 (CET: Game.GetQuestsSystem():SetFactStr(\"${input.bodyName}_spawn\", 1)). The body spawns at (${input.spotX}, ${input.spotY}, ${input.spotZ}) wearing ${input.appearanceName}; Codeware's GetFixedEntityIdsFromSpawnerEntityID on the community id ${ids.communityId} returns one entity, of class PlayerPuppet, whose record is ${ids.recordName} and whose IsReplacer() is true."
977
+ - "Set ${input.bodyName}_spawn back to 0: the body despawns."
978
+ - "Set both facts to 0 before any save; they persist in it."
979
+ expected: "The community spawns and despawns the body on the fact, and the body is a PlayerPuppet replacer."
980
+ - title: The switch needs a plugin (Part B)
981
+ steps:
982
+ - "Do not set ${input.bodyName}_replacer to 1 without a RED4ext plugin that guards the resize handler: the vanilla node's enable switched control and then crashed on the body's first resize event (observed in game). With such a guard in place, V walked as the body."
983
+ - "With the guard in place: ${input.bodyName}_replacer 1 switches to the body and 0 switches back. Check V's HUD (not the showroom proxy) while in the body."
984
+ expected: "V plays as the body with her own HUD, and returns cleanly."
985
+ claim:
986
+ idSuffix: "${input.bodyName}.spawns"
987
+ claim: "Setting ${input.bodyName}_spawn to 1 spawns ${ids.recordName} through the mod's community at the spot, a PlayerPuppet replacer wearing ${input.appearanceName} from ${input.targetApp}, with V's HUD on its template."
988
+ testRows:
989
+ - gate: R-1
990
+ title: "The replacer record and its template path"
991
+ expected: "cp2077.tweakdb.record confirms ${ids.recordName}; cp2077.tweakdb.flat reads its entityTemplatePath as mod\\${input.modSlug}\\${input.bodyName}\\${input.bodyName}.ent."
992
+ manual: false
993
+ probes:
994
+ - kind: cp2077.tweakdb.record
995
+ params: { id: "${ids.recordName}" }
996
+ - kind: cp2077.tweakdb.flat
997
+ params: { id: "${ids.recordName}.entityTemplatePath" }
998
+ - gate: R-2
999
+ title: "The body spawns and despawns on its fact"
1000
+ expected: "With ${input.bodyName}_spawn at 1 the community's one entity exists, is a PlayerPuppet, and IsReplacer() is true; at 0 it is gone (the manual checklist's second item)."
1001
+ manual: true
1002
+ probeKinds: [cp2077.lua.eval]
1003
+ evidence: ["ModWright research"]