<?xml version="1.0" encoding="ISO-8859-1"?>
<rss version="2.0">
    <channel>
        <title>Audeuro's site</title>
        <link>http://www.byond.com/members/Audeuro</link>
        <description></description>
        <lastBuildDate>Fri, 10 Feb 2012 19:14:46 +0000</lastBuildDate>
        <language>en-us</language>
    
                <item>
            <title>That propagation issue</title>
            <link>http://www.byond.com/members/Audeuro?command=view_post&amp;post=200235</link>
            <guid>http://www.byond.com/members/Audeuro?command=view_post&amp;post=200235</guid>
            <pubDate>Thu, 26 Jan 2012 07:06:16 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Audeuro?command=view_comments&amp;post=200235#comments</comments>
            
            <description>Tom, Lummox- I'm not entirely sure whether you actually messed with the nameserver or not other than changing the record data, but next time you might consider dropping the TTL to a lower value (It sits at 86400, which is 24 hours, by default) a day before the update so that the propagation in the worst-cases you've seen won't take so long.</description>
        </item>
                <item>
            <title>Conclusion</title>
            <link>http://www.byond.com/members/Audeuro?command=view_post&amp;post=122610</link>
            <guid>http://www.byond.com/members/Audeuro?command=view_post&amp;post=122610</guid>
            <pubDate>Fri, 06 Jan 2012 06:39:16 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Audeuro?command=view_comments&amp;post=122610#comments</comments>
            
            <description>The title has nothing to do with this post other than that it's probably going to be my last one on this blog. I've got a &lt;a href=&quot;http://www.audeuro.com&quot;&gt;personal blog&lt;/a&gt; that I'm going to be trying to use more often than I do now to show off projects that I have going on.&lt;br&gt;
&lt;br&gt;
Before I go off on a tangent about my current projects/set of projects, I have my own personal set of mini-rants about the site updates and some things that have stemmed from it.&lt;br&gt;
&lt;br&gt;
The first mini-rant is about this 'cash shop' idea people keep trying to throw out there. Cash shops are a good idea, but it's not something that should be integrated into the BYOND site and software.&lt;br&gt;
&lt;br&gt;
From a design perspective, it doesn't make much sense to have a cash shop for your game created by the people that wrote the software you made your game in. From a player's perspective, it's also confusing to have to use this third party system for a cash shop. From Tom/Lummox/BYOND's standpoint, it's an implementation nightmare. It's easy to tell them that they would do well with adding a cash shop for micro-transactions, but when it comes to actually implementing that and integrating it with the software it sort of blows. There's so many different scenarios that you have to consider such as items with one use, items with multiple use, lifetime items. Then you also have to consider how it actually behaves, if it should be broadcasted to all servers, one server, a polling method.&lt;br&gt;
&lt;br&gt;
The only realistic way to implement it would really be just offering the items and then making the developer poll for that information, keeping track of real uses, and also making them responsible for 'clearing' the purchase in that the item is no longer available to the user. Even then, that's sort of ugly and you're better off just implementing it yourself.&lt;br&gt;
&lt;br&gt;
My second mini-rant is about the update itself. It's awesome. As someone that's had to deal with problem users on the front page and as someone that tries to keep up with recent going ons, it provides a much more organized method of doing so. Instead of traveling back and forth between the members page and the forum, I can instead stick to one place. That's all on that topic.&lt;br&gt;
&lt;br&gt;
The rest of this post is dedicated to my recent project. I'm working on a 2D renderer so that I can participate in the next &lt;a href=&quot;http://www.ludumdare.com&quot;&gt;Ludum Dare&lt;/a&gt;. It's actually a three-part project, the renderer, the scene (map) editor, and the sprite editor. I had done quite a bit on the renderer to the point where I'm pretty happy with it.&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://puu.sh/cyYT&quot; rel=&quot;thumbnail&quot;&gt;&lt;img src=&quot;http://puu.sh/cyYT&quot; width=&quot;300&quot; height=&quot;200&quot;&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
This is the renderer itself. Basically, it has three categories of renderable objects: Scene objects, dynamics, and overlays. The scene objects are managed by the Scene class itself. Dynamics are drawn next and include what would typically be implemented as a /mob or an /obj in DM- anything that can move. The third category is overlays, which would be things like the command console and any sort of HUD. The picture is about how far I've gotten on it so far.&lt;br&gt;
&lt;br&gt;
The second part of the project is the sprite editor, SpritED. It's not a sprite editor in the sense that it edits images, it's a sprite editor in the sense that it takes 24-bit bitmap spritesheets and makes sprite definition files out of the information I give it, including state names, bounding boxes, and animation information. It is complete, as of now (except when I started writing the next section I realized I forgot to add in a density toggle :\):&lt;br&gt;
&lt;br&gt;
(Clicking does not open thumbnail viewer)&lt;br&gt;
&lt;img src=&quot;http://puu.sh/cyYl&quot;&gt;&lt;br&gt;
&lt;img src=&quot;http://puu.sh/cyZO&quot;&gt;&lt;br&gt;
&lt;img src=&quot;http://puu.sh/cyZP&quot;&gt;&lt;br&gt;
&lt;img src=&quot;http://puu.sh/cz0c&quot;&gt;&lt;br&gt;
&lt;img src=&quot;http://puu.sh/cz0f&quot;&gt;&lt;br&gt;
&lt;br&gt;
The final part is the scene editor, ScenED. It loads sprite definition files and allows them to be placed on the map. There's not much more to it than that.&lt;br&gt;
&lt;br&gt;
(Still no thumbnail viewer)&lt;br&gt;
&lt;img src=&quot;http://puu.sh/cz0L&quot;&gt;&lt;br&gt;
&lt;br&gt;
Oh, and a picture showing off the command console:&lt;br&gt;
&lt;img src=&quot;http://puu.sh/cz1o&quot;&gt;&lt;br&gt;
&lt;br&gt;
That wraps that up. Happy 2012, y'all, and I'll see ya around. Maybe.&lt;br&gt;
&lt;br&gt;
[EDIT]&lt;br&gt;
&lt;br&gt;
To clarify or shorten up my point about the new layout, it's basically lurker's paradise and it makes me happy.</description>
        </item>
                <item>
            <title>Doing Stuff Badger</title>
            <link>http://www.byond.com/members/Audeuro?command=view_post&amp;post=122035</link>
            <guid>http://www.byond.com/members/Audeuro?command=view_post&amp;post=122035</guid>
            <pubDate>Mon, 19 Dec 2011 06:45:20 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Audeuro?command=view_comments&amp;post=122035#comments</comments>
            
            <description>Sorry, there's no badgers here- I just needed some filler for the title and that was the first word that popped into mind. I thought I'd drop by again to mention a project that I recently started.&lt;br&gt;
