{"id":177,"date":"2009-09-15T07:27:29","date_gmt":"2009-09-14T21:27:29","guid":{"rendered":"http:\/\/www.doolwind.com\/blog\/?p=177"},"modified":"2009-09-15T07:27:29","modified_gmt":"2009-09-14T21:27:29","slug":"test-driven-game-development","status":"publish","type":"post","link":"https:\/\/www.doolwind.com\/blog\/test-driven-game-development\/","title":{"rendered":"Test Driven Game Development"},"content":{"rendered":"<p><a href=\"http:\/\/www.doolwind.com\/images\/blog\/TestDrivenGameDevelopment.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright\" title=\"Test Driven Game Development\" src=\"http:\/\/www.doolwind.com\/images\/blog\/TestDrivenGameDevelopment.png\" alt=\"\" width=\"134\" height=\"83\" \/><\/a>Test Driven Development (<a href=\"http:\/\/en.wikipedia.org\/wiki\/Test-driven_development\">TDD<\/a>) has steadily grown in popularity among non-game programmers.\u00a0 Despite this, it has not been widely adopted in game development.\u00a0 Today I&#8217;m going to discuss why TDD is suited to games development and how it frees developers and designers to experiment with &#8220;finding the fun&#8221; without breaking core gampelay.<\/p>\n<p><strong>Example &#8211; Mario<\/strong><\/p>\n<p>Let&#8217;s begin with an example.\u00a0 You&#8217;re writing <em>Super Mario Brothers<\/em> and want to experiment with how Mario jumps.\u00a0 You can change the jumping however you like, but he needs to always jump at least 20 pixels.\u00a0 Your unit test might look something like this:<\/p>\n<p>[Test]<br \/>\nvoid Mario_Can_Jump_20_Pixel_Gap()<br \/>\n{<br \/>\nMario mario = new Mario();<br \/>\nmario.Position = new Vector2(0,0);<\/p>\n<p>mario.Jump(Right);<br \/>\nmario.Update(10);<\/p>\n<p>Assert.IsTrue(mario.Position.X &gt;= 20);\u00a0\u00a0 \/\/ Has moved at least 20 pixels<br \/>\nAssert.IsTrue(mario.Position.Y == 0);\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Is on the ground<br \/>\n}<\/p>\n<p>You are now free to make any update you want to Jump() knowing that if the test passes, your requirements of jump at least 20 pixels is met.\u00a0 This is much easier than loading up a level, trying the jump and making sure it all works.<\/p>\n<p><strong>Advantages<\/strong><\/p>\n<p>So why would you want to use Test Driven Game Development?<\/p>\n<ol>\n<li><strong>Guarantee code works<\/strong>. With a full suite of unit tests you are guaranteed that your code does what it is supposed to do.\u00a0 Bugs will be found as soon as they are introduced as tests fail immediately.<\/li>\n<li><strong>Forces modular code<\/strong>.\u00a0 Notice there was no mention of UI, controllers or rendering in the example unit test.\u00a0 This &#8220;<a href=\"http:\/\/en.wikipedia.org\/wiki\/Separation_of_concerns\">Separation of Concerns<\/a>&#8221; is not only good design, it&#8217;s also required if want to have testable code.<\/li>\n<li><strong>Allows you to &#8220;find the fun&#8221;<\/strong>.\u00a0 Once you&#8217;re guaranteed that certain requirements are met, you&#8217;re free to experiment with gameplay to make it more enjoyable without breaking certain levels or unbalancing the game.\u00a0 This also extends to giving designers more freedom when scripting.\u00a0 Encouraging experimentation by designers without programmer intervention is invaluable.<\/li>\n<\/ol>\n<p><strong>Good and Bad<\/strong><\/p>\n<p>Some parts of game development are perfectly suited to TDD while others may cause more trouble than good.\u00a0 Firstly the areas that would greatly benefit from TDD:<\/p>\n<ol>\n<li><strong>Game Engine<\/strong>.\u00a0 Have a list of features\/API exposed that is perfect for unit testing.\u00a0 Unit tests serve as code documentation with code samples of usage.\u00a0 It helps reduce the changes of introducing breaking changes to new build of the engine.\u00a0 Performance tests can also be included.<\/li>\n<li><strong>Core Gameplay<\/strong>.\u00a0 Designers write up tests for core gameplay and formalize game design into testable units.\u00a0 Again, this frees designers and programmers to experiment without breaking core gameplay.<\/li>\n<\/ol>\n<p>The main area that TDD doesn&#8217;t fit is in UI and rendering:<\/p>\n<ol>\n<li><strong>User Interface\/Rendering<\/strong>.\u00a0 Even outside the games industry, UI is difficult to test with unit tests.\u00a0 This is particularly true for 3D UI&#8217;s.\u00a0 This issue can be overcome with a good separation of concerns.\u00a0 Keep UI and rendering separate from game logic so testability is still high.\u00a0 One solution is using the MVC pattern for your game engine.\u00a0 I will discuss this further in a future blog post.<\/li>\n<\/ol>\n<p><strong>Basic Tips<\/strong><\/p>\n<p>Below are some basic tips that will help get you started with TDD if you haven&#8217;t used it before.<\/p>\n<ol>\n<li><strong>Keep tests short<\/strong> &#8211; test only one thing in each unit test<\/li>\n<li><strong>Keep tests fast<\/strong> &#8211; run entire test suite in seconds<\/li>\n<li><strong>Keep tests thorough<\/strong> &#8211; use code coverage to determine what is and isn&#8217;t tested, making sure all critical code is tested.<\/li>\n<\/ol>\n<p><strong>Conclusion<\/strong><\/p>\n<p>I&#8217;ve touched briefly on why Test Driven Development works well with game development and I encourage you to read further into TDD if you have not used it before.\u00a0 As usual, I&#8217;d recommend picking a small project and experiment with TDD.\u00a0 Perseverance is key as it may seem as though things are slowing down, but as a project grows and evolves your efforts will be rewarded.<\/p>\n<p>If you&#8217;re currently using TDD for your game I&#8217;d be interested in hearing your story.<\/p>\n<p>For the <a href=\"http:\/\/www.amazon.com\/gp\/product\/0321146530?ie=UTF8&amp;tag=doosgamcodblo-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321146530\">definitive book<\/a> on Test Driven Development, check out:<\/p>\n<p><a href=\"http:\/\/www.amazon.com\/gp\/product\/0321146530?ie=UTF8&amp;tag=doosgamcodblo-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321146530\"><img decoding=\"async\" src=\"http:\/\/www.doolwind.com\/images\/blog\/TDDBook.jpg\" border=\"0\" alt=\"\" \/><\/a><img loading=\"lazy\" decoding=\"async\" style=\"border:none !important; margin:0px !important;\" src=\"http:\/\/www.assoc-amazon.com\/e\/ir?t=doosgamcodblo-20&amp;l=as2&amp;o=1&amp;a=0321146530\" border=\"0\" alt=\"\" width=\"1\" height=\"1\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Test Driven Development (TDD) has steadily grown in popularity among non-game programmers.\u00a0 Despite this, it has not been widely adopted in game development.\u00a0 Today I&#8217;m going to discuss why TDD is suited to games development and how it frees developers and designers to experiment with &#8220;finding the fun&#8221; without breaking core gampelay. Example &#8211; Mario <a class=\"more-link\" href=\"https:\/\/www.doolwind.com\/blog\/test-driven-game-development\/\">Read More<\/a><\/p>\n","protected":false},"author":2,"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":false,"_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":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"enabled":false},"version":2}},"categories":[33],"tags":[71],"class_list":["post-177","post","type-post","status-publish","format-standard","hentry","category-game-development","tag-tdd"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pgEc5-2R","_links":{"self":[{"href":"https:\/\/www.doolwind.com\/blog\/wp-json\/wp\/v2\/posts\/177","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.doolwind.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.doolwind.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.doolwind.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.doolwind.com\/blog\/wp-json\/wp\/v2\/comments?post=177"}],"version-history":[{"count":0,"href":"https:\/\/www.doolwind.com\/blog\/wp-json\/wp\/v2\/posts\/177\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.doolwind.com\/blog\/wp-json\/wp\/v2\/media?parent=177"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.doolwind.com\/blog\/wp-json\/wp\/v2\/categories?post=177"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.doolwind.com\/blog\/wp-json\/wp\/v2\/tags?post=177"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}