{"id":524,"date":"2020-10-25T08:43:44","date_gmt":"2020-10-25T13:43:44","guid":{"rendered":"https:\/\/badecho.com\/?p=524"},"modified":"2020-11-17T13:29:14","modified_gmt":"2020-11-17T18:29:14","slug":"hacking-dark-souls-iii-part-5","status":"publish","type":"post","link":"https:\/\/badecho.com\/index.php\/2020\/10\/25\/hacking-dark-souls-iii-part-5\/","title":{"rendered":"Omnifying (Hacking) Dark Souls III &#8211; Part 5 (Playtest Fixes)"},"content":{"rendered":"\n<h2>Our Hacking of Dark Souls III Has Been Tested on Stream<\/h2>\n\n\n\n<p>With the initial hacking of Dark Souls III now complete, a playtest of it was in order. The game received its debut earlier today on <a href=\"https:\/\/twitch.tv\/omni\" target=\"_blank\" rel=\"noreferrer noopener\">stream<\/a> to much acclaim and applause (insert Kappa?). I look forward to playing through it in its entirety &#8212; it is sure to be both punishing and beautiful. If you miss any of the live streams, be sure to check out previous broadcasts uploaded to my <a href=\"https:\/\/youtube.com\/c\/omniTTV\" target=\"_blank\" rel=\"noreferrer noopener\">YouTube<\/a>.<\/p>\n\n\n\n<p>Although it was a fairly smooth few hours of gameplay, a number of issues did pop up that required some fixing off-stream. I&#8217;ll be documenting those fixes in this article, and I feel this Omnified game is definitely going to be very enjoyable and playable following these fixes. What I&#8217;m doing here will more or less be a process template for future Omnified hackings: initial Omnification articles will be written while I&#8217;m hacking the game, with a follow up post-playtest article published containing any critical fixes.<\/p>\n\n\n\n<p>I&#8217;ll be going over all critical problems encountered with a link to the original article the particular hack in question was written in and then how I went about fixing it. Any other changes or fixes to the game in the future will get an individual article if notable enough!<\/p>\n\n\n\n<h2>I. Shifting Character Modules Issue<\/h2>\n\n\n\n<p>In the <a href=\"https:\/\/badecho.com\/index.php\/2020\/09\/25\/hacking-dark-souls-iii-part-1\/\" target=\"_blank\" rel=\"noreferrer noopener\">first hacking Dark Souls III article<\/a> on data structure analysis, we charted out the contents of the player&#8217;s root structure, including how we can find the <strong>SprjChrDataModule<\/strong> (which contains the player&#8217;s vitals) and the <strong><strong>SprjChrPhysicsModule<\/strong><\/strong> (which contains the player&#8217;s coordinates) inside of it. The player hook was further updated in the <a href=\"https:\/\/badecho.com\/index.php\/2020\/09\/28\/hacking-dark-souls-iii-part-2\/\" target=\"_blank\" rel=\"noreferrer noopener\">follow-up article<\/a> I wrote on Dark Soul III&#8217;s Apocalypse implementation.<\/p>\n\n\n\n<p>We found that the these data and physics modules could be found at offsets <strong>0x23D8 <\/strong>and <strong>0x2428<\/strong> respectively.  It was assumed, at the time of writing, that these offsets were static and wouldn&#8217;t change &#8212; this is a reasonable assumption to make. However, during the stream, I noticed that the location of these modules inside the root structure would randomly shift around. Sometimes the physics module would be found at <strong>0x2408<\/strong>, sometimes it would be found at <strong>0x2218<\/strong>, etc.<\/p>\n\n\n\n<p>Anyway, adding support for all the various places the modules <em>could<\/em> show up would be foolish, as there&#8217;s no guarantee there wouldn&#8217;t be any more places to add support for later on; it clearly isn&#8217;t how the data types were designed to be interacted with.<\/p>\n\n\n\n<p>What I did was look for code that was accessing the various modules <em>inside<\/em> the root structure, and tried to determine how the game code itself went about finding these modules. Eventually I stumbled on code that revealed the use of a <em>module collection<\/em> pointer, also found on the root structure, and located at the offset <strong>0x1F90<\/strong>. This pointer points to the starting address of all the modules for that character, and the collection pointer is indeed static.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"946\" height=\"533\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/10\/playtestFixesShifting.png\" alt=\"After hacking Dark Souls III and making it Omnified, I noticed the character modules would shift randomly in location. This picture shows the recently discovered module collection pointer and its contents.\" class=\"wp-image-526\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/10\/playtestFixesShifting.png 946w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/10\/playtestFixesShifting-300x169.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/10\/playtestFixesShifting-768x433.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/10\/playtestFixesShifting-480x270.png 480w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><figcaption>Here are the contents of the easily locatable module collection structure.<\/figcaption><\/figure><\/div>\n\n\n\n<p>I realized that this pointer was our golden ticket right away, as I previously saw a similar practice being followed in Sekiro&#8217;s code, which shares many similarities with Dark Souls III.<\/p>\n\n\n\n<p>Armed with a more reliable way to map our player data, the player hook has been updated to the following code:<\/p>\n\n\n\n<h3>Player Hook With Shifting Module Support<\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Gets the player's root, coordinates, and vitals structs.\n\/\/ rcx: Address of player's root struct.\ndefine(omniPlayerHook, &quot;DarkSoulsIII.exe&quot; + C1A78C)\n\nassert(omniPlayerHook, 48 8B 01 FF 90 C0 02 00 00)\nalloc(getPlayer,$1000, omniPlayerHook)\nalloc(player,8)\nalloc(playerCoords,8)\nalloc(playerVitals,8)\n\nregistersymbol(omniPlayerHook)\nregistersymbol(player)\nregistersymbol(playerCoords)\nregistersymbol(playerVitals)\n\ngetPlayer:\n  push rbx\n  push rcx\n  push rdx\n  mov rbx,player\n  mov [rbx],rcx  \n  mov rdx,[rcx+1F90]\n  mov rcx,rdx\n  mov rdx,[rcx+68]\n  mov rbx,playerCoords\n  mov [rbx],rdx\n  mov rdx,[rcx+18]\n  mov rbx,playerVitals\n  mov [rbx],rdx\n  pop rdx\n  pop rcx\n  pop rbx\ngetPlayerOriginalCode:\n  mov rax,[rcx]\n  call qword ptr [rax+000002C0]\n  jmp getPlayerReturn\n\n\nomniPlayerHook:\n  jmp getPlayer\n  nop 4\ngetPlayerReturn:\n<\/pre>\n\n\n<h2>II. Unreliable Morphing Scale ID Location<\/h2>\n\n\n\n<p>In the <a href=\"https:\/\/badecho.com\/index.php\/2020\/10\/09\/hacking-dark-souls-iii-part-4\/\" target=\"_blank\" rel=\"noreferrer noopener\">Dark Souls III Abomnification implementation article<\/a>, we found a place we thought suitable in memory to hold creatures&#8217; morphing scale IDs. Specifically, we chose the offset <strong>0x39C<\/strong> inside the <strong>SprjCharPhysicsModule<\/strong> to be the home for the creature&#8217;s ID.<\/p>\n\n\n\n<p>While this seemed to be OK at the time, it was found to actually be unreliable during the playtest. A new and easier to find place was designated as the home for the morph scale ID: offset <strong>0x1194<\/strong> in the <strong>PlayerIns<\/strong> and <strong>EnemyIns<\/strong> root structures.<\/p>\n\n\n\n<p>There were also difficulties in retrieving the <strong>EnemyIns<\/strong> structure while executing inside our Abomnification application code (where our custom scaling occurs). We previously identified a reliable way for retrieving it to be by dereferencing the <strong>r12<\/strong> register and looking at offset <strong>0x58.<\/strong> However, this caused a number of Abomnifications to fail, and it was discovered we needed to also add support for looking at the <strong>0x68<\/strong> offset as well, as the <strong>EnemyIns<\/strong> could also appear there.<\/p>\n\n\n\n<p>Here is the updated code for the Abomnification initiation point hook using the new morph scale index location.<\/p>\n\n\n\n<h3>Updated Abomnification Initiation Hook<\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Initiates the Abomnification system, generating new scaling parameters\n\/\/ for a creature.  \n\/\/ rbx: Target physics module.\ndefine(omnifyAbomnificationHook,&quot;DarkSoulsIII.exe&quot;+9D2360)\n\nassert(omnifyAbomnificationHook,66 0F 7F B3 80 00 00 00)\nalloc(initiateAbomnification,$1000,omnifyAbomnificationHook)\n\nregistersymbol(omnifyAbomnificationHook)\n\ninitiateAbomnification:\n  pushf\n  \/\/ Ensure that the player coordinates pointer has been initialized.\n  push rax\n  mov rax,playerCoords\n  cmp [rax],0\n  pop rax\n  je initiateAbomnificationOriginalCode\n  \/\/ Ensure that the we aren't about the Abomnify the player.\n  push rax\n  mov rax,playerCoords\n  cmp rbx,[rax]\n  pop rax\n  je initiateAbomnificationOriginalCode\n  \/\/ Load the address to the morph scale ID and then call the Abomnification\n  \/\/ system.\n  push rax\n  push rcx\n  \/\/ The root structure can be found here on the physics\n  \/\/ module.\n  mov rcx,[rbx+8]\n  lea rax,[rcx+1194]\n  pop rcx\n  push rax\n  call executeAbomnification\n  pop rax\ninitiateAbomnificationOriginalCode:\n  popf\n  movdqa [rbx+00000080],xmm6\n  jmp initiateAbomnificationReturn\n\nomnifyAbomnificationHook:\n  jmp initiateAbomnification\n  nop 3\ninitiateAbomnificationReturn:\n<\/pre>\n\n\n<p>The initiation point now grabs the <strong>EnemyIns<\/strong> structure from the physics module, and uses the new offset instead. This new one works great!<\/p>\n\n\n\n<p>Here is the updated code for the Abomnification application hook:<\/p>\n\n\n\n<h3>Updated Abomnification Application Hook<\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Applies the Abomnification system.\n\/\/ [rax]: Width matrix values \n\/\/ [rax+10]: Height matrix values\n\/\/ [rax+20]: Depth matrix values\ndefine(omnifyApplyAbomnificationHook, &quot;DarkSoulsIII.exe&quot; + D279FC)\n\nassert(omnifyApplyAbomnificationHook, 0F 28 00 4B 8D 14 76)\nalloc(applyAbomnification,$1000, omnifyApplyAbomnificationHook)\nalloc(abomnifyPlayer,8)\nalloc(disableAbomnify,8)\nalloc(skipTypeCheck,8)\n\nregistersymbol(omnifyApplyAbomnificationHook)\nregistersymbol(abomnifyPlayer)\nregistersymbol(disableAbomnify)\nregistersymbol(skipTypeCheck)\n\napplyAbomnification:\n  pushf\n  cmp [disableAbomnify],1\n  je applyAbomnificationOriginalCode\n  \/\/ Ensure that the player root structure pointer has been initialized.\n  push rax\n  mov rax,player\n  cmp [rax],0\n  pop rax\n  je applyAbomnificationOriginalCode\n  \/\/ Backing up a few registers we'll be using to perform calculations\n  \/\/ on the original matrix values with updated scaling parameters.\n  sub rsp,10\n  movdqu [rsp],xmm0\n  sub rsp,10\n  movdqu [rsp],xmm1\n  push rbx\n  push rcx\n  \/\/ We take a look at the address stored at the place we expect to\n  \/\/ find the enemy root structure, and see if it is a valid pointer.\n  mov rbx,[r12+58]\n  lea rcx,[rbx]\n  call checkBadPointer\n  cmp ecx,0\n  je checkAbomnifyType\n  \/\/ The root structure sometimes appears at 0x68 instead.\n  mov rbx,[r12+68]\n  lea rcx,[rbx]\n  call checkBadPointer\n  cmp ecx,0\n  jne applyAbomnificationExit\n  \/\/ We do another check to ensure that it isn't a humanoid model.\n  \/\/ Human scaling is done in the applyAbomnificationHuman hook.\ncheckAbomnifyType:\n  cmp [skipTypeCheck],1\n  je checkAbomnifyPlayer\n  push rax\n  mov rax,[rbx]  \n  cmp ax,0x3EB8\n  pop rax\n  jne applyAbomnificationExit\n  \/\/ We then further check to see if the root structure address differs\n  \/\/ from the player's own root structure.\ncheckAbomnifyPlayer:\n  cmp [abomnifyPlayer],1\n  je loadScaleData\n  mov rcx,player\n  cmp rbx,[rcx]\n  je applyAbomnificationExit  \nloadScaleData:\n  \/\/ Now that we know our data is good, we want to check if a morph scale\n  \/\/ ID has actually been assigned yet by the Abomnification system.\n  mov rcx,[rbx+1194]\n  cmp rcx,0\n  je applyAbomnificationExit\n  \/\/ This should never happen, but we want to ensure we aren't going to access\n  \/\/ memory beyond the allocated bounds of our sandbox region.\n  cmp ecx,#999\n  ja applyAbomnificationExit\n  \/\/ Each creature has morph scale data that takes up a total of 48 bytes.\n  \/\/ So we want to multiply the size of each section by our ID to get the\n  \/\/ offset to apply to our base morphScaleData, which will give us the\n  \/\/ location to our creature-specific morph scale data.\n  push rax\n  push rdx\n  mov rax,rcx\n  mov rcx,#48\n  mul rcx\n  mov ecx,eax\n  pop rdx\n  pop rax\n  mov rbx,morphScaleData\n  add rbx,rcx\napplyAbomnificationScaleAdjustment:\n  \/\/ We want to then do one final check to ensure that some sort of morph\n  \/\/ scale data has actually been initialized for the creature.\n  lea rcx,[rbx+4]\n  call checkBadPointer\n  cmp ecx,0\n  jne applyAbomnificationExit\n  mov rcx,[rbx+4]\n  cmp rcx,0\n  je applyAbomnificationExit\n  \/\/ We load the scaling parameter for the creature's width, and then multiply\n  \/\/ the live width matrix values by it.\n  movss xmm0,[rbx+4]\n  shufps xmm0,xmm0,0\n  movdqu xmm1,[rax]\n  mulps xmm1,xmm0\n  movdqu [rax],xmm1\n  \/\/ We load the scaling parameter for the creature's height, and then multiply\n  \/\/ the live height matrix values by it.\n  movss xmm0,[rbx+8]\n  shufps xmm0,xmm0,0\n  movdqu xmm1,[rax+10]\n  mulps xmm1,xmm0\n  movdqu [rax+10],xmm1\n  \/\/ We load the scaling parameter for the creature's depth, and then multiply\n  \/\/ the live depth matrix values by it.\n  movss xmm0,[rbx+C]\n  shufps xmm0,xmm0,0\n  movdqu xmm1,[rax+20]\n  mulps xmm1,xmm0\n  movdqu [rax+20],xmm1  \napplyAbomnificationExit:\n  \/\/ Restore backed up values.\n  pop rcx\n  pop rbx\n  movdqu xmm1,[rsp]\n  add rsp,10\n  movdqu xmm0,[rsp]\n  add rsp,10\napplyAbomnificationOriginalCode:\n  popf\n  movaps xmm0,[rax]\n  lea rdx,[r14+r14*2]\n  jmp applyAbomnificationReturn\n\n\nomnifyApplyAbomnificationHook:\n  jmp applyAbomnification\n  nop 2\napplyAbomnificationReturn:\n<\/pre>\n\n\n<h2>III. Humanoid Bodies and Armor Not Morphing<\/h2>\n\n\n\n<p>Another issue with the Abomnification system that I observed was that most humanoid NPCs were failing to morph at all, as well as more complicated armors worn by them. This was no good! Everything needs to be Abomnified!<\/p>\n\n\n\n<p>I determined that our current Abomnification application hook was successfully applying scaling to all incoming rendering requests. That meant that there was another function in code purposed to handle the rendering of humanoid NPC models and their outfits. I located this code by putting on an outfit that had a nice wavy cloak, and then repeating the steps I followed in the <a href=\"https:\/\/badecho.com\/index.php\/2020\/10\/09\/hacking-dark-souls-iii-part-4\/\" target=\"_blank\" rel=\"noreferrer noopener\">Abomnification implementation article for Dark Souls III<\/a> to find the original Abomnification application hook location.<\/p>\n\n\n\n<p>Eventually I found a matrix multiplication routine at <strong>&#8220;DarkSoulsIII.exe&#8221;+C2FBCE<\/strong>, and implemented another Abomnification application hook there, basically identical to the original one.<\/p>\n\n\n\n<p>After wiring it up (and enabling it to work on the player character temporarily) I was <em>super <\/em>thrilled to see that the player&#8217;s cloak was actually morphing! This was a big deal because, although I&#8217;d been able to get more and more parts of the models morphing with each game I&#8217;ve done, I&#8217;ve never been able to get long wavy cloaks and dresses in FromSoftware games to morph.<\/p>\n\n\n\n<p>Unfortunately, the hook has no effect (from what I&#8217;ve seen) on enemy dresses. Cloaks and complicated armor do appear to be working now however. As well as faces and weapons, which were not previously. All in all, I think we&#8217;re good here. Game is way more streamable now for me.<\/p>\n\n\n\n<p>Here is the new Abomnification application hook for human NPC body types:<\/p>\n\n\n\n<h3>Humanoid\/Clothing Abomnification Application Hook<\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Applies the Abomnification for humans. \ndefine(omnifyApplyAbomnificationHumanHook, &quot;DarkSoulsIII.exe&quot; + C2FBCE)\n\nassert(omnifyApplyAbomnificationHumanHook, 0F 28 00 4B 8D 0C 76)\nalloc(applyAbomnificationHuman,$1000, omnifyApplyAbomnificationHumanHook)\nalloc(disableAbomnifyHuman,8)\n\nregistersymbol(omnifyApplyAbomnificationHumanHook)\nregistersymbol(disableAbomnifyHuman)\n\napplyAbomnificationHuman:\n  pushf  \n  cmp [disableAbomnifyHuman],1\n  je applyAbomnificationHumanOriginalCode\n  \/\/ Ensure that the player root structure pointer has been initialized.\n  push rax\n  mov rax,player\n  cmp [rax],0\n  pop rax\n  je applyAbomnificationHumanOriginalCode\n  \/\/ Backing up a few registers we'll be using to perform calculations\n  \/\/ on the original matrix values with updated scaling parameters.\n  sub rsp,10\n  movdqu [rsp],xmm0\n  sub rsp,10\n  movdqu [rsp],xmm1\n  push rbx\n  push rcx\n  \/\/ We take a look at the address stored at the place we expect to\n  \/\/ find the enemy root structure, and see if it is a valid pointer.\n  mov rbx,[rsp+162]\n  lea rcx,[rbx]\n  call checkBadPointer\n  cmp ecx,0\n  jne applyAbomnificationHumanExit  \n  \/\/ We then further check to see if the root structure address differs\n  \/\/ from the player's own root structure.\n  cmp [abomnifyPlayer],1\n  je loadScaleHumanData\n  mov rcx,player\n  cmp rbx,[rcx]\n  je applyAbomnificationHumanExit  \nloadScaleHumanData:\n  \/\/ Now that we know our data is good, we want to check if a morph scale\n  \/\/ ID has actually been assigned yet by the Abomnification system.\n  mov rcx,[rbx+1194]\n  cmp rcx,0\n  je applyAbomnificationHumanExit\n  \/\/ This should never happen, but we want to ensure we aren't going to access\n  \/\/ memory beyond the allocated bounds of our sandbox region.\n  cmp ecx,#999\n  ja applyAbomnificationHumanExit\n  \/\/ Each creature has morph scale data that takes up a total of 48 bytes.\n  \/\/ So we want to multiply the size of each section by our ID to get the\n  \/\/ offset to apply to our base morphScaleData, which will give us the\n  \/\/ location to our creature-specific morph scale data.\n  push rax\n  push rdx\n  mov rax,rcx\n  mov rcx,#48\n  mul rcx\n  mov ecx,eax\n  pop rdx\n  pop rax\n  mov rbx,morphScaleData\n  add rbx,rcx\napplyAbomnificationHumanScaleAdjustment:\n  \/\/ We want to then do one final check to ensure that some sort of morph\n  \/\/ scale data has actually been initialized for the creature.\n  lea rcx,[rbx+4]\n  call checkBadPointer\n  cmp ecx,0\n  jne applyAbomnificationHumanExit\n  mov rcx,[rbx+4]\n  cmp rcx,0\n  je applyAbomnificationHumanExit\n  \/\/ We load the scaling parameter for the creature's width, and then multiply\n  \/\/ the live width matrix values by it.\n  movss xmm0,[rbx+4]\n  shufps xmm0,xmm0,0\n  movdqu xmm1,[rax]\n  mulps xmm1,xmm0\n  movdqu [rax],xmm1\n  \/\/ We load the scaling parameter for the creature's height, and then multiply\n  \/\/ the live height matrix values by it.\n  movss xmm0,[rbx+8]\n  shufps xmm0,xmm0,0\n  movdqu xmm1,[rax+10]\n  mulps xmm1,xmm0\n  movdqu [rax+10],xmm1\n  \/\/ We load the scaling parameter for the creature's depth, and then multiply\n  \/\/ the live depth matrix values by it.\n  movss xmm0,[rbx+C]\n  shufps xmm0,xmm0,0\n  movdqu xmm1,[rax+20]\n  mulps xmm1,xmm0\n  movdqu [rax+20],xmm1  \napplyAbomnificationHumanExit:\n  \/\/ Restore backed up values.\n  pop rcx\n  pop rbx\n  movdqu xmm1,[rsp]\n  add rsp,10\n  movdqu xmm0,[rsp]\n  add rsp,10\napplyAbomnificationHumanOriginalCode:\n  popf\n  movaps xmm0,[rax]\n  lea rcx,[r14+r14*2]\n  jmp applyAbomnificationHumanReturn\n\n\nomnifyApplyAbomnificationHumanHook:\n  jmp applyAbomnificationHuman\n  nop 2\napplyAbomnificationHumanReturn:\n<\/pre>\n\n\n<h2>IV. Predator Parameter Optimization<\/h2>\n\n\n\n<p>Like Sekiro, Dark Souls III has a sensitive movement system that experiences a type of &#8220;resonance&#8221; when manipulated from the outside, resulting in enemies phasing out of existence if boosted a bit.<\/p>\n\n\n\n<p>99% of movement anomalies appear to have been resolved by tuning some of the Predator system&#8217;s external parameters to the following values:<\/p>\n\n\n\n<ul><li><strong>positiveLimit<\/strong>: 0.8<\/li><li><strong>negativeLimit<\/strong>: -0.8<\/li><li><strong>positiveLimitCorrection<\/strong>: 0<\/li><li><strong>negativeLimitCorrection<\/strong>: 0<\/li><li><strong>enemySpeedX<\/strong>: 2.0<\/li><\/ul>\n\n\n\n<p>For an explanation as to what these parameters mean, and what the significance of the new values might be, you&#8217;ll need to consult the Predator general overview article, which is unfortunately not available yet! I&#8217;ll put a link here when it is.<\/p>\n\n\n\n<h2>Ready to Get This Game On<\/h2>\n\n\n\n<p>Alright! With these fixes, the game is damn well ready for showtime. Hacking Dark Souls III and getting it Omnified (and writing about it all on this site) has been a great experience, and with this fixes the game is ready to play. Really looking forward to it. And I hope to see you there! I&#8217;ll be streaming it most days on my stream at: <a href=\"https:\/\/twitch.tv\/omni\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/twitch.tv\/omni<\/a>. <\/p>\n\n\n\n<p>Make sure to check out the <a href=\"https:\/\/badecho.com\/index.php\/category\/stream-info\/\" target=\"_blank\" rel=\"noreferrer noopener\">Stream Info<\/a> section on my hackpad for the latest stream schedule news and information.<\/p>\n\n\n\n<p>Thanks for your interest! Have a good one.<\/p>\n\n\n\n<p><em>~Omni<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Our Hacking of Dark Souls III Has Been Tested on Stream With the initial hacking of Dark Souls III now [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[18,9],"tags":[23,24,40],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\r\n<title>Hacking Dark Souls III - Part 5 (Playtest Fixes) - omni&#039;s hackpad<\/title>\r\n<meta name=\"description\" content=\"With the initial hacking of Dark Souls III now complete, a playtest of it was in order. Here&#039;s the results and fixes to all problems found.\" \/>\r\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\r\n<link rel=\"canonical\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/25\/hacking-dark-souls-iii-part-5\/\" \/>\r\n<meta property=\"og:locale\" content=\"en_US\" \/>\r\n<meta property=\"og:type\" content=\"article\" \/>\r\n<meta property=\"og:title\" content=\"Hacking Dark Souls III - Part 5 (Playtest Fixes) - omni&#039;s hackpad\" \/>\r\n<meta property=\"og:description\" content=\"With the initial hacking of Dark Souls III now complete, a playtest of it was in order. Here&#039;s the results and fixes to all problems found.\" \/>\r\n<meta property=\"og:url\" content=\"https:\/\/badecho.com\/index.php\/2020\/10\/25\/hacking-dark-souls-iii-part-5\/\" \/>\r\n<meta property=\"og:site_name\" content=\"omni&#039;s hackpad\" \/>\r\n<meta property=\"article:published_time\" content=\"2020-10-25T13:43:44+00:00\" \/>\r\n<meta property=\"article:modified_time\" content=\"2020-11-17T18:29:14+00:00\" \/>\r\n<meta property=\"og:image\" content=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/10\/playtestFixesShifting.png\" \/>\r\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\r\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/badecho.com\/#website\",\"url\":\"https:\/\/badecho.com\/\",\"name\":\"omni&#039;s hackpad\",\"description\":\"Game Code Disassembly. Omnified Modification. Madness.\",\"publisher\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/badecho.com\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/10\/25\/hacking-dark-souls-iii-part-5\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/10\/playtestFixesShifting.png\",\"width\":946,\"height\":533,\"caption\":\"Here are the contents of the easily locatable module collection structure.\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/10\/25\/hacking-dark-souls-iii-part-5\/#webpage\",\"url\":\"https:\/\/badecho.com\/index.php\/2020\/10\/25\/hacking-dark-souls-iii-part-5\/\",\"name\":\"Hacking Dark Souls III - Part 5 (Playtest Fixes) - omni&#039;s hackpad\",\"isPartOf\":{\"@id\":\"https:\/\/badecho.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/10\/25\/hacking-dark-souls-iii-part-5\/#primaryimage\"},\"datePublished\":\"2020-10-25T13:43:44+00:00\",\"dateModified\":\"2020-11-17T18:29:14+00:00\",\"description\":\"With the initial hacking of Dark Souls III now complete, a playtest of it was in order. Here's the results and fixes to all problems found.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/badecho.com\/index.php\/2020\/10\/25\/hacking-dark-souls-iii-part-5\/\"]}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/10\/25\/hacking-dark-souls-iii-part-5\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/10\/25\/hacking-dark-souls-iii-part-5\/#webpage\"},\"author\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"headline\":\"Omnifying (Hacking) Dark Souls III &#8211; Part 5 (Playtest Fixes)\",\"datePublished\":\"2020-10-25T13:43:44+00:00\",\"dateModified\":\"2020-11-17T18:29:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/10\/25\/hacking-dark-souls-iii-part-5\/#webpage\"},\"publisher\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"image\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/10\/25\/hacking-dark-souls-iii-part-5\/#primaryimage\"},\"keywords\":\"Dark Souls III,Hacking,Playtesting\",\"articleSection\":\"Dark Souls III,Games\",\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\",\"name\":\"Matt Weber\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/badecho.com\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/7e345ac2708b3a41c7bd70a4a0440d41?s=96&d=mm&r=g\",\"caption\":\"Matt Weber\"},\"logo\":{\"@id\":\"https:\/\/badecho.com\/#personlogo\"}}]}<\/script>\r\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/524"}],"collection":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/comments?post=524"}],"version-history":[{"count":6,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/524\/revisions"}],"predecessor-version":[{"id":701,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/524\/revisions\/701"}],"wp:attachment":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/media?parent=524"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/categories?post=524"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/tags?post=524"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}