&lt;br&gt;
Years ago, I started out on BYOND messing around and never actually accomplishing anything. (For a mostly complete auto-biography of my BYONDlife, see a few posts back) To this day I still haven't really accomplished anything other than, alongside &lt;a href=&quot;http://members.byond.com/Tiberath&quot;&gt;Tiberath,&lt;/a&gt; helping bring up one of the greatest guilds BYOND had in those days.&amp;lt;/bias&amp;gt; Recently, I came to the realization that it wasn't that I just wasn't satisfied with where I thought BYOND was going (which I've recently reformed my opinion on), I just wasn't really satisfied with BYOND itself (through no fault of BYOND's, mind. I guess I just started losing interest?).&lt;br&gt;
&lt;br&gt;
So, I started working on a game outside of BYOND.&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://images.audeuro.com/progress.png&quot; rel=&quot;thumbnail&quot;&gt;&lt;img src=&quot;http://images.audeuro.com/progress.png&quot; width=&quot;320&quot; height=&quot;240&quot;&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
This is the first bit of real progress that I made. Not only was I able to load the multi-colored squares from a sprite sheet, I re-used that functionality for the text and managed to get my terribly-drawn font on the screen. Oh, also, FPS counter.&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://images.audeuro.com/rectangle.png&quot; rel=&quot;thumbnail&quot;&gt;&lt;img src=&quot;http://images.audeuro.com/rectangle.png&quot; width=&quot;320&quot; height=&quot;240&quot;&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
The next bit of progress I made is evident in this picture. I set it up to limit the frame rate from the 1300 fps I was experiencing in the first picture to 60 fps and added a render queue to it. Rendering a new tile on the screen was as simple as deriving from IRenderable and adding that to the renderObjects vector in the renderer's class. The black square is a result of 64 squares being created and added to the renderObjects.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://images.audeuro.com/ugh.png&quot; rel=&quot;thumbnail&quot;&gt;&lt;img src=&quot;http://images.audeuro.com/ugh.png&quot; width=&quot;320&quot; height=&quot;240&quot;&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
This next one was taken during a time of much frustration and sadness. I set it up so that it didn't render objects that weren't in view of the camera (I messed up part of it in this screenshot, don't judge me), but in doing so I ran across a strange bug where my primitives (the black square and the console) were flickering whenever my text at the bottom was updated at a quick rage. After four or five hours of debugging, I determined that that was a direct result of keeping 2D texture mapping on when I drew my non-texture mapped primitives (whoops!)&lt;br&gt;
&lt;br&gt;
The last picture is about where I'm at right now, having been at work since I fixed the problem with not turning off 2D texture mapping. The point of this post wasn't really just to point out that I'm actually doing something for once and pointing out a bunch of screenshots of nothing interesting at all.&lt;br&gt;
&lt;br&gt;
A few posts back (the auto-biography one), I expressed much discontent with BYOND that might've come off too incredibly negatively. That wasn't really my goal of that post, it just sort of turned out that way. Last Thursday and Friday, I decided I was going to actually try writing a game in Java to show the people I've come across saying that I dislike Java because I don't 'know' Java why I hate Java. I spent a few hours on it and wrote exactly 8 classes before I realized that I hate Java and gave up.&lt;br&gt;
&lt;br&gt;
After that, the &lt;a href=&quot;http://www.ludumdare.com&quot;&gt;Ludum Dare&lt;/a&gt; took place (Saturday and Sunday). Watching various people work on their games and listening to the great music, I was inspired to start working on a serious game again (except not in Java).&lt;br&gt;
&lt;br&gt;
Some time between the second and third screenshots, it just sort of hit me. Here I was, working on (eventually, ) a game in C++. Just working away, thinking through my problems. Getting frustrated in the process, but managing to get by. I started out with BYOND long ago and slowly evolved into lower-level languages. If it wasn't for BYOND, I would no doubt be a crack-addicted gamer monkey hiding in a ditch somewhere. Alright, that was an exaggeration, but I wouldn't be where I am today if it wasn't for the effort put into BYOND by Dan, Tom, Lummox, and everyone else that's put in work on the project over the many years.&lt;br&gt;
&lt;br&gt;
So I suppose this is mostly an apology post of sorts. My last on the BYOND subject was sort of harsh and overly-judgmental, and I didn't really want it to come off that way. I hope BYOND lives on forever (one can dream, right? Surely Tom or Lummox have achieved immortality) , as this is where my roots are.&lt;br&gt;
&lt;br&gt;
That is all.</description>
        </item>
                <item>
            <title>Savefiles - Buffered I/O</title>
            <link>http://www.byond.com/members/Audeuro?command=view_post&amp;post=121905</link>
            <guid>http://www.byond.com/members/Audeuro?command=view_post&amp;post=121905</guid>
            <pubDate>Wed, 14 Dec 2011 07:13:39 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Audeuro?command=view_comments&amp;post=121905#comments</comments>
            
            <description>I'm sure I've had a previous post about DM's /savefile's before, but I figured I'd go ahead and make another one for this feature of DM that so many people over-look when using savefiles.&lt;br&gt;
&lt;br&gt;
Let's look at this snippet of code:&lt;br&gt;
&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
&lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/savefile/F = &lt;span class=&quot;dmkeyword&quot;&gt;new&lt;/span&gt;&lt;br&gt;F.cd = ckey&lt;br&gt;F[&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;Hi&amp;quot;&lt;/span&gt;] &amp;lt;&amp;lt; &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;There&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
What is this doing? The first line creates a new savefile (with no explicit name, so a temporary file). The second line navigates within the savefile to the `ckey` directory. The third line writes the string &quot;There&quot; to the &quot;Hi&quot; directory in the `ckey` directory of the savefile. Now let's say &quot;Hi&quot; was our variable, and now we want to store an &quot;MP&quot; variable.&lt;br&gt;
&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
F[&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;MP&amp;quot;&lt;/span&gt;] &amp;lt;&amp;lt; 6
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
This is how one generally goes about storing separate variables- one directory is delegated for each variable. This is, by default, how Read()/Write() do it. Why? I can only imagine because it's incredibly flexible. If you add or delete a var from the object, none of your other vars are affected.&lt;br&gt;
&lt;br&gt;
That's good, from a developer's standpoint. They don't want to have to do that much work to ensure that stuff doesn't break, but what about from a server's standpoint? What are the implications of having a one-to-one directory-to-var relationship in your saving?&lt;br&gt;
&lt;br&gt;
Bloat. Without going into too much detail, every directory you create adds on another 14 + length(directory name) bytes to your savefile. This may not seem like a lot when you only have a few vars, but what if you have, say, 10 vars? That's an additional 140 bytes + the lengths of all of the names. 140 bytes? That's not too bad. What if you want to allow the character to have up to 3 characters (seems reasonable) per key? That's a good 140 * 3 = 420 bytes. That's not too bad, right?&lt;br&gt;
&lt;br&gt;
Well, let's switch back to the developer's standpoint for a second. Upon processing one header, DS is given a parent ID for the node that it has to look-up before it can even read the data. This is organized in a tree structure, so generally this won't take that long and shouldn't ever be considered a bottleneck. If it is, you might revamp your design.&lt;br&gt;
&lt;br&gt;
So what's the point of all of this? Well, there are ways to squeeze every last bit of performance and size out of savefiles that you can. This is done by using them in one of the ways that they were actually intended to be used. Let's look at the following snippet:&lt;br&gt;
&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
&lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/savefile/F = &lt;span class=&quot;dmkeyword&quot;&gt;new&lt;/span&gt;&lt;br&gt;F &amp;lt;&amp;lt; &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;Hi&amp;quot;&lt;/span&gt;&lt;br&gt;F &amp;lt;&amp;lt; &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;There&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
What would this savefile look like if we used ExportText() on it?&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;
. = &quot;Hi&quot;,&quot;There&quot;
&lt;/pre&gt;
&lt;br&gt;
&lt;br&gt;
Notice that we have stored two strings in one directory (&quot;.&quot;). This is because when you open the savefile or change the directory using 'cd', a buffer is created to write the current directory's data, starting at the beginning of the directory. This means that if we were to change directories and then come back to this one and start writing again, the new data will over-write what was already there. Let's look at the entirety of the snippet from above:&lt;br&gt;
&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
&lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/savefile/F = &lt;span class=&quot;dmkeyword&quot;&gt;new&lt;/span&gt;&lt;br&gt;F.cd = ckey&lt;br&gt;F[&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;Hi&amp;quot;&lt;/span&gt;] &amp;lt;&amp;lt; &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;There&amp;quot;&lt;/span&gt;&lt;br&gt;F[&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;MP&amp;quot;&lt;/span&gt;] &amp;lt;&amp;lt; 6
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
The second line creates the new buffer for the `ckey` directory. From there, the third line essentially creates a new buffer for the &quot;Hi&quot; directory within, writes &quot;There&quot; to it, then stores it in &quot;Hi&quot;, overwriting any data that was there. The same goes for the &quot;MP&quot; line with the number '6'.&lt;br&gt;
&lt;br&gt;
But how can we use this knowledge of DS/DD creating buffers for the current directory and appending data to our advantage? Well, we can avoid creating new directories for every single variable and instead store them sequentially in the savefile. The pitfall of this is that if you make any changes to your saveable vars, you need to add that to your code manually and allow for backwards compatibility, usually by having the first entry be a version number for the format, so you can do your reads based on the version number.&lt;br&gt;
&lt;br&gt;
I wrote up a small datum to assist in easing into the buffered IO mentality:&lt;br&gt;
&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
BufferedIO&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;&lt;br&gt;        filename = &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br&gt;        savefile/save = null&lt;br&gt;    New(fname)&lt;br&gt;        filename = fname&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(filename) Open()&lt;br&gt;    Read()&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(!save || save.eof) &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; null&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/ret = null&lt;br&gt;        save &amp;gt;&amp;gt; ret&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; ret&lt;br&gt;    Write(data)&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(!save || istype(data, /savefile)) &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 0&lt;br&gt;        save &amp;lt;&amp;lt; data&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 1&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;&lt;br&gt;        Clear()&lt;br&gt;            save.eof = -1&lt;br&gt;        EOF()&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; (save &amp;amp;&amp;amp; save.eof)&lt;br&gt;        Open(fname = &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;)&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(fname) filename = fname&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(!filename) &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 0&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(save) Close()&lt;br&gt;            save = &lt;span class=&quot;dmkeyword&quot;&gt;new&lt;/span&gt; /savefile(filename)&lt;br&gt;        Close()&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(!save) &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 0&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;del&lt;/span&gt; save&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 1&lt;br&gt;        cd(dir)&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(!save) &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 0&lt;br&gt;            save.cd = dir&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 1&lt;br&gt;        File()&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; save
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
Let's say you want to store HP, MP, and ATK vars:&lt;br&gt;
&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
mob/&lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;&lt;br&gt;    HP = 40&lt;br&gt;    MP = 30&lt;br&gt;    ATK = 20&lt;br&gt;&lt;br&gt;mob/&lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;/Save()&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/BufferedIO/IO = &lt;span class=&quot;dmkeyword&quot;&gt;new&lt;/span&gt;(&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;player.sav&amp;quot;&lt;/span&gt;)&lt;br&gt;    IO.cd(&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;playername&amp;quot;&lt;/span&gt;)&lt;br&gt;    IO.Write(0)      &lt;span class=&quot;dmcomment&quot;&gt;// Version number&lt;/span&gt;&lt;br&gt;    IO.Write(HP)&lt;br&gt;    IO.Write(MP)&lt;br&gt;    IO.Write(ATK)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
What does this look like in the savefile?&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;
playername = 0,40,30,20
&lt;/pre&gt;
&lt;br&gt;
&lt;br&gt;
Now, how would you read this?&lt;br&gt;
&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
mob/&lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;/Load()&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/BufferedIO/IO = &lt;span class=&quot;dmkeyword&quot;&gt;new&lt;/span&gt;(&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;player.sav&amp;quot;&lt;/span&gt;)&lt;br&gt;    IO.cd(&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;playername&amp;quot;&lt;/span&gt;)&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/version = IO.Read()&lt;br&gt;    HP = IO.Read()&lt;br&gt;    MP = IO.Read()&lt;br&gt;    ATK = IO.Read()
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
Say you delete the MP var. Remove IO.Write(MP), increment the version number, then if(version &amp;lt; 1) in Load(), you can simply call IO.Read(), like so:&lt;br&gt;
&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
mob/&lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;&lt;br&gt;    HP = 40&lt;br&gt;&lt;span class=&quot;dmcomment&quot;&gt;//    MP = 30&lt;/span&gt;&lt;br&gt;    ATK = 20&lt;br&gt;&lt;br&gt;mob/&lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;/Save()&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/BufferedIO/IO = &lt;span class=&quot;dmkeyword&quot;&gt;new&lt;/span&gt;(&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;player.sav&amp;quot;&lt;/span&gt;)&lt;br&gt;    IO.cd(&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;playername&amp;quot;&lt;/span&gt;)&lt;br&gt;    IO.Write(1)      &lt;span class=&quot;dmcomment&quot;&gt;// Version number&lt;/span&gt;&lt;br&gt;    IO.Write(HP)&lt;br&gt;&lt;span class=&quot;dmcomment&quot;&gt;//    IO.Write(MP)&lt;/span&gt;&lt;br&gt;    IO.Write(ATK)&lt;br&gt;&lt;br&gt;mob/&lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;/Load()&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/BufferedIO/IO = &lt;span class=&quot;dmkeyword&quot;&gt;new&lt;/span&gt;(&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;player.sav&amp;quot;&lt;/span&gt;)&lt;br&gt;    IO.cd(&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;playername&amp;quot;&lt;/span&gt;)&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/version = IO.Read()&lt;br&gt;    HP = IO.Read()&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(version &amp;lt; 1) IO.Read()&lt;br&gt;&lt;span class=&quot;dmcomment&quot;&gt;//    MP = IO.Read()&lt;/span&gt;&lt;br&gt;    ATK = IO.Read()
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
Most people won't find this a very useful feature, and more won't ever use it, but if you're really interested in squeezing every last bit out of the /savefile format, I'd give it a shot.</description>
        </item>
                <item>
            <title>GEE (Getting Excited Easily)</title>
            <link>http://www.byond.com/members/Audeuro?command=view_post&amp;post=121813</link>
            <guid>http://www.byond.com/members/Audeuro?command=view_post&amp;post=121813</guid>
            <pubDate>Sun, 11 Dec 2011 10:07:36 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Audeuro?command=view_comments&amp;post=121813#comments</comments>
            
            <description>Acronyms might be the new trend. Anywho, I've been working on this project that I briefly mentioned in the last post. It's basically a server/client setup that handles versioning and distribution on the user-level for a project. It's generally meant for use with applications that have a launcher-type setup to download more efficient updates by only downloading exactly what's changed from version to version.&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://images.audeuro.com/patchcl.png&quot; rel=&quot;thumbnail&quot;&gt;&lt;img src=&quot;http://images.audeuro.com/patchcl.png&quot; height=&quot;400px&quot; width=&quot;500px&quot;&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
This is a picture of my testing of the basic functionality of the patch client. Up until this point the client didn't actually do anything but send the server some information and the server output it. However, tonight I set it up so that the server not only received that information but it processed and would guess the right version if the serial wasn't given and THEN it would even go so far as to figure out what's changed exactly and send information to the client about the latest version's serial, whether it needs to update or not, and a list of modified files with their CRC32s. This picture represents this all working (save for a minor misconfiguration between one or two of those executions).&lt;br&gt;
&lt;br&gt;
The moral of this story, I suppose, is that I put in a lot of effort (the project is almost complete) to get nothing more to show for it than those three lines from the console, but it got me so excited to see that output that I nearly cried. Do YOU have a &lt;a href=&quot;http://rampantgames.com/blog/2004/10/black-triangle.html&quot;&gt;Black Triangle&lt;/a&gt;-ish story?</description>
        </item>
                <item>
            <title>Conway's Game of Life</title>
            <link>http://www.byond.com/members/Audeuro?command=view_post&amp;post=121755</link>
            <guid>http://www.byond.com/members/Audeuro?command=view_post&amp;post=121755</guid>
            <pubDate>Fri, 09 Dec 2011 22:02:05 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Audeuro?command=view_comments&amp;post=121755#comments</comments>
            
            <description>Breaking the trend of two word titles, I took a few minutes out of working on my patch server to write and &quot;release&quot; this &lt;a href=&quot;http://files.byondhome.com/Audeuro/src/Life_src.zip&quot;&gt;BYOND Version&lt;/a&gt; of &lt;a href=&quot;http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life&quot;&gt;Conway's Game of Life&lt;/a&gt; (Download link first, wikipedia link second). It's interesting to experiment with.&lt;br&gt;
&lt;br&gt;
To use it, first use Create and specify a map width and height. From here, you can either Generate the cells (You can specify a seed here or leave it 0 which won't seed the PRNG at all any further than it's already done by DS) or you can just click on cells to toggle the &quot;alive&quot; state (white = dead, black = alive). Once you've generated the cells or got it set up how you want it, hit &quot;Start&quot; and watch it go. Once it reaches an end, it'll automagically stop and tell you how many ticks it took. It won't stop if it hits an oscillating pattern and you have to Stop it manually or just Create a new map (no need to Stop it in that case).</description>
        </item>
                <item>
            <title>Public Opinion</title>
            <link>http://www.byond.com/members/Audeuro?command=view_post&amp;post=121654</link>
            <guid>http://www.byond.com/members/Audeuro?command=view_post&amp;post=121654</guid>
            <pubDate>Tue, 06 Dec 2011 07:48:52 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Audeuro?command=view_comments&amp;post=121654#comments</comments>
            
            <description>Next week is finals week and then it's Winter break. As it is, my list of things to accomplish during Winter break is relatively small and slowly diminishing. As such, I need something to keep me preoccupied during those long winter days where I find myself absolutely bored.&lt;br&gt;
&lt;br&gt;
So I've decided to do a public survey of sorts. The idea is that I ask you what I should work on over the Winter break, then you write in the comments of this post something relevant to the question, preferably answering it to some extent. Restrictions for answers:&lt;br&gt;
&lt;br&gt;
&lt;ul&gt;

&lt;li&gt;Must be programming or technical design related&lt;/li&gt;

&lt;li&gt;If it's a programming project, it should be language agnostic unless it's DM-specific&lt;/li&gt;

&lt;li&gt;May or may not be relevant to BYOND&lt;/li&gt;

&lt;/ul&gt;
&lt;br&gt;
&lt;br&gt;
The first two are restrictions, the third is more of a statement. I'm terrible at anything that isn't programming, and the thing I'm least terrible at in the other group of items is technical design. I will take a weighted average of the serious answers and determine from there what I'll be spending my spare time on.</description>
        </item>
                <item>
            <title>Sudden Realizations</title>
            <link>http://www.byond.com/members/Audeuro?command=view_post&amp;post=121594</link>
            <guid>http://www.byond.com/members/Audeuro?command=view_post&amp;post=121594</guid>
            <pubDate>Sun, 04 Dec 2011 12:52:38 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Audeuro?command=view_comments&amp;post=121594#comments</comments>
            
            <description>As I approach development of my first game outside of BYOND, it suddenly hit me that I was actually going to handle a lot of issues that BYOND naturally took care of for me. I'm not talking the obvious things like networking and graphics, I'm talking things like distribution, update handling, and user management.&lt;br&gt;
&lt;br&gt;
Before I even started my project, my initials questions to myself were about distribution. How am I going to distribute my game? I'm obviously going to use &lt;a href=&quot;http://www.audeuro.com&quot;&gt;my website&lt;/a&gt;, but are there other places I can advertise where I'll be able to net an exposure to at least 50 players? With BYOND, most people don't ask these questions. They should, but they don't. They already have the hub right in front of them, which automagically provides publicity through the listing (if it's in a state to be released) that will net them exposure to, let's say, at least 100 players a day.&lt;br&gt;
&lt;br&gt;
I decided to fore-go completely answering my previous question for the time being as it wasn't absolutely essential, so I started thinking some more. How am I going to handle updates? Am I going to just post them on my website and mention that there's been a change in the places I used for distribution? But then, that's sort of inefficient, isn't it? Then it hit me: AHA! I can write a patch server to handle patching of all game files from version to version, then I can write a game launcher to poll the server and update! Like, y'know, a lot of games do. With BYOND, this isn't an issue. Updating your game is as simple as incrementing a version number in your code, the same version number on the website, and uploading the new files. Maybe posting a changelog somewhere, if you really want to. You don't actually have to worry about distributing updates because BYOND handles that for you.&lt;br&gt;
&lt;br&gt;
The third issue I came up with was user management. BYOND already provides authentication services as well as identification services. If I want to do a propagating ban on someone, Dream Daemon's hostban tool is the best you're going to find. Someone may have ten or fifteen different keys that you're not even aware of and they're all tied together via the pager or BYOND's website for hostban to utilize. Additionally, you don't have to worry about user registration and integrating that with your software.&lt;br&gt;
&lt;br&gt;
Long story short, BYOND provides some nifty services that a lot of us take for granted. Use them.</description>
        </item>
                <item>
            <title>Removed Enthusiasm</title>
            <link>http://www.byond.com/members/Audeuro?command=view_post&amp;post=121525</link>
            <guid>http://www.byond.com/members/Audeuro?command=view_post&amp;post=121525</guid>
            <pubDate>Fri, 02 Dec 2011 13:00:32 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Audeuro?command=view_comments&amp;post=121525#comments</comments>
            
            <description>I'm sorry to have tricked you, but this is actually going to be an auto-biography that leads up to the primary topic.&lt;br&gt;
&lt;br&gt;
Back in 2004, I joined BYOND with the sole intention of playing &lt;a href=&quot;http://games.byond.com/Skysaw.MyLifeasASpy&quot;&gt;cool&lt;/a&gt; &lt;a href=&quot;http://games.byond.com/Malver.ARWG&quot;&gt;games&lt;/a&gt;, little aware of the technical world. My programming knowledge up to that point consisted of limited VB6 that my mother had taught me, and another BASIC variant entitled 'Learn to Program: BASIC' that my friend who introduced me to BYOND had also introduced me to. Oh, also failing to understand C entirely while modifying another program, but that's largely irrelevant.&lt;br&gt;
&lt;br&gt;
After playing MLaaS for quite a while, my friend introduced me to the developer side of BYOND, pitching it as incredibly cool. I spent a year or two making dumb mistakes and not quite 'getting it'. Around 2007, everything just sort of 'clicked'. Programming made a lot more sense, and I found myself a lot better at it. I found myself interested in things like networking and taught myself C++. It took a few months and I finally started getting pretty good at it, to the point where I could write simple applications like DreamConfig, which was used to write or amend a hostban.txt for DreamDaemon on Linux.&lt;br&gt;
&lt;br&gt;
After I started actually getting incredibly proficient in C++, March of 2008, life happened and I had to take an extended leave of absence as I moved into a completely new life with completely new people, studying in my free time for when I actually got a computer hooked back up. It wasn't until I graduated and went to college in 2010 that I actually got a stable computer running and was able to get back into the BYOND scheme of things.&lt;br&gt;
&lt;br&gt;
At the time of writing it's December of 2011. A fully year and a few months have passed since I first managed to re-acquaint myself with the virtual world. Since then, I've been involved in research projects, some private and some public, with other members of BYOND, tearing apart the internals of BYOND slowly. When I say slowly, I mean really slowly.&lt;br&gt;
&lt;br&gt;
== End autobiography&lt;br&gt;
&lt;br&gt;
The projects I've been directly involved in have either completed due to the full extent of the subject matter being researched or halted due to lack of motivation. The latter part of this is what the title of this post is about. At one point, I was having a discussion with someone about Linux. The picture we were painting, so to speak, was of a full set of BYOND on Linux- the Pager, Dream Seeker, Dream Daemon, and Dream Maker, aptly code-named Dream Link, Dream Wanderer, Dream Daemon (already exists, just supplement it with DreamConfig), and Dream Builder.&lt;br&gt;
&lt;br&gt;
After tossing the idea back and forth a little bit, I set forth doing some mock-ups. I switched back and forth for a few months between re-drawing the various controls that interfaces offer that didn't already exist in Qt and doing some research on how the Pager communicates with the hub and, to a much lesser extent, how DS communicates with DD/DS. The Pager &amp;lt;-&amp;gt; Hub research wasn't going too bad until I hit a brick-wall with the authentication. I tried numerous things, including writing a proxy to analyze my traffic with BYOND.com's hub and writing a hub emulator that sat on the other end and forged the intro packet to the Pager over and over and over again with the same data, only to reach the conclusion every time I looked at it. After talking to Tom about it a bit, he expresses interest, to some extent, in our project, but is unable to offer any help.&lt;br&gt;
&lt;br&gt;
Fast forward a little bit and Tom publically announces a Flash client. Suddenly, the general consensus is that multi-platform isn't an issue anymore because of the Flash client. This is &quot;Removes Enthusiasm #1&quot;.&lt;br&gt;
&lt;br&gt;
Don't get me wrong, I can appreciate the effort that Tom and Lummox are putting in with the Flash client. It will be interesting to see a working server/client model with Flash that allows for larger-scale multiplayer games than have been previously done with Flash (that I'm aware of). The problem is that while it is a somewhat-ok solution to multiplatform issues, a Flash client will never be able to completely beat out a stand-alone client. With the stand-alone client, you have the freedom to actually play single-player games on Linux (using DreamDaemon to host and connecting locally) that you aren't allowed with the Flash client. You can actually play games with full interfaces as the developers may or may not have intended, or at least exactly as the equivalent Windows users would play it.&lt;br&gt;
&lt;br&gt;
I said the last one was &quot;Removes Enthusiasm #1&quot;, so that must mean there's at least one more, right? I mean, I did number it at after all. After Tom announced the Flash client, it seemed like people made a lot of unrealistic expectations about the Flash client. We'll call this #2. Will it allow BYOND's developers to develop for a wider audience? Yes. Will it bring in more players and more developers? Yes. Will that really help BYOND? No.&lt;br&gt;
&lt;br&gt;
So now I seem like I'm contradicting myself. I made it sound two paragraphs ago like it would be absolutely amazing because it will provide a greater server/client functionality than seen in Flash to-date by myself, then I go off and say I don't think it'll help BYOND. The problem is that I don't see it really helping BYOND all that much. You're going to bring in new users, that's alright. Most of them will probably be better than the current user-base. You're also bringing in new developers. That's alright as well, but what type of developers are they?&lt;br&gt;
&lt;br&gt;
Most of the new developers brought in by the Flash client are going to be the type that grew largely when people started realizing that Flash games could generate a lot of money. They're the ones that are great at making small games that will catch your attention for limited amount of time probably 4, 5, or even 6 days a week, when you're bored listening to some professor lecture about thermodynamics or what-have-you. They'll be good at making these games, and they'll make quite a few of them. Or at least, we can hope they will. We all love those games. This will improve the cash-flow to BYOND and actually generate some funding to the project, that's true, but how will it actually &lt;i&gt;benefit&lt;/i&gt; BYOND?&lt;br&gt;
&lt;br&gt;
Looking at the &lt;a href=&quot;http://www.byond.com/members/?command=view_tracker&amp;tracker=1&quot;&gt;bug tracker&lt;/a&gt; and the &lt;a href=&quot;http://www.byond.com/members/?command=view_tracker&amp;tracker=4&quot;&gt;feature tracker&lt;/a&gt;, I can see stacks of feature requests and bug reports lined up just waiting to be hammered. Will they get done? Most of them. The feature requests will slowly dwindle, as will the bug reports. What's left? A large player-base that absolutely loves these short Flash games, and a large developer-base that absolutely loves these short Flash games. Ultimately, you don't really have people pushing the engine to its absolute limits all-around trying to figure out what it can or can't do, what it should be able to or shouldn't be able to do, they're mainly in this one, now incredibly large, corner of BYOND. It'll get optimized to do what they want to do, and then it'll just sort of hit a brick wall.&lt;br&gt;
&lt;br&gt;
Is that the only possible way for it to end? No. I've played out countless scenarios in my head, the majority of them leading to no real extension to the software outside of the Flash client, some even leading to Dream Seeker being mostly phased out or unmaintained. It could always go the other way, though, but we can't accurately predict that.&lt;br&gt;
&lt;br&gt;
It's clear that my points of &quot;Removes Enthusiasm&quot; aren't in order of importance, because #2 isn't THAT big of a deal, where-as #3 sort of is. The Flash client comes out. It succeeds, it fails, who knows. I hope for the former. I, along with many others that I know here on BYOND, am the type of guy that likes to take something, study it, analyze it, try to figure out how it works, and re-create it. If there's three things that I like they'd have to be continued maintenance, improving compatibility, and improving efficiency, no matter how terrible I am at them. Writing a new DS parallel in Linux with C++ and Qt would hit not only the first and the second, but it would also hit the third as we could make recommendations to Tom and Lummox ways that they might be able to improve their protocol or other things.&lt;br&gt;
&lt;br&gt;
The Flash client is already coming out, so that removes motivation (See: #1) to work on a native Linux, et al. client to parallel Dream Seeker because people are expecting the Flash client to alleviate multi-platform issues. What's next? Reversing the protocol the Flash client uses to communicate with DD. That's fun, for a little bit. Once it's completely documented, there's no where else to go. It's a new protocol, new technology. It's already probably going to be pretty dang optimized as it is. There's not going to be any room for improvement because the feature-set is set in stone until it's updated by Tom or Lummox, then that's another few hours spent figuring out what actually changed. Sure, it hits point 1, but there's not much of point 2 or point 3.&lt;br&gt;
&lt;br&gt;
The point of it is, the flash client's going to come out and it's not going to be all that entertaining for very long (for me, at least). There's not going to be much more that I can actually do around here for entertainment. This is #3.&lt;br&gt;
&lt;br&gt;
== End rant&lt;br&gt;
&lt;br&gt;
As a summary, for those of you who decided to skip to the very bottom because it's a decent-sized book, the points of demotivation are:&lt;br&gt;
&lt;br&gt;
#1. People feel that the Flash client is going to alleviate multi-platform concerns.&lt;br&gt;
#2. The announcement of the Flash client generated unrealistic expectations from a lot of people.&lt;br&gt;
#3. After the Flash client, there's not much left to do.&lt;br&gt;
&lt;br&gt;
And to summarize my position on the Flash client itself- I support it despite the fact that I don't feel like it will actually help the actual development of the software that much and it'll essentially drive off anything left keeping me here. I appreciate the work you do, Tom, and the attempts that you are making to keep the project a-float. As such, I will continue to support BYOND by renewing my membership when it comes to an end (as long as I can afford it), but my general activity (that was already pretty low) will start dwindling. Thank you for providing me with an awesome starting point and experience.&lt;br&gt;
&lt;br&gt;
P.S. I'm sorry to any that endured reading the entirety of this post. If you exist, you deserve a medal. I started writing this at 6:15 AM CST while having a hard time sleeping, yet being tired. As such, the structure and general efficiency in conveying coherent thoughts is probably non-existent and incredibly low respectively.</description>
        </item>
                <item>
            <title>Unit Testing</title>
            <link>http://www.byond.com/members/Audeuro?command=view_post&amp;post=121373</link>
            <guid>http://www.byond.com/members/Audeuro?command=view_post&amp;post=121373</guid>
            <pubDate>Sun, 27 Nov 2011 21:10:42 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Audeuro?command=view_comments&amp;post=121373#comments</comments>
            
            <description>You've written some software or a game. You go to add a cool new feature that interacts with previous features A, B, and G. Little did you know, you broke feature B to some extent in the process. Three months later, your client points out to you that feature B isn't working properly. You move, frantically, in an attempt to fix feature B to work properly again before your client becomes overly dissatisfied.&lt;br&gt;
&lt;br&gt;
This scenario could have been prevented if you had a good system for regularly testing incremental changes in place. If you haven't read &lt;a href=&quot;http://www.byond.com/members/DreamMakers?command=view_post&amp;post=35998&quot;&gt;Deadron's article&lt;/a&gt; on unit testing in a while, I highly recommend you do so again. It's a good read and it can help remind you why test-driven development is a great way to do things.&lt;br&gt;
&lt;br&gt;
For BYOND, &lt;a href=&quot;http://www.byond.com/developer/Deadron/Test&quot;&gt;Deadron.Test&lt;/a&gt; is a great test framework. It will help you feel encouraged to switch to test-driven development with its ease of use and lack of required intervention. With &lt;a href=&quot;http://www.byond.com/developer/Deadron/Test&quot;&gt;Deadron.Test&lt;/a&gt;, it's automated for you such that you just have to make an /obj/test/verb and your test is already ran.&lt;br&gt;
&lt;br&gt;
For C++, I wrote a similar &lt;a href=&quot;http://files.byondhome.com/Audeuro/test.tar&quot;&gt;testing framework&lt;/a&gt; inspired by &lt;a href=&quot;http://www.byond.com/developer/Deadron/Test&quot;&gt;Deadron.Test&lt;/a&gt;. The process for using it is like so:&lt;br&gt;
&lt;br&gt;
&lt;ul&gt;

&lt;li&gt;Create a new set of header and source files for your test(s).&lt;/li&gt;

&lt;li&gt;Create a new class derived from TestFramework::UnitTest&lt;/li&gt;

&lt;li&gt;Define the public `bool Run(void)` function. A return of 'true' indicates success, a return of 'false' indicates failure. You can use Message(const char *) to supply a message to go along with the failure message.&lt;/li&gt;

&lt;li&gt;Define `const char * Name(void) const` to return a name for your unit test.&lt;/li&gt;

&lt;li&gt;Use the `DefTest(unitTestClass)` macro on your class in the source file.&lt;/li&gt;

&lt;li&gt;To make the unit tests actually run, create a new `TestFramework::Core` instance and call `bool Run()` on it. A return value of true indicates success on all tests, a return value of false indicates a failure. It outputs which tests pass and the test that fails (if one fails).&lt;/li&gt;

&lt;li&gt;Make sure that testing.cpp is compiled &lt;b&gt;last&lt;/b&gt;&lt;/li&gt;

&lt;li&gt;&lt;b&gt;Optional:&lt;/b&gt; If you wish to create a new variable of some type belonging to your testing class, you can define `void Clean()` to do any necessary clean-up after your test concludes. This can be an easy way to avoid the redundancy of cleaning up in the several scenarios that the test may fail without causing any leaking of any sort.&lt;/li&gt;

&lt;/ul&gt;
&lt;br&gt;
&lt;br&gt;
Other recommendations:&lt;br&gt;
&lt;ul&gt;

&lt;li&gt;Do not put stack-based variables outside of Run(). The way the testing framework is setup, your test class gets constructed inside of a static global (allocated at program startup), which never gets destroyed.&lt;/li&gt;

&lt;li&gt;Create two builds for your application, one to function and one to run the unit tests. I personally use CMake and have it build the normal application without the testing framework then a second version with &quot;TESTVER&quot; defined and my testing framework included. My `main()` is one giant #ifdef/#else/#endif. You can do it however you want, but I do not recommend including the testing framework in a release build.&lt;/li&gt;

&lt;/ul&gt;
&lt;br&gt;
&lt;br&gt;
After months of usage and refining, I have simplified the process of using it as much as possible. After you've got it running tests and you've written a test class or two, it starts to come naturally to you.&lt;br&gt;
&lt;br&gt;
Using a test-driven development cycle has saved me from going bald, and it could save your hair too. There have been countless times where I've written up a new piece of code to interact with something else only to find that that something else didn't completely operate the way I wanted it to because of some changes I made else-where. Now that I know how to write unit tests, this happens no more.</description>
        </item>
            
    </channel>
</rss>


