{"id":1472,"date":"2011-09-28T21:55:08","date_gmt":"2011-09-28T20:55:08","guid":{"rendered":"http:\/\/positech.co.uk\/cliffsblog\/?p=1472"},"modified":"2011-09-28T21:55:08","modified_gmt":"2011-09-28T20:55:08","slug":"anatomy-of-a-gratuitous-bug","status":"publish","type":"post","link":"https:\/\/www.positech.co.uk\/cliffsblog\/2011\/09\/28\/anatomy-of-a-gratuitous-bug\/","title":{"rendered":"Anatomy of  a gratuitous bug"},"content":{"rendered":"<p>I think I&#8217;ve fixed a bug in the gratuitous space battles campaign game. I&#8217;ll know &#8216;officially&#8217; soon, but it fixed it on my machine :D Here&#8217;s what was involved.<\/p>\n<p>A player complained of a random crash bug at the end of some campaign battles. I could not ever reproduce it, and back-and-forth emails began. Eventually, this awesome customer provided me with exact steps to reproduce, and all their save game data to let me replicate it. First run through and&#8230;.. nothing. It was fine. Roughly every third run-through, in release mode it crashed&#8230;<\/p>\n<p><span style=\"color: #333399;\"><strong>Step 1<\/strong>! Hurrah! it actually crashes for me. This is 50% of the battle because then I *KNOW* that it is the games fault, and not the gamers system, or software. This is good, although frustrating news.<\/span><\/p>\n<p><span style=\"color: #333399;\"><strong>Step 2<\/strong>! It crashes in debug mode. This is another 25% of the battle because I can actually see what data is corrupt. As it turned out, the &#8216;firstfleet&#8217; pointer in the code that assigns captured ships to the players winning fleet is clearly trashed. How did this happen?<\/span><\/p>\n<p><span style=\"color: #333399;\"><strong>Step 3<\/strong>&#8230; debugging. It transpires that the firstfleet pointer is accessed multiple times before this point, and after being initialised, confirming that it *must* have been valid, and becomes invalid between initialisation and access when adding captured ships to the fleet. This means we\u00a0 can step through and watch what happens, if I break on initialisation..<\/span><\/p>\n<p><span style=\"color: #333399;\"><strong>Step 4<\/strong> discovery! Stepping through the code confirms my suspicions. Once the battle ends, the code updates all the players fleets and removes ships that died in battle. Then, other code innocently picks the first of the players fleets in the battle, and initialises a dialog box listing the enemy captured ships that will be assigned to the fleet. Later&#8230;. *drum roll* it deletes any fleets that are now empty. Can you see the bug yet?<\/span><\/p>\n<p><span style=\"color: #333399;\"><strong>Step 5<\/strong>: fix! Changing the code that naievely picked the &#8216;first fleet&#8217; to pick the first player fleet that still has some intact ships ensures that the later deletion of an empty fleet, and invalidation of the pointer is harmless, because the captured ships are now getting added to a surviving fleet. Bug probably fixed, pending the player confirming that a new exe fixes it.<\/span><\/p>\n<p>Why did I not spot this bug six months ago? Well here is what has to happen.<\/p>\n<ol>\n<li>The player has to fight a battle with multiple fleets at once (common).<\/li>\n<li>He has to win (fairly common)<\/li>\n<li>The ai has to lose by the right margin to leave some captured ships (fairly rare).<\/li>\n<li>The winning player has to have enough ships removed from the *first* fleet in the list to have that fleet entirely deleted, despite winning overall. (pretty darned rare).<\/li>\n<\/ol>\n<p>Simply put, This didn&#8217;t happen to me once in testing. It hasn&#8217;t happened to many players either, as I understand it. And if it has happened to you&#8230; I may have good news :D<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I think I&#8217;ve fixed a bug in the gratuitous space battles campaign game. I&#8217;ll know &#8216;officially&#8217; soon, but it fixed it on my machine :D Here&#8217;s what was involved. A player complained of a random crash bug at the end of some campaign battles. I could not ever reproduce it, and back-and-forth emails began. Eventually,<\/p>\n<p class=\"text-right\"><span class=\"screen-reader-text\">Continue Reading&#8230; Anatomy of  a gratuitous bug<\/span><a class=\"btn btn-secondary continue-reading\" href=\"https:\/\/www.positech.co.uk\/cliffsblog\/2011\/09\/28\/anatomy-of-a-gratuitous-bug\/\">Continue Reading&#8230;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[105,4],"tags":[],"class_list":["post-1472","post","type-post","status-publish","format-standard","hentry","category-gratuitous-space-battles","category-programming"],"_links":{"self":[{"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/posts\/1472","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/comments?post=1472"}],"version-history":[{"count":1,"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/posts\/1472\/revisions"}],"predecessor-version":[{"id":1473,"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/posts\/1472\/revisions\/1473"}],"wp:attachment":[{"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/media?parent=1472"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/categories?post=1472"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.positech.co.uk\/cliffsblog\/wp-json\/wp\/v2\/tags?post=1472"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}