{"id":1821,"date":"2016-10-29T22:03:11","date_gmt":"2016-10-29T21:03:11","guid":{"rendered":"https:\/\/www.entropywins.wtf\/blog\/?p=1821"},"modified":"2018-07-31T13:01:15","modified_gmt":"2018-07-31T12:01:15","slug":"refactoring-horrible-lua-code","status":"publish","type":"post","link":"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/","title":{"rendered":"Object Orientated Lua code"},"content":{"rendered":"<p>During the last few weeks I&#8217;ve been refactoring some horrible <a href=\"https:\/\/www.lua.org\/\">Lua<\/a> code. This has been a ton of fun so far, and I learned many new things about Lua that I&#8217;d like to share.<\/p>\n<p><strong>Such\u00a0Horrible Code<\/strong><\/p>\n<p><a href=\"https:\/\/github.com\/JeroenDeDauw\/FinalRushPro5\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"1822\" data-permalink=\"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/final-rush-pro-5-large\/\" data-orig-file=\"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/10\/Final-Rush-Pro-5.large_.png\" data-orig-size=\"256,256\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"final-rush-pro-5-large\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/10\/Final-Rush-Pro-5.large_.png\" class=\" wp-image-1822 alignright\" src=\"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/10\/Final-Rush-Pro-5.large_.png\" alt=\"final-rush-pro-5-large\" width=\"206\" height=\"206\" \/><\/a>The code in question is that of a scripted <a href=\"http:\/\/www.faforever.com\/\">Supreme Commander Forged Alliance Forever<\/a> Map called Final Rush Pro v4. Essentially all the code resides in a single <a href=\"https:\/\/github.com\/JeroenDeDauw\/FinalRushPro5\/blob\/v4.0.7\/Final%20Rush%20Pro4%204v4_script.lua\">Lua file slightly\u00a0over 2500 lines long<\/a>. It is entirely procedural, uses global state all over, contains plenty of copy pasted code and, unsurprisingly, does not have a single test. What&#8217;s more is that at least some of the code must have been written by people not even at home with procedural programming, as there are several instances when massive\u00a0if-else blocks are used rather than loops.<\/p>\n<p><strong>Much Refactoring<\/strong><\/p>\n<p>The high level approach I took was to identify cohesive sets of code in the huge file and move them out in dedicated files. These dedicated files would then have their dependencies explicitly defined and could be cleaned up one by one. This graph shows the lines of code of the\u00a0Lua file that acts as entry point over time:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"1823\" data-permalink=\"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/final-rush-loc\/\" data-orig-file=\"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/10\/final-rush-loc.jpg\" data-orig-size=\"415,250\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"final-rush-loc\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/10\/final-rush-loc.jpg\" class=\"alignnone size-full wp-image-1823\" src=\"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/10\/final-rush-loc.jpg\" alt=\"final-rush-loc\" width=\"415\" height=\"250\" \/><\/p>\n<p>The first example can be seen in\u00a0<a href=\"https:\/\/github.com\/JeroenDeDauw\/FinalRushPro5\/commit\/bf20e0c63fa27dc7d51008dcab3c56b1f4096999\">moving the &#8220;PrebuildTents&#8221; code into its own file<\/a>. This code, coincidentally, nicely illustrates the\u00a0copy pasting and\u00a0insane use of if-else over loops. One huge issue that remains when simply moving the code like that is that it remains in global\/static scope.\u00a0In other words, it&#8217;s not possible to\u00a0use the code in the file with two different sets of local values.\u00a0I did some searching on how to idiosyncratically achieve polymorphism in Lua.<\/p>\n<p>One of the first things I\u00a0read through was the <a href=\"https:\/\/www.lua.org\/pil\/16.html\">Object Orientated Programming pages<\/a> of the <a href=\"https:\/\/www.lua.org\/pil\/\">Programming in Lua book<\/a>. Following that approach, I created the <a href=\"https:\/\/github.com\/JeroenDeDauw\/FinalRushPro5\/blob\/0fe77c4fddb2a661ec00635946bbb98b74967e85\/spec\/Test_spec.lua#L1-L14\">very first version<\/a> of a simple wrapper around a list of player armies.\u00a0As you can see there, I wrote tests for that code (more on those tests\u00a0below). I was not too happy with that approach as it does not provide nice encapsulation. After looking at the code of some of the more prominent Lua tools I came across, I decided to go with a <a href=\"https:\/\/github.com\/JeroenDeDauw\/FinalRushPro5\/blob\/f9f1030cd76f689bed9db7385a668cd59d89b66a\/src\/PlayerArmies.lua\">closure based approach<\/a> instead. Initially I would define a <em>this<\/em> local table, which would then get functions bound to it. I switched to <a href=\"https:\/\/github.com\/JeroenDeDauw\/FinalRushPro5\/blob\/3e1ce140cda38bd0e0cd35e500f4dbf3582a38a2\/src\/PrebuildTents.lua\">returning a map at the end of the closure<\/a>, which makes it more clear what the public functions are, and leaves one less local variable to worry about. (The closure is assigned to <em>newInstance<\/em> rather than just returned due to the way the import mechanism of the framework\u00a0works, which is different than Lua&#8217;s native <em>require<\/em>.)<\/p>\n<p>A downside of how the code in the files is organized is that you essentially need to read backwards when looking at how it is\u00a0invoked. The public functions are listed at the very end of the file, with\u00a0their dependencies defined before, and their dependencies defined before that. It would\u00a0be nice to have the public functions more clearly visible at the top of the file, which is where you need to look\u00a0for the constructor signature already.<\/p>\n<p>Now the\u00a0creating of cohesive sets of code is mostly done, the <a href=\"https:\/\/github.com\/JeroenDeDauw\/FinalRushPro5\/blob\/53917578898731d65d34a5cd8317a7324e63234d\/Final%20Rush%20Pro%205_script.lua\">entry point file<\/a> is down to 44 Lines of Code. It defaults some options coming from the framework\/game, and then invokes\u00a0<a href=\"https:\/\/github.com\/JeroenDeDauw\/FinalRushPro5\/blob\/8f848792565745a95f9590787ecbf220c36e5b94\/src\/FinalRushPro.lua\">a high level module<\/a> that sets up the various aspects of the game, which totals 70 Lines of Code.<\/p>\n<p>My next steps are further cleanup of individual sets of code, with a focus on minimizing dependencies and separating concerns. For this I&#8217;m using\u00a0practices, principles and patterns which are by and large language agnostic, so I won&#8217;t get into them here.\u00a0You can find the code of the new version of the map in the <a href=\"https:\/\/github.com\/JeroenDeDauw\/FinalRushPro5\">Final Rush Pro 5<\/a> repository on GitHub, including many small refactoring commits in the git history.<\/p>\n<p><b>Very Environment<\/b><\/p>\n<p>My first modifications to the code where with Notepad++ on Windows. While that editor provides\u00a0syntax\u00a0highlighting, there is no static code analysis or any of the essential things that require it, such as navigating to definitions. Hence I switched to my usual development environment, IntelliJ on Linux, using the <a href=\"https:\/\/plugins.jetbrains.com\/plugin\/5055\">IntelliJ Lua plugin<\/a>.<\/p>\n<p>While that switch to Linux\u00a0made refactoring the code easier, it also prevent me from (manually) testing the code. This code, like many legacy balls of mud, binds very tightly to its framework, in this case the Supreme Commander game that only runs on Windows.\u00a0While it&#8217;s often good to remove such binding, it&#8217;s not a trivial task, and not something I&#8217;d want to attempt without a fast feedback cycle.<\/p>\n<p>The lack of fast feedback drove me to find a\u00a0Lua testing tool to use. Several are <a href=\"http:\/\/lua-users.org\/wiki\/UnitTesting\">listed on the lua-users wiki<\/a>. After checking the project health of several tools, I decided\u00a0to go with <a href=\"http:\/\/olivinelabs.com\/busted\/\">Busted<\/a>, which I installed via <a href=\"https:\/\/luarocks.org\/\">LuaRocks<\/a>. I then proceeded to create a wrapper for the list of players in the game (to replace code that was not only crappy but also incorrect) using <a href=\"https:\/\/en.wikipedia.org\/wiki\/Test-driven_development\">Test Driven Development<\/a>, resulting in a nice <a href=\"https:\/\/github.com\/JeroenDeDauw\/FinalRushPro5\/blob\/da7389b2ee25facc0080a31beb2d7d59eac1b40c\/spec\/PlayerArmies_spec.lua\">spec for the wrapper<\/a>.<\/p>\n<p>Unfortunately the same approach would not work for\u00a0cleaning up most of the other code. The framework binding was just too high, and in a lot of cases, contrary to the typical scenario I&#8217;m used to (which are not games), perhaps simply the best that can be done. Hence I switched back to Windows.<\/p>\n<p>On Windows I installed IntelliJ with the Lua plugin, <a href=\"https:\/\/tortoisegit.org\/\">TortoiseGit<\/a>, and Busted. The latter was quite a hurdle, since my Windows administration skills are not exactly stellar. For Busted\u00a0I needed to install Lua (ya really), LuaRocks and the <a href=\"http:\/\/www.mingw.org\/\">MinGW compiler<\/a>. Being able to run the tests in the IDE&#8217;s terminal was worth it though.<\/p>\n<p><strong>Wow Release<\/strong><\/p>\n<p>Version 5 of the map has now been released, see <a href=\"https:\/\/www.entropywins.wtf\/blog\/2016\/11\/27\/final-rush-pro-5\/\">the release post<\/a> for details on the new features.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>During the last few weeks I&#8217;ve been refactoring some horrible Lua code. This has been a ton of fun so&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[5,7],"tags":[24,32,328,415,435,95,433,332,432,179,436,215,252,434],"class_list":["post-1821","post","type-post","status-publish","format-standard","hentry","category-gaming","category-programming","tag-aod","tag-art-of-defence","tag-clean-code","tag-encapsulation","tag-final-rush-pro","tag-forged-alliance","tag-forged-alliance-forever","tag-legacy-code","tag-lua","tag-oop","tag-polymorphism","tag-refactoring","tag-supreme-commander","tag-survival"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Object Orientated Lua code - Blog of Jeroen De Dauw<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Object Orientated Lua code - Blog of Jeroen De Dauw\" \/>\n<meta property=\"og:description\" content=\"During the last few weeks I&#8217;ve been refactoring some horrible Lua code. This has been a ton of fun so&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog of Jeroen De Dauw\" \/>\n<meta property=\"article:published_time\" content=\"2016-10-29T21:03:11+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-07-31T12:01:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/10\/Final-Rush-Pro-5.large_.png\" \/>\n<meta name=\"author\" content=\"Jeroen\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/JeroenDeDauw\" \/>\n<meta name=\"twitter:site\" content=\"@JeroenDeDauw\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeroen\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2016\\\/10\\\/29\\\/refactoring-horrible-lua-code\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2016\\\/10\\\/29\\\/refactoring-horrible-lua-code\\\/\"},\"author\":{\"name\":\"Jeroen\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#\\\/schema\\\/person\\\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"headline\":\"Object Orientated Lua code\",\"datePublished\":\"2016-10-29T21:03:11+00:00\",\"dateModified\":\"2018-07-31T12:01:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2016\\\/10\\\/29\\\/refactoring-horrible-lua-code\\\/\"},\"wordCount\":996,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#\\\/schema\\\/person\\\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"image\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2016\\\/10\\\/29\\\/refactoring-horrible-lua-code\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/10\\\/Final-Rush-Pro-5.large_.png\",\"keywords\":[\"AoD\",\"Art of Defence\",\"Clean Code\",\"Encapsulation\",\"Final Rush Pro\",\"Forged Alliance\",\"Forged Alliance Forever\",\"Legacy code\",\"Lua\",\"OOP\",\"Polymorphism\",\"Refactoring\",\"Supreme Commander\",\"Survival\"],\"articleSection\":[\"Gaming\",\"Programming\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2016\\\/10\\\/29\\\/refactoring-horrible-lua-code\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2016\\\/10\\\/29\\\/refactoring-horrible-lua-code\\\/\",\"url\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2016\\\/10\\\/29\\\/refactoring-horrible-lua-code\\\/\",\"name\":\"Object Orientated Lua code - Blog of Jeroen De Dauw\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2016\\\/10\\\/29\\\/refactoring-horrible-lua-code\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2016\\\/10\\\/29\\\/refactoring-horrible-lua-code\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/10\\\/Final-Rush-Pro-5.large_.png\",\"datePublished\":\"2016-10-29T21:03:11+00:00\",\"dateModified\":\"2018-07-31T12:01:15+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2016\\\/10\\\/29\\\/refactoring-horrible-lua-code\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2016\\\/10\\\/29\\\/refactoring-horrible-lua-code\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2016\\\/10\\\/29\\\/refactoring-horrible-lua-code\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/10\\\/Final-Rush-Pro-5.large_.png\",\"contentUrl\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/10\\\/Final-Rush-Pro-5.large_.png\",\"width\":256,\"height\":256},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2016\\\/10\\\/29\\\/refactoring-horrible-lua-code\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Object Orientated Lua code\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/\",\"name\":\"Entropy Wins\",\"description\":\"A blog on Software Architecture, Design and Craftsmanship\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#\\\/schema\\\/person\\\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#\\\/schema\\\/person\\\/4e2ef14f2ca7dc3a0ac137d1692b66b7\",\"name\":\"Jeroen\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g\",\"caption\":\"Jeroen\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g\"},\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/in\\\/jeroendedauw\\\/\",\"https:\\\/\\\/x.com\\\/https:\\\/\\\/twitter.com\\\/JeroenDeDauw\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Object Orientated Lua code - Blog of Jeroen De Dauw","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/","og_locale":"en_US","og_type":"article","og_title":"Object Orientated Lua code - Blog of Jeroen De Dauw","og_description":"During the last few weeks I&#8217;ve been refactoring some horrible Lua code. This has been a ton of fun so&hellip;","og_url":"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/","og_site_name":"Blog of Jeroen De Dauw","article_published_time":"2016-10-29T21:03:11+00:00","article_modified_time":"2018-07-31T12:01:15+00:00","og_image":[{"url":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/10\/Final-Rush-Pro-5.large_.png","type":"","width":"","height":""}],"author":"Jeroen","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/JeroenDeDauw","twitter_site":"@JeroenDeDauw","twitter_misc":{"Written by":"Jeroen","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/#article","isPartOf":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/"},"author":{"name":"Jeroen","@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"headline":"Object Orientated Lua code","datePublished":"2016-10-29T21:03:11+00:00","dateModified":"2018-07-31T12:01:15+00:00","mainEntityOfPage":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/"},"wordCount":996,"commentCount":1,"publisher":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"image":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/#primaryimage"},"thumbnailUrl":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/10\/Final-Rush-Pro-5.large_.png","keywords":["AoD","Art of Defence","Clean Code","Encapsulation","Final Rush Pro","Forged Alliance","Forged Alliance Forever","Legacy code","Lua","OOP","Polymorphism","Refactoring","Supreme Commander","Survival"],"articleSection":["Gaming","Programming"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/","url":"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/","name":"Object Orientated Lua code - Blog of Jeroen De Dauw","isPartOf":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/#primaryimage"},"image":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/#primaryimage"},"thumbnailUrl":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/10\/Final-Rush-Pro-5.large_.png","datePublished":"2016-10-29T21:03:11+00:00","dateModified":"2018-07-31T12:01:15+00:00","breadcrumb":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/#primaryimage","url":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/10\/Final-Rush-Pro-5.large_.png","contentUrl":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/10\/Final-Rush-Pro-5.large_.png","width":256,"height":256},{"@type":"BreadcrumbList","@id":"https:\/\/www.entropywins.wtf\/blog\/2016\/10\/29\/refactoring-horrible-lua-code\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.entropywins.wtf\/blog\/"},{"@type":"ListItem","position":2,"name":"Object Orientated Lua code"}]},{"@type":"WebSite","@id":"https:\/\/www.entropywins.wtf\/blog\/#website","url":"https:\/\/www.entropywins.wtf\/blog\/","name":"Entropy Wins","description":"A blog on Software Architecture, Design and Craftsmanship","publisher":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.entropywins.wtf\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7","name":"Jeroen","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g","caption":"Jeroen"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g"},"sameAs":["https:\/\/www.linkedin.com\/in\/jeroendedauw\/","https:\/\/x.com\/https:\/\/twitter.com\/JeroenDeDauw"]}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p74TBF-tn","jetpack-related-posts":[{"id":1832,"url":"https:\/\/www.entropywins.wtf\/blog\/2016\/11\/27\/final-rush-pro-5\/","url_meta":{"origin":1821,"position":0},"title":"Final Rush Pro 5","author":"Jeroen","date":"2016-11-27","format":false,"excerpt":"I'm happy to announce the immediate availability of the Final Rush Pro 5 map for Supreme Commander Forged Alliance Forever. During the past few weeks I've been reworking version 4 of the map, and have added many new features, fixed some bugs and improved balance\u00a0in the team vs team modes.\u2026","rel":"","context":"In &quot;Gaming&quot;","block_context":{"text":"Gaming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/gaming\/"},"img":{"alt_text":"final-rush-pro-5-large","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/10\/Final-Rush-Pro-5.large_.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":1669,"url":"https:\/\/www.entropywins.wtf\/blog\/2016\/04\/30\/name-all-the-things\/","url_meta":{"origin":1821,"position":1},"title":"Name All The Things!","author":"Jeroen","date":"2016-04-30","format":false,"excerpt":"I've created a new release of the \"NameStuff\" mod for Supreme Commander Forged Alliance, now titled \"Name All The Things\". So no, this is not a post where I rant about good variable naming :) The mod automatically sets names for your units, which can change based on their status.\u2026","rel":"","context":"In &quot;Gaming&quot;","block_context":{"text":"Gaming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/gaming\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/04\/atn-game2.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/04\/atn-game2.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/04\/atn-game2.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/04\/atn-game2.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":248,"url":"https:\/\/www.entropywins.wtf\/blog\/2009\/07\/26\/on-to-0-2-refactoring-fun\/","url_meta":{"origin":1821,"position":2},"title":"On to 0.2 &#8211; Refactoring fun","author":"Jeroen","date":"2009-07-26","format":false,"excerpt":"Since the 0.1 release of Maps and Semantic Maps, I've gotten quite some feedback on what features are in demand and what could be improved. Although I've not gotten any specific feedback on the extensions source code itself, I decided that refactoring it to get it as high quality as\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":834,"url":"https:\/\/www.entropywins.wtf\/blog\/2010\/05\/19\/supreme-commander-strategic-warfare-3\/","url_meta":{"origin":1821,"position":3},"title":"Supreme Commander: Strategic Warfare 3","author":"Jeroen","date":"2010-05-19","format":false,"excerpt":"Two days back I did the effort of recording a replay (download) of a Supreme Commander Forged Alliance game I did a little over a month back. Like my 2 previous similar video's, it's filmed from an overview altitude, giving you a good strategic perspective on what's going on. The\u2026","rel":"","context":"In &quot;Gaming&quot;","block_context":{"text":"Gaming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/gaming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":353,"url":"https:\/\/www.entropywins.wtf\/blog\/2009\/08\/28\/net-c-to-vb-refactoring\/","url_meta":{"origin":1821,"position":4},"title":".Net C# to VB + refactoring","author":"Jeroen","date":"2009-08-28","format":false,"excerpt":"While translating some of the C# code of MyDownloader to VB.Net for the .Net download library, I've already come across quite some awkward code. IMHO, the underneath example could go into the code horrors section of The Code Project. [cc lang=\"csharp\" width=\"607\"] private void RestartDownload() { int currentTry = 0;\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1539,"url":"https:\/\/www.entropywins.wtf\/blog\/2016\/01\/16\/faf-science-percivals-vs-t1-pds\/","url_meta":{"origin":1821,"position":5},"title":"FAF science: Percivals vs T1 PDs","author":"Jeroen","date":"2016-01-16","format":false,"excerpt":"I've decided to start with writing small to the point blog posts on Supreme Commander Forged Alliance whenever I stumble upon a good topic. For those who don't know it, this is the best Real Time Strategy game out there. It's been said that it is to Star Craft what\u2026","rel":"","context":"In &quot;Gaming&quot;","block_context":{"text":"Gaming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/gaming\/"},"img":{"alt_text":"Supreme Commander Fogred Alliance: Four Corners map","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/01\/four-corners.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/01\/four-corners.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/01\/four-corners.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/01\/four-corners.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/01\/four-corners.jpg?resize=1050%2C600&ssl=1 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/1821","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/comments?post=1821"}],"version-history":[{"count":11,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/1821\/revisions"}],"predecessor-version":[{"id":2257,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/1821\/revisions\/2257"}],"wp:attachment":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/media?parent=1821"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/categories?post=1821"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/tags?post=1821"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}