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,918 @@
1
+ game: cyberpunk2077
2
+ topic: player.control
3
+ title: How the engine transfers player control between entities - the player system's control
4
+ switch, the device takeover's camera-only route, the control flags, and the multiplayer puppet
5
+ facts:
6
+ - id: cp2077.player.control.local-player-control-existing-object
7
+ claim: "PlayerSystem exposes a script-visible native that switches the local player's controlled
8
+ object to any existing entity: LocalPlayerControlExistingObject(entityID: EntityID), declared
9
+ beside GetLocalPlayerMainGameObject() (the player's main object, V) and
10
+ GetLocalPlayerControlledGameObject() (the object currently controlled), which can differ."
11
+ status: verified
12
+ verified_on: "2.31"
13
+ source: tools\redmod\scripts\core\systems\playerSystem.script:13-15
14
+ tags:
15
+ - playersystem
16
+ - control-transfer
17
+ - possession
18
+ - native
19
+ - id: cp2077.player.control.cctv-camera-is-the-worked-example
20
+ claim: The one vanilla caller is the prototype SimpleCCTVCamera. TakeControl(true) caches the main
21
+ object's id, calls LocalPlayerControlExistingObject on its own entity id, activates its own
22
+ camera component (m_camera.Activate) and registers input listeners on itself for CameraMouseX,
23
+ CameraAim and UI_Exit, which then arrive at its OnAction; TakeControl(false) unregisters,
24
+ deactivates the camera and calls LocalPlayerControlExistingObject with the cached puppet id.
25
+ So a controlled object receives the player's input through its own listeners and may own the
26
+ active camera.
27
+ status: verified
28
+ verified_on: "2.31"
29
+ source: tools\redmod\scripts\cyberpunk\devices\cameras\simpleCCTVCamera.script:34-52, :62-70
30
+ tags:
31
+ - playersystem
32
+ - control-transfer
33
+ - cctv
34
+ - input
35
+ - camera
36
+ related:
37
+ - cp2077.player.control.local-player-control-existing-object
38
+ - id: cp2077.player.control.takeover-system-never-switches-the-controlled-object
39
+ claim: The shipped quickhack device control (cameras, turrets, the sniper nest) does not use the
40
+ control switch. TakeOverControlSystem.RegisterAsCurrentObject keeps a weak m_controlledObject
41
+ of its own, registers the system on input (RegisterSystemOnInput), sets the player state
42
+ machine's IsControllingDevice flag (PSMSetIsPlayerControllDevice) and sends a
43
+ DeviceStartPlayerCameraControlEvent with the device's yaw and pitch limits; the player
44
+ system's controlled object stays V throughout (RegisterObjectHandle reads it as the
45
+ PlayerPuppet). A mod that drove the camera this way got its input under restrictions rather
46
+ than by ownership.
47
+ status: verified
48
+ verified_on: "2.31"
49
+ source: tools\redmod\scripts\core\systems\takeOverControlSystem.script:314-320, :330-352, :363-392
50
+ tags:
51
+ - takeovercontrolsystem
52
+ - device-control
53
+ - camera
54
+ - psm
55
+ related:
56
+ - cp2077.player.control.local-player-control-existing-object
57
+ - id: cp2077.player.control.control-flags-and-their-gates
58
+ claim: "Entity carries three control natives - IsControlledByAnyPeer, IsControlledByLocalPeer,
59
+ IsControlledByAnotherClient - and GameObject a fourth, IsPlayerControlled. Shipped gameplay
60
+ gates on IsPlayerControlled: an NPC's reaction to an instigator that is neither the player nor
61
+ player-controlled returns early (NPCPuppet.script:5026), the sense component refuses a
62
+ breacher that is not player-controlled (senseComponent.script:688), and the security area
63
+ controller and target tracking read it too. A puppet the engine reports as player-controlled
64
+ would therefore be treated as the player by those paths."
65
+ status: verified
66
+ verified_on: "2.31"
67
+ source: tools\redmod\scripts\core\entity\entity.script:13-15; core\entity\gameObject.script:262;
68
+ cyberpunk\NPC\NPCPuppet.script:5026; core\components\senseComponent.script:688
69
+ tags:
70
+ - isplayercontrolled
71
+ - control-flags
72
+ - npc-reactions
73
+ - senses
74
+ - id: cp2077.player.control.effect-on-a-scripted-puppet-unread
75
+ claim: "LocalPlayerControlExistingObject on a ScriptedPuppet crashes the game at once: called from
76
+ the CET context on a spawned android with nothing else changed, the main thread faulted with
77
+ an access violation nine bytes into the unnamed engine native at .text+0x102214 (address-file
78
+ hash 3318354421), reading a field at 0x30CD8 of a null object - the shape of a missing
79
+ component or controller the switch expects on a player body. No shipped source says what that
80
+ is; V and, by class design, the multiplayer Muppet (input-handler and locomotion components)
81
+ are the bodies the engine controls. The input-routing, flag and body-ownership questions are
82
+ therefore unanswerable through this native for a plain puppet. Decoded from the executable
83
+ afterwards: the null object is the player system's per-player native object, found by EntityID
84
+ in a container at PlayerSystem+0x58 by the switch's caller (.text+0x102DA0, hash 2188581991,
85
+ lookup hash 4218969667) with no null check; V's entry is created by
86
+ cp::PlayerSystem::OnPlayerMainObjectSpawned (hash 2050111212), which is the hash-resolved
87
+ routine a plugin would call to register a puppet, at the risk of displacing the main player
88
+ object."
89
+ status: verified
90
+ verified_on: "2.31"
91
+ source: "%LOCALAPPDATA%\\REDEngine\\ReportQueue\\Cyberpunk2077-20260922-150823-35088-37196
92
+ (stacktrace.txt, Cyberpunk2077.dmp); bin\\x64\\cyberpunk2077_addresses.json entry
93
+ 0001:00102214"
94
+ tags:
95
+ - control-transfer
96
+ - scriptedpuppet
97
+ - open-question
98
+ - launch
99
+ related:
100
+ - cp2077.player.control.local-player-control-existing-object
101
+ - cp2077.player.control.cctv-camera-is-the-worked-example
102
+ - id: cp2077.player.control.muppet-is-an-input-driven-puppet-without-a-template
103
+ claim: The multiplayer puppet Muppet extends gamePuppetBase, answers IsPlayer() true, and resolves
104
+ HitRepresentation and Item_Attachment_Slot slot components; its locomotion is native -
105
+ gameMuppetLocomotionComponent (eight undecoded bytes on gameMuppetComponent),
106
+ gameMuppetInputHandlerComponent (no decoded fields) and a gameMuppetMoveState (desiredSpeed,
107
+ isJumping, isFalling, isDoubleJumped, moveStyle, jump and land frame ids). No shipped entity
108
+ template is known to carry the components and the addresses file names no Muppet symbol, so it
109
+ stays an investigation, not a route.
110
+ status: verified
111
+ verified_on: "2.31"
112
+ source: tools\redmod\scripts\cyberpunk\muppet\muppet.script:1-47; RED4ext.SDK ad72777
113
+ Generated/game/MuppetLocomotionComponent.hpp, MuppetInputHandlerComponent.hpp,
114
+ MuppetMoveState.hpp
115
+ tags:
116
+ - muppet
117
+ - multiplayer
118
+ - locomotion
119
+ - sdk
120
+ - id: cp2077.player.control.addresses-file-names-no-control-native
121
+ claim: The game's address file (bin\x64\cyberpunk2077_addresses.json, linker map timestamp 68af45ea)
122
+ has 987,479 entries and 84 with a symbol string; the only player-system symbol is
123
+ cp::PlayerSystem::OnPlayerMainObjectSpawned, and nothing names the control switch, the mover
124
+ or the muppet. Any native beyond the script-visible ones is disassembly work.
125
+ status: verified
126
+ verified_on: "2.31"
127
+ source: ModWright field verification
128
+ tags:
129
+ - addresses
130
+ - symbols
131
+ - red4ext
132
+ - id: cp2077.player.control.replacers-are-other-player-bodies
133
+ claim: 'The game plays V in other bodies through "replacers": PlayerPuppet-class entities spawned
134
+ from Character records that derive from Character.Player_Replacer_Puppet_Base (itself derived
135
+ from Character.Player_Puppet_Base, with an empty appearanceName, the tag Replacer and one stat
136
+ modifier). PlayerPuppet.IsReplacer() is GetRecord().GetID() != Character.Player_Puppet_Base;
137
+ IsJohnnyReplacer and IsVRReplacer test Character.johnny_replacer and
138
+ Character.q000_vr_replacer. Thirteen records derive from the replacer base on 2.31:
139
+ johnny_replacer, braindance_replacer, q000_vr_replacer, e3_v_solo_female (template
140
+ player_wa_fpp_replacer.ent), kurt_replacer, mq303_lina_replacer, mq304_assassin_replacer_male
141
+ and _female, q304_netrunner_replacer_theo, _bella and _combined, mws_se5_03_player,
142
+ android_replacer and android_replacer_f.'
143
+ status: verified
144
+ verified_on: "2.31"
145
+ source: tools\redmod\scripts\cyberpunk\player\player.script:582-605; the vanilla index record/flat
146
+ rows for Character.Player_Replacer_Puppet_Base and its children
147
+ tags:
148
+ - playersystem
149
+ - replacer
150
+ - playerpuppet
151
+ - tweakdb
152
+ - possession
153
+ related:
154
+ - cp2077.player.control.local-player-control-existing-object
155
+ - id: cp2077.player.control.android-replacer-is-v-in-the-android-app
156
+ claim: "Character.android_replacer (and _f for the wa body) is a shipped playable android:
157
+ entityTemplatePath base\\quest\\minor_quests\\mq060\\entities\\mq060_android_replacer_v2.ent,
158
+ attachment slots WeaponRight, WeaponLeft, RightArm, PersonalLink and Consumable, the player's
159
+ stat pools, savable, priority Quest. The template's entity class is PlayerPuppet with 111
160
+ components - V's player_ma_fpp.ent set minus the hairstyle and genitals customization
161
+ controllers - carrying V's player_man_skeleton.rig, the FPP deformation and shadow rigs, V's
162
+ arm and fist meshes, gamestateMachineComponent StateMachine, gameFPPCameraComponent camera and
163
+ TPPRepresentation, and thirteen appearances that point into corpo__android_ma.app (the MaxTac,
164
+ Arasaka, Kang Tao, Militech and NCPD droids, Kerry's five bodyguards, the mq060 Nitro Youth
165
+ communication droid) plus a tutorial_ma_dummy_player_fpp default. It is V's body wearing the
166
+ android's appearance file."
167
+ status: verified
168
+ verified_on: "2.31"
169
+ source: tools\redmod\tweaks\base\gameplay\static_data\database\characters\npcs\records\quest\minor_quests\mq060.tweak
170
+ (Character.android_replacer);
171
+ base\quest\minor_quests\mq060\entities\mq060_android_replacer_v2.ent
172
+ tags:
173
+ - replacer
174
+ - android
175
+ - playerpuppet
176
+ - template
177
+ - appearance
178
+ related:
179
+ - cp2077.player.control.replacers-are-other-player-bodies
180
+ - id: cp2077.player.control.replacer-switch-is-a-quest-node
181
+ claim: "The switch to a replacer body is the quest node type questReplacer_NodeType (a
182
+ questIGameManagerNonSignalStoppingNodeType): enable Bool, objectRef gameEntityReference,
183
+ audioOverrideAppearanceName CName. No script-visible function performs it - PlayerSystem's
184
+ script API has none and Codeware only declares the class. mq060's Yaiba showroom phase runs
185
+ the protocol: activate the community entry android_replacer (phase spawn, spawner
186
+ #mq060_communityArea), wait on questCharacterSpawned_ConditionType for it, teleport the local
187
+ player, then a questGameManagerNodeDefinition with questReplacer_NodeType enable 1 and
188
+ objectRef names [android_replacer]; the same phase adds the gameplay restrictions ForceStand,
189
+ NoCombat and NoJump under the source mq060_android_replacer and removes them later, and
190
+ deactivates the community entry at the end."
191
+ status: verified
192
+ verified_on: "2.31"
193
+ source: RED4ext.SDK ad72777 include/RED4ext/Scripting/Natives/Generated/quest/Replacer_NodeType.hpp;
194
+ base\quest\minor_quests\mq060\phases\mq060_yaiba_showroom.questphase (nodes 174, 8, 9, 7, 79,
195
+ 94, 206); Codeware 1.20.3 Codeware.Global.reds:30446
196
+ tags:
197
+ - replacer
198
+ - quest-node
199
+ - questphase
200
+ - playersystem
201
+ - possession
202
+ related:
203
+ - cp2077.player.control.replacers-are-other-player-bodies
204
+ - cp2077.player.control.android-replacer-is-v-in-the-android-app
205
+ - id: cp2077.player.control.player-system-reacts-to-the-controlled-record
206
+ claim: "The player system's script reacts to the body changing rather than causing it:
207
+ OnLocalPlayerChanged(controlledObject) reads the controlled puppet's record id and sets
208
+ UI_PlayerStats.isReplacer (false for Character.Player_Puppet_Base, true for johnny_replacer,
209
+ kurt_replacer and anything else); OnLocalPlayerPossesionChanged takes gamedataPlayerPossesion
210
+ (Default, Johnny) and sets the UI theme Possessed for Johnny; OnGameRestored re-applies it
211
+ from the fact isPlayerPossessedByJohnny. Prereqs NotReplacerPrereq, NotJohnnyReplacerPrereq
212
+ and NotVRReplacerPrereq gate content on the replacer state."
213
+ status: verified
214
+ verified_on: "2.31"
215
+ source: tools\redmod\scripts\core\systems\playerSystem.script:27-100;
216
+ core\gameplay\prereqs.script:439-477; RED4ext.SDK Generated/game/data/PlayerPossesion.hpp
217
+ tags:
218
+ - playersystem
219
+ - replacer
220
+ - possession
221
+ - blackboard
222
+ - ui
223
+ related:
224
+ - cp2077.player.control.replacers-are-other-player-bodies
225
+ - id: cp2077.player.control.replacer-enable-stores-the-body-through-its-entity-stub
226
+ claim: On 2.31 the questReplacer_NodeType execute (fn_15CBD0) calls the player system's virtual at
227
+ slot 0x208 (fn_15CCB0) to enable and 0x210 (fn_28D8864) to disable. The enable, when no
228
+ replacer is active, runs a store step fn_15BD98 and then the same control switch the script
229
+ native LocalPlayerControlExistingObject runs, and returns true without checking the store. The
230
+ store fetches gameICommunitySystem and gameIEntityStubSystem by their class statics, looks the
231
+ body's entity id up through the stub system's virtual at 0x1D0, and only if a stub is found
232
+ asks the community system's virtual at 0x270 for a spawn request built from the stub's spawn
233
+ data (stub+0x30, its blocks at +0xB0 and +0xB8) and registers it; with no stub it returns
234
+ false. A body spawned by CET's exEntitySpawner and one spawned by Codeware's
235
+ DynamicEntitySystem both return false, and the enable then crashes on the first entity-resize
236
+ event exactly as the bare switch does.
237
+ status: verified
238
+ verified_on: "2.31"
239
+ source: ModWright field verification
240
+ tags:
241
+ - replacer
242
+ - playersystem
243
+ - entity-stub
244
+ - community
245
+ - native
246
+ - version-pinned
247
+ detail: "Observed in game (2026-09-22, 21:10), the other half: a body spawned by a mod community
248
+ entry has a stub, and the store alone returned true. Called alone, the store also fills the
249
+ player system's stored-replacer slot (+0x604D8). The next enable (slot 0x208) then returns
250
+ false without switching, and the community's Deactivate no longer despawns the body. The
251
+ disable (slot 0x210) releases it, after which the enable returns true and switches. So the
252
+ store belongs inside the enable only."
253
+ related:
254
+ - cp2077.player.control.replacer-switch-is-a-quest-node
255
+ - cp2077.player.control.vanilla-replacer-bodies-spawn-from-communities
256
+ - cp2077.player.control.community-replacer-body-still-crashes-on-resize
257
+ - id: cp2077.player.control.community-replacer-body-still-crashes-on-resize
258
+ claim: Switching the player to a community-spawned Character.android_replacer whose store step
259
+ succeeded still crashes the game within about a second, at the same site as the bare control
260
+ switch. The site is fn_1866ED8+0x23, a write at 0x34, reached from the entity-resize handler
261
+ of an entTriggerActivatorComponent whose native object is null. The crash is the same through
262
+ the plugin's call to the player system's enable (slot 0x208) and through the vanilla
263
+ questReplacer_NodeType run from a mod quest phase. The body's six
264
+ entTriggerActivatorComponents are identical in the replacer template and in V's
265
+ player_ma_fpp.ent, so the missing native object is runtime state, not template data.
266
+ status: verified
267
+ verified_on: "2.31"
268
+ source: ModWright field verification
269
+ tags:
270
+ - replacer
271
+ - crash
272
+ - trigger-activator
273
+ - community
274
+ - questphase
275
+ related:
276
+ - cp2077.player.control.replacer-enable-stores-the-body-through-its-entity-stub
277
+ - cp2077.player.control.sound-trigger-activator-object-is-gated-and-resize-is-unchecked
278
+ - id: cp2077.player.control.sound-trigger-activator-object-is-gated-and-resize-is-unchecked
279
+ claim: entTriggerActivatorComponent (type static exe+0x342D7D8, size 0x150, vtable .rdata 0x2BA8B70
280
+ on 2.31) keeps its physics trigger object at +0x140, just past its properties (height +0x128,
281
+ radius +0x12C, channels +0x130, maxContinousDistance +0x134, enableCCD +0x138).
282
+ fn_422FE8(component) creates the object through a system reached from the owner's runtime
283
+ scene. For an activator whose channels carry bit 5 (TC_SoundAmbientArea, the
284
+ SoundTriggerActivator bound to the camera), the component's bounds method fn_3BD58C creates
285
+ the object only while the id of the entity at component+0x120 equals a global id at
286
+ *(*(*(exe+0x342AC00)+0xA8)+0x140)+0x250, and destroys it otherwise. The component's
287
+ entity-resize handler fn_1866EA0 passes +0x140 to fn_1866ED8, which writes the new extents at
288
+ +0x28..+0x34 with no null check. So a resize that reaches a body before the body's first
289
+ bounds pass crashes with a write at 0x34.
290
+ status: verified
291
+ verified_on: "2.31"
292
+ source: ModWright field verification
293
+ tags:
294
+ - trigger-activator
295
+ - crash
296
+ - sound
297
+ - physics
298
+ - version-pinned
299
+ detail: >-
300
+ That the gate id is the audio listener is inferred from the channel alone. A cyberware mod's
301
+ plugin (version 0.1.6) guards the handler with a RED4ext hook and reads the gate id beside V's
302
+ and the body's.
303
+
304
+ Observed in game (2026-09-22, 22:13): the gate. Before the switch the gate id was V's (1).
305
+ After the replacer enable it was the body's (9011773), and V's three activators were disabled
306
+ with no object. After the disable it was V's again; V's activators were back, and the body's
307
+ sound object was gone.
308
+ related:
309
+ - cp2077.player.control.community-replacer-body-still-crashes-on-resize
310
+ - cp2077.player.control.replacer-body-walk-chain
311
+ - id: cp2077.player.control.replacer-body-walk-chain
312
+ claim: >-
313
+ The player can be switched into the shipped android replacer body and back, walking, looking
314
+ and jumping with V's own state machine animating the body's legs, by this chain on 2.31: 1. a
315
+ mod community entry spawns Character.android_replacer, so the
316
+ body has an entity stub;
317
+ 2. the player system's replacer enable (slot 0x208) stores it and
318
+ switches control;
319
+ 3. right after the enable, the body's missing sound-ambient trigger
320
+ object is made with fn_422FE8;
321
+ 4. the replacer disable (slot 0x210) hands control back. Despawning the community body after
322
+ such a round trip crashed the game in the entity's detach (fn_1B3A1C) on a component whose
323
+ vtable pointer was null. The same entry had despawned cleanly when the body was never the
324
+ player.
325
+ status: verified
326
+ verified_on: "2.31"
327
+ source: ModWright field verification
328
+ tags:
329
+ - replacer
330
+ - control-transfer
331
+ - community
332
+ - trigger-activator
333
+ - crash
334
+ detail: The despawn crash was the caller's fault. The mod's plugin released the entity handle it had
335
+ already handed to the by-value enable (see
336
+ cp2077.player.control.replacer-enable-takes-the-handle-by-value), so the body was freed early.
337
+ A later plugin version (0.1.7) fixes it; not yet tested in game.
338
+ related:
339
+ - cp2077.player.control.sound-trigger-activator-object-is-gated-and-resize-is-unchecked
340
+ - cp2077.player.control.vanilla-replacer-bodies-spawn-from-communities
341
+ - cp2077.player.control.replacer-enable-takes-the-handle-by-value
342
+ - id: cp2077.player.control.replacer-enable-takes-the-handle-by-value
343
+ claim: "The player system's replacer enable (slot 0x208, fn_15CCB0 on 2.31) takes its Handle<Entity>
344
+ argument by value. Under the MSVC x64 ABI the caller passes a pointer to a temporary, and the
345
+ function itself releases it on every path (thunk_FUN_140100bc8(param_2) before it returns).
346
+ The quest node's execute fn_15CBD0 copies the resolved handle into a local with an explicit
347
+ reference increment, passes its address, and never releases that local. A native caller must
348
+ do the same: hand over a copy and not destruct it. Destructing it drops one reference per
349
+ call, and the body is later freed while still in use. The store step fn_15BD98 and the switch
350
+ fn_15C2A4 take the same handle by reference."
351
+ status: verified
352
+ verified_on: "2.31"
353
+ source: ModWright field verification
354
+ tags:
355
+ - replacer
356
+ - native
357
+ - abi
358
+ - handle
359
+ - crash
360
+ - version-pinned
361
+ related:
362
+ - cp2077.player.control.replacer-enable-stores-the-body-through-its-entity-stub
363
+ - id: cp2077.player.control.v-left-behind-under-a-replacer
364
+ claim: >-
365
+ While a replacer body is the controlled object, V's main PlayerPuppet renders as her
366
+ first-person entity, standing and headless. Three things were observed: - Queueing
367
+ ActivateTPPRepresentationEvent on her shows her third-person
368
+ body and head. This is the event
369
+ TakeOverControlSystem.EnablePlayerTPPRepresenation queues when V takes
370
+ over a camera or turret. Items.PlayerWaTppHead slotted in
371
+ AttachmentSlots.TppHead alone showed nothing.
372
+ - A workspot played on her (PlayInDeviceSimple) does animate her. - Her state machine does not
373
+ run: GetPlayerStateMachineBlackboard()
374
+ returns nothing, and setting the animation input 'crouch' directly
375
+ changes nothing.
376
+ So vanilla's takeover crouch cannot be reproduced on her through the state machine. That
377
+ crouch is the Crouch locomotion state, entered from the PSM blackboard's IsControllingDevice
378
+ (CrouchDecisions), with CrouchEvents setting the input 'crouch' to 1.0.
379
+ status: verified
380
+ verified_on: "2.31"
381
+ source: ModWright field verification
382
+ tags:
383
+ - replacer
384
+ - tpp
385
+ - representation
386
+ - workspot
387
+ - crouch
388
+ - psm
389
+ related:
390
+ - cp2077.player.control.replacer-body-walk-chain
391
+ - id: cp2077.player.control.takeover-pose-is-the-security-cam-anim-set
392
+ claim: "V's third-person animation sets for the security-camera takeover are
393
+ base\\animations\\player\\female\\body\\tpp_pwa_security_cam.anims (rig
394
+ base\\characters\\entities\\player\\player_woman_skeleton.rig) and
395
+ base\\animations\\player\\male\\body\\tpp_pma_security_cam.anims (rig
396
+ player_man_skeleton.rig). Each holds three clips of 12.23 s: idle_hacking, fpp_crouch_idle and
397
+ fpp_idle_stand."
398
+ status: verified
399
+ verified_on: "2.31"
400
+ source: the mod's .modwright/cache/templates/cyberpunk2077/2.31 entries
401
+ cp2077/anims/tpp_pwa_security_cam.anims and tpp_pma_security_cam.anims (animAnimSet
402
+ animations[].animation.name, duration, rig)
403
+ tags:
404
+ - animation
405
+ - takeover
406
+ - tpp
407
+ - workspot
408
+ - player
409
+ detail: A cyberware mod (v0.12.3) plays them on V while the replacer body is possessed, through two
410
+ workspots of its own (fpp_crouch_idle, idle_hacking). Which clip is the pose the game shows
411
+ during a takeover is not yet confirmed in game.
412
+ related:
413
+ - cp2077.player.control.v-left-behind-under-a-replacer
414
+ - id: cp2077.player.control.v-tpp-representation-lists-her-appearance-slots
415
+ claim: >-
416
+ V's player_ma_fpp.ent carries a gameTPPRepresentationComponent named TPPRepresentation with: -
417
+ affectedAppearanceSlots: AttachmentSlots.Chest, Torso, Outfit, Head,
418
+ Eyes and RightArm;
419
+ - attachedObjectInfo: Items.PlayerMaTppHead in AttachmentSlots.TppHead; - detachedObjectInfo:
420
+ Items.PlayerFppHead in TppHead. So activating the representation switches those slots' items
421
+ and the head by itself. mq060_android_replacer_v2.ent's TPPRepresentation lists no appearance
422
+ slots and attaches nothing. Its visible body is the appearance's own third-person garment
423
+ meshes: for the Arasaka droid, h0 (head), t0 (torso), a0 (arms) and l0 (legs), all bound to
424
+ V's skeleton. Those show in the first-person view.
425
+ status: verified
426
+ verified_on: "2.31"
427
+ source: ModWright field verification
428
+ tags:
429
+ - replacer
430
+ - tpp
431
+ - representation
432
+ - appearance
433
+ - fpp
434
+ related:
435
+ - cp2077.player.control.v-left-behind-under-a-replacer
436
+ - id: cp2077.player.control.android-replacer-loads-the-showroom-hud
437
+ claim: mq060_android_replacer_v2.ent's WidgetHudComponent 'hud_component' (CRUID
438
+ 2309867932290777088) loads base\gameplay\gui\hud_yaiba_proxy.inkhud with no external material.
439
+ V's player_ma_fpp.ent loads base\gameplay\gui\prototype_hud.inkhud with
440
+ base\materials\ui_main_hud.mt. So playing as the android replacer shows mq060's showroom proxy
441
+ HUD overlays instead of V's HUD.
442
+ status: verified
443
+ verified_on: "2.31"
444
+ source: ModWright field verification
445
+ tags:
446
+ - replacer
447
+ - hud
448
+ - ui
449
+ - template
450
+ - id: cp2077.player.control.vanilla-replacer-bodies-spawn-from-communities
451
+ claim: "Every vanilla replacer body read so far is spawned through the community system before
452
+ questReplacer_NodeType runs, never placed as a plain entity: mq060 activates the community
453
+ entry android_replacer (questCommunityTemplate_NodeType, spawner #mq060_communityArea); q304's
454
+ debug replacer setup phase activates a spawn set (questSpawnSet_NodeType Activate, reference
455
+ #q304_replacer, entries replacer_theo / replacer_bella, phase default), waits on
456
+ questCharacterSpawned_ConditionType, teleports the body onto the local player
457
+ (questTeleportPuppetNodeDefinition, destination refLocalPlayer), hides the player
458
+ (questShowWorldNode_NodeType isPlayer, show 0), and only then enables the replacer. Both
459
+ entries sit in the always-loaded community registry with alwaysSpawned true_, one time period
460
+ Day, quantity 1 and one spot each, inactive on start."
461
+ status: verified
462
+ verified_on: "2.31"
463
+ source: ep1\quest\main_quests\q304\phases\subphases\q304_debug_replacer_setup.questphase (nodes 3,
464
+ 4, 5, 6, 9, 14); base\quest\minor_quests\mq060\phases\mq060_yaiba_showroom.questphase (node
465
+ 174); base\worlds\03_night_city\_compiled\default\always_loaded_1.streamingsector from
466
+ ep1_1_nightcity.archive (the worldCommunityRegistryNode's items for community ids
467
+ 14864550580650116736 and 2958581958812022049)
468
+ tags:
469
+ - replacer
470
+ - community
471
+ - spawn-set
472
+ - questphase
473
+ - entity-stub
474
+ related:
475
+ - cp2077.player.control.replacer-switch-is-a-quest-node
476
+ - cp2077.quests.scenes.vanilla-quest-community-shape
477
+ - id: cp2077.player.control.replacer-take-death-guard-releases
478
+ claim: "While the replacer body is the player, vanilla god mode Immortal on the body
479
+ (GodModeSystem.AddGodMode, with the mod's own source name) plus a Health stat-pool listener
480
+ turns the body's death into a release: shot down in real combat, the body's health stopped at
481
+ 1%, the listener fired, the take released on the next frame (the replacer disable), and V came
482
+ back with no flatline screen. An earlier run without the guard ended in the flatline screen."
483
+ status: verified
484
+ verified_on: "2.31"
485
+ source: ModWright field verification
486
+ tags:
487
+ - replacer
488
+ - death
489
+ - godmode
490
+ - immortal
491
+ - statpool
492
+ - release
493
+ related:
494
+ - cp2077.player.control.v-left-behind-under-a-replacer
495
+ - id: cp2077.player.control.v-crouch-idle-is-in-player-locomotion
496
+ claim: V's own crouch idle is the clip fpp_crouch_idle in
497
+ base\animations\player\female\body\player_locomotion.anims (player_woman_skeleton.rig) and
498
+ ...\male\body\player_locomotion.anims (player_man_skeleton.rig), 6.77 s on both. The
499
+ security-cam sets tpp_pwa_security_cam.anims / tpp_pma_security_cam.anims, which V's FPP
500
+ entity also lists, hold another clip of the same name at 12.23 s, the length of their
501
+ idle_hacking and fpp_idle_stand. tpp_pwa_locomotion.anims holds only idle_hacking.
502
+ status: verified
503
+ verified_on: "2.31"
504
+ source: basegame_1_engine.archive and basegame_4_animation.archive (the animAnimation names and
505
+ durations); base\characters\entities\player\player_wa_fpp.ent (its animation set list)
506
+ tags:
507
+ - player
508
+ - crouch
509
+ - animation
510
+ - anims
511
+ - workspot
512
+ - pose
513
+ detail: "The file-read claim stands. The in-game reading drawn from it earlier does not: a later
514
+ test showed no workspot ever played on V under the take, and the takeover pose in question is
515
+ vanilla's camera-takeover pose, not V's plain crouch
516
+ (cp2077.player.control.v-takeover-pose-is-the-device-control-state)."
517
+ - id: cp2077.player.control.v-takeover-pose-is-the-device-control-state
518
+ claim: "V's pose during a camera or turret takeover comes from her state machine's device-control
519
+ flags: PlayerStateMachine.IsControllingDevice and IsInteractingWithDevice on her local
520
+ blackboard, set the way TakeOverControlSystem.PSMSetIsPlayerControllDevice sets them. Set
521
+ while V is still the controlled player and followed by the replacer enable, V is left behind
522
+ in that pose, seen from the body."
523
+ status: verified
524
+ verified_on: "2.31"
525
+ source: ModWright field verification
526
+ tags:
527
+ - replacer
528
+ - pose
529
+ - psm
530
+ - blackboard
531
+ - takeover
532
+ - device-control
533
+ related:
534
+ - cp2077.player.control.v-left-behind-under-a-replacer
535
+ - id: cp2077.player.control.workspot-play-on-v-before-the-replacer-does-nothing
536
+ claim: "WorkspotGameSystem.PlayInDeviceSimple(device, V, ...) on V's main object, called right after
537
+ the replacer enable, leaves her out of any workspot: IsActorInWorkspot(V) false,
538
+ IsWorkspotEnabled(V) false, the extended info inactive and GetDeviceUser(device) none. The
539
+ q104, security-cam and stance workspots all looked the same because none played."
540
+ status: verified
541
+ verified_on: "2.31"
542
+ source: ModWright field verification
543
+ tags:
544
+ - replacer
545
+ - workspot
546
+ - pose
547
+ - id: cp2077.player.control.player-tpp-head-wrapper-gates-the-security-cam-idle
548
+ claim: "V's FPP entity lists tpp_pwa_security_cam.anims (tpp_pma for the male rig) at priority 199,
549
+ gated by the variable player_tpp_head, the friendlyName of Items.PlayerWaTppHead, the head her
550
+ TPPRepresentation component attaches in AttachmentSlots.TppHead. Item friendlyNames are
551
+ anim-wrapper keys: every weapon set is gated by its weapon's name the same way. While
552
+ player_tpp_head is on, V's idle clips resolve to the security-cam set: the takeover pose
553
+ unarmed, a crouch idle armed."
554
+ status: verified
555
+ verified_on: "2.31"
556
+ source: base\characters\entities\player\player_wa_fpp.ent (entAnimatedComponent root,
557
+ animations.gameplay); TweakDB Items.PlayerWaTppHead (friendlyName, entityName
558
+ player_wa_tpp_head);
559
+ tools\redmod\scripts\core\components\animationControllerComponent.script:178
560
+ (SetAnimWrapperWeight)
561
+ tags:
562
+ - player
563
+ - animation
564
+ - anim-wrapper
565
+ - tpp
566
+ - idle
567
+ - pose
568
+ detail: "After the releases in one in-game test the variable stayed on: the TppHead slot held
569
+ PlayerFppHead again, a second DeactivateTPPRepresentationEvent and a full show/hide cycle with
570
+ V controlled changed nothing. A later mod version (v0.12.9) sets the wrapper to 0
571
+ (AnimationControllerComponent.SetAnimWrapperWeight) after the release, and in the next test
572
+ V's idle was normal after the release (\"no pose or crouch, that is working correctly\")."
573
+ - id: cp2077.player.control.replacer-body-first-person-mesh-set
574
+ claim: "The android replacer body in first person shows a second body with a weapon drawn, and V's
575
+ own hands next to the android's. Hiding the droid head garment (h0_007_ma_droid__heavy)
576
+ removes the second body. Hiding V's first-person arm meshes on the body (right_arm, left_arm:
577
+ a0_000_pwa_fpp__full_r/l), her nails and her personal link removes her hands. The droid torso,
578
+ the proxy mesh and V's torso change nothing. Gun and fists both work with that set hidden."
579
+ status: verified
580
+ verified_on: "2.31"
581
+ source: ModWright field verification
582
+ tags:
583
+ - replacer
584
+ - fpp
585
+ - meshes
586
+ - garment
587
+ - first-person
588
+ related:
589
+ - cp2077.player.control.v-tpp-representation-lists-her-appearance-slots
590
+ - id: cp2077.player.control.npc-toggled-mesh-returns-when-the-player-moves
591
+ claim: IComponent.Toggle(false) on an NPC's visual components (garment meshes) hides them only until
592
+ the player moves. Then they are enabled again, even with the NPC's
593
+ entVisualControllerComponent toggled off. On the replacer body (the player) the same toggles
594
+ held.
595
+ status: verified
596
+ verified_on: "2.31"
597
+ source: ModWright field verification
598
+ tags:
599
+ - npc
600
+ - meshes
601
+ - visibility
602
+ - hide
603
+ - id: cp2077.player.control.spawn-set-despawn-only-its-own
604
+ claim: spawn::Set::DespawnObject (hash 3168866665, exe+0x65CEFC on 2.31), which CET's
605
+ exEntitySpawner.Despawn calls on its own set, searches that set's spawned-entity array (+0x10,
606
+ count +0x1C) for the entity and returns without doing anything when it isn't there. It
607
+ despawns only what the set spawned, never an arbitrary world NPC.
608
+ status: verified
609
+ verified_on: "2.31"
610
+ source: maximegmd/CyberEngineTweaks src/reverse/RTTIExtender.cpp (TEMP_Spawner::Despawn) and
611
+ src/reverse/Addresses.h; Cyberpunk2077.exe 2.31 at rva 0x65CEFC
612
+ tags:
613
+ - spawn
614
+ - despawn
615
+ - cet
616
+ - npc
617
+ - id: cp2077.player.control.device-pose-needs-a-lead-before-the-switch
618
+ claim: V's device-control flags give the camera-takeover pose only when her state machine runs with
619
+ them before the replacer enable. Set in the same frame as the enable, V stays in her current
620
+ stance. Set a second or two ahead, she moves into the pose as the take begins.
621
+ status: verified
622
+ verified_on: "2.31"
623
+ source: ModWright field verification
624
+ tags:
625
+ - replacer
626
+ - pose
627
+ - psm
628
+ - timing
629
+ related:
630
+ - cp2077.player.control.v-takeover-pose-is-the-device-control-state
631
+ - id: cp2077.player.control.npc-chunkmask-zero-hides-until-reregistered
632
+ claim: "Setting chunkMask to 0 on an NPC's skinned meshes (entSkinnedMeshComponent.chunkMask;
633
+ MeshComponent has its own field) hides them durably. The engine re-enables them when the
634
+ player moves, but they draw nothing. The reverse needs a re-register: with the original masks
635
+ back on enabled components the NPC stays invisible until each is toggled off and on, and then
636
+ shows at once."
637
+ status: verified
638
+ verified_on: "2.31"
639
+ source: ModWright field verification
640
+ tags:
641
+ - npc
642
+ - meshes
643
+ - visibility
644
+ - hide
645
+ - chunkmask
646
+ related:
647
+ - cp2077.player.control.npc-toggled-mesh-returns-when-the-player-moves
648
+ - id: cp2077.player.control.npc-weapon-and-weakspots-are-separate-objects
649
+ claim: "Hiding an NPC's own visual components leaves its held weapon and its weak points visible.
650
+ The weapon is the ItemObject in AttachmentSlots.WeaponRight or WeaponLeft (the android's
651
+ rifle: a gameweaponObject with 19 visual components). The weak points are WeakspotObjects
652
+ listed by the NPC's WeakspotComponent.GetWeakspots. Each needs the same hide. For weak points,
653
+ vanilla also blocks the highlight and the targeting with a WeakspotRequestAttributeChangeEvent
654
+ (blockHighlight, blockDamage)."
655
+ status: verified
656
+ verified_on: "2.31"
657
+ source: ModWright field verification
658
+ tags:
659
+ - npc
660
+ - weapon
661
+ - weakspot
662
+ - hide
663
+ - id: cp2077.player.control.v-detection-cyberware-fires-on-the-body
664
+ claim: "While V controls the replacer body, the body is the player: enemies that see it raise the
665
+ global stealth detection, and V's Synaptic Accelerator fires. The accelerator is a
666
+ DetectionMeterEffector applied on V: it listens to UI_Stealth.highestHostileDetectionOnPlayer
667
+ (or highestDetectionOnPlayer) and applies its status effect in stacks as the detection passes
668
+ each step."
669
+ status: verified
670
+ verified_on: "2.31"
671
+ source: ModWright field verification
672
+ tags:
673
+ - replacer
674
+ - cyberware
675
+ - detection
676
+ - stealth
677
+ - effector
678
+ detail: A mod version (v0.12.10) wraps DetectionMeterEffector.OnDetectionChanged to return early
679
+ while a take is active, and in a later test the body under a hostile android's detection left
680
+ it quiet ("no synaptic accelerator - it drew its weapon but not attacking"); it fired again
681
+ once V was back.
682
+ - id: cp2077.player.control.replacer-take-works-end-to-end
683
+ claim: >-
684
+ The replacer-body take works end to end on 2.31. Its pieces: - V's device-control flags set a
685
+ second or more before the enable, from
686
+ the quickhack's upload start or a 1 s console lead;
687
+ - the enable on a community-spawned replacer body; - V shown in third person; - a first-person
688
+ pass hiding the droid head and V's own first-person
689
+ arms, nails and personal link;
690
+ - the target's meshes, weapon-slot items and weak points hidden with
691
+ chunkMask 0, and the target frozen;
692
+ - god mode Immortal and a health-floor release; - a release that clears V's flags and the
693
+ player_tpp_head wrapper,
694
+ and restores the target with the masks back and an off-on.
695
+ The real quickhack starts it and ends it on the hack's timer. A player rifle preset
696
+ (Items.Preset_Masamune_Arasaka_2077) equipped on the body sits in the android's hands and
697
+ fires.
698
+ status: verified
699
+ verified_on: "2.31"
700
+ source: ModWright field verification
701
+ tags:
702
+ - replacer
703
+ - take
704
+ - end-to-end
705
+ - quickhack
706
+ - weapon
707
+ related:
708
+ - cp2077.player.control.device-pose-needs-a-lead-before-the-switch
709
+ - cp2077.player.control.npc-chunkmask-zero-hides-until-reregistered
710
+ - cp2077.player.control.replacer-take-death-guard-releases
711
+ - id: cp2077.player.control.replacer-body-cannot-be-dismembered
712
+ claim: "The android replacer template (mq060_android_replacer_v2.ent) carries no dismemberment
713
+ component: its puppet's dismembermentComponent field is null, and no DismembermentComponent is
714
+ listed. V's FPP templates (player_ma_fpp.ent, player_wa_fpp.ent) have none either. Only their
715
+ skinned meshes' acceptDismemberment flags mention it. So the body can't lose limbs, and of its
716
+ damage only health can carry to the NPC it stands for. Vanilla dismembers an NPC through
717
+ DismembermentComponent.RequestDismemberment(obj, bodyPart, woundType, …), which queues a
718
+ DismembermentEvent for the NPC's own component."
719
+ status: verified
720
+ verified_on: "2.31"
721
+ source: the mod's .modwright/cache/templates/cyberpunk2077/2.31 entries for
722
+ mq060_android_replacer_v2.ent and player_ma_fpp.ent;
723
+ base\characters\entities\player\player_wa_fpp.ent;
724
+ tools\redmod\scripts\core\components\dismembermentComponent.script:59-124
725
+ tags:
726
+ - replacer
727
+ - dismemberment
728
+ - damage
729
+ - template
730
+ - id: cp2077.player.control.npc-equipment-points-at-player-presets
731
+ claim: An NPC's equipment pools name the same item records the player uses. Character.android_guards
732
+ (base arasaka_android_android2_masamune_ma) has primaryEquipment pool
733
+ Character.ArasakaAssaultRiflePool, whose entries are Items.Preset_Masamune_Arasaka_2077,
734
+ Items.Preset_Kyubi_Military and Items.Preset_Masamune_Military, each equipped in
735
+ AttachmentSlots.WeaponRight. AIActionTransactionSystem.CalculateEquipmentItems(puppet,
736
+ 'PrimaryEquipment', items, powerLevel) rolls the pool with a seed from the puppet's entity id,
737
+ so it computes the same pick the NPC got.
738
+ status: verified
739
+ verified_on: "2.31"
740
+ source: .modwright-cache/cyberpunk2077/vanilla.sqlite (Character.android_guards chain,
741
+ Character.ArasakaAssaultRiflePool and its inlines);
742
+ tools\redmod\scripts\core\systems\transactionSystem.script:104-200
743
+ tags:
744
+ - npc
745
+ - equipment
746
+ - weapon
747
+ - tweakdb
748
+ - id: cp2077.player.control.replacer-take-carries-health-and-weapon
749
+ claim: The replacer take can carry the target's state into the body and back. The target's Health
750
+ share set on the body right after the possess (StatPoolsSystem.RequestSettingStatPoolValue,
751
+ percentage) shows on the HUD. The target's own weapon record, given to the body with an
752
+ EquipRequest, is drawn and fires. The body's Health share set on the target at a non-floor
753
+ release leaves it alive at that share.
754
+ status: verified
755
+ verified_on: "2.31"
756
+ source: ModWright field verification
757
+ tags:
758
+ - replacer
759
+ - take
760
+ - health
761
+ - weapon
762
+ - statpool
763
+ related:
764
+ - cp2077.player.control.npc-equipment-points-at-player-presets
765
+ - cp2077.player.control.replacer-body-cannot-be-dismembered
766
+ detail: "Open: the bridge's GetStatPoolValue(bodyId, Health, true) read 100% while the HUD showed
767
+ the carried 60%. After a later set to 35% both agreed."
768
+ - id: cp2077.player.control.scaffolded-replacer-body-matches-hand-built
769
+ claim: A replacer body generated by ModWright's new-player-replacer scaffold (its own .ent copy of
770
+ the android replacer template with one appearance and V's HUD rewritten in both HUD component
771
+ copies, a TweakXL record deriving Character.Player_Replacer_Puppet_Base, and the community
772
+ sector, block and fact-gated phase) works in place of a hand-built one. ArchiveXL merges its
773
+ phase and block, TweakXL reads the record without error, the community spawns a PlayerPuppet
774
+ of the new record with IsReplacer true at the spot, the plugin's replacer enable switches
775
+ control to it with V's own HUD and no ArchiveXL HUD patch, and the whole hack take runs on it.
776
+ status: verified
777
+ verified_on: "2.31"
778
+ source: ModWright field verification
779
+ tags:
780
+ - replacer
781
+ - scaffold
782
+ - hud
783
+ - community
784
+ - acceptance
785
+ related:
786
+ - cp2077.player.control.replacer-take-works-end-to-end
787
+ - cp2077.player.control.android-replacer-loads-the-showroom-hud
788
+ detail: The bare replacer-on switch leaves V headless, as in earlier tests; the take (the mod's
789
+ possess command or the hack) is what shows her whole. A body that had been the player
790
+ despawned cleanly with body-off.
791
+ - id: cp2077.player.control.replacer-body-is-the-player-to-npcs
792
+ claim: "While a replacer body is the player, every NPC treats it as the player, whatever it looks
793
+ like. A hostile squad attacked the body of its own Scavenger android. A target NPC hidden
794
+ during the take (visuals off, collision off, AI component toggled off, its time dilated to
795
+ 0.0001) still sensed and reacted: the body's gunfire, which comes from the player, or V
796
+ standing in its sight, put it into combat and onto the minimap."
797
+ status: verified
798
+ verified_on: "2.31"
799
+ source: ModWright field verification
800
+ tags:
801
+ - replacer
802
+ - player
803
+ - attitude
804
+ - senses
805
+ - npc
806
+ - take
807
+ related:
808
+ - cp2077.player.control.replacer-enable-stores-the-body-through-its-entity-stub
809
+ detail: A later mod version (v0.12.24) gives the body the target's attitude group, and turns the
810
+ hidden target's SenseComponent and ReactionManagerComponent off for the take; untested.
811
+ - id: cp2077.player.control.teleport-to-node-streams-a-raw-teleport-falls-through
812
+ claim: "TeleportationFacility.TeleportToNode(player, a fast-travel point's marker) takes V across
813
+ the map and the destination streams in. A raw TeleportationFacility.Teleport of V to a far
814
+ position, 1 m or 5 m above the target's height, fell through the not-yet-streamed ground, and
815
+ the game put V back. A fast-travel point is registered for this only once the save has it:
816
+ Arasaka Waterfront FT 03 and Dogtown's Luxor High were \"not a registered point\"."
817
+ status: verified
818
+ verified_on: "2.31"
819
+ source: ModWright field verification
820
+ tags:
821
+ - teleport
822
+ - fast-travel
823
+ - streaming
824
+ - player
825
+ - bridge
826
+ - id: cp2077.player.control.a-hustle-pin-is-found-by-its-journal-id
827
+ claim: "An NCPD hustle's map pin is found from script by its quest id: among
828
+ MappinSystem.GetAllMappins(), the PointOfInterestMappin whose
829
+ JournalManager.GetEntry(GetJournalPathHash()).GetId() is the id (for example ma_wat_nid_01).
830
+ The Repeatable NCPD Gigs mod finds hustles this way. Its GetWorldPosition is the hustle's
831
+ position, and the FastTravelMappin nearest it (GetPointData) is the terminal to travel to."
832
+ status: verified
833
+ verified_on: "2.31"
834
+ source: ModWright field verification
835
+ tags:
836
+ - journal
837
+ - mappin
838
+ - hustle
839
+ - ncpd
840
+ - bridge
841
+ - id: cp2077.player.control.v-left-unable-to-walk-after-a-release
842
+ claim: "After a take ends, V can be left able to look but not walk, though her state machine reads
843
+ clean (no movement restriction, not in a workspot, the device-control pose off). The recovery,
844
+ in a quickhack mod, is a free-V routine (an instant workspot exit if she is still in one, the
845
+ pose entity deleted, the device pose off, the player_tpp_head wrapper at 0), run after every
846
+ release: the replacer-body take has done it at 0.5 s and 2 s since v0.12.8, and the drone take
847
+ from v0.12.35 after the Wyvern died (at 0.1 s and 1.5 s). A separate cleanup that strips the
848
+ NoJump and NoRadialMenus restrictions fixes a different leftover."
849
+ status: verified
850
+ verified_on: "2.31"
851
+ source: ModWright field verification
852
+ tags:
853
+ - release
854
+ - take
855
+ - v
856
+ - movement
857
+ - workspot
858
+ - recovery
859
+ related:
860
+ - cp2077.player.control.replacer-take-death-guard-releases
861
+ - id: cp2077.player.control.the-game-ships-human-replacers
862
+ claim: "Besides the androids, the game's replacer records (deriving
863
+ Character.Player_Replacer_Puppet_Base) include human bodies on V's rig:
864
+ Character.mq304_assassin_replacer_male (ep1 assasin_ma_replacer.ent, on
865
+ player_man_skeleton.rig, wearing nicola_ma.app _mq304__nicola_fpp), johnny_replacer,
866
+ kurt_replacer, mq303_lina_replacer, q304_netrunner_replacer_bella / _theo / _combined,
867
+ e3_v_solo_female (player_wa_fpp_replacer.ent), mws_se5_03_player, q000_vr_replacer and
868
+ braindance_replacer. A male human replacer template is the base for a body that wears a male
869
+ NPC's look, as the android replacer is for androids."
870
+ status: verified
871
+ verified_on: "2.31"
872
+ source: ModWright field verification
873
+ tags:
874
+ - replacer
875
+ - human
876
+ - body
877
+ - template
878
+ related:
879
+ - cp2077.player.control.replacer-take-death-guard-releases
880
+ - id: cp2077.player.control.human-look-on-a-human-replacer-body
881
+ claim: "A male human NPC's look worn by a replacer body built on the game's male assassin replacer
882
+ template (V's rig) renders correctly and plays normally: the man_base-rig gang meshes fit
883
+ player_man_skeleton, the look's own cyberarm shows, and movement, behaviour and firing are
884
+ V's. In first person the look's head group and its neck items (a spiked choker) must be
885
+ hidden, before the switch or they flash."
886
+ status: verified
887
+ verified_on: "2.31"
888
+ source: ModWright field verification
889
+ tags:
890
+ - replacer
891
+ - human
892
+ - body
893
+ - look
894
+ - fpp
895
+ related:
896
+ - cp2077.player.control.the-game-ships-human-replacers
897
+ - cp2077.npc.appearance.a-human-looks-head-group
898
+ - id: cp2077.player.control.weapon-safe-reads-is-aiming-at-friendly
899
+ claim: "Out of combat the player's state machine lowers the gun (the weapon-safe state) and the
900
+ crosshair shows friendly when PlayerPuppet .IsAimingAtFriendly() is true. It is set on look-at
901
+ changes from PlayerPuppet.IsTargetFriendlyNPC: the target's attitude toward the player is
902
+ AIA_Friendly, unless the target carries BaseStatusEffect.IgnoreWeaponSafe. A replacer body
903
+ that is the player inherits this against whatever group reads Friendly toward it.
904
+ BaseStatusEffect.DoNotBlockShootingOnFriendlyFire is the NPC AI's friendly-fire condition, not
905
+ the player's."
906
+ status: verified
907
+ verified_on: "2.31"
908
+ source: tools\redmod\scripts\cyberpunk\player\psm\defaultTransition.script:163-170
909
+ (ShouldEnterSafe); crosshairTransitions.script:59; cyberpunk\player\player.script:786-821,
910
+ 1732-1756; core\ai\actions\tweakAIConditionChecks.script:2178
911
+ tags:
912
+ - player
913
+ - weapon-safe
914
+ - attitude
915
+ - friendly
916
+ - replacer
917
+ detail: A quickhack mod (v0.12.66) wraps IsAimingAtFriendly to return false for the take's body
918
+ (untested when recorded).