{"id":410,"date":"2020-10-19T00:19:52","date_gmt":"2020-10-19T05:19:52","guid":{"rendered":"http:\/\/badecho.com\/?p=410"},"modified":"2021-06-18T10:47:20","modified_gmt":"2021-06-18T15:47:20","slug":"apocalypse-system","status":"publish","type":"post","link":"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/","title":{"rendered":"The Apocalypse System"},"content":{"rendered":"\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_11 counter-hierarchy counter-decimal ez-toc-grey\">\r\n<div class=\"ez-toc-title-container\">\r\n<p class=\"ez-toc-title\">Table of Contents<\/p>\r\n<span class=\"ez-toc-title-toggle\"><a class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\"><i class=\"ez-toc-glyphicon ez-toc-icon-toggle\"><\/i><\/a><\/span><\/div>\r\n<nav><ul class=\"ez-toc-list ez-toc-list-level-1\"><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#An_Overview_of_the_Apocalypse_System\" title=\"An Overview of the Apocalypse System\">An Overview of the Apocalypse System<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Origins_of_the_Apocalypse_System\" title=\"Origins of the Apocalypse System\">Origins of the Apocalypse System<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Basic_Mechanics_of_the_Apocalypse_System\" title=\"Basic Mechanics of the Apocalypse System\">Basic Mechanics of the Apocalypse System<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Player_Apocalypse\" title=\"Player Apocalypse\">Player Apocalypse<\/a><ul class=\"ez-toc-list-level-4\"><li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Primary_Dice_Roll_Effects\" title=\"Primary Dice Roll Effects\">Primary Dice Roll Effects<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#God_Mode_Powers!\" title=\"God Mode Powers!\">God Mode Powers!<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Enemy_Damage_Statistics\" title=\"Enemy Damage Statistics\">Enemy Damage Statistics<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Enemy_Apocalypse\" title=\"Enemy Apocalypse\">Enemy Apocalypse<\/a><ul class=\"ez-toc-list-level-4\"><li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Base_Player_Damage_Adjustments\" title=\"Base Player Damage Adjustments\">Base Player Damage Adjustments<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Chance_of_Player_Critical_Damage\" title=\"Chance of Player Critical Damage\">Chance of Player Critical Damage<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Kamehameha\" title=\"Kamehameha\">Kamehameha<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Player_Damage_Statistics\" title=\"Player Damage Statistics\">Player Damage Statistics<\/a><\/li><\/ul><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Apocalypse_System_API\" title=\"Apocalypse System API\">Apocalypse System API<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Player_Apocalypse_Function\" title=\"Player Apocalypse Function\">Player Apocalypse Function<\/a><ul class=\"ez-toc-list-level-4\"><li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Parameters\" title=\"Parameters\">Parameters<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Return_Values\" title=\"Return Values\">Return Values<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Initiation_Point_Implementation\" title=\"Initiation Point Implementation\">Initiation Point Implementation<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Enemy_Apocalypse_Function\" title=\"Enemy Apocalypse Function\">Enemy Apocalypse Function<\/a><ul class=\"ez-toc-list-level-4\"><li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Parameters-2\" title=\"Parameters\">Parameters<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Return_Values-2\" title=\"Return Values\">Return Values<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-21\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Initiation_Point_Implementation-2\" title=\"Initiation Point Implementation\">Initiation Point Implementation<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-22\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#External_Parameters\" title=\"External Parameters\">External Parameters<\/a><ul class=\"ez-toc-list-level-4\"><li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-23\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Example_of_Changing_Parameter_Value\" title=\"Example of Changing Parameter Value\">Example of Changing Parameter Value<\/a><\/li><\/ul><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-24\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Apocalypse_System_Code_Analysis\" title=\"Apocalypse System Code Analysis\">Apocalypse System Code Analysis<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-25\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Player_Apocalypse-2\" title=\"Player Apocalypse\">Player Apocalypse<\/a><ul class=\"ez-toc-list-level-4\"><li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-26\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Player_Apocalypse_Code_%E2%80%93_First_Steps\" title=\"Player Apocalypse Code &#8211; First Steps\">Player Apocalypse Code &#8211; First Steps<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-27\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Player_Apocalypse_Code_%E2%80%93_Primary_Dice_Roll\" title=\"Player Apocalypse Code &#8211; Primary Dice Roll\">Player Apocalypse Code &#8211; Primary Dice Roll<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-28\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Player_Apocalypse_Code_%E2%80%93_Extra_Damage\" title=\"Player Apocalypse Code &#8211; Extra Damage\">Player Apocalypse Code &#8211; Extra Damage<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-29\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Player_Apocalypse_Code_%E2%80%93_Teleportitis\" title=\"Player Apocalypse Code &#8211; Teleportitis\">Player Apocalypse Code &#8211; Teleportitis<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-30\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Player_Apocalypse_Code_%E2%80%93_Risk_of_Murder_Roll\" title=\"Player Apocalypse Code &#8211; Risk of Murder Roll\">Player Apocalypse Code &#8211; Risk of Murder Roll<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-31\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Player_Apocalypse_Code_%E2%80%93_Sudden_Orgasm\" title=\"Player Apocalypse Code &#8211; Sudden Orgasm\">Player Apocalypse Code &#8211; Sudden Orgasm<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-32\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Player_Apocalypse_Code_%E2%80%93_Update_Stats_and_Cleanup\" title=\"Player Apocalypse Code &#8211; Update Stats and Cleanup\">Player Apocalypse Code &#8211; Update Stats and Cleanup<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-33\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Enemy_Apocalypse-2\" title=\"Enemy Apocalypse\">Enemy Apocalypse<\/a><ul class=\"ez-toc-list-level-4\"><li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-34\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Enemy_Apocalypse_Code_%E2%80%93_First_Steps\" title=\"Enemy Apocalypse Code &#8211; First Steps\">Enemy Apocalypse Code &#8211; First Steps<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-35\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Enemy_Apocalypse_Code_%E2%80%93_Base_Damage_and_Critical_Hits\" title=\"Enemy Apocalypse Code &#8211; Base Damage and Critical Hits\">Enemy Apocalypse Code &#8211; Base Damage and Critical Hits<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-36\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Enemy_Apocalypse_Code_%E2%80%93_Kamehameha\" title=\"Enemy Apocalypse Code &#8211; Kamehameha\">Enemy Apocalypse Code &#8211; Kamehameha<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-37\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Enemy_Apocalypse_Code_%E2%80%93_Update_Stats_and_Cleanup\" title=\"Enemy Apocalypse Code &#8211; Update Stats and Cleanup\">Enemy Apocalypse Code &#8211; Update Stats and Cleanup<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-38\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Complete_Code_for_the_Apocalypse\" title=\"Complete Code for the Apocalypse\">Complete Code for the Apocalypse<\/a><ul class=\"ez-toc-list-level-4\"><li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-39\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Player_Apocalypse_Code_%E2%80%93_Complete\" title=\"Player Apocalypse Code &#8211; Complete\">Player Apocalypse Code &#8211; Complete<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-40\" href=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#Enemy_Apocalypse_Code_%E2%80%93_Complete\" title=\"Enemy Apocalypse Code &#8211; Complete\">Enemy Apocalypse Code &#8211; Complete<\/a><\/li><\/ul><\/li><\/ul><\/li><\/ul><\/nav><\/div>\r\n<h2><span class=\"ez-toc-section\" id=\"An_Overview_of_the_Apocalypse_System\"><\/span>An Overview of the Apocalypse System<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The Apocalypse system is a game-neutral <a rel=\"noreferrer noopener\" href=\"https:\/\/badecho.com\/index.php\/what-is-omnified\/\" target=\"_blank\">Omnified<\/a> process that completely overhauls the system in a game responsible for handling damage dealt to and by the player. When implemented into a game, the existing damage system is augmented by the introduction of several dice rolls that apply random effects of varying punishment to the character. These random effects are then typically displayed on screen in the form of an event log.<\/p>\n\n\n\n<p>The Apocalypse system was the first formalized Omnified system that I made, and therefore it will be the first to have its own detailed analysis article. All aspects of the Apocalypse system, from its usage to its inner workings, will be covered here. If you would like to start off with a quick primer on what my Apocalypse system is all about, check out the video below for a general overview: <\/p>\n\n\n\n<figure class=\"wp-block-embed aligncenter is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"What is Apocalypse?\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/pUzMjc4UO4A?feature=oembed&amp;wmode=opaque\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><figcaption>New to the Apocalypse? Get up to speed with this quick general overview video.<\/figcaption><\/figure>\n\n\n\n<h2><span class=\"ez-toc-section\" id=\"Origins_of_the_Apocalypse_System\"><\/span>Origins of the Apocalypse System<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The Apocalypse system evolved from the earliest of my hacks, which primarily dealt with increases of damage to the player. The first of these hacks would simply cause the player to die upon receiving any kind of damage, but eventually I figured out how to apply a static increase to the damage, such as 69x damage (which is just the most <em>perfect<\/em> multiplier one could apply to damage, ya hear?).<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"482\" height=\"402\" src=\"http:\/\/badecho.com\/wp-content\/uploads\/2020\/10\/OneHitDeath.png\" alt=\"Shows how most damage would affect the player before the Apocalypse system: by simply murdering them in one hit.\" class=\"wp-image-413\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2020\/10\/OneHitDeath.png 482w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/10\/OneHitDeath-300x250.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2020\/10\/OneHitDeath-480x400.png 480w\" sizes=\"(max-width: 482px) 100vw, 482px\" \/><figcaption>Prior to the Apocalypse system, damage hacks simply made it so you always got one shot.<\/figcaption><\/figure><\/div>\n\n\n\n<p>In the early days of this Omnified adventure I&#8217;m on, I really desired to try to do something new and exciting for each game that I Omnified. So instead of doing just an across-the-board damage increase for all damage, I eventually would apply different increases to the damage based on where the damage was going (shields vs health, etc.). Sometimes the damage would be enough to one shot the player all the time, or sometimes it would require several shots. The amount of damage was dependent on the game; it was whatever made sense.<\/p>\n\n\n\n<p>One day, that all changed. I discovered the power of <em>randomness<\/em>. Put a different way: I figured out how to write some code that allowed me to generate random numbers in assembly easily. Instead of static damage amounts, what about random damage amounts? Instead of random damage amounts, what if we had random effects based on the damage? Of course, there would also need to be some way to display to viewers on my <a rel=\"noreferrer noopener\" href=\"https:\/\/twitch.tv\/omni\" target=\"_blank\">stream<\/a> which random effects were going off at a given point of time.<\/p>\n\n\n\n<p>So, one fateful evening, while Omnifying Resident Evil 3 on stream, I wrote the first implementation of the Apocalypse system, which eventually became game-neutralized and the first of my Omnified systems. A new era was dawning!<\/p>\n\n\n\n<h2><span class=\"ez-toc-section\" id=\"Basic_Mechanics_of_the_Apocalypse_System\"><\/span>Basic Mechanics of the Apocalypse System<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The Apocalypse system is composed of two separate and distinct modules: the <em>Player Apocalypse<\/em> and the <em>Enemy Apocalypse<\/em>. The Player Apocalypse handles damage being done to the player from an enemy. The Enemy Apocalypse handles damage being done to an enemy from the player.<\/p>\n\n\n\n<p>Both of these modules introduce probability and chance into how damage is handled in the game, albeit in very different ways, with the odds definitely being stacked against the player. They are also both responsible for data collection and recordkeeping of various statistics specific to the area the respective module operates in.<\/p>\n\n\n\n<h3 id=\"player-apocalypse-basic-mechanics\"><span class=\"ez-toc-section\" id=\"Player_Apocalypse\"><\/span>Player Apocalypse<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The Player Apocalypse, as stated previously, is responsible for handling damage done to the player by enemies.<\/p>\n\n\n\n<p>The Apocalypse system changes what happens following the player getting smacked by a baddie. Right before the game applies the damage from the hit to the player&#8217;s health, a (typically) 10-sided die is cast. What happens next is dependent on the result of the roll.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Primary_Dice_Roll_Effects\"><\/span>Primary Dice Roll Effects<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>The potential outcomes from the primary dice roll are as follows:<\/p>\n\n\n\n<ul><li>1-4: Extra Damage<ul><li>Damage is increased by <strong>extraDamageX<\/strong> (default: 2.0).<\/li><\/ul><\/li><li>5-6: Teleportitis<ul><li>Normal damage applies.<\/li><li>The player is teleported by having all coordinate axes shifted by +\/- 5 units, all randomly determined and then multiplied by <strong>teleportitisDisplacementX<\/strong> (default: 1.0).<\/li><li>If <strong>negativeVerticalDisplacementEnabled<\/strong> (default: 1) is false, the Y-axis (or Z-axis, depending on<strong> <\/strong>the value of <strong>yIsVertical <\/strong>(default: 1)) will be shifted by 0-10 instead, to prevent negative vertical displacement.<\/li><li>A copyright friendly length Tom Petty&#8217;s <em>Free Fallin&#8217;<\/em> plays if we&#8217;re being teleported beneath the ground (because we will most likely fall to our deaths).<\/li><\/ul><\/li><\/ul>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"600\" height=\"338\" src=\"http:\/\/badecho.com\/wp-content\/uploads\/2020\/10\/FallingDeath.gif\" alt=\"Shows the player falling through the ground to their death due to the Apocalypse system.\" class=\"wp-image-414\"\/><figcaption>Due to a teleportitis effect, the player is teleported beneath the ground and falls to death. <\/figcaption><\/figure><\/div>\n\n\n\n<ul><li>7-9: Risk of Murder Roll<ul><li>A separate 5-sided die is cast, which depending on the result, causes the following:<ul><li>1-3: Normal damage applies, with a chance of Fatalis occurring. <a href=\"https:\/\/badecho.com\/index.php\/2021\/03\/01\/apocalypse-system-adding-fatalis-debuff\/\" target=\"_blank\" rel=\"noreferrer noopener\">Check out my article on the Fatalis debuff<\/a> for more information on it.<\/li><li>4-5: 69x damage. You just got SIXTY NINED.<ul><li>A Duke Nukem <em>Holy Shit!<\/em> sound effect plays.<\/li><\/ul><\/li><\/ul><\/li><\/ul><\/li><li>10: Sudden Orgasm<ul><li>The player experiences a spontaneous orgasm on the battle field and is fully healed.<\/li><li>The classic anime <em>WOWWWW!<\/em> sound effect plays.<\/li><\/ul><\/li><\/ul>\n\n\n\n<p>Once the roll concludes, a signal fires to the display system (which we&#8217;ll cover in much greater detail in an Omnified display system article) to create an event log entry concerning the roll, so that the player and audience are cognizant of WTF just happened.<\/p>\n\n\n\n<p>The full heal effect that the player receives if the die roll is 10 is meant to be  a bit of fun randomness injected into the overly oppressive nature of all the other effects. It has a very small chance of happening, but when it does, it can feel damn good!<\/p>\n\n\n\n<p>You may have noticed several terms in <strong>bold<\/strong>. These are what are known as <em>external parameters<\/em>, and are meant to be able to be configurable by consuming bits of code (i.e. the game specific hacks that are initiating the Omnified system). These will be covered in greater detail and grouped together in a list in <a href=\"#external-parameters\" target=\"_blank\" rel=\"noreferrer noopener\">a later section in this article<\/a>. <\/p>\n\n\n\n<p>The primary dice roll is the main feature of the Player Apocalypse, however it also provides other functionality appropriate for the place in code it has been injected into&#8230;including the power of <em>immortality<\/em> (queue omnGasm).<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"God_Mode_Powers!\"><\/span>God Mode Powers!<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>That&#8217;s right, nestled in with all the horrifying and punishing code of the Player Apocalypse, there is code that provides god mode support! If the <strong>playerGodMode<\/strong> (default: 0) external parameter is set to 1, no roll occurs in response to damage, and the damage amount is reset to 0. <\/p>\n\n\n\n<p>This is <em>mainly<\/em> used for debugging purposes&#8230;however I have been known from time to time to get tired of the bullshit difficult encounters (whose <em>bullshittiness<\/em> is entirely my own fault!) and throw it on. In secret. Shh&#8230;<\/p>\n\n\n\n<p>But that aside, it is quite handy to have automatic god mode support added to a game whenever I implement Apocalypse system support into it. So, if you are ever just looking to cheat like a bad panda, and you see an Omnified hack available for a game, it&#8217;ll serve your purposes (if you know how to turn it on that is ;)).<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Enemy_Damage_Statistics\"><\/span>Enemy Damage Statistics<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Since the Player Apocalypse becomes the authority ultimately on how much damage the player is receiving from enemy sources, it also makes sense that it should govern statistics related to damage done to the player by enemies. The Apocalypse system tracks a number of game-related statistics, with the Player Apocalypse being responsible for three enemy damage related stats:<\/p>\n\n\n\n<ul><li><strong>lastDamageToPlayer<\/strong>: The most recent amount of damage done to the player.<\/li><li><strong>maxDamageToPlayer<\/strong>: The highest amount of damage done to the player during the current session.<\/li><li><strong>totalDamageToPlayer<\/strong>: The cumulative amount of damage done to the player over the current session.<\/li><\/ul>\n\n\n\n<p>These statistics are made available as simple text dumps for on-stream display; however, there is currently work being done on formal data contracts for the statistics that will be fed into specialized stat display programs (an article will be written for that later!).<\/p>\n\n\n\n<p>That wraps up basic functionality for the Player Apocalypse! Now onto the other important component of the Apocalypse system: the Enemy Apocalypse! <\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Enemy_Apocalypse\"><\/span>Enemy Apocalypse<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Whereas the Player Apocalypse handles damage done to the player from enemies, the Enemy Apocalypse handles damage done to enemies from the player. <\/p>\n\n\n\n<p>The intended purpose of the Enemy Apocalypse was to collect statistics related to damage done to enemies by the player as well as provide the ability to fine tune the player&#8217;s damage. A number of other little features have come about however along this Omnified journey. <\/p>\n\n\n\n<p>Some random effects that benefit the player have also been added! However, these are meant to be brief bits of respite for gameplay, and are not in any way meant to compete with the punishing random effects caused by the Player Apocalypse. <\/p>\n\n\n\n<p>With that, let&#8217;s go over the basic mechanics of the Enemy Apocalypse.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Base_Player_Damage_Adjustments\"><\/span>Base Player Damage Adjustments<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>At the outset of the Enemy Apocalypse, the player damage is multiplied against the <strong>playerDamageX<\/strong> (default: 1.0) external parameter. Since we&#8217;re overhauling damage to enemies, why not provide the means to shape player damage at its base. This is typically always left at its default value, however I may adjust this if I disagree with a particular game design decision (e.g. hardest difficulty nerfs player damage by 50%, I don&#8217;t subscribe to that crap). <\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Chance_of_Player_Critical_Damage\"><\/span>Chance of Player Critical Damage<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Implementation of the Apocalypse system adds a bit of spice to normal combat by adding the ability for the player to score critical damage! The amount of extra damage is not massive, however it is enough that it definitely feels good when it happens!<\/p>\n\n\n\n<p>A roll to first see if the player scores a critical hit is cast. The chance that damage by the player becomes critical is <strong>6.25%<\/strong>. And yes, this critical hit chance percentage was borrowed directly from Pok\u00e9mon. No, believe it or not, I have never played Pok\u00e9mon, however it was the first percentage that popped up when I Googled &#8220;critical hit chance&#8221; (I was looking for what a good percentage was!). That made me laugh, so it stuck.<\/p>\n\n\n\n<p>If the roll is such that the damage will be critical, another roll is cast to determine the critical damage multiplier, which can be anywhere from <strong>2.0<\/strong> to <strong>5.0<\/strong>. If a critical hit does occur, it is logged in the Apocalypse event log so the stream can see the details, and a lovely Chocobo &#8220;Kweh&#8221; (<a href=\"https:\/\/www.youtube.com\/watch?v=Gwe6r5puMe0\" target=\"_blank\" rel=\"noreferrer noopener\">or &#8220;Woheeho&#8221;, or &#8220;Wark&#8221;!?<\/a>) sound effect is played live for all the sleeping viewers to wake up to.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Kamehameha\"><\/span>Kamehameha<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>I love it when overwhelming odds are stacked against the player; creating those very kinds of experiences are what I do! However, I do love it when there&#8217;s that very, very rare bit of RNG that can just change everything. Something that should only ever happen once per game, if even that. With the Apocalypse system, the chance for a Kamehameha is that something.<\/p>\n\n\n\n<p>Yes, the term &#8220;Kamehameha&#8221; is a reference to that ultimate attack ability used by the protagonist in <em>Dragon Ball Z<\/em>&#8230;and that&#8217;s basically what it is. An attack that does a ridiculous amount of damage. 10000x the amount of damage that would&#8217;ve been otherwise applied, actually. When one occurs, the audience will hear Goku doing his &#8220;Kamehameha&#8221; war cry (from the Japanese version of the show &#8212; apparently people find this version annoying so I thought it perfect!).<\/p>\n\n\n\n<p>But, there&#8217;s only a 1 in 1000 chance for it to occur for any given attack by the player. So&#8230;it definitely doesn&#8217;t happen that much. But if it does, and if it happens to be on the right target, it is game changing! RNG is RNG however, and sometimes we&#8217;ll go through entire games without having it go off!<\/p>\n\n\n\n<p>This is checked after the critical hit chance rolls, so it is technically possible for a critical attack to also be Kamehameha&#8217;d. Not sure if that&#8217;s ever happened however! Also completely unnecessary. <\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Player_Damage_Statistics\"><\/span>Player Damage Statistics<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>The Enemy Apocalypse is the ultimate authority on how much damage enemies receive from the player. Because of this, it is also responsible for statistical data collection of the player&#8217;s damage to enemies; indeed, this is the primary purpose of the Enemy Apocalypse.<\/p>\n\n\n\n<p>The Enemy Apocalypse is responsible for maintaining three player damage related stats:<\/p>\n\n\n\n<ul><li><strong>lastDamageByPlayer<\/strong>: The most recent amount of damage done by the player.<\/li><li><strong>maxDamageByPlayer<\/strong>: The highest amount of damage done by the player during the current session.<\/li><li><strong>totalDamageByPlayer<\/strong>: The cumulative amount of damage done by the player over the current session.<\/li><\/ul>\n\n\n\n<p>Like how the Player Apocalypse handles its own statistics, these are made available as simple text dumps for on-stream display, with more to come in the future.<\/p>\n\n\n\n<p>And that&#8217;s the Enemy Apocalypse for you. Now that basic mechanics have been covered, we&#8217;ll go over the API for the Apocalypse system, used to integrate it into whatever game we&#8217;re hacking.<\/p>\n\n\n\n<h2><span class=\"ez-toc-section\" id=\"Apocalypse_System_API\"><\/span>Apocalypse System API<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Integration of the Apocalypse system and its subsystems require proper construction of initiation points that call Player and Enemy Apocalypse functions when the game is processing incoming damage. This section serves to list these functions, the parameters they require, and other important information certain to be useful if correct operation is desired.<\/p>\n\n\n\n<p>All external parameters supported by the Apocalypse system are also covered here. These allow for extensive customization of the Apocalypse system&#8217;s behavior from a consuming hack.<\/p>\n\n\n\n<p>The physical organization and location of the functions described in this section is covered in the <a href=\"#apocalypse-system-code\">next section<\/a> after this that provides an overview of the Apocalypse code itself. <\/p>\n\n\n\n<h3 id=\"player-apocalypse-api\"><span class=\"ez-toc-section\" id=\"Player_Apocalypse_Function\"><\/span>Player Apocalypse Function<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Player Apocalypse functionality is initiated by calling the <strong>executePlayerApocalypse<\/strong> function. It must be called whenever the player is receiving enemy damage.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Parameters\"><\/span>Parameters<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<ol><li>Damage Amount<ul><li>Data Type: <strong>float<\/strong><\/li><li>This is the amount of damage the game is trying to apply to the players health. <\/li><li>Expected to be a positive value. <\/li><li>Damage amounts below a configurable threshold will be ignored by the Apocalypse system. <\/li><\/ul><\/li><li>Player&#8217;s Current Health Value<ul><li>Data Type: <strong>float <\/strong><\/li><li>While this will often be identical to the source of truth for the player&#8217;s current health in memory, it is <em>most<\/em> important that the value provided here is what is being used as the working health value that is about to have the damage amount subtracted from it in the original game code. This temporary value will either be stored in a register or nearby on the stack. More information will be provided in additional initiation point implementation information found below. <\/li><\/ul><\/li><li>Player&#8217;s Maximum Health Value<ul><li>Data Type: <strong>float<\/strong><\/li><li>This is used if a spontaneous orgasm (full heal) outcome is rolled. <\/li><\/ul><\/li><li>Player Coordinates (aligned at X-coordinate) <ul><li>Data Type: <strong>memory address<\/strong><\/li><li>This must be the address in memory to the start of the player&#8217;s live location coordinates. <\/li><li>The coordinates may be directly manipulated by the Apocalypse function, so it must be the source of truth for the player&#8217;s coordinates. <\/li><li>The data type of the individual coordinates is expected to be floating point. I have only hacked a single game that used anything other than floating point for player coordinates (and it was only used when the player was on land and not underwater). Support will be added for additional data types if needed. <\/li><\/ul><\/li><\/ol>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Return_Values\"><\/span>Return Values<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<ul><li><strong>eax<\/strong>: Set to an updated damage amount.<\/li><li><strong>ebx<\/strong>: Set to an updated working health value for the player.<\/li><\/ul>\n\n\n\n<h4 id=\"player-apocalypse-initiation-point\"><span class=\"ez-toc-section\" id=\"Initiation_Point_Implementation\"><\/span>Initiation Point Implementation<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>The location of an Omnified process&#8217;s initiation point is critical in the successful operation of all Omnified game-neutral systems. The initiation point for the Player Apocalypse needs to be injected right into the game&#8217;s <strong>damage application<\/strong> code for damage occurring to the player.<\/p>\n\n\n\n<p>The damage application code is made up of instructions that are applying a damage amount to a current, working health value. It is many times a simple arithmetic operation that is taking a current health value, and subtracting the damage amount from it.<\/p>\n\n\n\n<p>This is markedly different from the much more easily located <strong>health update<\/strong> code, which is where the player&#8217;s source of truth health value is being assigned a new, updated health value (that has had an amount of damage subtracted from it).<\/p>\n\n\n\n<p>Finding the damage application code requires the that the intrepid reverse engineer start at the health update code (easily found by looking for code writing to the health in memory), and then working your way backwards. The damage update code can sometimes be very far from the health update code, and it is sometimes nearby.<\/p>\n\n\n\n<p>To learn skills and techniques that will help you do this, check out <a rel=\"noreferrer noopener\" href=\"https:\/\/badecho.com\/index.php\/tag\/apocalypse\/\" target=\"_blank\">Apocalypse implementation articles<\/a> I&#8217;ve written for specific games.<\/p>\n\n\n\n<p>Around 60% of the games I&#8217;ve Omnified use the same damage application code for both damage going to the player and damage going to enemies. The remaining 40% have had separate (and sometimes very far apart in terms of location in the code) damage application code functions for damage going to the player vs enemies.<\/p>\n\n\n\n<p>So, obviously, in the event that damage application code is being shared between the two, you&#8217;ll want to ensure that we can identify the target and see if it matches known player vitality structures.<\/p>\n\n\n\n<p>When you&#8217;ve found a good place for the initiation point, you should be able to provide values for the damage amount and working player health easily. Once the Player Apocalypse function is done executing, you will want to replace the values where you got the damage amount and working player health from with the values found in the <strong>eax<\/strong> and <strong>ebx<\/strong> registers respectively. <\/p>\n\n\n\n<h3 id=\"enemy-apocalypse-api\"><span class=\"ez-toc-section\" id=\"Enemy_Apocalypse_Function\"><\/span>Enemy Apocalypse Function<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Enemy Apocalypse functionality is initiated by calling the <strong>executeEnemyApocalypse<\/strong> function. It must be called whenever enemies are receiving damage from the player, and only the player.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Parameters-2\"><\/span>Parameters<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<ol><li>Damage Amount<ul><li>Data Type: <strong>float<\/strong><\/li><li>This is the amount of damage the game is trying to apply to the enemy&#8217;s health.<\/li><li>Expected to be a positive value.<\/li><li>Damage amounts below a configurable threshold will be ignored by the Apocalypse system.<\/li><\/ul><\/li><li>Enemy&#8217;s Current Health Value<ul><li>Data Type: <strong>float<\/strong><\/li><li>Much like the second parameter for the <strong>executePlayerApocalypse<\/strong> function, it is better if this is the working, temporary value of the health involved in the damage application operation.<\/li><\/ul><\/li><\/ol>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Return_Values-2\"><\/span>Return Values<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<ul id=\"block-66e5ffc7-53ff-49b6-99e1-0209a403a240\"><li><strong>eax<\/strong>: Set to an updated damage amount.<\/li><li><strong>ebx<\/strong>: Set to an updated working health value for the enemy.<\/li><\/ul>\n\n\n\n<h4 id=\"enemy-apocalypse-initiation-point\"><span class=\"ez-toc-section\" id=\"Initiation_Point_Implementation-2\"><\/span>Initiation Point Implementation<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Refer to the <a href=\"#player-apocalypse-initiation-point\" target=\"_blank\" rel=\"noreferrer noopener\">Initiation Point Implementation section<\/a> for the <strong>executePlayerApocalypse<\/strong> function. All of that applies here as well, except that we should only be calling this function if an enemy is receiving the damage. Additionally, we ideally only want to call this if it is the player that is doing the damage.<\/p>\n\n\n\n<p>The purpose of the Enemy Apocalypse is to record player-specific damage statistics as well as shape the damage done by the player. It is not intended to handle damage to enemies from other enemies or the environment. This can lead to &#8220;Chocobo overload&#8221; (as I like to put it) during big battles with all the critical hits going off.<\/p>\n\n\n\n<p>While determining the target of the damage is typically very easy to do, determining the <em>source<\/em> of the damage is something I&#8217;ve observed to often be <em>very<\/em> difficult. The damage application code may exist as a common routine purposed for abstract number crunching and it has no need at all to know where the damage is coming from. You will need to really flex your reverse engineering muscles to find it.<\/p>\n\n\n\n<p>Luckily for you, can pick up tips and techniques I use to find this sort of thing by referring to my (hopefully soon to be many) <a href=\"https:\/\/badecho.com\/index.php\/tag\/apocalypse\/\" target=\"_blank\" rel=\"noreferrer noopener\">game-specific Apocalypse implementation articles<\/a>.<\/p>\n\n\n\n<h3 id=\"external-parameters\"><span class=\"ez-toc-section\" id=\"External_Parameters\"><\/span>External Parameters<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The Apocalypse system, like the other Omnified systems, have a number of configurable parameters that we can set to fine tune the system&#8217;s implementation into a particular game. To change the value of these parameters, we can simply redefine the value right under the Apocalypse systems&#8217; initiation points like so:<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Example_of_Changing_Parameter_Value\"><\/span>Example of Changing Parameter Value<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nnameOfExternalParameter:\n  dd (float)3.0\n<\/pre>\n\n\n<p>The above code changes the value of this parameter from whatever its default is to a new value of 3.0. Let&#8217;s now go over all the external parameters made available by the Apocalypse system:<\/p>\n\n\n\n<ul><li><strong>damageThreshold<\/strong><ul><li>Data Type: <strong>float<\/strong><\/li><li>Default: <strong>3.5<\/strong><\/li><li>This is the minimum value the damage amount must be to be eligible for Apocalypse system processing. This is useful to avoid insignificant dot damage triggering random effect rolls. This parameter also helps in getting around issues that will occur for games that enjoy executing damage application code even if the damage amount is 0.<\/li><\/ul><\/li><li><strong>negativeVerticalDisplacementEnabled<\/strong><ul><li>Data Type: <strong>4 bytes<\/strong><\/li><li>Default: <strong>1<\/strong><\/li><li>Normally, the vertical axis is subjected to the same range of potential modification during teleportitis as the other axes (+\/-5). Obviously, if the vertical axis is changed by a negative amount, it can (and often will) result in the player falling through the ground. <\/li><li>This is great as falling through the ground into the abyss and dying is one of the most hilarious deaths possible &#8212; however, not all games have a<em> <\/em>&#8220;killzone&#8221; beneath the walkable terrain (<em>cough<\/em> Monster Hunter World <em>cough<\/em>). <\/li><li>When that is the case, the player will just fall forever, probably in a sort of loop. This is obviously <em>not good<\/em> behavior, and is why this option exists. When negative vertical displacement is disabled, the vertical axis will instead be subjected to a (base) 0-10 modification range.<\/li><li>Setting this to any value other than <strong>1<\/strong> disables the option.<\/li><\/ul><\/li><li><strong>yIsVertical<\/strong><ul><li>Data Type: <strong>4 bytes<\/strong><\/li><li>Default: <strong>1<\/strong><\/li><li>Because the vertical axis is treated differently during teleportitis, it is important to know exactly which coordinate axis is the vertical one. In most games, the Y axis is, however there are a few I&#8217;ve encountered where the Z axis is instead.<\/li><li>Setting this to any value other than <strong>1<\/strong> will cause the Z axis to be treated as the vertical axis.<\/li><\/ul><\/li><li><strong>teleportDisplacementX<\/strong><ul><li>Data Type: <strong>float<\/strong><\/li><li>Default: <strong>1.0<\/strong><\/li><li>The base +\/-5 randomly generated displacement amounts generated during teleportitis are multiplied by this prior to effectuating the change. So, if you wish to, for example, double the average displacement amounts, you would want to set this to <strong>2.0<\/strong>, etc.<\/li><\/ul><\/li><li><strong>extraDamageX<\/strong><ul><li>Data Type: <strong>float<\/strong><\/li><li>Default: <strong>2.0<\/strong><\/li><li>Rolling a 1 through 4 during the Player Apocalypse primary dice roll will multiply the base damage amount by <strong>extraDamageX<\/strong>. This effect is the most likely outcome of any that can occur during the primary dice roll.<\/li><li>This essentially means that the majority of damage done in the game will always be higher than it ever would&#8217;ve been in a non-Omnified game; however, in some games, double damage is still not enough to present a challenge (<em>cough<\/em> Yakuza <em>cough<\/em>), and this allows us to bump up the typical damage to be higher.<\/li><li>Be aware, however, that the intention behind the extra damage effect is for it to seriously maim the character, and not one-shot them typically (that&#8217;s for the 69&#8217;s baby!). So if too many one shots are occurring from extra damage rolls, you could lower this &#8212; interestingly enough, however, I&#8217;ve never lowered this to below <strong>2.0<\/strong>. I&#8217;ve actually only ever increased it. I&#8217;ve made other changes to gameplay to ensure a fine balance of one-shots and maim-shots.<\/li><\/ul><\/li><li><strong>playerGodMode<\/strong><ul><li>Data Type: <strong>4 bytes<\/strong><\/li><li>Default: <strong>0<\/strong><\/li><li>If this is set to 1, then no Apocalypse rolls will occur when the player receives damage, and damage is reset. If the Apocalypse system has been implemented correctly, the player will be impervious to damage from enemies.<\/li><li>Only dirty cheaters would ever think of using this.<\/li><li>Great for testing though!<\/li><\/ul><\/li><li><strong>fatalisResultUpper<\/strong><ul><li>Data Type: <strong>4 bytes<\/strong><\/li><li>Default: <strong>3<\/strong><\/li><li>This is the upper bounds for the roll that determines whether the player is getting inflicted with the <a href=\"https:\/\/badecho.com\/index.php\/2021\/03\/01\/apocalypse-system-adding-fatalis-debuff\/\" target=\"_blank\" rel=\"noreferrer noopener\">Fatalis debuff<\/a>. Increasing this will decrease the chance of a Fatalis being applied.<\/li><\/ul><\/li><li><strong>gokuResultUpper<\/strong><ul><li>Data Type: <strong>4 bytes<\/strong><\/li><li>Default: <strong>1000<\/strong> (decimal)<\/li><li>This is the upper bounds for the Kamehameha roll during the Enemy Apocalypse. A Kamehameha will only occur if the resulting random roll yields a value of <strong>69 <\/strong>(decimal), so increasing this will decrease the odds of that happening.<\/li><li>1 in 1000 is, from my experience, good odds for this powerful ability &#8212; however you may wish to increase this value for games where attacks from the player are <em>very<\/em> rapid (for example, this was increased to <strong>5000<\/strong> for Yakuza 0).<\/li><\/ul><\/li><li><strong>playerCritChanceResultUpper<\/strong><ul><li>Data Type: <strong>4 bytes<\/strong><\/li><li>Default: <strong>800<\/strong> (decimal)<\/li><li>This is the upper bounds for the critical hit chance roll during the Enemy Apocalypse. Increasing this will decrease the chance of a critical hit occurring.<\/li><\/ul><\/li><li><strong>playerCritDamageResultUpper<\/strong><ul><li>Data Type: <strong>4 bytes<\/strong><\/li><li>Default: <strong>50<\/strong><\/li><li>This is the upper bounds for the critical damage roll during the Enemy Apocalypse. The damage roll is divided by <strong>10.0<\/strong> to get the final (in <strong>float<\/strong>) damage amount. So, to increase the maximum damage to, let&#8217;s say, <strong>6.5x<\/strong>, you&#8217;d want to set this to <strong>65.<\/strong><\/li><\/ul><\/li><li><strong>playerCritDamageResultLower<\/strong><ul><li>Data Type: <strong>4 bytes<\/strong><\/li><li>Default: <strong>20<\/strong><\/li><li>This is the lower bounds for the critical damage roll during the Enemy Apocalypse. The damage roll is divided by <strong>10.0<\/strong> to get the final (in <strong>float<\/strong>) damage amount. So, to decrease the minimum damage to, let&#8217;s say, <strong>1.5x<\/strong>, you&#8217;d want to set this to <strong>15.<\/strong><\/li><\/ul><\/li><li><strong>disableTeleportitis<\/strong><ul><li>Data Type: <strong>4 bytes<\/strong><\/li><li>Default: <strong>0<\/strong><\/li><li>This will disable the teleportitis effect from being applied to the player if set to <strong>1<\/strong>. Instead, the default effect of Extra Damage will be applied.<\/li><\/ul><\/li><li><strong>disableSixtyNine<\/strong><ul><li>Data Type: <strong>4 bytes<\/strong><\/li><li>Default: <strong>0<\/strong><\/li><li>This will disable the sixty nine effect from being applied to the player if set to <strong>1<\/strong>. Instead, the default Risk of Murder effect of Normal Damage will be applied.<\/li><\/ul><\/li><li><strong>coordinatesAreDoubles<\/strong><ul><li>Data Type: <strong>4 bytes<\/strong><\/li><li>Default: <strong>0<\/strong><\/li><li>If this is set to 1 the Apocalypse system will treat the player&#8217;s coordinates as if they are doubles instead of floats. Typically, coordinates are stored as floats in games, but some do use doubles. If you&#8217;re playing a game that does, this needs to be set to 1 or you&#8217;ll have problems.<\/li><\/ul><\/li><\/ul>\n\n\n\n<p>Note that other symbols like the ones listed above do exist in the Apocalypse code, however they really aren&#8217;t intended to ever be changed outside of the Omnified framework. You will only ever see the above parameters modified in Omnified game hacks that use the Apocalypse system.<\/p>\n\n\n\n<h2 id=\"apocalypse-system-code\"><span class=\"ez-toc-section\" id=\"Apocalypse_System_Code_Analysis\"><\/span>Apocalypse System Code Analysis<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Let&#8217;s take a look at how the Apocalypse system actually works. The code for the Apocalypse system can be found in the Omnified framework library file (<strong>Omnified.lua<\/strong>) and is referenced and imported by a particular Omnified game&#8217;s hack file. <\/p>\n\n\n\n<p>I&#8217;ll be writing an Omnified Design article talking about how I make use of these kinds of &#8220;include files&#8221; inside the assembly in Cheat Engine, and will link it here when that becomes available! <\/p>\n\n\n\n<p>We&#8217;re going to take a look at the code inside the Omnified framework right now that deals with the Apocalypse system. To find examples and explanations for writing code to consume the Apocalypse functions, I again will refer you to the various <a href=\"https:\/\/badecho.com\/index.php\/tag\/apocalypse\/\">Apocalypse implementation articles<\/a> that have been written for my Omnified games.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Player_Apocalypse-2\"><\/span>Player Apocalypse<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The Player Apocalypse&#8217;s code is found in the function <strong>executePlayerApocalypse<\/strong>. Refer to the <a href=\"#player-apocalypse-api\">Apocalypse System API section<\/a> above for high level information concerning this function. In this section, we&#8217;re going to get down and dirty with the code.<\/p>\n\n\n\n<p>The chief responsibility of the code at the start of the Player Apocalypse function is to preserve all the data found in registers that we&#8217;ll be writing to. Following that, it must load the parameters for the function required at the start from the stack into temporary registers so we can work with them.<\/p>\n\n\n\n<p>The only registers that <em>aren&#8217;t<\/em> backed up are the registers that we&#8217;ll be using to hold the function&#8217;s return values: <strong>rax<\/strong> and <strong>rbx<\/strong>. Also, while I normally back up conditional registers in most of my assembly injections (with <strong>pushf<\/strong> and <strong>popf<\/strong>), note that I do not do that here, as this is code to be called from our code, and not code that is an invader in enemy lands (i.e. not-our-code).<\/p>\n\n\n\n<p>Finally, we determine whether or not we want Player Apocalypse execution to occur; if the damage amount is below our configured damage threshold or if God Mode is enabled, we do not want execution to occur and we exit immediately.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Player_Apocalypse_Code_%E2%80%93_First_Steps\"><\/span>Player Apocalypse Code &#8211; First Steps<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nexecutePlayerApocalypse:\n  \/\/ Backing up a few SSE registers we'll be using to\n  \/\/ hold the parameters provided to this function.\n  sub rsp,10\n  movdqu [rsp],xmm0\n  sub rsp,10\n  movdqu [rsp],xmm1\n  sub rsp,10\n  movdqu [rsp],xmm2\n  sub rsp,10\n  movdqu [rsp],xmm3  \n  \/\/ Load the player's health parameter.\n  movss xmm3,[rsp+58]\n  \/\/ Load the damage amount parameter.\n  movss xmm0,[rsp+60]\n  \/\/ Check if the damage being done is enough to warrant Apocalypse execution.\n  mov rax,damageThreshold\n  ucomiss xmm0,[rax]  \n  jbe exitPlayerApocalypse\n  \/\/ If God Mode is disabled, then we apply the Apocalypse.\n  cmp [playerGodMode],1\n  jne applyApocalypse\n  \/\/ Otherwise, we zero out our final damage amount register and exit.\n  xorps xmm0,xmm0\n  jmp exitPlayerApocalypse  \n<\/pre>\n\n\n<p>Once we&#8217;ve determine to go on and apply the Apocalypse, we go about conducting the main function of the Player Apocalypse: the primary dice roll. We then direct execution to the particular area of code corresponding to whatever effect must occur due to the result of the roll.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Player_Apocalypse_Code_%E2%80%93_Primary_Dice_Roll\"><\/span>Player Apocalypse Code &#8211; Primary Dice Roll<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\napplyApocalypse:\n  \/\/ If the player has the Fatalis debuff, all damage is fatal.\n  cmp [fatalisState],1\n  jne applyApocalypseRoll\n  \/\/ To make good on the Fatalis debuff, we set the damage equal to the health.\n  movss xmm0,xmm3\n  jmp updateEnemyDamageStats\napplyApocalypseRoll:\n  \/\/ Load the parameters for generating the dice roll random number.\n  push [apocalypseResultLower]\n  push [apocalypseResultUpper]\n  mov rax,playerApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  \/\/ Our random roll value is in eax -- we back it up to the &quot;apocalypseResult&quot;\n  \/\/ symbol so that the value can be displayed by the event logging display code.\n  mov [apocalypseResult],eax\n  cmp eax,4\n  jle extraDamage\n  cmp eax,6\n  jle teleportitis\n  cmp eax,9\n  jle riskOfMurder\n  jmp suddenGasm\n<\/pre>\n\n\n<p>The labels used in the jump statements should all be self-explanatory as they all correspond to the effect documented in the <a href=\"#player-apocalypse-basic-mechanics\">Player Apocalypse Basic Mechanics section<\/a>.<\/p>\n\n\n\n<p>The first effect we must implement is the <em>extra damage<\/em> effect. It occurs if the roll is 1 through 4. This is a rather simple effect to implement; all it must do is multiply the working damage amount by the <strong>extraDamageX<\/strong> external parameter.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Player_Apocalypse_Code_%E2%80%93_Extra_Damage\"><\/span>Player Apocalypse Code &#8211; Extra Damage<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nextraDamage:\n  mulss xmm0,[extraDamageX]\n  jmp updateEnemyDamageStats\n<\/pre>\n\n\n<p>The next effect to implement is the much more complicated <em>teleportitis <\/em>effect, which occurs if the roll is 5 or 6. Refer to the <a href=\"##player-apocalypse-basic-mechanics\">basic mechanics section<\/a> for a high level description of what teleportitis does.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Player_Apocalypse_Code_%E2%80%93_Teleportitis\"><\/span>Player Apocalypse Code &#8211; Teleportitis<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\ncommitTeleportitis:\n  \/\/ Some games will disable modifications being made to the player's coordinates\n  \/\/ during certain animations such as weapon attacks or getting knocked back.\n  \/\/ This code needs to be hooked into and temporarily disabled in order for \n  \/\/ teleportitis to work. This can be done by checking the &quot;teleported&quot; symbol \n  \/\/ and preventing those coordinates from being reset. That code will then \n  \/\/ need to set this symbol to 0. In most games I've hacked, this is not \n  \/\/ required. In fact, only one: Dark Souls I.\n  mov [teleported],1\n  \/\/ Load the player coordinates address parameter.\n  mov rbx,[rsp+48]\n  \/\/ Load the parameters for generating the random displacement value to be \n  \/\/ applied to the X coordinate.\n  push [teleportitisResultLower]\n  push [teleportitisResultUpper]\n  mov rax,playerApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  \/\/ The random number is an integer and will need to be converted to a float.\n  mov [teleportitisResult],eax\n  cvtsi2ss xmm1,[teleportitisResult]\n  \/\/ The random number is divided by the following divisor to bring it into the\n  \/\/ expected range (0-10) along with some decimal precision (3 decimal places).\n  divss xmm1,[teleportitisDivisor]\n  \/\/ We cannot generate random negative integers, we instead shift what we have \n  \/\/ here by a negative amount. The range 0 to 10 becomes -5 to 5.\n  subss xmm1,[teleportitisShifter]\n  \/\/ We finally take what we have and then multiply it by the displacement \n  \/\/ multiplier to get the final displacement value to apply to the player's \n  \/\/ X coordinate.\n  mulss xmm1,[teleportitisDisplacementX]\n  \/\/ We then take the player's current X coordinate from memory and add the\n  \/\/ displacement value to it.\n  cmp [coordinatesAreDoubles],1\n  je loadXAsDouble\n  movss xmm2,[rbx]\n  jmp addChangeToX\nloadXAsDouble:\n  cvtsd2ss xmm2,[rbx]\naddChangeToX:\n  addss xmm2,xmm1\n  \/\/ The updated X coordinate is committed back into the memory, which will \n  \/\/ move the player.\n  cmp [coordinatesAreDoubles],1\n  je commitXAsDouble\n  movss [rbx],xmm2\n  jmp teleportY\ncommitXAsDouble:\n  cvtss2sd xmm1,xmm2\n  movsd [rbx],xmm1\nteleportY:\n  \/\/ Load the parameters for generating the random displacement value to be \n  \/\/ applied to the Y coordinate. \n  push [teleportitisResultLower]\n  push [teleportitisResultUpper]\n  mov rax,playerApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  mov [teleportitisResult],eax\n  cvtsi2ss xmm1,[teleportitisResult]\n  divss xmm1,[teleportitisDivisor]\n  \/\/ If the Y-axis is not the vertical axis, then we we don't need to check \n  \/\/ whether vertical displacement is enabled.\n  cmp [yIsVertical],1\n  jne skipYSkipCheck\n  \/\/ If negative vertical displacement is not enabled we do not want to shift it,\n  \/\/ this causes the random value to remain in the range of 0 to 10.\n  cmp [negativeVerticalDisplacementEnabled],1\n  jne skipNegativeVerticalYDisplacement\nskipYSkipCheck:\n  subss xmm1,[teleportitisShifter]\nskipNegativeVerticalYDisplacement:\n  mulss xmm1,[teleportitisDisplacementX]\n  \/\/ The vertical displacement value is logged and displayed to viewers as \n  \/\/ changes to are often the most consequential. We make sure the Y-axis is \n  \/\/ the vertical one before logging it.\n  cmp [yIsVertical],1\n  jne skipLastYVerticalDisplacement\n  movss [lastVerticalDisplacement],xmm1\nskipLastYVerticalDisplacement:\n  \/\/ We then take the player's current Y coordinate from memory and add the\n  \/\/ displacement value to it.\n  cmp [coordinatesAreDoubles],1\n  je loadYAsDouble\n  movss xmm2,[rbx+4]\n  jmp addChangeToY\nloadYAsDouble:\n  cvtsd2ss xmm2,[rbx+8]\naddChangeToY:\n  addss xmm2,xmm1\n  \/\/ The updated Y coordinate is commited back into the memory, which will \n  \/\/ move the player.\n  cmp [coordinatesAreDoubles],1\n  je commitYAsDouble\n  movss [rbx+4],xmm2\n  jmp teleportZ\ncommitYAsDouble:\n  cvtss2sd xmm1,xmm2  \n  movsd [rbx+8],xmm1\nteleportZ:\n  \/\/ Load the parameters for generating the random displacement value to be \n  \/\/ applied to the Z coordinate. \n  push [teleportitisResultLower]\n  push [teleportitisResultUpper]\n  mov rax,playerApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  mov [teleportitisResult],eax\n  cvtsi2ss xmm1,[teleportitisResult]\n  divss xmm1,[teleportitisDivisor]\n  \/\/ Like the Y-axis, the Z-axis can sometimes be the vertical axis. So checks \n  \/\/ similar to the ones made in the Y coordinate displacement code are made.\n  cmp [yIsVertical],0\n  jne skipZSkipCheck\n  cmp [negativeVerticalDisplacementEnabled],1\n  jne skipNegativeVerticalZDisplacement\nskipZSkipCheck:\n  subss xmm1,[teleportitisShifter]\nskipNegativeVerticalZDisplacement:\n  mulss xmm1,[teleportitisDisplacementX]\n  cmp [yIsVertical],0\n  jne skipLastZVerticalDisplacement\n  movss [lastVerticalDisplacement],xmm1\nskipLastZVerticalDisplacement:\n  \/\/ We then take the player's current Z coordinate from memory and add the\n  \/\/ displacement value to it.\n  cmp [coordinatesAreDoubles],1\n  je loadZAsDouble\n  movss xmm2,[rbx+8]  \n  jmp addChangeToZ\nloadZAsDouble:\n  cvtsd2ss xmm2,[rbx+10]\naddChangeToZ:\n  addss xmm2,xmm1\n  \/\/ The updated Z coordinate is commited back into the memory, which will \n  \/\/ move the player.\n  cmp [coordinatesAreDoubles],1\n  je commitZAsDouble\n  movss [rbx+8],xmm2\n  jmp updateEnemyDamageStats\ncommitZAsDouble:\n  cvtss2sd xmm1,xmm2\n  movsd [rbx+10],xmm1  \n  jmp updateEnemyDamageStats\n<\/pre>\n\n\n<p>Next, we need to implement the effect that occurs if the roll is 7, 8, or 9: the <em>risk of murder roll<\/em>. This is another dice roll that then needs to occur, be logged, and have its own special effects executed. Information on <a href=\"https:\/\/badecho.com\/index.php\/2021\/03\/01\/apocalypse-system-adding-fatalis-debuff\/\" target=\"_blank\" rel=\"noreferrer noopener\">Fatalis can be found here<\/a>.<\/p>\n\n\n\n<p>Let&#8217;s go over the code for this special roll as well as all of its effects.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Player_Apocalypse_Code_%E2%80%93_Risk_of_Murder_Roll\"><\/span>Player Apocalypse Code &#8211; Risk of Murder Roll<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nriskOfMurder:\n  \/\/ Load the parameters for generating the Risk of Murder dice roll random \n  \/\/ number.\n  push [riskOfMurderResultLower]\n  push [riskOfMurderResultUpper]\n  mov rax,playerApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  \/\/ Our Risk of Murder roll is in eax -- we back it up to the &quot;riskOfMurderResult&quot; \n  \/\/ symbol so that the value can be displayed by the event logging display code.\n  mov [riskOfMurderResult],eax\n  cmp eax,3\n  \/\/ If the resulting roll is 4 or 5, then the player is getting sixty nined.\n  jg sixtyNine\n  \/\/ Otherwise, normal damage applies, however there is also now a very slight chance\n  \/\/ of Fatalis being applied, but only if it is not already active.  \n  cmp [fatalisState],1\n  je updateEnemyDamageStats\n  push [fatalisResultLower]\n  push [fatalisResultUpper]\n  mov rax,playerApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  \/\/ The Fatalis roll is in eax -- we throw it into the &quot;fatalisResult&quot; symbol\n  \/\/ so we can report on it.\n  mov [fatalisResult],eax\n  \/\/ Fatalis will only be applied if the roll landed on the maximum possible value.\n  cmp eax,[fatalisResultUpper]\n  jne updateEnemyDamageStats\n  mov [fatalisState],1\n  jmp updateEnemyDamageStats  \nsixtyNine:\n  \/\/ Check if sixty nine is disabled, if so, just apply normal damage.\n  cmp [disableSixtyNine],1\n  jne commitSixtyNine\n  mov [riskOfMurderResult],1\n  jmp updateEnemyDamageStats\ncommitSixtyNine:\n  mulss xmm0,[sixtyNineDamageX]\n  jmp updateEnemyDamageStats\n<\/pre>\n\n\n<p>The final effect from the primary dice roll is the <em>sudden orgasm<\/em> effect, which is only if the roll lands on a 10 (decimal). This needs to heal the player to full and nullify the damage.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Player_Apocalypse_Code_%E2%80%93_Sudden_Orgasm\"><\/span>Player Apocalypse Code &#8211; Sudden Orgasm<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nsuddenGasm:  \n  \/\/ Load the player's maximum health parameter. This is stored in the final \n  \/\/ player health (prior to damage applied) register.\n  movss xmm3,[rsp+50]\n  \/\/ We zero out our final damage amount register.\n  xorps xmm0,xmm0\n  jmp applyPlayerApocalypseExit\n<\/pre>\n\n\n<p>All effects are implemented! We are getting to the end. The final parts of the code need to update the three separate game statistics being maintained by the Player Apocalypse, set the return values, and restore backed up values to the stack.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Player_Apocalypse_Code_%E2%80%93_Update_Stats_and_Cleanup\"><\/span>Player Apocalypse Code &#8211; Update Stats and Cleanup<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nupdateEnemyDamageStats:\n  \/\/ If the final damage amount is less than or equal to the current max damage \n  \/\/ to the player, it doesn't need to be updated obviously!\n  ucomiss xmm0,[maxDamageToPlayer]\n  jna skipMaxEnemyDamageUpdate\n  movss [maxDamageToPlayer],xmm0\nskipMaxEnemyDamageUpdate:\n  \/\/ We save the final damage amount as the last damage to be done to the player,\n  \/\/ and add it to the running total.\n  movss [lastDamageToPlayer],xmm0\n  movss xmm1,xmm0\n  addss xmm1,[totalDamageToPlayer]\n  movss [totalDamageToPlayer],xmm1\napplyPlayerApocalypseExit:\n  \/\/ Because Apocalypse execution is complete, we trigger an event log entry for \n  \/\/ it by setting &quot;logApocalypse&quot; to 1.\n  mov [logApocalypse],1\n  jmp exitPlayerApocalypse\nexitPlayerApocalypse:\n  \/\/ We commit our final damage amount to eax.\n  movd eax,xmm0\n  \/\/ We commit our final working player health to ebx.\n  movd ebx,xmm3\n  \/\/ Restore backed up values.\n  movdqu xmm3,[rsp]\n  add rsp,10\n  movdqu xmm2,[rsp]\n  add rsp,10\n  movdqu xmm1,[rsp]\n  add rsp,10\n  movdqu xmm0,[rsp]\n  add rsp,10  \n  \/\/ This function has 4 parameters, each require 8 bytes. 4x8 == 20 (hex).\n  ret 20\n<\/pre>\n\n\n<p>Tada! We&#8217;ve covered the code for the Player Apocalypse. To get the entire working code, check out the <a href=\"#apocalypse-code-complete\">complete Apocalypse code section<\/a>.<\/p>\n\n\n\n<h3><span class=\"ez-toc-section\" id=\"Enemy_Apocalypse-2\"><\/span>Enemy Apocalypse<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The Enemy Apocalypse&#8217;s code is found in the function <strong>executeEnemyApocalypse<\/strong>. Refer to the <a href=\"#enemy-apocalypse-api\">Apocalypse System API section<\/a> above for high level information concerning this function. Let&#8217;s get down and dirty with this little bit of code now!<\/p>\n\n\n\n<p>Much like the Player Apocalypse code, the chief responsibility of the code at the start of this function is to preserve data to the stack and to load parameter values that are needed. Also like the Player Apocalypse code, the <strong>eax<\/strong> and <strong>ebx<\/strong> registers aren&#8217;t backed up as they are used as return values.<\/p>\n\n\n\n<p>And finally&#8230;<em>also<\/em> like the Player Apocalypse code, we want to completely forego Enemy Apocalypse execution if the damage doesn&#8217;t meet defined thresholds &#8212; fortunately for us, there is no God Mode for enemies!<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Enemy_Apocalypse_Code_%E2%80%93_First_Steps\"><\/span>Enemy Apocalypse Code &#8211; First Steps<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nexecuteEnemyApocalypse:\n  \/\/ Backing up a few SSE registers we'll be using to\n  \/\/ hold the parameters provided to this function.\n  sub rsp,10\n  movdqu [rsp],xmm0\n  sub rsp,10\n  movdqu [rsp],xmm1  \n  sub rsp,10\n  movdqu [rsp],xmm2\n  \/\/ Load the enemy's health parameter.  \n  movss xmm1,[rsp+38]\n  \/\/ Load the damage amount parameter.\n  movss xmm0,[rsp+40]\n  \/\/ Check if the damage being done is enough to warrant Apocalypse execution.\n  mov rax,damageThreshold\n  ucomiss xmm0,[rax]  \n  jbe exitEnemyApocalypse  \n<\/pre>\n\n\n<p>Already simpler than the Player Apocalypse! The next thing we need to do is apply the player damage multiplier to the damage amount and perform critical hit chance evaluation. If the hit is a critical one, we want to then see how much extra damage is done, otherwise we continue on.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Enemy_Apocalypse_Code_%E2%80%93_Base_Damage_and_Critical_Hits\"><\/span>Enemy Apocalypse Code &#8211; Base Damage and Critical Hits<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\napplyPlayerDamage:\n  \/\/ Apply our base player damage multiplier to the damage amount.\n  mulss xmm0,[playerDamageX]\n  \/\/ Load the parameters for generating the critical hit check.\n  push [playerCritChanceResultLower]\n  push [playerCritChanceResultUpper]\n  mov rax,enemyApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  \/\/ Our random roll value is in eax -- we back it up to the \n  \/\/ &quot;playerCritChanceResult&quot; symbol so that the value can be displayed by the \n  \/\/ event logging display code.\n  mov [playerCritChanceResult],eax\n  \/\/ We can't generate random floats, only random integers. So, to have \n  \/\/ a 6.25% crit chance, we generate a number in the range of 0 to 400, and \n  \/\/ then check if the value is less than or equal to 25 (25\/400 = 0.0625).\n  cmp eax,25\n  jg checkKamehameha  \n  \/\/ Load the parameters for generating the critical hit damage.\n  push [playerCritDamageResultLower]\n  push [playerCritDamageResultUpper]\n  mov rax,enemyApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  \/\/ Our random roll value is in eax -- we back it up to the \n  \/\/ &quot;playerCritDamageResult&quot; symbol so that the value can be displayed by \n  \/\/ the event logging display code.\n  mov [playerCritDamageResult],eax\n  \/\/ We can't generate floating point random numbers, so we convert it to float\n  \/\/ and divide it by our divisor to put it in range with one level of decimal\n  \/\/ precision.\n  cvtsi2ss xmm2,[playerCritDamageResult]\n  divss xmm2,[playerCritDamageDivisor]\n  mulss xmm0,xmm2\n  \/\/ We signal to the event logging system that a crit occurred by setting\n  \/\/ the &quot;logPlayerCrit&quot; symbol to 1.\n  mov [logPlayerCrit],1\n<\/pre>\n\n\n<p>We now have a beautifully functional critical hit system in any game of our choosing! Next we need to implement the final pro-player goodie: the amazing Kamehameha!<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Enemy_Apocalypse_Code_%E2%80%93_Kamehameha\"><\/span>Enemy Apocalypse Code &#8211; Kamehameha<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\ncheckKamehameha:\n  \/\/ Load the parameters for generating the Kamehameha check.\n  push [gokuResultLower]\n  push [gokuResultUpper]\n  mov rax,enemyApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  \/\/ Our random roll value is in eax -- we back it up to the &quot;gokuResult&quot;\n  \/\/ symbol so that the value can be displayed by the event logging display code.\n  mov [gokuResult],eax\n  \/\/ If the roll is exactly 69, a Kamehameha has occurred! Big damage time baby.\n  cmp eax,#69\n  jne updatePlayerDamageStats\n  \/\/ We signal to the event logging system that a Kamehameha occurred by setting\n  \/\/ the &quot;logKamehameha&quot; symbol to 1.\n  mov [logKamehameha],1\n  mulss xmm0,[gokuDamageX]  \n<\/pre>\n\n\n<p>The final bits of code deal with updating relevant damage statistics, setting return values, and restoring backed up values. All very similar to the Player Apocalypse, except in the enemy domain.<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Enemy_Apocalypse_Code_%E2%80%93_Update_Stats_and_Cleanup\"><\/span>Enemy Apocalypse Code &#8211; Update Stats and Cleanup<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nupdatePlayerDamageStats:\n  \/\/ Sometimes the enemy health is hidden from the player by the game. Well I like\n  \/\/ flexing my muscle and displaying it anyway on stream with the \n  \/\/ &quot;lastEnemyHealthValue&quot; symbol. We perform a mock damage application here and \n  \/\/ store it there.\n  subss xmm1,xmm0\n  movss [lastEnemyHealthValue],xmm1\n  \/\/ If the final damage amount is less than or equal to the current max damage \n  \/\/ from the player, it doesn't need to be updated obviously!\n  ucomiss xmm0,[maxDamageByPlayer]\n  jna skipMaxPlayerDamageUpdate\n  movss [maxDamageByPlayer],xmm0\nskipMaxPlayerDamageUpdate:\n  \/\/ We save the final damage amount as the last damage to be done from the \n  \/\/ player, and add it to the running total.\n  movss [lastDamageByPlayer],xmm0\n  movss xmm1,xmm0\n  addss xmm1,[totalDamageByPlayer]\n  movss [totalDamageByPlayer],xmm1\nexitEnemyApocalypse:\n  \/\/ We commit our final damage amount to eax.\n  movd eax,xmm0\n  \/\/ We commit our final damage amount to ebx, which actually never changes. It\n  \/\/ is simply used to calculate what the health will be to display with the\n  \/\/ &quot;lastEnemyHealthValue&quot; stat, and also for purposes of polymorphism, in a \n  \/\/ manner of speaking.\n  movss xmm1,[rsp+38]\n  movd ebx,xmm1\n  movdqu xmm2,[rsp]\n  add rsp,10\n  movdqu xmm1,[rsp]\n  add rsp,10\n  movdqu xmm0,[rsp]\n  add rsp,10\n  \/\/ This function has 2 parameters, each require 8 bytes. 2x8 == 10 (hex).\n  ret 10\n<\/pre>\n\n\n<p>Hooray! That&#8217;s all the code for the Apocalypse system! <\/p>\n\n\n\n<p>Well almost. You may be wondering about the code that actually ends up displaying all the events and stats to the viewer on the stream. Well, these technologies are actually independent of the Apocalypse system, and are meant to be used with other systems and code as well. <\/p>\n\n\n\n<p>I have some big things going on with them, development-wise, and when that concludes, that technology will get its own article. Until then, let it suffice to say that the data is made available by the already provided assembly code, and that we have a bunch of LUA running on an independent timer throwing all the data together and piping it out to the stream.<\/p>\n\n\n\n<h3 id=\"apocalypse-code-complete\"><span class=\"ez-toc-section\" id=\"Complete_Code_for_the_Apocalypse\"><\/span>Complete Code for the Apocalypse<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Here is the complete code for the Apocalypse system. Note that the cleanup portion of the code is not included &#8212; it is all boilerplate and simple <strong>dealloc<\/strong> and <strong>unregistersymbol<\/strong> statements. I&#8217;ll be putting up an actual code repository and\/or download for the Omnified framework sooner or later, and if you need it real bad, you can grab it for there.<\/p>\n\n\n\n<p>Let&#8217;s start with the Player Apocalypse:<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Player_Apocalypse_Code_%E2%80%93_Complete\"><\/span>Player Apocalypse Code &#8211; Complete<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Player Apocalypse System Function\n\/\/ [rsp+48]: Player's coordinates (aligned at X-coord)\n\/\/ [rsp+50]: Max Player Health Amount\n\/\/ [rsp+58]: Player's Health Amount\n\/\/ [rsp+60]: Damage Amount\n\/\/ Updated damage is in EAX. \n\/\/ Updated health before damage is in EBX.\nalloc(executePlayerApocalypse,$1000)\nalloc(playerApocalypseRandomState,8)\nalloc(logApocalypse,8)\nalloc(negativeOne,8)\nalloc(apocalypseResult,8)\nalloc(apocalypseResultUpper,8)\nalloc(apocalypseResultLower,8)\nalloc(teleported,8)\nalloc(teleportitisResult,8)\nalloc(teleportitisResultUpper,8)\nalloc(teleportitisResultLower,8)\nalloc(teleportitisDivisor,8)\nalloc(teleportitisShifter,8)\nalloc(lastVerticalDisplacement,8)\nalloc(negativeVerticalDisplacementEnabled,8)\nalloc(yIsVertical,8)\nalloc(teleportitisDisplacementX,8)\nalloc(coordinatesAreDoubles,8)\nalloc(riskOfMurderResult,8)\nalloc(riskOfMurderResultUpper,8)\nalloc(riskOfMurderResultLower,8)\nalloc(fatalisResult,8)\nalloc(fatalisResultUpper,8)\nalloc(fatalisResultLower,8)\n\/\/ fatalisState: 0 = not active; 1 = active; 2 = cured (used for announcement, then set to 0)\nalloc(fatalisState,8)\nalloc(extraDamageX,8)\nalloc(sixtyNineDamageX,8)\nalloc(maxDamageToPlayer,8)\nalloc(lastDamageToPlayer,8)\nalloc(totalDamageToPlayer,8)\nalloc(playerGodMode,8)\nalloc(disableTeleportitis,8)\nalloc(disableSixtyNine,8)\n\nregistersymbol(executePlayerApocalypse)\nregistersymbol(logApocalypse)\nregistersymbol(teleported)\nregistersymbol(apocalypseResult)\nregistersymbol(negativeVerticalDisplacementEnabled)\nregistersymbol(yIsVertical)\nregistersymbol(teleportitisDisplacementX)\nregistersymbol(riskOfMurderResult)\nregistersymbol(fatalisResult)\nregistersymbol(fatalisResultUpper)\nregistersymbol(fatalisState)\nregistersymbol(extraDamageX)\nregistersymbol(maxDamageToPlayer)\nregistersymbol(lastDamageToPlayer)\nregistersymbol(totalDamageToPlayer)\nregistersymbol(lastVerticalDisplacement)\nregistersymbol(coordinatesAreDoubles)\nregistersymbol(playerGodMode)\nregistersymbol(disableTeleportitis)\nregistersymbol(disableSixtyNine)\n\nexecutePlayerApocalypse:\n  \/\/ Backing up a few SSE registers we'll be using to\n  \/\/ hold the parameters provided to this function.\n  sub rsp,10\n  movdqu [rsp],xmm0\n  sub rsp,10\n  movdqu [rsp],xmm1\n  sub rsp,10\n  movdqu [rsp],xmm2\n  sub rsp,10\n  movdqu [rsp],xmm3  \n  \/\/ Load the player's health parameter.\n  movss xmm3,[rsp+58]\n  \/\/ Load the damage amount parameter.\n  movss xmm0,[rsp+60]\n  \/\/ Check if the damage being done is enough to warrant Apocalypse execution.\n  mov rax,damageThreshold\n  ucomiss xmm0,[rax]  \n  jbe exitPlayerApocalypse\n  \/\/ If God Mode is disabled, then we apply the Apocalypse.\n  cmp [playerGodMode],1\n  jne applyApocalypse\n  \/\/ Otherwise, we zero out our final damage amount register and exit.\n  xorps xmm0,xmm0\n  jmp exitPlayerApocalypse  \napplyApocalypse:\n  \/\/ If the player has the Fatalis debuff, all damage is fatal.\n  cmp [fatalisState],1\n  jne applyApocalypseRoll\n  \/\/ To make good on the Fatalis debuff, we set the damage equal to the health.\n  movss xmm0,xmm3\n  jmp updateEnemyDamageStats\napplyApocalypseRoll:\n  \/\/ Load the parameters for generating the dice roll random number.\n  push [apocalypseResultLower]\n  push [apocalypseResultUpper]\n  mov rax,playerApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  \/\/ Our random roll value is in eax -- we back it up to the &quot;apocalypseResult&quot;\n  \/\/ symbol so that the value can be displayed by the event logging display code.\n  mov [apocalypseResult],eax\n  cmp eax,4\n  jle extraDamage\n  cmp eax,6\n  jle teleportitis\n  cmp eax,9\n  jle riskOfMurder\n  jmp suddenGasm\nextraDamage:\n  mulss xmm0,[extraDamageX]\n  jmp updateEnemyDamageStats\nteleportitis:\n  \/\/ Check if teleportitis is disabled. If so, we instead apply extra damage.\n  cmp [disableTeleportitis],1\n  jne commitTeleportitis\n  mov [apocalypseResult],1\n  jmp extraDamage\ncommitTeleportitis:\n  \/\/ Some games will disable modifications being made to the player's coordinates\n  \/\/ during certain animations such as weapon attacks or getting knocked back.\n  \/\/ This code needs to be hooked into and temporarily disabled in order for \n  \/\/ teleportitis to work. This can be done by checking the &quot;teleported&quot; symbol \n  \/\/ and preventing those coordinates from being reset. That code will then \n  \/\/ need to set this symbol to 0. In most games I've hacked, this is not \n  \/\/ required. In fact, only one: Dark Souls I.\n  mov [teleported],1\n  \/\/ Load the player coordinates address parameter.\n  mov rbx,[rsp+48]\n  \/\/ Load the parameters for generating the random displacement value to be \n  \/\/ applied to the X coordinate.\n  push [teleportitisResultLower]\n  push [teleportitisResultUpper]\n  mov rax,playerApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  \/\/ The random number is an integer and will need to be converted to a float.\n  mov [teleportitisResult],eax\n  cvtsi2ss xmm1,[teleportitisResult]\n  \/\/ The random number is divided by the following divisor to bring it into the\n  \/\/ expected range (0-10) along with some decimal precision (3 decimal places).\n  divss xmm1,[teleportitisDivisor]\n  \/\/ We cannot generate random negative integers, we instead shift what we have \n  \/\/ here by a negative amount. The range 0 to 10 becomes -5 to 5.\n  subss xmm1,[teleportitisShifter]\n  \/\/ We finally take what we have and then multiply it by the displacement \n  \/\/ multiplier to get the final displacement value to apply to the player's \n  \/\/ X coordinate.\n  mulss xmm1,[teleportitisDisplacementX]\n  \/\/ We then take the player's current X coordinate from memory and add the\n  \/\/ displacement value to it.\n  cmp [coordinatesAreDoubles],1\n  je loadXAsDouble\n  movss xmm2,[rbx]\n  jmp addChangeToX\nloadXAsDouble:\n  cvtsd2ss xmm2,[rbx]\naddChangeToX:\n  addss xmm2,xmm1\n  \/\/ The updated X coordinate is committed back into the memory, which will \n  \/\/ move the player.\n  cmp [coordinatesAreDoubles],1\n  je commitXAsDouble\n  movss [rbx],xmm2\n  jmp teleportY\ncommitXAsDouble:\n  cvtss2sd xmm1,xmm2\n  movsd [rbx],xmm1\nteleportY:\n  \/\/ Load the parameters for generating the random displacement value to be \n  \/\/ applied to the Y coordinate. \n  push [teleportitisResultLower]\n  push [teleportitisResultUpper]\n  mov rax,playerApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  mov [teleportitisResult],eax\n  cvtsi2ss xmm1,[teleportitisResult]\n  divss xmm1,[teleportitisDivisor]\n  \/\/ If the Y-axis is not the vertical axis, then we we don't need to check \n  \/\/ whether vertical displacement is enabled.\n  cmp [yIsVertical],1\n  jne skipYSkipCheck\n  \/\/ If negative vertical displacement is not enabled we do not want to shift it,\n  \/\/ this causes the random value to remain in the range of 0 to 10.\n  cmp [negativeVerticalDisplacementEnabled],1\n  jne skipNegativeVerticalYDisplacement\nskipYSkipCheck:\n  subss xmm1,[teleportitisShifter]\nskipNegativeVerticalYDisplacement:\n  mulss xmm1,[teleportitisDisplacementX]\n  \/\/ The vertical displacement value is logged and displayed to viewers as \n  \/\/ changes to are often the most consequential. We make sure the Y-axis is \n  \/\/ the vertical one before logging it.\n  cmp [yIsVertical],1\n  jne skipLastYVerticalDisplacement\n  movss [lastVerticalDisplacement],xmm1\nskipLastYVerticalDisplacement:\n  \/\/ We then take the player's current Y coordinate from memory and add the\n  \/\/ displacement value to it.\n  cmp [coordinatesAreDoubles],1\n  je loadYAsDouble\n  movss xmm2,[rbx+4]\n  jmp addChangeToY\nloadYAsDouble:\n  cvtsd2ss xmm2,[rbx+8]\naddChangeToY:\n  addss xmm2,xmm1\n  \/\/ The updated Y coordinate is commited back into the memory, which will \n  \/\/ move the player.\n  cmp [coordinatesAreDoubles],1\n  je commitYAsDouble\n  movss [rbx+4],xmm2\n  jmp teleportZ\ncommitYAsDouble:\n  cvtss2sd xmm1,xmm2  \n  movsd [rbx+8],xmm1\nteleportZ:\n  \/\/ Load the parameters for generating the random displacement value to be \n  \/\/ applied to the Z coordinate. \n  push [teleportitisResultLower]\n  push [teleportitisResultUpper]\n  mov rax,playerApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  mov [teleportitisResult],eax\n  cvtsi2ss xmm1,[teleportitisResult]\n  divss xmm1,[teleportitisDivisor]\n  \/\/ Like the Y-axis, the Z-axis can sometimes be the vertical axis. So checks \n  \/\/ similar to the ones made in the Y coordinate displacement code are made.\n  cmp [yIsVertical],0\n  jne skipZSkipCheck\n  cmp [negativeVerticalDisplacementEnabled],1\n  jne skipNegativeVerticalZDisplacement\nskipZSkipCheck:\n  subss xmm1,[teleportitisShifter]\nskipNegativeVerticalZDisplacement:\n  mulss xmm1,[teleportitisDisplacementX]\n  cmp [yIsVertical],0\n  jne skipLastZVerticalDisplacement\n  movss [lastVerticalDisplacement],xmm1\nskipLastZVerticalDisplacement:\n  \/\/ We then take the player's current Z coordinate from memory and add the\n  \/\/ displacement value to it.\n  cmp [coordinatesAreDoubles],1\n  je loadZAsDouble\n  movss xmm2,[rbx+8]  \n  jmp addChangeToZ\nloadZAsDouble:\n  cvtsd2ss xmm2,[rbx+10]\naddChangeToZ:\n  addss xmm2,xmm1\n  \/\/ The updated Z coordinate is commited back into the memory, which will \n  \/\/ move the player.\n  cmp [coordinatesAreDoubles],1\n  je commitZAsDouble\n  movss [rbx+8],xmm2\n  jmp updateEnemyDamageStats\ncommitZAsDouble:\n  cvtss2sd xmm1,xmm2\n  movsd [rbx+10],xmm1  \n  jmp updateEnemyDamageStats\nriskOfMurder:\n  \/\/ Load the parameters for generating the Risk of Murder dice roll random \n  \/\/ number.\n  push [riskOfMurderResultLower]\n  push [riskOfMurderResultUpper]\n  mov rax,playerApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  \/\/ Our Risk of Murder roll is in eax -- we back it up to the &quot;riskOfMurderResult&quot; \n  \/\/ symbol so that the value can be displayed by the event logging display code.\n  mov [riskOfMurderResult],eax\n  cmp eax,3\n  \/\/ If the resulting roll is 4 or 5, then the player is getting sixty nined.\n  jg sixtyNine\n  \/\/ Otherwise, normal damage applies, however there is also now a very slight chance\n  \/\/ of Fatalis being applied, but only if it is not already active.  \n  cmp [fatalisState],1\n  je updateEnemyDamageStats\n  push [fatalisResultLower]\n  push [fatalisResultUpper]\n  mov rax,playerApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  \/\/ The Fatalis roll is in eax -- we throw it into the &quot;fatalisResult&quot; symbol\n  \/\/ so we can report on it.\n  mov [fatalisResult],eax\n  \/\/ Fatalis will only be applied if the roll landed on the maximum possible value.\n  cmp eax,[fatalisResultUpper]\n  jne updateEnemyDamageStats\n  mov [fatalisState],1\n  jmp updateEnemyDamageStats  \nsixtyNine:\n  \/\/ Check if sixty nine is disabled, if so, just apply normal damage.\n  cmp [disableSixtyNine],1\n  jne commitSixtyNine\n  mov [riskOfMurderResult],1\n  jmp updateEnemyDamageStats\ncommitSixtyNine:\n  mulss xmm0,[sixtyNineDamageX]\n  jmp updateEnemyDamageStats\nsuddenGasm:  \n  \/\/ Load the player's maximum health parameter. This is stored in the final \n  \/\/ player health (prior to damage applied) register.\n  movss xmm3,[rsp+50]\n  \/\/ We zero out our final damage amount register.\n  xorps xmm0,xmm0\n  jmp applyPlayerApocalypseExit\nupdateEnemyDamageStats:\n  \/\/ If the final damage amount is less than or equal to the current max damage \n  \/\/ to the player, it doesn't need to be updated obviously!\n  ucomiss xmm0,[maxDamageToPlayer]\n  jna skipMaxEnemyDamageUpdate\n  movss [maxDamageToPlayer],xmm0\nskipMaxEnemyDamageUpdate:\n  \/\/ We save the final damage amount as the last damage to be done to the player,\n  \/\/ and add it to the running total.\n  movss [lastDamageToPlayer],xmm0\n  movss xmm1,xmm0\n  addss xmm1,[totalDamageToPlayer]\n  movss [totalDamageToPlayer],xmm1\napplyPlayerApocalypseExit:\n  \/\/ Because Apocalypse execution is complete, we trigger an event log entry for \n  \/\/ it by setting &quot;logApocalypse&quot; to 1.\n  mov [logApocalypse],1\n  jmp exitPlayerApocalypse\nexitPlayerApocalypse:\n  \/\/ We commit our final damage amount to eax.\n  movd eax,xmm0\n  \/\/ We commit our final working player health to ebx.\n  movd ebx,xmm3\n  \/\/ Restore backed up values.\n  movdqu xmm3,[rsp]\n  add rsp,10\n  movdqu xmm2,[rsp]\n  add rsp,10\n  movdqu xmm1,[rsp]\n  add rsp,10\n  movdqu xmm0,[rsp]\n  add rsp,10  \n  \/\/ This function has 4 parameters, each require 8 bytes. 4x8 == 20 (hex).\n  ret 20\n  \nplayerApocalypseRandomState:\n  dd 0\n  \nlogApocalypse:\n  dd 0\n  \napocalypseResult:\n  dd 0\n  \napocalypseResultUpper:\n  dd #10\n  \napocalypseResultLower:\n  dd 1\n  \nteleportitisResult:\n  dd 0\n  \nteleportitisResultUpper:\n  dd #10000\n  \nteleportitisResultLower:\n  dd 0\n  \nteleportitisDivisor:\n  dd (float)1000.0\n  \nteleportitisShifter:\n  dd (float)5.0\n\nnegativeVerticalDisplacementEnabled:\n  dd 1\n  \nyIsVertical:\n  dd 1\n\ncoordinatesAreDoubles:\n  dd 0\n  \nteleportitisDisplacementX:\n  dd (float)1.0\n    \nnegativeOne:\n  dd (float)-1.0\n\nriskOfMurderResult:\n  dd 0\n  \nriskOfMurderResultUpper:\n  dd #5\n  \nriskOfMurderResultLower:\n  dd 1\n  \nfatalisResult:\n  dd 0\n  \nfatalisResultUpper:\n  dd 3\n  \nfatalisResultLower:\n  dd 1\n  \nfatalisState:\n  dd 0\n  \nextraDamageX:\n  dd (float)2.0\n  \nsixtyNineDamageX:\n  dd (float)69.0\n  \nmaxDamageToPlayer:\n  dd 0\n  \nlastDamageToPlayer:\n  dd 0\n  \ntotalDamageToPlayer:\n  dd 0\n  \nplayerGodMode:\n  dd 0  \n  \ndisableTeleportitis:\n  dd 0\n  \ndisableSixtyNine:\n  dd 0\n<\/pre>\n\n\n<p>And next, the Enemy Apocalypse code:<\/p>\n\n\n\n<h4><span class=\"ez-toc-section\" id=\"Enemy_Apocalypse_Code_%E2%80%93_Complete\"><\/span>Enemy Apocalypse Code &#8211; Complete<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ Enemy Apocalypse System Function\n\/\/ [rsp+38]: Target Health Value\n\/\/ [rsp+40]: Damage Amount\nalloc(executeEnemyApocalypse,$1000)\nalloc(maxDamageByPlayer,8)\nalloc(lastDamageByPlayer,8)\nalloc(totalDamageByPlayer,8)\nalloc(logKamehameha,8)\nalloc(gokuResult,8)\nalloc(gokuResultUpper,8)\nalloc(gokuResultLower,8)\nalloc(gokuDamageX,8)\nalloc(playerDamageX,8)\nalloc(lastEnemyHealthValue,8)\nalloc(playerCritChanceResultUpper,8)\nalloc(playerCritChanceResultLower,8)\nalloc(playerCritChanceResult,8)\nalloc(playerCritDamageResultUpper,8)\nalloc(playerCritDamageResultLower,8)\nalloc(playerCritDamageResult,8)\nalloc(playerCritDamageDivisor,8)\nalloc(logPlayerCrit,8)\nalloc(enemyApocalypseRandomState,8)\n\nregistersymbol(executeEnemyApocalypse)\nregistersymbol(maxDamageByPlayer)\nregistersymbol(lastDamageByPlayer)\nregistersymbol(totalDamageByPlayer)\nregistersymbol(logKamehameha)\nregistersymbol(gokuDamageX)\nregistersymbol(gokuResultUpper)\nregistersymbol(playerDamageX)\nregistersymbol(lastEnemyHealthValue)\nregistersymbol(playerCritDamageResult)\nregistersymbol(logPlayerCrit)\n\nexecuteEnemyApocalypse:\n  \/\/ Backing up a few SSE registers we'll be using to\n  \/\/ hold the parameters provided to this function.\n  sub rsp,10\n  movdqu [rsp],xmm0\n  sub rsp,10\n  movdqu [rsp],xmm1  \n  sub rsp,10\n  movdqu [rsp],xmm2\n  \/\/ Load the enemy's health parameter.  \n  movss xmm1,[rsp+38]\n  \/\/ Load the damage amount parameter.\n  movss xmm0,[rsp+40]\n  \/\/ Check if the damage being done is enough to warrant Apocalypse execution.\n  mov rax,damageThreshold\n  ucomiss xmm0,[rax]  \n  jbe exitEnemyApocalypse  \napplyPlayerDamage:\n  \/\/ Apply our base player damage multiplier to the damage amount.\n  mulss xmm0,[playerDamageX]\n  \/\/ Load the parameters for generating the critical hit check.\n  push [playerCritChanceResultLower]\n  push [playerCritChanceResultUpper]\n  mov rax,enemyApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  \/\/ Our random roll value is in eax -- we back it up to the \n  \/\/ &quot;playerCritChanceResult&quot; symbol so that the value can be displayed by the \n  \/\/ event logging display code.\n  mov [playerCritChanceResult],eax\n  \/\/ We can't generate random floats, only random integers. So, to have \n  \/\/ a 6.25% crit chance, we generate a number in the range of 0 to 400, and \n  \/\/ then check if the value is less than or equal to 25 (25\/400 = 0.0625).\n  cmp eax,25\n  jg checkKamehameha  \n  \/\/ Load the parameters for generating the critical hit damage.\n  push [playerCritDamageResultLower]\n  push [playerCritDamageResultUpper]\n  mov rax,enemyApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  \/\/ Our random roll value is in eax -- we back it up to the \n  \/\/ &quot;playerCritDamageResult&quot; symbol so that the value can be displayed by \n  \/\/ the event logging display code.\n  mov [playerCritDamageResult],eax\n  \/\/ We can't generate floating point random numbers, so we convert it to float\n  \/\/ and divide it by our divisor to put it in range with one level of decimal\n  \/\/ precision.\n  cvtsi2ss xmm2,[playerCritDamageResult]\n  divss xmm2,[playerCritDamageDivisor]\n  mulss xmm0,xmm2\n  \/\/ We signal to the event logging system that a crit occurred by setting\n  \/\/ the &quot;logPlayerCrit&quot; symbol to 1.\n  mov [logPlayerCrit],1  \ncheckKamehameha:\n  \/\/ Load the parameters for generating the Kamehameha check.\n  push [gokuResultLower]\n  push [gokuResultUpper]\n  mov rax,enemyApocalypseRandomState\n  push rax\n  call generateRandomNumber\n  \/\/ Our random roll value is in eax -- we back it up to the &quot;gokuResult&quot;\n  \/\/ symbol so that the value can be displayed by the event logging display code.\n  mov [gokuResult],eax\n  \/\/ If the roll is exactly 69, a Kamehameha has occurred! Big damage time baby.\n  cmp eax,#69\n  jne updatePlayerDamageStats\n  \/\/ We signal to the event logging system that a Kamehameha occurred by setting\n  \/\/ the &quot;logKamehameha&quot; symbol to 1.\n  mov [logKamehameha],1\n  mulss xmm0,[gokuDamageX]  \nupdatePlayerDamageStats:\n  \/\/ Sometimes the enemy health is hidden from the player by the game. \n  \/\/ Well I like flexing my muscle and displaying it anyway on stream with the \n  \/\/ &quot;lastEnemyHealthValue&quot; symbol. We perform a mock damage application here and\n  \/\/ store it there.\n  subss xmm1,xmm0\n  movss [lastEnemyHealthValue],xmm1\n  \/\/ If the final damage amount is less than or equal to the current max damage \n  \/\/ from the player, it doesn't need to be updated obviously!\n  ucomiss xmm0,[maxDamageByPlayer]\n  jna skipMaxPlayerDamageUpdate\n  movss [maxDamageByPlayer],xmm0\nskipMaxPlayerDamageUpdate:\n  \/\/ We save the final damage amount as the last damage to be done from the \n  \/\/ player, and add it to the running total.\n  movss [lastDamageByPlayer],xmm0\n  movss xmm1,xmm0\n  addss xmm1,[totalDamageByPlayer]\n  movss [totalDamageByPlayer],xmm1\nexitEnemyApocalypse:\n  \/\/ We commit our final damage amount to eax.\n  movd eax,xmm0\n  \/\/ We commit our final damage amount to ebx, which actually never changes. It\n  \/\/ is simply used to calculate what the health will be to display with the\n  \/\/ &quot;lastEnemyHealthValue&quot; stat, and also for purposes of polymorphism, in a \n  \/\/ manner of speaking.\n  movss xmm1,[rsp+38]\n  movd ebx,xmm1\n  movdqu xmm2,[rsp]\n  add rsp,10\n  movdqu xmm1,[rsp]\n  add rsp,10\n  movdqu xmm0,[rsp]\n  add rsp,10\n  \/\/ This function has 2 parameters, each require 8 bytes. 2x8 == 10 (hex).\n  ret 10\n\n \ntotalDamageByPlayer:\n  dd 0\n\nmaxDamageByPlayer:\n  dd 0\n  \nlastDamageByPlayer:\n  dd 0  \n\nlogKamehameha:\n  dd 0\n\ngokuResult:\n  dd 0\n  \ngokuResultUpper:\n  dd #1000\n  \ngokuResultLower:\n  dd 0\n  \ngokuDamageX:\n  dd (float)10000.0\n  \nplayerDamageX:\n  dd (float)1.0\n  \nlastEnemyHealthValue:\n  dd 0\n  \nplayerCritChanceResult:\n  dd 0\n  \nplayerCritChanceResultUpper:\n  dd #800\n  \nplayerCritChanceResultLower:\n  dd 0\n  \nplayerCritDamageResult:\n  dd 0\n  \nplayerCritDamageResultUpper:\n  dd #50\n  \nplayerCritDamageResultLower:\n  dd #20\n  \nplayerCritDamageDivisor:\n  dd (float)10.0\n  \nlogPlayerCrit:\n  dd 0\n  \nenemyApocalypseRandomState:\n  dd 0\n<\/pre>\n\n\n<p>That&#8217;s it for this guide to the very first of my game-neutral Omnified systems. Hope this shed some light on what it is and how it works. If I was able to expand your mind a little bit at all, I am more than satisfied!<\/p>\n\n\n\n<p>To see the insane gameplay that the Apocalypse system affords us, check me out live on my Twitch stream at: <a href=\"https:\/\/twitch.tv\/omni\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/twitch.tv\/omni<\/a><\/p>\n\n\n\n<p>Got some questions, ask me on my Discord at: <a href=\"https:\/\/discord.gg\/omni\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/discord.gg\/omni<\/a><\/p>\n\n\n\n<p>Thank you for your interest, and your time. Safe travels.<\/p>\n\n\n\n<p><em>~Omni<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Table of Contents An Overview of the Apocalypse SystemOrigins of the Apocalypse SystemBasic Mechanics of the Apocalypse SystemPlayer ApocalypsePrimary Dice [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[16],"tags":[26,29,24,28],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\r\n<title>The Apocalypse System: Omnified Hacking Design - omni&#039;s hackpad<\/title>\r\n<meta name=\"description\" content=\"The Apocalypse System is a game-neutral Omnified process that completely overhauls how damage is handled in a game, replacing it with chaos.\" \/>\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\/19\/apocalypse-system\/\" \/>\r\n<meta property=\"og:locale\" content=\"en_US\" \/>\r\n<meta property=\"og:type\" content=\"article\" \/>\r\n<meta property=\"og:title\" content=\"The Apocalypse System: Omnified Hacking Design - omni&#039;s hackpad\" \/>\r\n<meta property=\"og:description\" content=\"The Apocalypse System is a game-neutral Omnified process that completely overhauls how damage is handled in a game, replacing it with chaos.\" \/>\r\n<meta property=\"og:url\" content=\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/\" \/>\r\n<meta property=\"og:site_name\" content=\"omni&#039;s hackpad\" \/>\r\n<meta property=\"article:published_time\" content=\"2020-10-19T05:19:52+00:00\" \/>\r\n<meta property=\"article:modified_time\" content=\"2021-06-18T15:47:20+00:00\" \/>\r\n<meta property=\"og:image\" content=\"http:\/\/badecho.com\/wp-content\/uploads\/2020\/10\/OneHitDeath.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\/19\/apocalypse-system\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"http:\/\/badecho.com\/wp-content\/uploads\/2020\/10\/OneHitDeath.png\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#webpage\",\"url\":\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/\",\"name\":\"The Apocalypse System: Omnified Hacking Design - omni&#039;s hackpad\",\"isPartOf\":{\"@id\":\"https:\/\/badecho.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#primaryimage\"},\"datePublished\":\"2020-10-19T05:19:52+00:00\",\"dateModified\":\"2021-06-18T15:47:20+00:00\",\"description\":\"The Apocalypse System is a game-neutral Omnified process that completely overhauls how damage is handled in a game, replacing it with chaos.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/\"]}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#webpage\"},\"author\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"headline\":\"The Apocalypse System\",\"datePublished\":\"2020-10-19T05:19:52+00:00\",\"dateModified\":\"2021-06-18T15:47:20+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#webpage\"},\"publisher\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"image\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2020\/10\/19\/apocalypse-system\/#primaryimage\"},\"keywords\":\"Apocalypse,Design,Hacking,Omnified\",\"articleSection\":\"Omnified Design\",\"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\/410"}],"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=410"}],"version-history":[{"count":33,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/410\/revisions"}],"predecessor-version":[{"id":1784,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/410\/revisions\/1784"}],"wp:attachment":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/media?parent=410"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/categories?post=410"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/tags?post=410"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}