Dean's Blog http://www.codeka.com.au/blog Development blog of Dean Harding. en-us Wed, 13 Jan 2016 10:46:00 GMT The unnamed RPG http://www.codeka.com.au/blog/2016/01/the-unnamed-rpg Wed, 13 Jan 2016 10:46:00 GMT http://www.codeka.com.au/blog/2016/01/the-unnamed-rpg <p>This post provides a bit of an overview of my plans for my as-yet unnamed RPG. One of the biggest lessons I learned with my previous game (<a href="http://www.gamedev.net/blog/2156/entry-2261734-what-have-i-done/">which I talked a bit about here</a>) is that players <em>want to</em> interact. The in-game chat was pretty much an afterthought in my previous game (in fact, it was the very last feature I added before going to &quot;alpha&quot;). Most of the work I did post-release was community-based features -- an alliance system, one-on-one and group private chats, and so on.</p><p>So I wanted to make sure my new game supported a vibrant community right from the beginning. Also, I was a little tired of the limitations of working with a phone, so I wanted something that ran on a PC. But more than that, I wanted something that was cross-platform (I personally use a Mac laptop and a Linux workstation, so it needed to run on those platforms as well as Windows, of course). Because I&#39;m a masochist, I decided make the game browser-based.</p><p>The first iteration I was using a &lt;canvas&gt; directly and drawing 2D sprites. It worked pretty well, but performance was generally pretty horrible -- and that was with practically nothing on the screen! I actually got pretty far with that 2D engine, including multiple players, chat, animations and so on. Here&#39;s a video:</p><p style="text-align: center;"><iframe width="600" height="370" src="https://www.youtube.com/embed/as0Ip-I2j3E" frameborder="0" allowfullscreen=""></iframe></p><p>That video didn&#39;t have pathfinding, but that was also added before I decided that the performance just wasn&#39;t there. My plan was going to be to use webgl to speed up the 2D engine, but as I was coding, this happened</p><p style="text-align: center;"><a href="https://twitter.com/codeka/status/651016812679708672"><img width="550" height="250" src="http://uploads.gamedev.net/blogs/monthly_01_2016/blogentry-146194-0-12226000-1452399267_thumb.png" /></a></p><p>So I made it fully 3D with three.js as the backend renderer. In fact it&#39;s actually not that hard to get webgl up and running -- the hardest part, at least for me, was content. The initial &quot;rewrite&quot; was still talking to the same backend server, so it still supported all those wonderful multiplayer features, but I had an MD2 model (from Quake) as my main character, and some procedurally generated tree I found somewhere as decoration.</p><p style="text-align: center;"><iframe width="600" height="450" src="https://www.youtube.com/embed/zKZzoRth2WU" frameborder="0" allowfullscreen=""></iframe></p><p>The most interesting thing about the rewrite is the terrain. I found <a href="http://www.gamasutra.com/blogs/AndreyMishkinis/20130716/196339/Advanced_Terrain_Texture_Splatting.php">this cool article on Gamasutra</a> and implemented it as a GLSL shader in three.js.</p><p>Then I taught myself how to use blender to create some basic 3D objects and animations. All the content in the <a href="https://www.youtube.com/watch?v=KpAs1-o8sxk">current gameplay video</a> was made by me in blender. Yay!</p><p>So that&#39;s where we are today. I&#39;ve have a few ideas for the basic premise behind the game and also some information on how the game has been &quot;architectured&quot; (I put it in quotes because it&#39;s much more organically developed than architectured...)</p> What's the deal with USB headphones? http://www.codeka.com.au/blog/2015/02/whats-the-deal-with-usb-headphones Sun, 22 Feb 2015 12:21:59 GMT http://www.codeka.com.au/blog/2015/02/whats-the-deal-with-usb-headphones <p>Why do these things exist? A while back, I bought a pair of Logitech&nbsp;H390 headphones. This is what they look like:</p><p style="text-align: center;"><img alt="" data-resp="eyJzdWNjZXNzIjp0cnVlLCJ1cmwiOiJodHRwOi8vbGg0LmdncGh0LmNvbS9uSEVFNklzRDFBUUlRVFBVTmM4ZGVVMkZZZUNrUS1fSEhXWDlyWjY0ZDVVSVVHT1VZT280bzM0VTcwTEEwTDRtVHVrM0Y0VzhZaHowMDF4eVljVTE9czEwMCIsImJsb2Jfa2V5IjoiQU1JZnY5NlkxWG9DSnFEajVsTnlqSUZlNGc1NUJVY0pqNElNNnlEWHdfeE1nQUctQkZnYXhtNG1HWk5lX3o4RlBfRU5fRWEwVmU0ejFGVWNFZDBGNHk4cVVaTFJUbWJwbXFVRy1ES1N5aUE0OWhYUWNSSWctNWY5MXdzb0hvX19uRUZWbHVhVkN3Z29YYksyTlBlamRzZ19TSXlpR0p0akZnIiwiaGVpZ2h0IjozMjAsIndpZHRoIjo0MjksImZpbGVuYW1lIjoibWVkaXVtLnBuZyIsInNpemUiOjI2MjU3MX0=" src="http://lh4.ggpht.com/nHEE6IsD1AQIQTPUNc8deU2FYeCkQ-_HHWX9rZ64d5UIUGOUYOo4o34U70LA0L4mTuk3F4W8Yhz001xyYcU1=s429" /></p><p>When I bought them, I didn&#39;t really spend a whole lot of time looking at the box, but the fact that the interface is USB is shown in that little info panel on the bottom-left. In retrospect, I probably should have spend more time reading that box because it turns out, USB is a horrible, weird interface for headphones and I can&#39;t for the life of me understand why they exist.</p><h2>Cons of USB headphones</h2><p>These are just the ones I ran into while using my headphones over the last year or so:</p><ul><li>They only work in a couple of places. PC, sure. Maybe I could plug them into my Android phone with a USB-A to micro-USB adapter, but I never bothered to buy one in case it didn&#39;t work. A Ninentdo DS or practically anything else that&#39;s not a PC? Forget it!</li><li>Even when it works, because the headset shows up as a separate device, you can get yourself into weird situations where audio would continue routing to your main speakers and not the headphones. Both Windows (as of version 7, I haven&#39;t tried newer versions) and Linux have fairly clunky interfaces for choosing which output device to use. In most cases, with regular headphones, once you plug in all audio is automatically routed to the headphones.</li><li>Because the DAC happens inside the headphones, you can be pretty sure the quality of that hardward is nowhere near the quality of the hardware in your desktop computer.</li></ul><h2>Pros of USB headphones</h2><p>&macr;\_(ツ)_/&macr;</p><p>Oh wait, I can think of one &quot;pro&quot;. The <a href="http://au.creative.com/p/gaming-headsets/sound-blaster-tactic3d-rage-usb">Creative Tactic3D Rage</a> headphones has illuminated ear cups. For some reason.</p><p style="text-align: center;"><img alt="" data-resp="eyJzdWNjZXNzIjp0cnVlLCJ1cmwiOiJodHRwOi8vbGg0LmdncGh0LmNvbS9samZtMjZBeldrN2tjcWpkOE1WeXJoY0poRnF1dFY4cTQ0dTAzbzFNamU4OFNzWkpDQ2drbmNwS0l4UXY2NHNEeDNtTVp5YlFPcFpMa0dBdTdZYzlJX3c9czEwMCIsImJsb2Jfa2V5IjoiQU1JZnY5NTFBM0xWWWNyNERITVpWekFzeEJKcEkxeVQ2WGZWMTlCZFc3SEtrM2hlYmpGanZ3MlBMVDgyZ2dnSHpGQzhKQnZJVl9GckJ6QTlrWGRvOV9sZlg5d0Z0OVZnSXpwN09HUjlDM19FV2tNSXBTa3E3U0NDUllLX3ByTnJMTTBaVDBYX2x1WUpoemRCdm0zQXhnSnpZZktJdXg2cWhBIiwiaGVpZ2h0IjoxODgsIndpZHRoIjo5NDQsImZpbGVuYW1lIjoiU2NyZWVuc2hvdCBmcm9tIDIwMTUtMDItMjIgMjM6MTk6MjYucG5nIiwic2l6ZSI6MTMwODM2fQ==" src="http://lh4.ggpht.com/ljfm26AzWk7kcqjd8MVyrhcJhFqutV8q44u03o1Mje88SsZJCCgkncpKIxQv64sDx3mMZybQOpZLkGAu7Yc9I_w=s800" /></p> Connecting from your Android device to your host computer via adb http://www.codeka.com.au/blog/2014/11/connecting-from-your-android-device-to-your-host-computer-via-adb Sat, 22 Nov 2014 20:45:00 GMT http://www.codeka.com.au/blog/2014/11/connecting-from-your-android-device-to-your-host-computer-via-adb <p>Sometimes when I&#39;m on the road, and using someone else&#39;s Wi-Fi (typically when I&#39;m in a hotel), they will allow you to connect your phone and your laptop to the internet via their Wi-Fi. But, for security reasons, they typically won&#39;t allow your phone to connect to your computer over the Wi-Fi network. This make debugging certain applications quite difficult: I can&#39;t run a server on my laptop and have my phone connect to it.</p><p>But luckily, in recent versions of adb, a new command has been added: adb reverse. It&#39;s basically the opposite of <a href="http://developer.android.com/tools/help/adb.html#forwardports">adb forward</a>, which lets you forward ports from the host to your device, adb reverse allows you to forward ports from your device to your host.</p><p>So let&#39;s say I have a server running on my host computer, listening on port 8080. I want my phone to connect to it, so I run:</p><pre class="brush: text">$ adb reverse tcp:8080 tcp:8080</pre><p>And then connect to 127.0.0.1:8080 on the phone and problem solved!</p><p>Like adb forward, the parameters correspond to server/destination ports. But in the case of adb reverse, the first parameter is the port on the device and the second is the port on the host you want to forward to.</p> A battery widget with support for monitoring your wearable battery level http://www.codeka.com.au/blog/2014/09/a-battery-widget-with-support-for-monitoring-your-wearable-battery-level Tue, 09 Sep 2014 13:59:00 GMT http://www.codeka.com.au/blog/2014/09/a-battery-widget-with-support-for-monitoring-your-wearable-battery-level <p>I released the first version of &quot;<a href="https://play.google.com/store/apps/details?id=au.com.codeka.advbatterygraph">Advanced Battery Monitor</a>&quot; towards the end of last year, to not much fanfare at all. I used it and a couple of my friends used it, and that&#39;s about it.</p><p>But since getting my hands on an Android Wear watch (Moto 360, to be precise), I added a new feature to my graph to also monitor the battery <em>on the watch</em>.</p><p>Here you can see my phone + watch battery level thoughout the day today:</p><p style="text-align: center;"><img alt="" data-resp="eyJzdWNjZXNzIjp0cnVlLCJ1cmwiOiJodHRwOi8vbGg2LmdncGh0LmNvbS9lWnpxTFRLWVNUOEk1UHJlTFV1MzZwTnNNSDdHOGh0eXZBLVYyMWxHZnN6ZEFldml4TlF0MENCbkpZUFB2bEZyYVRQYlczNEVUN1o0bFhXdzdRa3M9czEwMCIsImJsb2Jfa2V5IjoiQU1JZnY5NVoyckN3a1hsVEFNclF3MkFKVUpqSjA3SDRfbm44LTdlMy14VVpYc0hYXzlUa2E1ZW15MEd5MVVBSDUyeHFOU0duZmtVWXVKM3RMaTBOMjJBd1RFYkxhanRJUXlBQk5oTW5FLWljS2RRZVFrZnJmOUdDQmpqZFJLcmJYLV82U1RaZFVjVndEWmExVUozQ2p3WFdOSXhqbGZJeXJ3IiwiaGVpZ2h0IjoyNjQsIndpZHRoIjoxMDgwLCJmaWxlbmFtZSI6IlNjcmVlbnNob3RfMjAxNC0wOS0wOS0yMy0zMC0yMS5wbmciLCJzaXplIjo1MzA3NzJ9" src="http://lh6.ggpht.com/eZzqLTKYST8I5PreLUu36pNsMH7G8htyvA-V21lGfszdAevixNQt0CBnJYPPvlFraTPbW34ET7Z4lXWw7Qks=s800" /></p><p>The green line represents my phone&#39;s battery, the blue my watch&#39;s. I use both devices fairly heavily throughout the day, so I&#39;ll let you make of these graphs as you will.</p><p>The other feature I&#39;ve added is the ability to export your battery data. The app only keeps battery data for up to a week, but you can export the whole data by tapping the widget to get into the &quot;settings&quot; and using the Export option.</p><p style="text-align: center;"><img alt="" data-resp="eyJzdWNjZXNzIjp0cnVlLCJ1cmwiOiJodHRwOi8vbGg2LmdncGh0LmNvbS9ha3BqQ0VSTUhjT1ZLandBUUoyQzAtOHJhQ20xY00tRUxWbVltUWloQlVLcEl2RmM0OENoUG9tVm1jbHpTbU4yckFpOWVYN2x4Vm9oSy1ieV9sbzRjdz1zMTAwIiwiYmxvYl9rZXkiOiJBTUlmdjk0U1hyMjJPNXpjRzdVdXk0ekM0NERTVGZOdWRmUXN1NHp2ZlZWOWszUlVzSkJZX1dKcHp4YUJrTTJDaXNzazBGQVpoSThydG1LVmlhQVRnTF9ybkdSUkJVNU9QT29OaUkwTWRyVjc5TU1peTQyVkxSdTV4Tjc5ZUpkd3dGWlQxQzlDWW1mUGZPaTlFYzFEb0Q0WElrYzdlX19nY3ciLCJoZWlnaHQiOjEyODAsIndpZHRoIjo3NjgsImZpbGVuYW1lIjoiU2NyZWVuc2hvdF8yMDE0LTA5LTA5LTIzLTU2LTE2LnBuZyIsInNpemUiOjEwODQxOH0=" src="http://lh6.ggpht.com/akpjCERMHcOVKjwAQJ2C0-8raCm1cM-ELVmYmQihBUKpIvFc48ChPomVmclzSmN2rAi9eX7lxVohK-by_lo4cw=s400" /></p><p>The source code for the widget is available on github:&nbsp;<a href="https://github.com/codeka/advbatterygraph">https://github.com/codeka/advbatterygraph</a></p><p>And of course, the widget itself can be downloaded from the <a href="https://play.google.com/store/apps/details?id=au.com.codeka.advbatterygraph">Play Store</a>:</p><p style="text-align: center;"><a href="https://play.google.com/store/apps/details?id=au.com.codeka.advbatterygraph"><img alt="" data-resp="eyJzdWNjZXNzIjp0cnVlLCJ1cmwiOiJodHRwOi8vbGgzLmdncGh0LmNvbS8zdjJ3MGl2STU3VUhKSExILVlxYTVKQTVOeDhHSmpYcmdHSlN6QUlMMWE4WTQ0czRPREpaWXpFUm5fLW96T0U0bkd3RFdlYkt3d1FwYWg5UC1OTVRZUkE9czEwMCIsImJsb2Jfa2V5IjoiQU1JZnY5NXpFR0RvVS1ZODkzbDNKTW45OE1IelBET3Vncmc2U1JNbnF2SUt6VmtEQTJrWkUzTjZMY0Z6NlpZclVjSVpoTHNpdjNNWmpudGM2aEFCMkhqX005UXJDcl9YSUhLaVVyOURTS3BUVTExTmliZ3BsWFd4U2FmbzBsYUF1X0JsZDY0U1BfNmJaZjlLY3RRTWNQRnozbzcxZnZCYk5RIiwiaGVpZ2h0Ijo0NSwid2lkdGgiOjEyOSwiZmlsZW5hbWUiOiJlbl9nZW5lcmljX3JnYl93b180NS5wbmciLCJzaXplIjo4MTcxfQ==" src="http://lh3.ggpht.com/3v2w0ivI57UHJHLH-Yqa5JA5Nx8GJjXrgGJSzAIL1a8Y44s4ODJZYzERn_-ozOE4nGwDWebKwwQpah9P-NMTYRA=s400" /></a></p><p>&nbsp;</p> Playing around with a random level generator http://www.codeka.com.au/blog/2014/08/playing-around-with-a-random-level-generator Mon, 25 Aug 2014 11:09:00 GMT http://www.codeka.com.au/blog/2014/08/playing-around-with-a-random-level-generator <p>So, one of the things I&#39;ve been toying with recently is the idea of a Diablo-style hack &amp; slash. One of the most important aspects of the hack &amp; slash is level generation. There&#39;s lots of ways you can generate levels and lots of different &quot;looks&quot; you can give your levels. I plan to explore a few different techniques over the next few weeks. My first attempt, which I&#39;ve included below, gives a sort of cavernous look that I think would be good for boss levels:</p><script src="/blob/AMIfv94WoAkp7jGjPq2RvIBgpJ5q5L7ScKOlWgYXTSJ2TBKJjzo_gYWcDv8kslnr_Hau-UBSb_FxYS5-q7EZOHmyTPiK-LrFJmSejrjc7bZ0U6tcMgYbdJUhN2a96s4R9kcQTf11jtqF68sEL1OWZRaS7Ht_Au3YhA"></script><p>The technique is quite simple, I &quot;borrowed&quot; the idea from <a href="http://www.roguebasin.com/index.php?title=Cellular_Automata_Method_for_Generating_Random_Cave-Like_Levels">this page</a>. Basically, the algorithm runs as:</p><ol><li>Fill the board with random walls. Each square starts with a 45% chance of being filled.</li><li>Each iteration, for each square, count the number of walls around that square. If there is more than 5, fill the wall in a new version of the map.</li><li>Repeat step 2 until the map is &quot;stable&quot; (that is, until two iterations produce the same map).</li></ol><p>In the example above, you just let it run normally, it&#39;ll do a few iterations, then complete the run in one go and pause for a few seconds so you can see the outcome. You can click &quot;stop&quot; then use the &quot;reset&quot; and &quot;step&quot; buttons to manually progress through the iterations.</p><p>There&#39;s a couple of problems with this, though. Firstly, it tends to make very open levels. I guess depending on the game, that may or may not be OK, but for our purposes, I think I&#39;d like something a little more close-quarters. Another problem is that it produces overly &quot;smooth&quot; walls, that is, there are no sharp corners and no sharp points. Again, depending on your level design, that may or may not be OK, but I&#39;d like to do something about it.</p><p>For the second problem, the solution is actually quite simple: just don&#39;t run the algorithm so many times. If we cap the number of iterations to, say, 10, then we end up with more jagged walls. But that introduces an extra problem: sometimes it will leave behind very tiny &quot;islands&quot; of walls, which the old alorithm would have smoothed away. That can be fixed by a &quot;manual&quot; cleanup afterward where we simply remove the small islands.</p><p>For the first problem, we modify the algorithm slightly:</p><pre class="brush: js"> Map.prototype.iterate = function() { var newMap = new Map(this.width, this.height); newMap.clearMap(); for (var x = 0; x &lt; this.width; x++) { for (var y = 0; y &lt; this.height; y++) { if (this.numWallsWithinSteps(x, y, 1) &gt;= 5) { newMap.setCell(x, y, 1); } else if (this.stepNo &lt; 6 &amp;&amp; this.numWallsWithinSteps(x, y, 2) &lt; 2) { newMap.setCell(x, y, 1); } } } newMap.stepNo = this.stepNo + 1; return newMap; };</pre><p><span style="font-size: 12pt;">The above algorithm can be seen in the map below:</span></p><script src="/blob/AMIfv96VjhYKBIbPWrx-x3ymC5un3cwHUGZxA9mA24gv2atCpzBDuA9R1YUmCc3YuQ35g_MGiMskeW-2PMXONeBg2irdRbI5KzfEpE15qbeNLU59szNRU3zXP2L62VbjzBh4onxaOSmK0eqezFdsc2i70MwD99lTFQ"></script><p>As you can see, this version results in much more &quot;cramped&quot; level than the first version. You can download the full code for the final version <a href="http://www.codeka.com.au/blob/AMIfv96gW71Xfu3gbw1XEGhLHK3r27_SZsuwA3XVTPFNTWHFZWwwbjCMVHazMpXrA6pJxWJBaj0cDi4hnVx1YDXWPJH3zf2XOgKzMSxz5Lq73EKMeZxuiBoUqmqOc1RV6hjkJ4IY6F-eMnfqlP18glCaZRVT8D52Xw/download">here</a>.</p><p>This is a pretty simple algorithm and produces nice levels for boss fights, but next time, we&#39;ll want to try a slightly more complicated algorithm for generating the room/corridor style levels that you come to expect.</p>