<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3603566345830909173</id><updated>2011-11-27T15:58:36.412-08:00</updated><category term='C++'/><category term='PHP'/><category term='Data Structures'/><category term='Joomla'/><category term='SQL'/><category term='Tango'/><category term='XFire'/><category term='Stack'/><category term='Kingdom Wars'/><category term='Java'/><category term='Boost'/><category term='CPU Wars'/><category term='FSDEV'/><category term='D'/><title type='text'>The Mind of Sauron</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>23</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-7144598504663460578</id><published>2008-02-05T19:34:00.000-08:00</published><updated>2008-02-05T19:35:07.818-08:00</updated><title type='text'>Migration!</title><content type='html'>I moved to &lt;a href="http://www.sauron.fsdev.net/"&gt;http://www.sauron.fsdev.net/&lt;/a&gt;  Don't worry, I'm okay!  Just go there if you're following an out-of-date link.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-7144598504663460578?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/7144598504663460578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=7144598504663460578' title='38 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/7144598504663460578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/7144598504663460578'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/02/migration.html' title='Migration!'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>38</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-2332695774285855763</id><published>2008-01-30T15:03:00.000-08:00</published><updated>2008-01-30T15:14:50.340-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Data Structures'/><title type='text'>I Hate Specifications</title><content type='html'>I got the pleasurable experience of writing a specification.  General Brownlow was complaining to me that he hasn't been doing anything with relation to the game because he hasn't been given any specific tasks to complete.  I found this rather humorous, since the last time I tried to convince him to do something he did something completely different.  Then the time after than he ignored it and persisted in doing that different thing.  Weird.&lt;br /&gt;&lt;br /&gt;So he's incapable of drawing.  Acutally, I don't really know whether he is or not, he just refuses to do it.  I asked him for a storyboard for another project, you see, and he completely ignored it and write a small novel.  I told him we don't have the time or resources to write a game off of a book.  He said they did it for Halo.  I told him that I will personally rape Halo and then proceed to violate its children.&lt;br /&gt;&lt;br /&gt;He laughed.&lt;br /&gt;&lt;br /&gt;So this time around I decided to get wise and write a task for him that's more suited to his quixotic habits.  I asked him to write a game universe.  Five of them, in fact.&lt;br /&gt;&lt;br /&gt;Why do I want game universes?  I want a variety so I can pick the best one!  Well, actually I'm expecting them to find one pet universe and work almost exclusively on that.  My hope then is for their guilty conscience to force them to think about the other universes they need to write drafts of so that they're thinking of new ideas to put in their pet universe.&lt;br /&gt;&lt;br /&gt;The other part of my preference for a complete game universe draft before I'm code-complete on the first version of the game is to facilitate all those activities of game universe design before they try and put it in a game.  Techmarine seems hell-bent on writing all this into Unreal Tournament, however, I'm reasonably confident he won't be able to make an RPG out of an FPS.  I hope.&lt;br /&gt;&lt;br /&gt;The other motive is for me to buy time to write the game.  It's very difficult, requiring lots of careful forethought about how different systems need to be written to allow for easy modification at a later date.&lt;br /&gt;&lt;br /&gt;I just hated writing that specification though.  I bristled at having to use language such as "will consist of" and "shall have."  It's just so much like a school assignment.  If I don't use that language they'll read everything as a suggestion, and will completely ignore important things like concept art and the minutae of the game universe.  The concept art is necessary to evolve into the artwork for the 2D mockup (the first version of the game, and the testbed for many of the mathematical and technological aspects of the game engine itself) and it's also going to be an absolute necessity in order to create a web page for the game as well.  We can't stick with the Joomla! default theme.  I know it's fully W3C valid, but that can't stop us!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-2332695774285855763?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/2332695774285855763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=2332695774285855763' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/2332695774285855763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/2332695774285855763'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/i-hate-specifications.html' title='I Hate Specifications'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-5807803876803752758</id><published>2008-01-29T15:19:00.000-08:00</published><updated>2008-01-29T20:01:03.483-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Kingdom Wars'/><title type='text'>Massive Economies</title><content type='html'>Building a massively-multiplayer game does raise an interesting problem: how to craft a massive game that will also have a stable economy?  It's almost ridiculous, since this is a problem big enough to require the hiring of a consultant from the financial world.  That consultant would probably leave when he or she learned that we need their help to construct an imaginary economy.&lt;br /&gt;&lt;br /&gt;So the game designer gets to add another dirty-job to the list: economist.&lt;br /&gt;&lt;br /&gt;In other games this isn't quite as difficult a task.  In a game like Might and Magic every kind of player asset (currency and items) come from a single source: the environment.  The environment is really a term for the game.  It could be drops from monsters, quest rewards, or NPC (non-player character) transactions.  In a non-multiplayer game like Might and Magic, the old-school ones, this is permisable.  There are no other players, thus it's just you and the game.  Anything you loose is by definition put back into the environment.&lt;br /&gt;&lt;br /&gt;What is not the environment?  I define that to be anything that's owned by the player.&lt;br /&gt;&lt;br /&gt;How do goods cycle back into the environment?  As stated, through NPC transactions, through consumable items, and by either destroying or discarding items.  In a multiplayer environment we also have a global economic standpoint, which comes to include inactive players and stuff lost when an account or character is deleted.&lt;br /&gt;&lt;br /&gt;So ultimately it's like the Circle of Life from The Lion King.  Everything comes from and goes back to the environment.  In theory stuff also goes on inside the environment, however, that really isn't relevant since we can statistically simulate the wealth distribution inside the environment based on Saber-metrics (AI skill, character power ratings, proximity to other characters and how their ratings in specific areas compare, and other such things).&lt;br /&gt;&lt;br /&gt;This is all well and dandy, however, there is another element that I want to discuss here.  The goal of Kingdom Wars is to create a game that focuses also upon the interaction between players, and not just the playing of the game itself.  This emphasis on human interaction should extend to the economy.  This makes my goal simple: keep the money in the hands of players as long as possible before returning it to the environment.&lt;br /&gt;&lt;br /&gt;By doing this I hope to make it more interesting, involving players with certain production skills they can develop to make money and then spend it by paying other players who have different skills for their services.  This makes the game much more dynamic, with fluctuating prices that add that element of a gamble to the equation.  Not only do you have to be a warrior, but now you have to think like a stock-market investor and buy low, sell high.&lt;br /&gt;&lt;br /&gt;Biodude and I even entertained the concept of totally devaluing monster drops and completely removing NPC merchants altogether.  This would force players to adopt a more frugal play style involving greater shrewdness.  It also will cultivate greater levels of social networking, since friends usually help friends out.&lt;br /&gt;&lt;br /&gt;Earlier on the &lt;a href="http://f.fsdev.net/"&gt;FSDEV Forum&lt;/a&gt; I categorized the &lt;a href="http://forum.fsdev.net/viewtopic.php?f=4&amp;amp;t=7"&gt;three different main types of MMORPG player&lt;/a&gt;.  The first was a Grinder, who is a introverted individual who maintains few friends.  Those friends are very good, however.  The Grinder will rarely team up, prefering to go it alone.  The next is the Economist, a player that spends more time working the game market than other players.  The last kind is the Networker, a player that makes friends with everyone and is quick to both ask for help and give help to those friends.  Networkers are always in groups of friends.  They're really clique-ish, if you know what I mean.&lt;br /&gt;&lt;br /&gt;The concept of making the game more about player production skills and less about "farming" the game environment through self-power is a direct aim to make the game more people-oriented.  This reflects my goal to make the game more communication-oriented, and to elevate it as a place to meet friends that follow you outside the game and into other parts of the digital world.  This contrasts greatly with the current game model where it's almost impossible to find friends that you met inside a game without using cues from those friends.  You shouldn't have to comb the Internet for your buddies, they should be right there already!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-5807803876803752758?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/5807803876803752758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=5807803876803752758' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/5807803876803752758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/5807803876803752758'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/massive-economies.html' title='Massive Economies'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-3732607641928137395</id><published>2008-01-28T16:29:00.000-08:00</published><updated>2008-01-28T16:31:19.293-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tango'/><category scheme='http://www.blogger.com/atom/ns#' term='Data Structures'/><category scheme='http://www.blogger.com/atom/ns#' term='D'/><category scheme='http://www.blogger.com/atom/ns#' term='Stack'/><title type='text'>Fixed the ArrayStack</title><content type='html'>If fixed my poor little ArrayStack.  It should work now.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;module tango.util.collection.ArrayStack;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Standard implementation of a stack using an array as a data container.&lt;br /&gt;* This stack automatically shrinks itself when it gets too big.&lt;br /&gt;*&lt;br /&gt;* @author Chris Miller&lt;br /&gt;* @date 28 Jan 2008&lt;br /&gt;*/&lt;br /&gt;public class ArrayStack(K) {&lt;br /&gt;&lt;br /&gt;   // l_bound=the first element (the top of the stack)&lt;br /&gt;   // when the stack is empty, l_bound==data.length+1&lt;br /&gt;   private uint l_bound;&lt;br /&gt;&lt;br /&gt;   private K[] data;&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * The amount by which the array grows when it needs to in order to&lt;br /&gt;    * address more elements.&lt;br /&gt;    */&lt;br /&gt;   private float grow_size=1.50f; // DO NOT CHANGE THIS WITHOUT&lt;br /&gt;   // LOOKING AT THE CONTRACT TOWARDS THE END OF THE FILE!!!&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * The ratio of array size to actual data size that the stack will&lt;br /&gt;    * resize to the number of elements times the grow_size to when this&lt;br /&gt;    * ratio is met.&lt;br /&gt;    */&lt;br /&gt;   private float shrink_threshold=4.00f; // DO NOT CHANGE THIS WITHOUT&lt;br /&gt;   // LOOKING AT THE CONTRACT TOWARDS THE END OF THE FILE!!!&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Creates a new ArrayStack with room for five elements.&lt;br /&gt;    */&lt;br /&gt;   public this(){&lt;br /&gt;       this(5iu);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Creates a new ArrayStack with room for &amp;lt;tt&amp;gt;size&amp;lt;/tt&amp;gt; elements.&lt;br /&gt;    */&lt;br /&gt;   // see DMD 1.00 spec pg. 157, it's really cool!&lt;br /&gt;   public this(uint size)&lt;br /&gt;    in { assert(size!=0ui); }&lt;br /&gt;    body {&lt;br /&gt;       data=new K[size];&lt;br /&gt;       l_bound=size;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Pushes a new element &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; onto the top of the stack.  It will&lt;br /&gt;    * also use this time to perform any array resizing that it may need.&lt;br /&gt;    * If it's giving you trouble due to constant resizing of the array,&lt;br /&gt;    * consider using &amp;lt;tt&amp;gt;fast_push&amp;lt;/tt&amp;gt;, which doesn't check for memory&lt;br /&gt;    * use issues.&lt;br /&gt;    */&lt;br /&gt;   public void push(K e) {&lt;br /&gt;       else if(data.length-l_bound&amp;lt;=data.length*shrink_threshold&lt;br /&gt;               &amp;amp;&amp;amp;!isEmpty()&amp;amp;&amp;amp;data.length&amp;gt;=5)&lt;br /&gt;           ensureCapacity((data.length-l_bound)*grow_size);&lt;br /&gt;       fast_push(e);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Does the same thing as &amp;lt;tt&amp;gt;push&amp;lt;/tt&amp;gt;, only this does not check&lt;br /&gt;    * for memory use problems (a really big array with nothing in it).&lt;br /&gt;    */&lt;br /&gt;   public void fast_push(K e) {&lt;br /&gt;       if(l_bound&amp;lt;=1ui)&lt;br /&gt;           ensureCapacity(data.length*grow_size);&lt;br /&gt;       data[--l_bound]=e;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Ensures that the array has enough room for &amp;lt;tt&amp;gt;capacity&amp;lt;/tt&amp;gt; number&lt;br /&gt;    * of elements, including elements already in the array.&lt;br /&gt;    *&lt;br /&gt;    * &amp;lt;b&amp;gt;NOTE&amp;lt;/b&amp;gt;: If you use this, consider using &amp;lt;tt&amp;gt;fast_push&amp;lt;/tt&amp;gt; and&lt;br /&gt;    * &amp;lt;tt&amp;gt;fast_pop&amp;lt;/tt&amp;gt; due to otherwise active auto-resizing features&lt;br /&gt;    * that will try and keep your memory usage down!&lt;br /&gt;    */&lt;br /&gt;   // ensure the total capacity of the array, not just for new elements&lt;br /&gt;   public void ensureCapacity(uint capacity)&lt;br /&gt;    in { assert(capacity&amp;gt;=data.length-l_bound&amp;amp;&amp;amp;capacity!=0ui); }&lt;br /&gt;    body {&lt;br /&gt;        K[capacity] new_data;&lt;br /&gt;        new_data[new_data.length-(data.length-l_bound)..new_data.length]=&lt;br /&gt;           data[l_bound..data.length];&lt;br /&gt;       l_bound=new_data.length-(data.length-l_bound);&lt;br /&gt;       data=new_data;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Peeks at the element at the top of the stack without changing&lt;br /&gt;    * anything in the stack.  Returns &amp;lt;tt&amp;gt;null&amp;lt;/tt&amp;gt; if the stack is empty.&lt;br /&gt;    */&lt;br /&gt;   public K peek() {&lt;br /&gt;       if(l_bound==data.length+1)&lt;br /&gt;           return null;&lt;br /&gt;       return data[l_bound];&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Returns the element at the top of the stack and removes it.  This&lt;br /&gt;    * version also checks for memory use.  See also &amp;lt;tt&amp;gt;fast_pop&amp;lt;/tt&amp;gt;.&lt;br /&gt;    */&lt;br /&gt;   public K pop() {&lt;br /&gt;       if(data.length-l_bound&amp;lt;=data.length*shrink_threshold&lt;br /&gt;               &amp;amp;&amp;amp;!isEmpty()&amp;amp;&amp;amp;data.length&amp;gt;=5)&lt;br /&gt;           ensureCapacity((data.length-l_bound)*grow_size);&lt;br /&gt;       return fast_pop();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Essentially the same as &amp;lt;tt&amp;gt;pop&amp;lt;/tt&amp;gt;, only different in that it&lt;br /&gt;    * does not perform memory checking to prevent runaway memory use.&lt;br /&gt;    * This makes it faster in certain situations because it doesn't&lt;br /&gt;    * constantly shrink the array.&lt;br /&gt;    */&lt;br /&gt;   public K fast_pop() {&lt;br /&gt;       if(l_bound==data.length+1)&lt;br /&gt;           return null;&lt;br /&gt;       return data[l_bound++];&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Returns whether the stack is empty or not.&lt;br /&gt;    */&lt;br /&gt;   public boolean isEmpty() { return l_bound==data.length+1; }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Gets the growth size, or the number by which the current storage&lt;br /&gt;    * array size is multiplied by to find the new storage array size&lt;br /&gt;    * when more space is needed.&lt;br /&gt;    */&lt;br /&gt;   public float getGrowSize() { return grow_size; }&lt;br /&gt;   /**&lt;br /&gt;    * Sets the growth size, or how much larger the new array size&lt;br /&gt;    * will be when the stack needs to make it bigger.&lt;br /&gt;    */&lt;br /&gt;   public void setGrowSize(float grow_size)&lt;br /&gt;    in{ assert(grow_size&amp;gt;1.0f&amp;amp;&amp;amp;grow_size!=shrink_threshold); }&lt;br /&gt;    body { this.grow_size=grow_size; }&lt;br /&gt;   /**&lt;br /&gt;    * Gets the shrink threshold, or the ratio of array size to element&lt;br /&gt;    * count at which the stack will resize the array to be smaller.&lt;br /&gt;    */&lt;br /&gt;   public float getShrinkThreshold() { return shrink_threshold; }&lt;br /&gt;   /**&lt;br /&gt;    * Sets the ratio at which the stack will shrink the container array to&lt;br /&gt;    * the number of elements times the grow size.&lt;br /&gt;    */&lt;br /&gt;   public void setShrinkThreshold(float shrink_threshold)&lt;br /&gt;    in { assert(shrink_threshold&amp;gt;grow_size); }&lt;br /&gt;    body {&lt;br /&gt;       this.shrink_threshold=shrink_threshold;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-3732607641928137395?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/3732607641928137395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=3732607641928137395' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/3732607641928137395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/3732607641928137395'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/fixed-arraystack.html' title='Fixed the ArrayStack'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-5885079013552575476</id><published>2008-01-27T20:33:00.000-08:00</published><updated>2008-01-27T20:44:51.457-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tango'/><category scheme='http://www.blogger.com/atom/ns#' term='Data Structures'/><category scheme='http://www.blogger.com/atom/ns#' term='D'/><category scheme='http://www.blogger.com/atom/ns#' term='Stack'/><title type='text'>Coding under the Influence</title><content type='html'>No, I wasn't drunk, my mind was just under the influence of being happy to code again.  It's been really hard for me to spend so much time doing nothing but get ready to code.&lt;br /&gt;&lt;br /&gt;This is another little anomaly which happened, though I'm not quite sure how it came to be.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;module tango.util.collection.ArrayStack;&lt;br /&gt;&lt;br /&gt;// written 20080122135351 PST&lt;br /&gt;// by Chris Miller (lord Sauron the Great {at} gmail {dot} com)&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Implementation of an stack data structure using an array.  This&lt;br /&gt;* implementation is auto-balancing and will shift itself to the front&lt;br /&gt;* of its array to prevent runaway memory useage.  It does this during&lt;br /&gt;* its routine ensure capacity routine.  It will also shrink its array&lt;br /&gt;* size in the event that its internal array becomes inordinately larger&lt;br /&gt;* than its current storage requirements.&lt;br /&gt;*/&lt;br /&gt;public class ArrayStack(K) {&lt;br /&gt;&lt;br /&gt;  // l_bound = left bound = the first element&lt;br /&gt;  // r_bound = right bound = the last element&lt;br /&gt;  uint l_bound=0, r_bound=0;&lt;br /&gt;&lt;br /&gt;  K[] data;&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Default constructor; constructs a brand new ArrayStack just for you!&lt;br /&gt;   * It begins with room for five (5) elements.  Obviously it can grow as&lt;br /&gt;   * needed.&lt;br /&gt;   */&lt;br /&gt;  public ArrayStack() { this(5); }&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Custom constructor; constructs a brand new ArrayStack just for you!&lt;br /&gt;   * It begins with room for uint size elements.&lt;br /&gt;   */&lt;br /&gt;  public ArrayStack(uint size) {&lt;br /&gt;      assert(size!=0);&lt;br /&gt;      ensureCapacity(size);&lt;br /&gt;  } // public ArrayStack(uint size)&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Utility to ensure that the ArrayStack has room for uint capacity&lt;br /&gt;   * number of elements.  It will also perform a rebalance should it have&lt;br /&gt;   * enough space allocated but unavailable because it's stuck at the&lt;br /&gt;   * wrong end of the array.&lt;br /&gt;   *&lt;br /&gt;   * Please note that it is not a good idea to ensure a capactiy greater&lt;br /&gt;   * than four times the current because it will assume on the next&lt;br /&gt;   * push that it needs to shrink itself to prevent memory abuse.&lt;br /&gt;   */&lt;br /&gt;  public void ensureCapacity(uint capacity) {&lt;br /&gt;      assert(capacity&amp;gt;=r_bound-l_bound);&lt;br /&gt;      if(data.length&amp;gt;=capacity) {&lt;br /&gt;          // shrink if we're grossly over-large&lt;br /&gt;          if(data.length&amp;gt;=capacity*4ui) {&lt;br /&gt;              // simply create a new array, let the garbage men&lt;br /&gt;              K[capacity] new_data=data[l_bound..r_bound];&lt;br /&gt;              data=new_data;&lt;br /&gt;              return;&lt;br /&gt;          // if the space left on the back of the stack and the&lt;br /&gt;          // space already taken in the array minus the null&lt;br /&gt;          // space on the front of the array is&lt;br /&gt;          // greater or equal to the desired capacity...&lt;br /&gt;          if(data.length-r_bound+(r_bound-l_bound)&amp;gt;=capacity)&lt;br /&gt;              return;&lt;br /&gt;          else rebalance();&lt;br /&gt;      } // if(data.length&amp;gt;=capacity)&lt;br /&gt;      K[capacity] new_data;&lt;br /&gt;      /* for(uint i=0; i!=r_bound-l_bound; i++)&lt;br /&gt;          new_data[i]=data[i+l_bound]; */&lt;br /&gt;      new_data[0..r_bound-l_bound] = data[l_bound..r_bound];&lt;br /&gt;      data=new_data;&lt;br /&gt;      r_bound-=l_bound; // make r_bound compensate for space at the&lt;br /&gt;      // beginning of the array that is no longer taken&lt;br /&gt;      l_bound=0;&lt;br /&gt;  } // public void ensureCapacity(uint capacity)&lt;br /&gt;&lt;br /&gt;  public K pop() {&lt;br /&gt;      if(r_bound-l_bound==0) // empty stack&lt;br /&gt;          return null;&lt;br /&gt;      return data[l_bound++];&lt;br /&gt;  } // public K pop()&lt;br /&gt;&lt;br /&gt;  public void rebalance() {&lt;br /&gt;      if(l_bound==0) return;&lt;br /&gt;      if(r_bound-l_bound==0) {&lt;br /&gt;          l_bound=0;&lt;br /&gt;          r_bound=0;&lt;br /&gt;          return;&lt;br /&gt;      } // if (r_bound-l_bound==0)&lt;br /&gt;      for(uint i=0; i!=r_bound-l_bound; i++)&lt;br /&gt;          data[i]=data[l_bound+i];&lt;br /&gt;      r_bound-=l_bound;&lt;br /&gt;      l_bound=0;&lt;br /&gt;  } // public void rebalance()&lt;br /&gt;&lt;br /&gt;  public K peek() {&lt;br /&gt;      if(r_bound-l_bound!=0)&lt;br /&gt;          return data[l_bound];&lt;br /&gt;      return null;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void push(K e) {&lt;br /&gt;      if(data.length-r_bound==0)&lt;br /&gt;          ensureCapacity(data.length*1.5f);&lt;br /&gt;      data[r_bound++]=e;&lt;br /&gt;  } // public void push(K e)&lt;br /&gt;&lt;br /&gt;} // class ArrayStack(K)&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;What's wrong?  If you look closely it re balances itself to the front of the array.  What's up with that?  At the first &lt;span style="font-family: courier new;"&gt;push &lt;/span&gt;call it's going to have to move the whole dang data block over one.  Actually, I think it might just do the dumb thing and shift it over zero places and then overwrite the first element.  I only caught the error while reading over the code&lt;br /&gt;&lt;br /&gt;I think I was really trying to create a queue, which is quite humorous to me.  This is the second time I've tried to write one data structure and ended up writing something completely different.  I really need to do this when I have more cylinders firing.  But hey, at least it gives you some humorous code to read through.  I tend to think it's really nice code, if only it'd work.  I think I'll just throw the whole thing out and start anew.  I know so much more about D now that I really think I could do a much better job with a fresh start.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-5885079013552575476?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/5885079013552575476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=5885079013552575476' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/5885079013552575476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/5885079013552575476'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/coding-under-influence.html' title='Coding under the Influence'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-4984473660861527288</id><published>2008-01-24T20:30:00.000-08:00</published><updated>2008-01-24T20:38:13.595-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FSDEV'/><category scheme='http://www.blogger.com/atom/ns#' term='Tango'/><category scheme='http://www.blogger.com/atom/ns#' term='D'/><category scheme='http://www.blogger.com/atom/ns#' term='Joomla'/><title type='text'>Additional Site Features</title><content type='html'>Web applications suck.  Interesting, since I'm typing into one right now.  Just can't seem to break free from the Web 2.0 bubble.  GMail, Blogger, Picasa...  yet I have to roll my own development backend using a bunch of different things.  It's just not fair.&lt;br /&gt;&lt;br /&gt;I just put the &lt;a href="http://svn.fsdev.net/"&gt;Subversion repository browser&lt;/a&gt; back up.  It's far better than it was a year ago when I first used it.  I'm also moving the &lt;a href="http://forum.fsdev.net/viewtopic.php?f=7&amp;amp;t=3"&gt;basic development toolkit list&lt;/a&gt; to the Forum.  I don't think I'll put much into Joomla for a while longer, since no one seems to use it.  It's good for super-global site news at least.  Who knows, with the Joomla! 1.5 stuff in the community cooker who knows what cool tools will pop up?  &lt;a href="http://www.jfusion.org/"&gt;JFusion&lt;/a&gt; is one that's coming into its own, though it needs more work.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://f.fsdev.net/"&gt;phpBB&lt;/a&gt; is nice, far better than Fireboard.  I can't really blame Fireboard, however.  I respect the heck out of both development teams.  One just has a better product at the moment, that's all.&lt;br /&gt;&lt;br /&gt;Why did I futz around with all these web things?  Because no one has given me &lt;a href="http://www.dsource.org/projects/tango/forums/topic/350"&gt;direction&lt;/a&gt; in the Tango project.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-4984473660861527288?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/4984473660861527288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=4984473660861527288' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/4984473660861527288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/4984473660861527288'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/additional-site-features.html' title='Additional Site Features'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-7247158457225305720</id><published>2008-01-24T18:09:00.000-08:00</published><updated>2008-01-24T18:11:44.968-08:00</updated><title type='text'>Nothing Comes in Black</title><content type='html'>Man, nothing these days comes in black.  I had to change themes.  The code formatting just doesn't go well on a black background.  I'm not going to sit there and fiddle with the colors!  I know from my Digital Arts class that I cannot pick good colors to save my life.  I can tell when colors do &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; work together, so I guess I'm okay in that respect.  It just means I have to rely on more artistic people to pick them for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-7247158457225305720?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/7247158457225305720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=7247158457225305720' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/7247158457225305720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/7247158457225305720'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/nothing-comes-in-black.html' title='Nothing Comes in Black'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-2950522114150834328</id><published>2008-01-24T16:14:00.000-08:00</published><updated>2008-01-24T18:06:34.201-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='D'/><title type='text'>Computer Science Never Dies</title><content type='html'>What am I doing right now?  What I did last year in AP Computer Science: writing data structures.  It's good for getting into D.  Tango lacks any queues or stacks, so I figure I'll write 'em.  Right now I'm having comprehensional altercations with the &lt;span style="font-family:courier new;"&gt;opApply &lt;/span&gt;function, which I think just filters elements during iteration and removes elements from the structure itself.  I'm not quite sure though.  It's spread over multiple files and interfaces and implemented very differently in different classes.  Here's what I've got going so far:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;module tango.util.collection.LinkedQueue;&lt;br /&gt;&lt;br /&gt;private import tango.util.collection.impl.CLCell;&lt;br /&gt;&lt;br /&gt;private import tango.util.collection.model.Queue,&lt;br /&gt;               tango.util.collection.model.Iterator;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Standard Queue implementation using a Linked List (circular doubly-linked).&lt;br /&gt; *&lt;br /&gt; * No iterator yet written, until such time please use while(!peek) { ... }&lt;br /&gt; *&lt;br /&gt; * @author Chris Miller&lt;br /&gt; */&lt;br /&gt;public class LinkedQueue(K) : Queue!(K) {&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Head node for the circular list.&lt;br /&gt;     */&lt;br /&gt;    private CLCell!(K) head=null;&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Creates a brand-new LinkedQueue, all prepped and ready just for you!&lt;br /&gt;     */&lt;br /&gt;    public LinkedQueue();&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Pushes an element onto the (back) of the queue (first in, first out).&lt;br /&gt;     */&lt;br /&gt;    public void push(K e) {&lt;br /&gt;        if(!head) {&lt;br /&gt;            head=new CLCell(e);&lt;br /&gt;            return;&lt;br /&gt;        } // if(!head)&lt;br /&gt;        head.addPrev(e);&lt;br /&gt;    } // public void push(K e)&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Peeks at the element that a call to pop() will return.  Returns &amp;lt;b&amp;gt;null&lt;br /&gt;     * &amp;lt;/b&amp;gt; if there are no more elements in the queue.&lt;br /&gt;     */&lt;br /&gt;    public K peek() { if(!head) return null; return head.element(); }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Returns the element from the front of the queue and removes that element&lt;br /&gt;     * from the queue as well.&lt;br /&gt;     */&lt;br /&gt;    public K pop() {&lt;br /&gt;        if(!head) return null;&lt;br /&gt;        else if(head.next() is head &amp;amp;&amp;amp; head.prev() is head) {&lt;br /&gt;            K temp=head.element();&lt;br /&gt;            head=null;&lt;br /&gt;            return temp;&lt;br /&gt;        } // else if(head.left==head &amp;amp;&amp;amp; head.right==head)&lt;br /&gt;        K temp=head.element();&lt;br /&gt;        head=head.next();&lt;br /&gt;        head.prev().unlink();&lt;br /&gt;        return temp;&lt;br /&gt;    } // public K pop()&lt;br /&gt;&lt;br /&gt;    private class LQueueIter : Iterator!(K) {&lt;br /&gt;        public bool more() {&lt;br /&gt;            return peek()!=null;&lt;br /&gt;        } // public bool more()&lt;br /&gt;        public K get() {&lt;br /&gt;            return pop();&lt;br /&gt;        }&lt;br /&gt;        int opApply(int delegate (inout V value) dg) {&lt;br /&gt;            return 0; // no idea what this does, I'll just leave it blank&lt;br /&gt;        }&lt;br /&gt;    } // private class LQueueIter : Iterator!(K)&lt;br /&gt;&lt;br /&gt;    unittest {&lt;br /&gt;        LinkedQueue!(int) test1=new LinkedQueue();&lt;br /&gt;        // add integers&lt;br /&gt;        for(int i=-50; i!=51; i++) {&lt;br /&gt;            test1.push(i);&lt;br /&gt;        } // for(int i=-50; i!=51; i++)&lt;br /&gt;        for(int i=-50; i!=51; i++) {&lt;br /&gt;            assert(test1.peek()==i);&lt;br /&gt;            assert(test1.peek()==test1.pop());&lt;br /&gt;        } // for(int i=-50; i!=51; i++)&lt;br /&gt;    } // unittest&lt;br /&gt;&lt;br /&gt;} // class LinkedQueue(K)&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;How did I format the code for this blog?  I spent a long time screwing around and then when Googling found &lt;a href="http://formatmysourcecode.blogspot.com/"&gt;this&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-2950522114150834328?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/2950522114150834328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=2950522114150834328' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/2950522114150834328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/2950522114150834328'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/computer-science-never-dies.html' title='Computer Science Never Dies'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-6967252144382183602</id><published>2008-01-20T23:49:00.000-08:00</published><updated>2008-01-21T00:21:50.186-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='D'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='Kingdom Wars'/><title type='text'>Fresh Effort</title><content type='html'>I wrote code tonight.  It was exhilarating, almost like I was doing something I shouldn't be doing.  It was too much fun to be legal.  I haven't even gotten close to the good stuff, either.  I just read some documentation and wrote a special singleton wrapper on a hash map for the purpose of globally storing references to SQLite database connections.  It wasn't much at all, and I'm not even sure if it compiles yet, but it was &lt;span style="font-style: italic;"&gt;fun&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I haven't done any real coding in a long while.  I had a few false-starts in Java, and I think two more in C++.  D on the other hand is being a lot of fun.  I'm trying to isolate the why.&lt;br /&gt;&lt;br /&gt;I think it's because I know that D performs on the same level as C++, which really does a lot to assuage my fears of running into a language-imposed technology barrier to the full potential of the game I'm writing.  I'm a recovering Java programmer, and Java is so slow that it becomes completely necessary to make performance enhancements a kind of second nature.   One of my biggest pet peeves in Java is String concatenation.  Think of something like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;String command_buffer = "";&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;while(magic_command_maker.hasMoreCommands())&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;command_buffer += magic_command_maker.nextCommand();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I have personally run code profiles on stuff like that.  A String in Java is an &lt;span style="font-style: italic;"&gt;immutable&lt;/span&gt; type.  It cannot be changed.  The &lt;span style="font-family:courier new;"&gt;+=&lt;/span&gt; operator just makes a new String the same length as the sum of the length of the two original Strings and then copies the character arrays of the two.  That's slow.  It's a memory allocation every time you add, and it's also setting you up for at least one block of memory to free later on, assuming that the part of the application that sent that String might still need it.  That's a best-case scenario.  Once I had a program that was spending literally 98.7% of its execution time in String concatenation.  Crazy!&lt;br /&gt;&lt;br /&gt;So I've established that I look for slow code before seeing it run.  It's just a side effect of having known Java as well as I have.  On the Allegro forums I think my signature still warns that I'm a recovering Java programmer.&lt;br /&gt;&lt;br /&gt;Java isn't all bad, however.  One thing I loved about Java was the API that worked everywhere and did all the mundane things for you.  I didn't have to write and test large data structures outside of my computer science class.  I never wrote my own GUI library.  I have never tried to tokenize a String by hand.  I really liked that toolbox that allowed me to focus on my job: writing the application.&lt;br /&gt;&lt;br /&gt;C++ has a ton of libraries, and don't get me wrong, they're great.  I think Boost C++ is awesome, and it's portable.  However, I don't like C++'s concept of the header file.  I think it really muddies the water with a ton of junk that really isn't relevant.  I was finding that I understood C++ as a language exceptionally well, but I was having a lot of difficulty getting the environment set up so I could start writing.  C++ seems to have a build tool for every library.&lt;br /&gt;&lt;br /&gt;D isn't like that.  In D it's a lot more like Java with the whole concept of a package or module and then the idea that a programmer imports that namespace into scope.  It doesn't leave me grepping around for the file location and then re-verifying whether or not it's on the build path.  In D, if it's not found, that means it's either not typed correctly or it's not on the build path to begin with.  I find that to be a much more elegant solution and really simplifies the reason I'm there: to write software.&lt;br /&gt;&lt;br /&gt;If you're wondering what brought on my happiness, if you refer back to revision two at the &lt;a href="http://kw.fsdev.net/"&gt;Kingdom Wars repository&lt;/a&gt;, you'll find the file db_handler.d.  It's the best code I've gotten to write in a long time.  That's a big problem for me. but I'm not going to let this fail this time.  If I just think that I have critical mass, I will have critical mass.  It's all a mind game.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-6967252144382183602?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/6967252144382183602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=6967252144382183602' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/6967252144382183602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/6967252144382183602'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/fresh-effort.html' title='Fresh Effort'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-8382175241266189473</id><published>2008-01-19T18:44:00.000-08:00</published><updated>2008-01-19T19:56:59.494-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='D'/><title type='text'>Downsides</title><content type='html'>D is really being charming.  It's far simpler to read, plus it features most Object-Oriented features that I really appreciated about Java.  Arrays know their own length and the return of the &lt;span style="font-family: courier new;"&gt;foreach &lt;/span&gt;loop really got me going.&lt;br /&gt;&lt;br /&gt;Then I was reading the Tango documentation, sine I think Tango will win and Phobos will die, or Tangobos will beat them both.  Anyways, I was reading this Tango documentation and found the &lt;a href="http://dsource.org/projects/tango/wiki/ChapterThreading#UsingFibers"&gt;Fiber&lt;/a&gt; and got really excited.  A hypothetical use scenario popped into my head.  It involved something that should take place across multiple frames, and using the &lt;span style="font-family: courier new;"&gt;yield()&lt;/span&gt; functionality to make it behave nicely without needing a special remembrance variable.  I also wryly noted that it was similar to a Python Generator, though that might have been function-level as well.  Either way, it was really really cool.&lt;br /&gt;&lt;br /&gt;So far the real downsides of D are as follows:&lt;br /&gt;&lt;br /&gt;D doesn't come with a standardized Windows installer, so it's harder to get going.  There is a project on &lt;a href="http://www.dsource.org/"&gt;DSource&lt;/a&gt; that's supposed to do that, however, I don't think it works yet.&lt;br /&gt;&lt;br /&gt;D is only one letter.  Ever try taking that single letter to Google?  It's madness I tell you!  All the sites that talk about D just say "D," but in order to filter out all the unrelated sites you really need to search for "D Programming Language."  I suspect that there's a ton of other D resources out there that I'm not seeing because they're effectively inaccessible.&lt;br /&gt;&lt;br /&gt;D's Tango/Phobos war is really hurting it.  It takes them time to make the other libraries compatible with both Tangos and Phobos.  Some libraries (not many) won't work with Tango, others not with Phobos.&lt;br /&gt;&lt;br /&gt;I think that Digital Mars should just ditch Phobos altogether, since Tango is really superior.  Than again many argue that Phobos encourages a C++-style emphasis on individual programming solutions in much the same way that the STL encourages programmers to write code that is very specific to the problem they are solving.&lt;br /&gt;&lt;br /&gt;So despite my preference of Tango, if I were at Digital Mars and in the position to make the change, I'd probably do something with Tangobos.  Tangobos is a kind of fusion on Tango and Phobos, allowing both to be used.  They did have a slight conflict over differences in how the root Object is written, but that's not really unsolvable.  When and if they make Tangobos the default, I'd rename it Charon just for good measure.  If it weren't that I'm making a game and not a library I'd make Charon myself, but as it is I'm a little busy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-8382175241266189473?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/8382175241266189473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=8382175241266189473' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/8382175241266189473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/8382175241266189473'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/downsides.html' title='Downsides'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-7278110812453140914</id><published>2008-01-17T12:23:00.000-08:00</published><updated>2008-01-17T15:34:31.181-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='D'/><category scheme='http://www.blogger.com/atom/ns#' term='Kingdom Wars'/><title type='text'>Thoughts on D</title><content type='html'>I just randomly re-investigated using the language D to make Kingdom Wars.  D is a really nice language, and I like it a lot.  However, I don't think I want to work with it on Kingdom Wars.&lt;br /&gt;&lt;br /&gt;Delivering cross-platform compatibility is a primary goal of Kingdom Wars.  While D is technically cross-platform, I'm not sure I want to use it.&lt;br /&gt;&lt;br /&gt;D has two compiler variants, the Digital Mars D compiler (DMD) and the GNU D Compiler (GDC).  Both behave almost exactly the same way.  However, in order to use Allegro, ZLib, and SQLite3, I'd have to first compile those libraries into object files and then use them.  This requires writing the tutorial for making those libraries and then writing the book on how to get D on Windows and Linux.&lt;br /&gt;&lt;br /&gt;D on Windows I'm not sure about.  All the libraries need to be compiled using MinGW, since the Visual Studio method is a can of worms I'm really not interested in opening up again.  This means I'd have to get DMD to work with MinGW.  The only way I know of to get this to work (at the moment) is using a DLL file.  I'm not certain I know how to make MinGW compile a DLL file.  I'm not certain I can make Boost, which still refuses to compile for me, compile into a DLL file for D to use.&lt;br /&gt;&lt;br /&gt;I'm I'm using D, do I really need Boost?  That's an interesting question in and of itself requiring more investigation.&lt;br /&gt;&lt;br /&gt;D on Linux is a different story.  The last time I tried to get D on Linux I ran into a rather long tutorial involving compiling my own build of GCC.  Man that was painful.  I got about seven pages into the fifteen page tutorial and called it quits.  Apparently it's easier now.&lt;br /&gt;&lt;br /&gt;So now I go to the D Wiki and look through the various libraries and stuff.  There's an Allegro library for D, and a complete object-oriented SQLite3 library for D.  That really sold it to me, since I had a lot of issues with SOCI in C++.&lt;br /&gt;&lt;br /&gt;So now I'm certain I'm going to use D.  GDC, actually.  I don't want to know the number of subtle differences between DMD and GDC.  So it's GDC on MinGW and GDC on Linux and GDC on OS X all around.&lt;br /&gt;&lt;br /&gt;This still doesn't get me around a few other problems, but I'll take them when I get there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-7278110812453140914?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/7278110812453140914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=7278110812453140914' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/7278110812453140914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/7278110812453140914'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/thoughts-on-d.html' title='Thoughts on D'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-5181840562028755786</id><published>2008-01-15T20:59:00.000-08:00</published><updated>2008-01-15T21:17:18.312-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Boost'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Boost Me Up</title><content type='html'>Wow, this whole thing has become my little development blog.  I'll try something that's not programming related someday.  I think.  It's just what's on my mind right now (hence the "Mind of Sauron" title).&lt;br /&gt;&lt;br /&gt;Boost C++ doesn't like me that much.  It doesn't want to build for me.  I went through a long and painful process trying to get it to work.  I'm still in it, though right now I'm waiting for mailing list help.  I'm trying to write a good &lt;a href="http://www.fsdev.net/index.php?option=com_openwiki&amp;amp;Itemid=22&amp;amp;id=code:kw_programming#windows"&gt;set of instructions&lt;/a&gt; for people to follow if they want to build the game.&lt;br /&gt;&lt;br /&gt;I have already determined that Boost cannot be built without its little Jam utility.  That sucks.&lt;br /&gt;&lt;br /&gt;So I run around in circles, flooding my desktop with various things and having to delete them all.  I actually spent most of my time with ZLib, which did not want to work on MinGW, probably because the only way it ever works on MinGW is through cross-compilation on Linux.  I think.  I found a &lt;a href="http://gnuwin32.sourceforge.net/"&gt;lovely site&lt;/a&gt; which has compiled it already which makes life for me easier.&lt;br /&gt;&lt;br /&gt;Back to boost, I got this absolutely lovely process of downloading the Boost Jam package, and trying to make it go by using the odd little &lt;span style="font-family:courier new;"&gt;build.bat&lt;/span&gt; file.  It told me this, which made me unhappy:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family: courier new;"&gt;C:\USERS\LORDSA~1\DESKTOP\BOOSTJAM&gt;build.bat &lt;span style="color: rgb(255, 0, 0);"&gt;mingw&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new; color: rgb(255, 102, 102);"&gt;###&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new; color: rgb(255, 102, 102);"&gt;### Using '&lt;span style="color: rgb(255, 0, 0);"&gt;msvc&lt;/span&gt;' toolset.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new; color: rgb(255, 102, 102);"&gt;###&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;C:\Users\LORDSA~1\DESKTOP\BOOSTJAM&gt;rd /S /Q bootstrap&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;C:\Users\LORDSA~1\DESKTOP\BOOSTJAM&gt;md bootstrap&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;C:\Users\LORDSA~1\DESKTOP\BOOSTJAM&gt;cl /nologo /GZ /Zi /MLd /Fobootstrap/ /Fdbootstrap/ -DNT -DYYDEBUG kernel32.lib advapi32.lib user32.lib /Febootstrap\jam0  command.c compile.c debug.c execnt.c expand.c filent.c glob.c hash.c hdrmacro.c headers.c jam.c jambase.c jamgram.c lists.c make.c make1.c newstr.c option.c output.c parse.c pathunix.c regexp.c rules.c scan.c search.c subst.c timestamp.c variable.c modules.c strings.c filesys.c builtins.c pwd.c class.c w32_getreg.c native.c modules/set.c modules/path.c modules/regex.c  modules/property-set.c modules/sequence.c modules/order.c&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;'cl' is not recognized as an internal or external command, operable program or batch file.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;C:\USERS\LORDSA~1\DESKTOP\BOOSTJAM&gt;g++&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;G++: no input files&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;C:\USERS\LORDSA~1\DESKTOP\BOOSTJAM&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;div id="1flw" class="ArwC7c ckChnd"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div id="1flw" class="ArwC7c ckChnd"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;I hope you can see why it made me unhappy.  For some reason it thinks that I'm using Visual Studio.  Bleh!&lt;br /&gt;&lt;br /&gt;I hope to hear back from the boost-users mailing list tomorrow morning, which will leave me antsy all through school, since I'll want to go home and see if it works.  That's life though.&lt;br /&gt;&lt;br /&gt;I'll get over it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-5181840562028755786?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/5181840562028755786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=5181840562028755786' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/5181840562028755786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/5181840562028755786'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/boost-me-up.html' title='Boost Me Up'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-7109647822114688698</id><published>2008-01-15T14:21:00.000-08:00</published><updated>2008-01-15T14:41:18.625-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Boost'/><category scheme='http://www.blogger.com/atom/ns#' term='Kingdom Wars'/><title type='text'>Options and Arguments</title><content type='html'>So now I know how I'll save objects.  I'll just write a special serialization handler which will translate everything to a SQL statement.  There's obviously more work to be done under that problem but I'll work on that later when I make it to the point where I'll have some data sets to work with.&lt;br /&gt;&lt;br /&gt;Now I'm going way back, right to where the application starts.  I was thinking about command-line arguments, specifically in the light of the Boost options library, which parses command-line arguments into a map for easier command-line functionality.  It also has the capability to parse configuration files from disk.  I got the great idea of saving all persistent user settings to a configuration file in the user's home directory, right under the Kingdom Wars application data directory.  This would be &lt;span style="font-family: courier new;"&gt;~/.kw&lt;/span&gt; in Linux, or something like &lt;span style="font-family: courier new;"&gt;C:\Users\MyUser\kw&lt;/span&gt; in Windows Vista.&lt;br /&gt;&lt;br /&gt;So I then got this crazy idea of parsing from &lt;span style="font-style: italic;"&gt;both&lt;/span&gt; the command line and the configuration file.  Then I went a little nuts and thought of doing it in three places.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;./ which is to say the location of the application binary.  A configuration file here could define settings that aren't going to change from user to user.  I haven't actually thought of any settings yet, but I suppose things like the URL of the Kingdom Wars master server would go here.  These settings would be parsed first and thrown into a options map.&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;~/.kw&lt;/span&gt; which is to say the configuration file in the user's home directory.  The configuration file here could control user-specific stuff, like what resolution to run at, online nick-name, and a target directory for screenshots, among other things.  These settings would be written to the &lt;span style="font-style: italic;"&gt;same&lt;/span&gt;&lt;span&gt; configuration map after parsing, overwriting settings from the global configuration and adding other settings specific to that user.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Command line arguments.  These are launch-specific settings, which probably won't be used as often.  Windows users might, however, since it's possible to specify persistent command-line arguments in Windows Explorer.  Every time you double-click, it's run with those settings.  Otherwise it'd be a nice development tool to be able to specify those settings via command-line, as opposed to hacking the configuration files left and right!&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;So then how to save those configurations?  Obviously the configuration settings in the application directory, which we'll assume we can't write to because it's either Linux (not root) or Vista (UAC popups everywhere).  We'll just save to the configuration file in the user's directory all the time.  What then about command line arguments?  Won't those be written as well?&lt;br /&gt;&lt;br /&gt;Yes.  I don't think that's a big problem, however.  Users who save their configuration settings are probably really expecting to save the current settings because they work.  The command line setting is more to allow people to recover from errors like a bad resolution or something like that.  Rather than track down the configuration file, they can just run something like &lt;span style="font-family: courier new;"&gt;./kingdomwars -Xres 1024 -Yres 768&lt;/span&gt;, which is a lot easier than the usual gambit of &lt;span style="font-family: courier new;"&gt;ls -la ~/ | grep "kingdom wars"; ls -ls ~/ | grep "kw"; ls ~/.kw/*.conf&lt;/span&gt; and so on and so forth.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-7109647822114688698?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/7109647822114688698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=7109647822114688698' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/7109647822114688698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/7109647822114688698'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/options-and-arguments.html' title='Options and Arguments'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-3542921578251903783</id><published>2008-01-14T09:50:00.000-08:00</published><updated>2008-01-14T10:02:28.737-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='Kingdom Wars'/><title type='text'>Object Serialization</title><content type='html'>My suspicions are confirmed.  &lt;a href="http://www.boost.org/libs/serialization/doc/index.html"&gt;Boost's serialization&lt;/a&gt; is not magical.&lt;br /&gt;&lt;br /&gt;It works by declaring boost::serialization::access as a friend of the class that needs to be serialized, and then you need to use a stream to write an external function that can serialize the data you want.&lt;br /&gt;&lt;br /&gt;Overall, I like it a lot.  It makes a lot of sense and I see where it will save me a load of time.  Boost automatically handles the problem of word size when making a binary serialization, and also allows for XML serialization as well.&lt;br /&gt;&lt;br /&gt;Boost also handles versioning, making it simple to still be able to use serialization from old versions.  I can't fathom having to toss out a MMO's player database because I can't read in old serializations.  That's be depressing and lame.&lt;br /&gt;&lt;br /&gt;Serialization in Boost also handles tracking down pointers.  Thank God, that was a problem I was on the verge of loosing sleep over.  Of course, this means I'm still going to have a lovely time organizing all the various serializations, however, that's a lot easier than having to invent object serialization as well.&lt;br /&gt;&lt;br /&gt;So how will this work?  I think I need to carefully divide data into two groups.  The first group is data that is runtime-specific, like a pointer to a image in memory or something like that.  The second group is persistent data, such as how much health and mana a character has.  The runtime-specifics need to be regenerated when the runtime changes, but they can't be regenerated meaningfully without the persistent data.  I mean, you could regenerate the runtime specifics, but it every time you did that everyone got back all their health it'd be rather curious.&lt;br /&gt;&lt;br /&gt;Thank you Boost for solving a billion problems so I can solve the other billion.  It's nice to be able to write games and not support libraries!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-3542921578251903783?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/3542921578251903783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=3542921578251903783' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/3542921578251903783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/3542921578251903783'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/object-serialization.html' title='Object Serialization'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-880066300654395006</id><published>2008-01-14T08:54:00.000-08:00</published><updated>2008-01-14T09:38:29.798-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Kingdom Wars'/><title type='text'>Rethinking the Starting Point</title><content type='html'>I wiped the Subversion repository to clear the way from the folly of the SOCI library.  I'm going to have to interface with SQLite directly now.&lt;br /&gt;&lt;br /&gt;I probably shouldn't be using SQL to begin with, however, I think it's a better idea for a few reasons.  First off, SQL will give me faster load times.  Second, by using SQL from the get-go, it'll be quite natural to re-translate all the SQLite3 query strings to MySQL, Postgre SQL, or Oracle SQL strings when I add the really big MMO server.&lt;br /&gt;&lt;br /&gt;I also took the opportunity to mess with USVN, which didn't work too well.  I'd imagine that I could build a Subversion/Joomla bridge using code snippets from USVN and just accepting that all I can do is edit users in Subversion, but that'd require brushing up on my PHP and learning how to write Joomla components.  I'm hoping I can avoid doing that myself!&lt;br /&gt;&lt;br /&gt;So then I run into the dilemma of how to handle object serialization, since that's a critical part of network communication.  Quite frankly, I haven't begun to read about that yet.  I think I can implement and use the Boost library's serialization stuff, but I'm only guessing.  I don't even know whether it's a framework or a magical end-all solution ready for use.   I'm assuming it's the former, and not the latter.&lt;br /&gt;&lt;br /&gt;As for the raw act of serialization, I'm certain that I want binary serialization and not something different like serialization to a XML object file.  This does raise an interesting problem.  What if the server has a different word size than the client?  That'd mess up the whole process.  Or perhaps that's some of what Boost's serialization stuff is supposed to mitigate?&lt;br /&gt;&lt;br /&gt;Finally, why serialize?  When the client first connects to the server there will already be other players and NPCs in the world.  By sending a normal state change message to the client we create a situation where the server is effectively talking about game objects that the client doesn't know about yet.  So the client has to send requests to the server to ask about the unknown objects.  The server should respond with the object serialization of the object in question, so that the client can take that object and insert it into the game state without needing to do things like construct the object.&lt;br /&gt;&lt;br /&gt;Using a binary serialization should allow us to simply create void space in a data structure and then blit the serialization over to it.  In theory.  I think it's a lot more complex than that, however, the best way to solve this problem is the make the simplest solution possible and then add complexity as needed.  After all, isn't it Occam's Razor that states that the simplest solution is the right one?  In this case, the simplest solution is going to be the fastest one.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-880066300654395006?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/880066300654395006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=880066300654395006' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/880066300654395006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/880066300654395006'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/rethinking-starting-point.html' title='Rethinking the Starting Point'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-4764313991127770162</id><published>2008-01-11T14:28:00.000-08:00</published><updated>2008-01-11T14:52:28.558-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='FSDEV'/><title type='text'>Almost There</title><content type='html'>For those who don't know, I've been almost obcessively consolidating all FSDEV authentication credentials into Joomla.  If it won't bridge, it goes.  Streber-PM is now considered inactive by me, and only still exists so I can migrate existing data in Streber-PM to Joomla, one way or another.&lt;br /&gt;&lt;br /&gt;Subversion has been an annoying sticking point in this process because of the way it's set up by DreamHost.  Thankfully it uses a simple .access file in the subversion directory, so I could write a bridge that mangles that directly.  That'd require mitigating the hash technique.  Subversion uses a shorter hash, an MD4 I think, and Joomla uses a SHA64.  By rights they should all use a WHIRLPOOL due to the near impossibility of hashing collisions, however, that's a bit off-topic.&lt;br /&gt;&lt;br /&gt;Luckily I found an interesting Subversion web interface called USVN, which administers the repository almost precisely the way I need it to.  Ideally I'd like to use the Tigris project management package but that needs Java Enterprise Edition and VMWare Player, both of which DreamHost is not interested in providing.  Given the implied memory usage, I have to agree with them.&lt;br /&gt;&lt;br /&gt;USVN represents an important step for my problem, specifically creating a PHP mechanism capable of interfacing with the Subversion repository.  All I have to do now is find out how to write a Joomla/USVN bridge that will have Joomla strong-arm the USVN software into Joomla's user tables.  From there I could simply add rights for specific users to the different projects in the various repositories.&lt;br /&gt;&lt;br /&gt;From there I think I could evolve that into another tool, which would be a bridge API that could allow me to script proceedures that would allow me to click a button from the Joomla administration interface and give rights to users depending on a more global status.&lt;br /&gt;&lt;br /&gt;For instance, all developers should have advisor status on the Web Amebeoa support ticket system.  Programmers (who are also developers) need Subversion write access as well.  All need to have their Fireboard ranking status changed to "Developer."  Rather than me run all over the administration tools and make each change by hand every time a new developer is inducted, I could write a little script that would do something like:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;rights_change($joomla_user_id, $global_rights_template["developer_programmer"]);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Which would theoretically execute a function stored in the array &lt;span style="font-family: courier new;"&gt;global_rights_template&lt;/span&gt; at index &lt;span style="font-family: courier new;"&gt;"developer_programmer"&lt;/span&gt;, which would do something along the lines of this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;$com_fireboard-&gt;set_rank($com_fireboard-&gt;joomuser_to_fireboard_user_lookup($joomla_user_id), $com_fireboard.ranks["developer"]);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;$com_usvn_bridge-&gt;change_rights($joomla_user_id, "read+write");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;$com_wats-&gt;set_rites($com_wats-&gt;joomuser_to_wats_user_lookup($joomla_user_id), "advisor");&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And so on and so forth.  Yes, my PHP is very rusty.  I don't know the exact APIs for those components, so I was rather guessing how it would be done.  I think Joomla should start enforcing a global rights system so that global rights templates can be created.  This would require plugins to integrate with that and implement an interface or agreement to respond to certain signals.  That way many different unrelated user rights could be controlled without an admin manually running all over the site backend all day.  It's an IT solution to a problem of boring stupid work.&lt;br /&gt;&lt;br /&gt;Will I ever do this?  Probably not.  I'll probably just wait until I can find some PHP guy who can do it for me and try and convince him to do it.  I'm not an IT weenie, or at least I try not to be, so I can get back to what I really need to be doing: coding a game.  Not a site.  But the game won't happen without a working site to facilitate team collaboration.  Crazy...  It's like I need to be about four different kinds of coder.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-4764313991127770162?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/4764313991127770162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=4764313991127770162' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/4764313991127770162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/4764313991127770162'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/almost-there.html' title='Almost There'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-6665841204055775232</id><published>2008-01-10T14:46:00.000-08:00</published><updated>2008-01-10T15:07:59.195-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XFire'/><category scheme='http://www.blogger.com/atom/ns#' term='Kingdom Wars'/><title type='text'>Improving Upon the Timeless</title><content type='html'>I was pondering the best way to implement a clan system for Kingdom Wars, rather simultainiously with other things, but I'm writing about it in different posts for coherency's sake.  If I did a raw brain dump I think the Internet itself would explode for the lack of coherency.  The mind is maddeningly literal, yet still extremely symbolic.&lt;br /&gt;&lt;br /&gt;Now that I've finished with my paradox, to clans.  Something I want for Kingdom Wars is for it to be better than every other game, and to incorporate improvements and features I think should have been in other games.  One thing that bugged me about other games is the clan features.  They either don't have 'em, or it's not very good.&lt;br /&gt;&lt;br /&gt;For instance, &lt;span style="font-style: italic;"&gt;Age of Empires III&lt;/span&gt;.  It has the best clan support I've seen yet from a strictly in-game point of view.  It has ranks, something that behaves like a message board, and it automatically prefixes the clan tag.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Shaiya&lt;/span&gt; had better ranking support, even though about four of the ranks were completely identical in rights.  If you're going to have identical rights in a ranking system, make sure there's some perk that's better than a simple numerical ranking.  Moving from six to five should be more exciting than a geometry class.&lt;br /&gt;&lt;br /&gt;In all fairness, I haven't yet tried the &lt;span style="font-style: italic;"&gt;Guild Wars&lt;/span&gt; clan system yet.  I'm still new there, and haven't yet joined a guild.  Hopefully it will supplant AOE3 as best clan support, but I'm not keeping my hopes up.&lt;br /&gt;&lt;br /&gt;So I got to thinking about what I want for the social tool that clans are.  A in-game clan ends up being limited to one game.  This is bad in my opinion, because the only way for players to network is in the game.  Clans where every member discloses their email, or their XFire name, or their MSN, or anything else like that, tend to come at a higher premium because the community is more valueable.  Clans that refuse social networking are more temporary and don't last as long.  I outlived three clans in &lt;span style="font-style: italic;"&gt;Last Chaos&lt;/span&gt; before I went inactive and resigned my fourth clan because I wouldn't be on enough to really feel myself a part of the group.&lt;br /&gt;&lt;br /&gt;Why would I feel left out?  I think it's because I couldn't communicate with my comrades and be there for them.  I would be taking up space in the guild, but not giving back.  How would I remedy this syndrome in Kingdom Wars?&lt;br /&gt;&lt;br /&gt;It's obvious that the solution is to have a mechanism to communicate with clan members from outside of the game.  This implies a link between the game clan chat and some external chat program.  Applications like Meebo and Trillian demonstrate the ability to bridge different communication mediums every day, so why not take some open-source tool and reverse-engineer it?  I'm charging for server connectivity and bandwidth, not the game itself, so I can legally do that under the GNU General Public License.  How I charge for that bandwidth is up to me.  I can charge up front like &lt;span style="font-style: italic;"&gt;Guild Wars&lt;/span&gt;, or I can charge per month.  I suppose that any pay-to-play MMO could be open-source.  You'd have to be insane to try and run an alternate server cluster for less than the original developers can deliver it.  Plus, if the original developers don't get their money, they can't build the product, so you're left with a orphaned product.  Not good business sense.  Open Source really is open for business.&lt;br /&gt;&lt;br /&gt;Back to game communication.&lt;br /&gt;&lt;br /&gt;I like the XFire clans and guilds tool.  I think it's a good idea to link people across games.  If I can, I'm going to have XFire be the transport mechanism for person-to-person in-game chat.  Then I can write a web-facing AJAX chat client for users logged into the website.  Kingdom Wars clans and guilds could be totally XFire based.  That'd be nice, since then I wouldn't have to write all the clan features myself, only write interfaces to them so that they could be manipulated from within the game.&lt;br /&gt;&lt;br /&gt;From there my only concern is that there would be too much of a risk of naming collisions with existing XFire clans.  However, it'd facilitate the ability of clans to span multiple games without the players having to go through the routine of "so who's gonna set up the clan site?"  No money for domains, nothing.  Of course, the XFire people might get a little annoyed, but that's life.  XFire was a shortcut, not a necessity.&lt;br /&gt;&lt;br /&gt;I also have a long list of other things I'd like the clans to be able to do, one of the biggest being a voice chat that can translate to typed text for the benefit of users that don't have microphones.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-6665841204055775232?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/6665841204055775232/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=6665841204055775232' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/6665841204055775232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/6665841204055775232'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/improving-upon-timeless.html' title='Improving Upon the Timeless'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-3123304687332160270</id><published>2008-01-10T12:16:00.000-08:00</published><updated>2008-01-10T12:29:51.826-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='Joomla'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Kingdom Wars'/><title type='text'>Pondering Application Ecosystem</title><content type='html'>I was thinking through the move from a standalone game to a MMO in the development cycle and ran into an interesting issue.  How will the game integrate with FSDEV.NET and Joomla?  Obviously I want people to have to register through Joomla, which has e-commerce built into it.  It also provides a good platform for offering support and general user forums, as well as it verifies that it's actually a human registering and not some robot (through email verification and later a catchpa).&lt;br /&gt;&lt;br /&gt;So, the Kingdom Wars server will login users against their username and password hash stored in Joomla.  I don't think it wise to try and access the database directly, since that would imply that Joomla would access KW databases directly.  I don't think that's a great idea since that could cause problems, specifically if something needs to be checked by the KW server before it can be input into the database.  The key to the UNIX architecture of good data in good data out is to prevent the bad data, and if the KW server can throw an exception before some bad data gets into the database, that's good.  I can then treat the database as a data source with higher trust rating, which means less parsing and access checking, which translates directly into speed and reduced costs.&lt;br /&gt;&lt;br /&gt;In the end every user needs to be represented in the KW database as some form of symbolic link to the user table from Joomla.  I don't know if foreign keys can span different database connections in SQL of the top of my head, so this is sort of going out on a limb.&lt;br /&gt;&lt;br /&gt;So I've established that the different applications do not have write access to the other's databases, and that they should contact the application and not the database for all data with a few exceptions.  This raises another problem: bridging C++ and PHP.&lt;br /&gt;&lt;br /&gt;I'm not fond of PHP.  It's a powerful language with many useful features and it's fun to work with, but I don't like the syntax as much and the lack of explicit type-checking scares me.  I keep having waking nightmares of incompatible types being used incorrectly and strange bugs in large projects forming a sort of &lt;span style="font-style: italic;"&gt;Kobayashi Maru&lt;/span&gt; scenario dooming me to a sick kind of mythological punishment by continuously working on an impossible project.  Reminds me of that poor bloke who's forever stuck rolling a boulder up a hill, but whenever he gets near the top it falls right back down and he has to start over again.&lt;br /&gt;&lt;br /&gt;Interesting problems, trying to bridge languages, servers, and potentially database types.  Sounds like fun, don't it?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-3123304687332160270?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/3123304687332160270/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=3123304687332160270' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/3123304687332160270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/3123304687332160270'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/pondering-application-ecosystem.html' title='Pondering Application Ecosystem'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-4233856378430923102</id><published>2008-01-09T17:27:00.000-08:00</published><updated>2008-01-09T17:44:57.720-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FSDEV'/><category scheme='http://www.blogger.com/atom/ns#' term='Kingdom Wars'/><title type='text'>Thinking about Object Serialization</title><content type='html'>As I moved into Joomla, nearly all work on Kingdom Wars came to a standstill.  SOCI wasn't behaving, and I was looking at the possibility of having to hand-compile a MinGW build of SOCI.  I still hope to someday write enough scripts to get the game working to the point that I can cross-compile the whole smash on the webserver using GCC and some clever bash scripts.  I think I'll need to buck up and learn how to write makefiles though.  SOCI's near refusal to compile doesn't bode well for that vision of an automated future.&lt;br /&gt;&lt;br /&gt;KW changed to a MMO-RPG because I began thinking about the amount of bandwidth needed to communicate a RTS between tens of thousands of potential connected users.  I'm not even sure the network and processing technology yet exists to coordinate all those game states.  I'm sure some clever load balancing by districting different map locations to different servers could do it, but I'm not sure I can deploy that many servers.  I also don't know if all those active connections between the client and the various servers would begin taxing the client system resources for networking stack tasks.  It would require a great deal of careful case studies.&lt;br /&gt;&lt;br /&gt;RPG's are simpler, and so Kingdom Wars v1.0 morphed into one.  I hope to revive the vision of a MMO-RTS for a later title.  Before I make either of them an MMO, I have to build them single-player.  This involves my dreaded topic: saving the game.  I've so far established that a save game would be the serializations of all the applicable in-game objects necessary to restore the game state and then re-attach the game views (AI and Human).  From there it's as simple as adding multiplayer support.  That adds networking, and thus lays down the core behavior of what will become client-server communication standards in the final release.  It'll provide a good local playground to test it, and it'll allow me to hook the test machines up using hubs and not switches, so I can use Wireshark on a third computer to sniff the traffic and look for anachronisms.&lt;br /&gt;&lt;br /&gt;This also breaches another topic.  I want KW to have the best clan-support of any game there is.  I want KW to have a web-facing aspect so there's a forum and clan pages in addition to the general game forum.  All the users need to be registered through Joomla anyways, so they can use the support ticket system.  I'm not writing all this infrastructure by hand, and Joomla represents a reasonable springboard to writing a more comprehensive application ecosystem.&lt;br /&gt;&lt;br /&gt;Overall I'm still excited as heck about KW and then Sovereign Crusades, since there's a lot of hard problems to solve, and a lot of glory to be had in them.  There hasn't been a SVN commit in a while, but that's okay.  They say 2008 is going to be the year of incompatibility between social networking sites.  If I build my games with a decent web-facing SDK, I could possibly hitch a ride on the social networking information highway to proliferate KW and SC.  Wouldn't that be neat?  A game where the friends you make in it are still contactable outside of it, without you having to pointedly ask "What's your MSN dude?"&lt;br /&gt;&lt;br /&gt;I would say "Welcome to Tomorrow," but it's not here yet.  I guess I'll have to run off to my Vulcan's forge and hammer it out if I want to enjoy it.  It's stuff like this that makes the job fun.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-4233856378430923102?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/4233856378430923102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=4233856378430923102' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/4233856378430923102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/4233856378430923102'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/thinking-about-object-serialization.html' title='Thinking about Object Serialization'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-7244696638232252591</id><published>2008-01-02T11:30:00.000-08:00</published><updated>2008-01-02T11:42:48.596-08:00</updated><title type='text'>Software Design</title><content type='html'>Stroll around the world of software long enough and you notice the subtle signatures of people trained to code from different countries.  US trained engineers build large, extensible, slow, and relatively mediocre systems.  Engineers trained in India tend to build smaller, lighter, faster, and less extensible solutions.  My recent beta testing experiences with the junk from Aeria Games and Entertainment has introduced me to the distinctive signature of Korean programmers: there will never need to be a port to a non-Asian language.&lt;br /&gt;&lt;br /&gt;First off, I don't dislike Asians.  We have significant cultural differences which does in fact distance us on a matter of principle.  Some of the lude crud I found in the beta test scared me straight into Guild Wars.  Apparently it's considered acceptable over there.  It's not my position to tell them how to live, it's only my right to tell them where I draw my line.&lt;br /&gt;&lt;br /&gt;Aside from that, however, were the translation errors.  They were all over the place.  I was shocked, since I can't imagine how so many errors came to be.  It's like they had some English 101 student with a Korean/English dictionary do it all by hand.  I don't think an online translator would work well due to all the game-invented nouns.   However, what where they thinking?  When you build a system as large as a game, you never hard-code the strings into the application!  Never!  You keep them in a string database!  Simple stuff, common sense, &lt;span style="font-style: italic;"&gt;not that hard!&lt;/span&gt;  Had they done that, they could have put a bid out on RentACoder or something to have someone who's an &lt;span style="font-style: italic;"&gt;interpreter&lt;/span&gt; change all the strings, probably with better results than anything else.&lt;br /&gt;&lt;br /&gt;What happened instead?  About 80,000 volunteer beta testers, myself included, had to read every painful paragraph and try to guess what the original meaning was.  Crazy.&lt;br /&gt;&lt;br /&gt;My first impression of the Korean signature: build it to work, who cares if we need to make it do more later!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-7244696638232252591?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/7244696638232252591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=7244696638232252591' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/7244696638232252591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/7244696638232252591'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2008/01/software-design.html' title='Software Design'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-6800158247171310801</id><published>2007-05-21T13:18:00.000-07:00</published><updated>2008-01-10T17:10:11.360-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Eclipse and NetBeans - Equals?</title><content type='html'>I recently took the stance of asserting that NetBeans and Eclipse were relatively equal IDEs.  They both have good GUI editors, both have advanced code refactoring tools, and both are very expandable via installable add-ons.  I thought that they were both equal.&lt;br /&gt;&lt;br /&gt;I was very, very stupid.&lt;br /&gt;&lt;br /&gt;After more work with NetBeans, it became really obvious to me that NetBeans' GUI editor is superior to Eclipse's Visual Editor in many ways, primarily in its ability to space Swing components like Visual Studio does.  I still believe that the GUI Editor in NetBeans is better than the Eclipse VE, though it is a very close contest.&lt;br /&gt;&lt;br /&gt;My massive displeasure with NetBeans came when working to get some SwingWorkers working to enable a multithreaded GUI.  NetBeans has comparatively nasty editing capabilities when compared to Eclipse, which seems born to have people type code into it.  NetBeans was clunky and annoying from day one.  I don't change things from their default settings all that often except to enforce coding standards (80-character wide, tab width of 4, etc.) so I'm critiquing things on their default settings.&lt;br /&gt;&lt;br /&gt;I didn't mind the decreased functionality of NetBeans for the most part.  I can live without having the space between the left parenthesis and the right curly bracket inserted for me.  Then I tried to use an Event to capture property changes from a SwingWorker in order to have it update a progress bar.  The event was necessary because the Worker thread is on the Swing thread group and won't yield to the system in order to update the graphics.  Something nasty happens in the event delivery system and things just don't work properly.&lt;br /&gt;&lt;br /&gt;So I've got this event, and the tutorial instructed to use a specified field in that event object to get the new value for the progress bar.  Imagine my curiosity when the NetBeans content assist told me that the field didn't exist.  My application wouldn't compile.&lt;br /&gt;&lt;br /&gt;I checked the Java Documentation and double-checked my version of Java.  That field should be there.  I opened up Eclipse and made a dummy event object and Eclipse told me that the field was there.&lt;br /&gt;&lt;br /&gt;NetBeans, for whatever reason, wasn't compatible with Sun's Java Standard Edition version 6.  Disgusted, I rebuilt my application in Eclipse in the matter of two hours and was essentially done.  Most of those two hours were spent messing with layout managers to try and see if I could get the GUI to layout nicely using a off-the-shelf layout manager so I could make the JFrame resizable, something that I couldn't make work in NetBeans.&lt;br /&gt;&lt;br /&gt;So from this perspective, Eclipse is better than NetBeans, though only slightly.  However, I already had a personal preference for Eclipse, so that basically solidified me as an Eclipse user.&lt;br /&gt;&lt;br /&gt;Sure, there are things in Eclipse that I don't like.  I don't like this whole "Working Set" thing, and I don't like how difficult it is to profile code (I don't read the tutorials, so I really have only myself to blame).  However, Eclipse is line for line a better IDE, and Sun would do well to realize that people use NetBeans only because Sun endorses it.  Those developers who build real applications use Eclipse.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-6800158247171310801?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/6800158247171310801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=6800158247171310801' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/6800158247171310801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/6800158247171310801'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2007/05/eclipse-and-netbeans-equals.html' title='Eclipse and NetBeans - Equals?'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-3758332783242770627</id><published>2007-05-09T13:15:00.000-07:00</published><updated>2008-01-10T17:09:23.709-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Java Swing - The Undead GUI Toolkit</title><content type='html'>I've seen a lot of really dumb things while programming.  However, Java's Swing GUI toolkit has today become the single dumbest thing I've ever seen.&lt;br /&gt;&lt;br /&gt;I hate Swing so much because it is so good, yet so bad.  What's bad about Swing?&lt;br /&gt;&lt;br /&gt;Concurrency.  Swing is not thread-safe.  It's not possible to make a multi-threaded Swing application without using a SwingWorker, which is a thread with some major madness in the mix.  Why do I hate that?&lt;br /&gt;&lt;br /&gt;The SwingWorker on paper is a good idea.  It's a thread which extends an abstract class which allows that thread to deliver events to the Swing event system, which allows the SwingWorker thread to be interrupted to perform things like updating the progress of a progress bar or painting the rollover image of a button, or even canceling the SwingWorker thread because of input from the user.  On paper, it's a wonderful idea to save Swing from its inability to behave nicely with the normal java.lang.Thread which we all know and love.&lt;br /&gt;&lt;br /&gt;SwingWorker, however, fails.  There are two distinct things I've seen that SwingWorker tries to do.  Its first function is to be a single Thread which will return a result at the end of the thread's execution without any interaction in the between time.  The other is to be a constantly updating thread which during its execution will periodically post an Integer value to the Swing GUI system to update a progress bar via the PropertyChangeListener.&lt;br /&gt;&lt;br /&gt;The first purpose I find logical and have successfully used.  It performs exactly as it's supposed to, no questions asked.&lt;br /&gt;&lt;br /&gt;The second is annoying because it's strictly for a progress bar and that only, with results to be displayed at the end of the process.  While that could be useful, I don't like it because it collides with the third use which is what I imagine most programmers will want most of the time.&lt;br /&gt;&lt;br /&gt;The third function which I'm unable to use is the ability to have the thread publish periodic chunks of data to the GUI.  This is a lot like publishing a simple Integer to the GUI to update the progress bar, however, it also publishes all kinds of data in addition to be updated along with that progress bar.&lt;br /&gt;&lt;br /&gt;I know that everyone right now is thinking something similar to "I've seen Swing applications do exactly what you're complaining you're having difficulty with!"  I've seen those things as well.  So why can't I get it to work at all?&lt;br /&gt;&lt;br /&gt;First of all, this is where I have my beef with Swing right now.  The SwingWorker thread class is wonderful except it tries to do all three of the capabilities which I have outlined.  This creates a very cluttered class which is very difficult to use, especially for a bonehead like me.  What would I do differently?&lt;br /&gt;&lt;br /&gt;I think I would have designed the whole Java event system differently from the ground up, probably using more reflection and runtime type checking instead of the String-based messaging system currently in use.  However, I also think that is more of a matter of taste and not really relevant.  Focusing in on SwingWorker, I would love to see SwingWorker split into three more abstract classes.  One for that single process which only needs to interact with the GUI once it's done.  One for the process which publishes regular Integers to that progress bar.  And one for the process which publishes data.&lt;br /&gt;&lt;br /&gt;You see, I think that the current SwingWorker is very cluttered with all three of those tasks.  It's very difficult to piece together how it's all supposed to fit together even when drawing from both the Java API Documentation and the extensive Java Tutorials on Sun's website.  Quite simply, I think that the current (current being Java 1.6) SwingWorker is too cluttered and confused for a person new to concurrency in Swing to easily use to make a functioning product.  That's I've spent three days now trying to get my business logic thread to play nice with the GUI is absolutely unacceptable.&lt;br /&gt;&lt;br /&gt;So, for the record, here's what I'd like to see happen, in order of desirability:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Swing be made totally Thread-safe, like AWT&lt;/li&gt;&lt;li&gt;SwingWorker be split into three specialized versions&lt;/li&gt;&lt;li&gt;SwingWorker be better documented so newcomers can experience more success&lt;/li&gt;&lt;/ol&gt;If Swing is so bad, then why don't I go off and use AWT?  Quite simply, Swing looks pretty.  AWT does not assume the native GUI toolkits, so it doesn't mesh well with the local environment.  In addition, AWT doesn't have anywhere near the number of widgets to play with when compared to Swing.  These strengths make Swing a clear winner in 50.001% of my criteria, however, that small a winning margin gives me great pain.  I know that Swing could be better.&lt;br /&gt;&lt;br /&gt;Let's hope Sun hears my pleas and answers them in Java 7!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-3758332783242770627?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/3758332783242770627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=3758332783242770627' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/3758332783242770627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/3758332783242770627'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2007/05/java-swing-undead-gui-toolkit.html' title='Java Swing - The Undead GUI Toolkit'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3603566345830909173.post-6654231479084543489</id><published>2007-05-03T09:46:00.000-07:00</published><updated>2008-01-10T17:09:07.163-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CPU Wars'/><title type='text'>AMD Quad-Core: Half Again the Power?</title><content type='html'>It seems that every time I prepare to buy a new bit of hardware that they announce a new gizmo which, in the six months or so it takes to release, will drastically reduce the price of whatever device I'm planning on buying.  It's all a conspiracy to make me waste my money I tell 'ya.  Beyond my financial paranoia, there is a world that works reasonably well I'm told.&lt;br /&gt;&lt;br /&gt;Big brother Advanced Micro Devices announced that they are expecting their new Quad-Core Opteron64 chips to run 50% faster than the leading Intel microprocessor solution.  That's a tough claim to back up, considering that Intel already has quad-core chips on market and they're insanely fast.&lt;br /&gt;&lt;br /&gt;My first reaction is quite naturally a wonder of how they expect to do this.  The background is that AMD just recently made a change from 90nm manufacturing to 65nm.  Intel is on 45nm, which is a clear advantage.  There is, however, a lot of talk about how Intel uses very, very old technology in their chips, and that this technology is rapidly approaching the end of its useful life.  AMD, on the other hand, is supposed to be using very recent, very advanced technology and upgrading every few models to keep the momentum going.&lt;br /&gt;&lt;br /&gt;I haven't personally seen any kind of proof of this.  I've never seen hard data that "Intel is using Generation &lt;span style="font-style: italic;"&gt;n&lt;/span&gt; technology and AMD is on Generation &lt;span style="font-style: italic;"&gt;n&lt;/span&gt;+5 technology."  From all the data I've seen, Intel is ahead.&lt;br /&gt;&lt;br /&gt;What makes me, a die-hard AMD fan, hopeful that the new breed of Penrose core Opterons will sweep the board?  Curiously enough, a precedent set down by The Enemy: Intel.&lt;br /&gt;&lt;br /&gt;Before Intel had released their new round of revolutionary Core 2 chips, they made an announcement about 2 years before the launch date that they were developing massively superior chips.  Yes, I scoffed and mocked them, laughing at their sensationalism citing their dismal performance statistics.  Then they delivered.&lt;br /&gt;&lt;br /&gt;I was pretty dang impressed.  Their multi-core architecture still sucks in comparison to AMD's core architecture, but the Intel chips are fast - unprecedentedly fast.&lt;br /&gt;&lt;br /&gt;Quite simply, Intel's ability to deliver upon their promise makes me confident that AMD will be able to deliver upon their new claim.  Intel will no doubt be fretting over this development of their past history bolstering my confidence in AMD's future, however, I guess that's what you get for competing for the same market niche.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3603566345830909173-6654231479084543489?l=mindofsauron.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mindofsauron.blogspot.com/feeds/6654231479084543489/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3603566345830909173&amp;postID=6654231479084543489' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/6654231479084543489'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3603566345830909173/posts/default/6654231479084543489'/><link rel='alternate' type='text/html' href='http://mindofsauron.blogspot.com/2007/05/amd-quad-core-half-again-power.html' title='AMD Quad-Core: Half Again the Power?'/><author><name>Lord Sauron</name><uri>http://www.blogger.com/profile/17998264438512165500</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp0.blogger.com/_iRcLYsVvUQw/R5YhDyGV0qI/AAAAAAAAA1Y/RjGhZ-SLIDI/S220/107693-1.jpg'/></author><thr:total>0</thr:total></entry></feed>
