<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Charles Solar &#187; Programming</title>
	<atom:link href="http://charlessolar.com/post/tag/programming/feed" rel="self" type="application/rss+xml" />
	<link>http://charlessolar.com</link>
	<description></description>
	<lastBuildDate>Fri, 29 Apr 2011 04:38:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Project Management 101</title>
		<link>http://charlessolar.com/post/237</link>
		<comments>http://charlessolar.com/post/237#comments</comments>
		<pubDate>Fri, 29 Apr 2011 04:36:17 +0000</pubDate>
		<dc:creator>Charles Solar</dc:creator>
				<category><![CDATA[Management]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[advice]]></category>
		<category><![CDATA[dry]]></category>
		<category><![CDATA[gmake]]></category>
		<category><![CDATA[kiss]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[project management]]></category>
		<category><![CDATA[series]]></category>
		<category><![CDATA[visual studio]]></category>

		<guid isPermaLink="false">http://www.mrlwork.com/?p=237</guid>
		<description><![CDATA[When working on projects its helpful to know in which direction you are headed.  Its good to place goals, do a bit of planning, and get things right to save time in the future.  Unfortunately however, there is little to no information online on how to successfully manage and keep a big software project going.  [...]]]></description>
			<content:encoded><![CDATA[<p>When working on projects its helpful to know in which direction you are headed.  Its good to place goals, do a bit of planning, and get things right to save time in the future.  Unfortunately however, there is little to no information online on how to successfully manage and keep a big software project going.  Sure there are management books on how to motivate people, or how to lead coworkers, or even how to plan every step of the project with careful diagrams, flow charts, and process graphs.  As far as I could find a year ago there was nothing on how to get down and dirty and manage things like a build process, or an automatic unit test suite, or how to deal with different platforms in your build system.  For the past year I have been working on a big project that required all these things and whenever I fell into a trap, or discovered a new idea, or came up with a new operation I wrote down little snip-its to be eventually published in this article.  I hope others looking for information on how to manage a project effectively and efficiently will find some of these ideas very helpful.</p>
<p><span id="more-237"></span>The very first obstacle that any project can face is most certainly compiling on any platform other than the &#8220;primary&#8221; operating system.  Putting developers outside their development comfort zone can breed resentment for the new platform.  This resentment manifests itself into very sub-par code for the platform in question and only breeds more resentment as the project progresses and developers start complaining about how the other platform &#8220;just is not working.&#8221;  I see this all the time when developers start using the Linux tool chain when used to Visual Studio, and when a Linux guru tries to use platforms like Windows.  What eventually ends up happening is a bunch of smelly code gets written for the platform no one likes and is put together using a terrible build system that only further breeds discomfort and anger against the offending OS.  This reflects in the final product where users of the accursed OS are shunned for their complaints, new feature requests are not taken seriously, and one by one new developers that were brought in to work on the platform leave the company because even they get shot down when offering advice to the &#8220;project gurus&#8221; who hate the operating system they do not understand.</p>
<p>Fortunately scenarios such as this can be quickly remedied before they even start.  As a general rule, never put someone on a project unless they understand all the pieces involved.  When a Linux developer is put in charge of a Windows build, their first instinct is going to want to build a set of recursive nmake files.  Nmake is sort of like a command line make tool for Windows for those unaware.  Development of the tool was canceled after Visual Studio 2005, but it still works and some Linux developers still try and use the woefully inadequate tool as a replacement to gnu make.  As the Linux developer learns about the limitations of nmake he starts building up his resentment for the platform in general.  The final product being a nmake build system that is full of quirky &#8220;hacks&#8221; to work around nmakes limitations and emulate some of the functionality of gnu make.  For example, with gnu make you can setup automatic dependency scanning so if a developer modifies a header file all .c and .cpp files that depend on it are recompiled.  If the Linux developer does not find similar functionality with nmake, he might just decide to setup nmake  to delete all object files every run and recompile the whole project each build.  This in turn causes other developers to not want to use the Windows compiler because Linux compiles in half the time and they can make quick changes without waiting hours for a new build.  This in turn causes development on Windows to slow to a trickle and the platform falls behind on enhancement requests as Windows developers start leaving for better prospects.  And thus the downward spiral continues.</p>
<p>In a different scenario lets put a Windows developer in charge of the Windows build.  He is most likely fluent in the best tool for compiling on Windows, Visual Studio.  He knows that nmake is a disaster and instead builds easy to maintain Visual Studio solutions which allows other developers to open the project and compile effortlessly.  He then utilizes Microsoft&#8217;s MSBuild tool to setup automated build and packaging processes and the project continues moving forward drawing in the best Windows development talent.</p>
<p>Sometimes due to lack of budget or development talent it is not always possible to put the best talent on the right job.  In my recent project I had to build both a Linux and Windows build system.  At the time I knew about Linux make and even maintained a couple make files, but other than that I had no experience writing one.  At these times its important to stick to the core principles of software development.  <a href="http://en.wikipedia.org/wiki/KISS_principle">KISS</a> ( Keep It Simple and Stupid ) and <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> ( Don&#8217;t Repeat Yourself ).  Using these two techniques developers on an unfamiliar system can sacrifice time for quality.  Building the gnu make system took me longer than someone who knew Linux make backwards and forwards, but the end result is about the same.  As an added benefit, the developer gains insight into how the new system works and in the future will not take so long to create new make files.</p>
<p>Learning how to effectively apply KISS and DRY is a skill worth developing as it takes quite a few mistakes and failures to get right.  The important questions to ask yourself while working is &#8220;Is this as simple and concise as it could be?&#8221; and &#8220;Is this same concept used more than once in my project?&#8221;  Google is most definitely your friend as you struggle with new software or design.  Basically, how I go about using a new system is imagine what I want it to do, and Google for others who got it to work that way.  In some cases people will instead tell you that your idea is dumb and is not what the software was designed to do.  Which may make poorly trained developers insert a hack or two into the system to make it work like he wants.  But this is the important point!  If you are using KISS and DRY you should <strong>never</strong> allow any hacks of any kind into your work.  Work with the software, do not make the software work for you.  The world is a much nicer place when software is doing the job it was designed to do as it was designed to do it.  <strong>Do not</strong> make software work how your warped perspective says it should work.  If you take nothing else from this article take that bit of advice.</p>
<p>When developing large systems it sometimes becomes apparent that some changes require large amounts of copy and pasting.  In my project I had 20-30 individual build projects with 20-30 individual makefiles and visual studio projects.  At one point each makefile held a lot of duplicate information.  If I wanted to add a CFLAG to the whole project I would have to edit each makefile or if I was lucky, have sed do it for me.  The whole system was one big violation of the DRY principle, and I was wasting valuable time writing sed scripts rather than doing real work.  Recognizing the problem I quickly redesigned the system to correctly leverage the capabilities of the makefile include directive.  Ideally when working on a project that contains many individual builds its advantageous to keep the actual build logic out of the makefiles.  The only thing needed for an individual build should be a list of source files and any extra flags the build might need.  By using the include directive you can separate the build and link implicit rules into different makefiles that your project makefiles include and use.  Changes to the global project are then applied to a single makefile and are included by all projects.</p>
<p>Same goes for Visual Studio projects.  In a solution containing 20-30 project files, changing something as simple as the release flags takes a long time.  Thankfully Visual Studio allows you to use property sheets which are basically a collection of properties that can be applied to many projects.  I use them for specifying all properties in the project except build type and source files.</p>
<p>I have uploaded the current version of my makefiles and property sheet to bitbucket, feel free to <a href="https://bitbucket.org/redcomet/build/src">check them out</a>.</p>
<p>Moving on to compilers and source files.  I think it is more important to pay attention to KISS and DRY when writing code then when writing a build system.  Build systems can be changed, code changes can get complicated, especially if you care about backwards compatibility.  When writing code start simple and get more complex.  Think of an easy representation to shoot for and adjust your expectations as the requirements get more specific.  Pay attention to things like namespaces, type names, capitalization, and other minor style issues.  Do not throw all your types into a single namespace as that gets confusing when you start dealing with fields of 30 or more types.  Pick a standard coding style and stick to it.  New users may have to get used to it, but the last thing you want is a code base covered in five different standards.  This obviously breaks programmer flow and causes severe loss of likability as users cannot adapt to your project and code based on their expectations rather then reading straight from the doc.</p>
<p>My next post will contain tips specifically for coding.  Related to GCC, Pimpls, smart pointers, and unit testing.</p>
]]></content:encoded>
			<wfw:commentRss>http://charlessolar.com/post/237/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Static Object Initialization in a Static Library</title>
		<link>http://charlessolar.com/post/230</link>
		<comments>http://charlessolar.com/post/230#comments</comments>
		<pubDate>Fri, 18 Dec 2009 03:34:23 +0000</pubDate>
		<dc:creator>Charles Solar</dc:creator>
				<category><![CDATA[Help]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[factory]]></category>
		<category><![CDATA[pluggable factories]]></category>

		<guid isPermaLink="false">http://www.mrlwork.com/?p=230</guid>
		<description><![CDATA[I ran into an interesting problem the other day that I think is worth sharing.  Fans of the pluggable factory design pattern, inversion of control, etc will be interested to know that these methods do not work very well when compiled into static libraries.  Sounds obvious but what may not be so obvious is why. [...]]]></description>
			<content:encoded><![CDATA[<p>I ran into an interesting problem the other day that I think is worth sharing.  Fans of the pluggable factory design pattern, inversion of control, etc will be interested to know that these methods do not work very well when compiled into static libraries.  Sounds obvious but what may not be so obvious is why.</p>
<p>I stumbled onto this problem when I changed one of my exe projects to a static library so I could setup two exe&#8217;s, one for unit tests, the other for releasing.  (Which by the way is a wonderful way to unit test an exe project)  Most of my projects these days use some form of inversion of control so I had static variables creating maker classes which would register themselves with the factory.  As explained in one of my previous articles <a href="http://www.mrlwork.com/post/50">here</a>.</p>
<p>When I changed my project to a static library and linked it to a separate exe project my maker classes stopped registering themselves.  Why does this happen?  Well after a bit of a research I found out that when you link in a static library, the linker only links code into your project that you actually use.  All extra code is left uninitialized and put in a corner to sit while the big boss code runs.  A very interesting side effect of static linking.</p>
<p>Anyway, to fix this problem in visual studio you need to set &#8220;Use Library Dependency Inputs&#8221; in Linker options on your exe project.  This will make the linker link in all the object files themselves, instead of selectively linking them as needed.  I am researching some way to do this per library, because as of right now if you set this it will link ALL libraries like that.</p>
<p>In linux it would seem the option is -z allextract, but I have not tested this one.</p>
<p>If you need your static objects from a static library to be initiated like normal, this should do the trick.</p>
]]></content:encoded>
			<wfw:commentRss>http://charlessolar.com/post/230/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Microsoft SQL User Defined Types</title>
		<link>http://charlessolar.com/post/170</link>
		<comments>http://charlessolar.com/post/170#comments</comments>
		<pubDate>Fri, 21 Aug 2009 16:25:29 +0000</pubDate>
		<dc:creator>Charles Solar</dc:creator>
				<category><![CDATA[Help]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[msdn]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.mrlwork.com/?p=170</guid>
		<description><![CDATA[User defined types in Microsoft SQL are really handy.  Using these objects you can construct queries like select duration.minutes from cdrs; select duration.seconds from cdrs; You can also program them to read weird string inputs that other data types can not handle.  Recently I wrote a custom data type to read a duration field of [...]]]></description>
			<content:encoded><![CDATA[<p>User defined types in Microsoft SQL are really handy.  Using these objects you can construct queries like</p>
<pre class="sql">select duration.minutes from cdrs;
select duration.seconds from cdrs;</pre>
<p>You can also program them to read weird string inputs that other data types can not handle.  Recently I wrote a custom data type to read a duration field of the format minutes:seconds.tenths; so standard input went something like &#8217;002:34.2.&#8217;</p>
<p>Writing a custom data type is actually very simple.  You just open a new sql data type project in Visual Studio and VS will integrate nicely with your sql server; even going so far as to upload the data type for you and run tests.  There are numerous tutorials online for programming a data type however so I will not cover that aspect.</p>
<p>Like I said I recently created a data type for my data parsing.  I put it into my table but soon found that assigning my specific data processing user permissions to the object was harder than you would expect.  I kept getting the error</p>
<pre class="sql">
[Microsoft][ODBC SQL Server Driver][SQL Server]EXECUTE permission denied on object 'data_type', database 'db', schema 'dbo'. (SQL-42000)
</pre>
<p>Trying</p>
<pre class="sql">
grant execute on [data_type] to cdr;
</pre>
<p>returned &#8216;object not found.&#8217;  Ms sql&#8217;s security assignment tool did not help either, it never did &#8216;find&#8217; the object I created.</p>
<p>I eventually found my way to <a href="http://msdn.microsoft.com/en-us/library/bb522526.aspx">this msdn page</a> which at least revealed the secret missing keyword.  To set the permission on the object use this query</p>
<pre class="sql">
grant execute on TYPE::[dbo].[data_type] to cdr;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://charlessolar.com/post/170/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Alternative to Unique Character Names in MMOs</title>
		<link>http://charlessolar.com/post/137</link>
		<comments>http://charlessolar.com/post/137#comments</comments>
		<pubDate>Mon, 17 Aug 2009 17:11:14 +0000</pubDate>
		<dc:creator>Charles Solar</dc:creator>
				<category><![CDATA[Game Design]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ramblings]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[mmo]]></category>

		<guid isPermaLink="false">http://www.mrlwork.com/?p=137</guid>
		<description><![CDATA[Unique character names in MMOs have long been a pet peeve of mine.  I am sure most of you have experienced the frustration when your favorite character name ends up taken by some else, and if you are like me it might take as many as 20 tries to get an available name.  Well, here [...]]]></description>
			<content:encoded><![CDATA[<p>Unique character names in MMOs have long been a pet peeve of mine.  I am sure most of you have experienced the frustration when your favorite character name ends up taken by some else, and if you are like me it might take as many as 20 tries to get an available name.  Well, here is a question for all you MMO programmers, why the hell are you still using character names as a unique identifier?  There are so many better options to identify players in the world, every name does not need to be unique.  In fact I frequently find that running across players entitled &#8216;FancyPants12&#8242; or &#8216;Moooo4me&#8217; does more damage to game play than a simple change would.  When I am in the process of being adsorbed into an MMO through very nicely executed immersion techniques, stumbling onto these players breaks flow, <a title="ScreenShot_071107_195300" href="http://www.flickr.com/photos/9248805@N04/3760387724/" target="_blank"><img class="alignleft" style="border: 0pt none; margin: 10px;" src="http://farm4.static.flickr.com/3436/3760387724_e785982fb8_m.jpg" border="0" alt="ScreenShot_071107_195300" width="240" height="160" /></a>disrupts my concentration and I find it harder to follow the story line (or even care about it).</p>
<p><small><a title="Attribution-ShareAlike License" href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank"><img class="alignleft" style="border: 0pt none;" src="../wp-content/plugins/photo-dropper/images/cc.png" border="0" alt="Creative Commons License" width="16" height="16" align="absmiddle" /></a> <a href="http://www.photodropper.com/photos/" target="_blank">photo</a> credit: <a title="Idhren" href="http://www.flickr.com/photos/9248805@N04/3760387724/" target="_blank">Idhren</a></small></p>
<p><small></small>I bring this up because this last weekend I started playing Aion.  A very nice game that I have high hopes for, but its probably the first MMO that I am actually interested in a bit of the lore; I even went so far as to read some of the important quest text.  Its shocking yes, but they really did do a good job making the player feel like they are not just a drop of water in an ocean; which is worthy of recognition in itself.  Unfortunately, Aion suffers from the unique name dilemma so while I am trying to rescue the damsel from a horde of black winged bandits I am constantly running into &#8216;XXSlayerXX&#8217; or &#8216;RoGeGardian&#8217; and that is just terrible from an immersion perspective.</p>
<p>But what can be done about it?  After all, a lot depends on character names.  PMs, brokers, mail, friend lists, etc etc.  Obviously a new system has to enhance game play, not restrict it.  I propose a system where each character is assigned a unique number, not a name, which can be used for all these means of communication with just a little extra effort on the programmers side.</p>
<p><span id="more-137"></span></p>
<p>To illustrate my concept I will run through a few normal MMO actions and highlight how this idea works in comparison to the character name.</p>
<p><strong>Auctions</strong></p>
<p>This is the easiest, when a character posts an item you simply register the item with the character id instead of the character name.  All transactions, searches, bids, use the character id instead of the name.  A really simple swap out in this instance.</p>
<p><strong>PMs</strong></p>
<p>Probably the first problem that would come to your mind.  Obviously having to type /tell 00283023 to talk to a player would be murder on your player base.  PMs can be handled nicely, it just takes a little more work and polish out of the box.  For instance, to talk to someone who made a comment in the chat window, just click on their name and reply.  The reply would pull the character number from the chat window so the player would see the character name but actually be replying using his number.  Now, if you want to type up a pm to someone you met in an instance but did not befriend, things get a little more complicated.  Lets say for the sake of argument that you remember his character name and you wish to send him a message.</p>
<p>There are two solutions I can think of off the top of my head.  First, typing /tell William will bring up a list of all &#8216;Williams&#8217; in the world sorted by last interaction.  Meaning if he met William during a live event the previous night, that William would be listed above a William he met out in the plains last week.  For this to work players would need to keep record of the players they meet and timestamps, not impossible but not very practical.</p>
<p>My next solution would be to improve the friend system to be more intelligent.  Instead of storing a list of people the player manually types in, it could store a list of acquaintances that the player has met over time.  It could list people he met, ordered by zones, time spent with the person, number of interactions with the person, etc.  This way the player would build a network of contacts in the world without having to manually type in their names or numbers.  These two systems not only improve the experience for the player, but also improve immersion since this is normally how people relate to each other.  I can think of five different &#8216;Chris&#8217;s I know, but when attempting to address one I use the social path that has been created between us.  My social network determines the means to communicate.</p>
<p><strong>Mail</strong></p>
<p>Another tricky problem which can be gracefully solved by an expansion on the friend list concept I wrote about above.  When the player tries to send mail he can browse his social network for a contact to send mail to.  This is a good time to mention that chatting with another player would make a new network with that person.  This includes someone chatting in general, city, trade, whatever.  To model those interactions a network of recent chat messages would be displayed for the player to pick out the appropriate recipient.</p>
<p><strong>Groups / Raids</strong></p>
<p>Most groups and raids are formed by pm messages or chat window invites.  Since we have already established that in the chat window a name is really a character id handing invite requests is as easy as opening a new pm.</p>
<p>A final note about the new social system.  Updating and management does not need to be left completely to the program.  With a new friends system comes a completely different way of interacting with players in the world.  Players should be able to modify their networks, add people to groups, tag communities of links.  I have more than once wished to have a system where I could tag players or organize relationships by specific words.  Not wishing to come off as an elitist but I am sure more than one of you have wanted to tag someone &#8216;noob&#8217;, &#8216;idiot&#8217;, or  &#8216;can&#8217;t play his class.&#8217;  With a more friendly social network system you could organize your contacts, including all the people you no longer want to interact with into a group.  Then when they say something in chat, send you a pm, invite you to a raid, you will have fair warning.</p>
<p>When all is said and done I am really advocating a new type of system for interacting with players in an online world.  One built on networks of links instead of a simple one dimensional friends list.</p>
]]></content:encoded>
			<wfw:commentRss>http://charlessolar.com/post/137/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu and the Future of Linux</title>
		<link>http://charlessolar.com/post/95</link>
		<comments>http://charlessolar.com/post/95#comments</comments>
		<pubDate>Tue, 16 Dec 2008 03:37:35 +0000</pubDate>
		<dc:creator>Charles Solar</dc:creator>
				<category><![CDATA[Operating Systems]]></category>
		<category><![CDATA[Ramblings]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[nokia]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.mrlwork.com/?p=95</guid>
		<description><![CDATA[Contrary to the many many posts about &#8217;10 reasons why ubuntu is the next #1 consumer desktop&#8217; or &#8216;Switching from windows to ubuntu&#8217; this post is about my experience with ubuntu and why as of this moment I am reinstalling windows vista. First off let me say that I use debain as the main operating [...]]]></description>
			<content:encoded><![CDATA[<p>Contrary to the many many posts about &#8217;10 reasons why ubuntu is the next #1 consumer desktop&#8217; or &#8216;Switching from windows to ubuntu&#8217; this post is about my experience with ubuntu and why as of this moment I am reinstalling windows vista.</p>
<p><span id="more-95"></span>First off let me say that I use debain as the main operating system for ALL my servers.  My asterisk, data, and web servers all run debian and I love the stability and flexibility that comes with debian and apt.  I have spent at least 4 years working with debian casually and through all the problems, ideas, and solutions that are typical in my line of work have presented me plenty of opportunities to exercise and expand my knowledge of linux.</p>
<p>It was just over a year ago that I tried moving to a linux environment on my laptop.  Since my laptop was custom built all the parts worked well with ubuntu and I had very little configuration troubles.  Unfortunately after a couple months I encountered problems caused by my tinkering that made me have to reformat.  I believe at the time I was trying to get Compiz or Beryl to work with my ATI card, something I think caused a lot of people some hair.  At the time I decided to reinstall Windows XP because I could no longer justify the inconvenience of playing around with linux when I could not make it do what I wanted.  This I will admit was because at the time I had very little experience with linux desktops, and my number one gripe was network configuration, which does not seem to have improved but more on that later.</p>
<p>This is a post about why I believe linux is not ready, nor should it try to compete in the PC desktop market.  Linux is an excellent server environment make no mistake, I would choose linux over Windows Server any day of the week.  I find the code for critical applications to be very well maintained, optimized, and in general very clean.  On the other hand, I find the code for desktop environments and &#8216;configuration GUIs&#8217; to be a joke and buggiest pieces of software I have had the misfortune to work with.</p>
<p>For further reference, 4 days ago I decided to reformat my Vista desktop to Kubuntu, an operating system I had worked with in vm&#8217;s and had pleasant experiences with.  I chose to leave Vista because of a bug with USB hand off to my virtual machines, which is a crucial element of programming a Nokia 810.  This inconvenience was the last straw for me and I made the decision to reformat to an operating system I felt would work better for control freaks like myself.</p>
<p>My first impressions of kubuntu, was the very excessive amount of useless garbage programs sitting in my application menu.  My second problem was with the desktop widget system which would seem like a good idea but is executed very poorly and is not very user friendly to say the least.  After removing as many of the useless programs I could and installing some other better programs I opened firefox and was greeted by the ugliest looking interface I have ever seen.  I will admit, I have never been a fan of the GTK interface.  Even on windows I found the layouts and graphics to be messy, unappealing, and bland.  So when I came to realization that my entire desktop would look this way I was a little put off right off the bat.</p>
<p>However I was determined to give this a chance since indeed I needed to be able to program my new Nokia 810 and linux was the only solution.  I visited the Ubuntu forums, a place which actually deserves the praise it gets, and found various things to do &#8216;Right after installing ubuntu.&#8217;</p>
<p>I installed more programs, added sources for my media and graphics, updated openoffice, speed tweaked the file system and boot process, and was fairly happy with the end result.  Firefox looked half decent, my programs had neat little effects like wiggle, darken, etc, and most of all it was running on par with my windows system.  So I began to seriously exercise the system and bring it up to my standards.  I installed dmraid to manage my nvidia raid array, I got my other disks provisioned in fstab for automatic mounting, configured all my programs to work exactly as I wanted them to, and in general personalized the system to my liking.</p>
<p>It was during this time that I started to notice the little problems and glitches.  Firstly, I was not happy to see that the network manager was still the worst configuration app in the entire system.  I ended up uninstalling it and setting a static ip in network/interfaces.  Then came the problem of getting my dual monitors to work, and in turn, get nvidia drivers installed.  The automatic &#8216;Install restricted drivers&#8217; wizard failed to produce any results, so I turned once again to the ubuntu forums and a script called <a href="http://www.albertomilone.com/nvidia_scripts1.html" target="_blank">Envy</a> which did the job very well.  Configuring TwinView was then just a simply xorg.conf edit.</p>
<p>This brings me to point number one.</p>
<p><strong>Linux is not ready because to much configuration is left to the command line</strong></p>
<p>The gui configuration utilities simply do not work.  Those that do work have limited functionality and you end up configuring it yourself in the command line.  When was the last time you saw a standard user open ms dos to configure his network settings?</p>
<p>So as I finished configuring various systems and building the system as I saw fit I decided to try to actually use the os.  Opening firefox still left me with flash backs from 10 years ago, but it worked fine, so all was good.  I then downloaded and installed pidgin, as I could not live without a constant line to any of the people on my buddy list and was once again greeted with those flashy windows 95 graphics.  At this point I was getting pretty frustrated.  Sure, my windows swayed, they faded, I could alt-tab like a pro but my applications looked like they were resurrected from my old DOS laptop.  Something had to be done, so I immediately went online searching for solutions.</p>
<p>I found that you have the option to install custom themes for things like text layouts, colors, window styles, etc.  Something that I have never really used on Windows but I went ahead and dived into the top rated everything to bring my operating system into the year 2008.  I found that these layouts helped a little bit, but the real problem, boxy art, out of date pictures, remained.  It was at this point that I decided to look for different GTK themes and customizations, hoping to fix the problem at the source.  However I soon found out that GTK artwork is non-existent, very hidden, or just not possible.  Tell me what is the point of a centralized graphics framework when you cannot change themes?  This definitely deserves a check-minus in my book, and introduces point number two.</p>
<p><strong>Linux is not ready because the system looks like crap</strong></p>
<p>While the underlying framework and core operating code is fantastic, the GUI&#8217;s and desktops need work.  KDE4 from my understanding is an attempt to mimic some of Vista&#8217;s features and has been touted as the better desktop.  I could not disagree more.  The system was buggy, slow, and definitely not user friendly at all.  As a side note, in the little time I spent analyzing and poking at KDE4 I could never figure out why we needed a separate desktop &#8216;Widget&#8217; to display files that are in the desktop folder.  The widgets sit on the desktop, but the widgets display the desktop files&#8230;</p>
<p>As an additional side note I have only had the pleasure of using Gnome, KDE and a splash of X during my brief forays into the linux desktop world, if there is a better desktop out there please feel free to post.</p>
<p>At this point I was pretty frustrated with the whole mess so I went to sleep and decided to work on it more in the morning.</p>
<p>After a good night sleep I was back on my computer and ready to tackle the operating system once more and amidst the endless forum searches, configuration tweaks, Dolphin crashes, I realized something.  This something is my third and final point and probably the one that will get the most flames.</p>
<p><strong>Linux is not ready because linux does not work for the user, the user works for linux</strong></p>
<p>Let me explain what I mean.  While I was wondering around the settings screens (the few that there are) I found myself continually frustrated at the limit of what I could change, configure, optimize, or just in general, &#8216;do.&#8217;  Linux is very much a arrogant bastard who would much rather give you a new world and say have fun then give you the tools to operate in its world.  When using windows, all the tools you need to change the system are given to you, right out of the box.  If you want to do something incredibly difficult, like add a 3d desktop or program your own file explorer, you are pretty screwed, but for most situations windows gives you the tools to handle the problem yourself in its world, not your own.  Linux on the other hand, even though its open source, is ruled by obscurity.  There is no consistency between the network configuration and the display configuration.  There is no intermingling of different programs, as was painfully pointed out to me when I tried to burn an iso image from a windows machine across the network.  All and all, linux is very introverted and unlikeable.  Now I must make a small note here, the ubuntu community needs to be given a handshake for their excellent effort on compiling useful guides and providing help to any strangers who grace their doorstep.  Unfortunately, all the smiles and friendly hand shakes do not detract from the serious design flaws inherent in any operating system in the hands of anyone who uses it.  And even though I hate to say this, I much prefer my operating system built by a money corporation where strict testing, quality assurance, and optimizations are kept at the forefront, not for the customers, but to make themselves competitive with other corporations.  On that note I would like to say that I might actually prefer to try a Mac OS next time I feel pined down by the Microsoft money machine.</p>
<p>So there in lies linux&#8217;s biggest problem.  It is not competing.  Not that it does not want to, it just can&#8217;t.  It can not compete with the multimillion dollar budgets of Apple and Microsoft dev teams, and it certainly cannot get any decent project management system in order to organize the thousands of varying and unique programs built for it since release. <strong>But this is OKAY</strong>.</p>
<p>Its OK that linux can not compete, its OK that the programs are different.  What is not ok is trying to convince people to install linux on a desktop or laptop pc where hardware is never consistent, drivers are always needed, and just getting the thing to recognize and deal with the thousands of different environments is itself a full time job.  No this is not where linux&#8217;s strength truly lies.  To find where the future of linux lies I took a look back at the device that started all of this.  The small, sexy, and very much in control Nokia 810.  This little device is run by a special operating system built off of debian called Maemo.  You will find no better example of synchronous design and program execution then here.  Why?  Because its not a pc, its not a computer that needs a new video card every two years, it does not need to know about any other devices outside of its own perfect little world.  <strong>That</strong> is what makes it the best version of linux I have used.  The system is still open, but users do not have to draw cards to tell whether they will spend 5 hours getting running or 5 days.  With this increase in freedom comes standardized programs and configuration GUIs, systems that actually WORK.  The Nokia works so flawlessly that it inspired me to first install Kubuntu, then write this article because I feel that the future of linux does not lie with the desktop pc, but with these small devices.  These devices, that have a set of unchanging hardware, guarantee that no network manager will crash when detecting your Broadcom modem model number x15220 from 1997.  It guarantees that when you run network configuration your settings will take effect on your true device, instead of usb0 or visa versa.  I am currently reinstalling Windows Vista on my computer and with that I will reinstall VMWare and find a solution to my original bug so I can setup the maemo sdk and start programming applications for this device.  Yet in order to do this I am ditching my linux desktop solely because I just could not stand it compared to Vista.  Vista is by no means perfect, and in some ways it can make me just as frustrated as Kubuntu did, but I can accomplish a hell of a lot more in a windows operating system at this time.</p>
<p>Maybe this will change, maybe there is some other desktop environment that people like me use and I am unaware of it.  Certainly if you the reader have any suggestions I would welcome them and maybe even consider reformating again to try them, but at this moment I stand by what I have said in this article and hope that those who read it can offer constructive feedback, good or bad.</p>
]]></content:encoded>
			<wfw:commentRss>http://charlessolar.com/post/95/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Pluggable Factories</title>
		<link>http://charlessolar.com/post/50</link>
		<comments>http://charlessolar.com/post/50#comments</comments>
		<pubDate>Tue, 12 Aug 2008 04:36:49 +0000</pubDate>
		<dc:creator>Charles Solar</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ramblings]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[factory]]></category>
		<category><![CDATA[pluggable]]></category>
		<category><![CDATA[static]]></category>

		<guid isPermaLink="false">http://www.mrlwork.com/?p=50</guid>
		<description><![CDATA[So in my last article I touched on the subject of what I termed static factories. I did a little searching online and found the original article that first gave me the idea.  Apparently this type of design is called pluggable factories.  A term I had forgotten until just now. Here is the basic idea, [...]]]></description>
			<content:encoded><![CDATA[<p>So in my last article I touched on the subject of what I termed static factories.  I did a little searching online and found the <a href="http://www.gamedev.net/reference/articles/article841.asp" target="_blank">original article</a> that first gave me the idea.  Apparently this type of design is called pluggable factories.  A term I had forgotten until just now.</p>
<p>Here is the basic idea, you have x number of objects your program can create.  These objects are all children of a base interface.  You have cleverly created an abstract factory to create the various instances of your objects, but there is a problem, you are asked to add several new objects and/or remove several objects.  So you jump back into your code and make a new object or remove an object.  You compile your code and try to use the new object, OOPS, you forgot to add it to the abstract factory!   Or, after removing the object you run some old data and OOPS, your program crashes as it tried to return an instance to a class that does not exist.</p>
<p>To be fair, if your program was written correctly it would not compile in the latter case, but that is besides the point.  Sometimes abstract factories can be a pain in the ass.  So, here is where pluggable factories step up to the plate.<br />
<span id="more-50"></span><br />
They offer you the ability to create or remove objects without modifying any part of the project.  All you, as the programmer, need to do is create a new cpp with two well defined classes and you can use your new object.  How does this work?  It relies on a very simple but powerful aftereffect of static objects.</p>
<p>See, the basic idea of a static object is that only one exists.  It gets setup at the start of your program and never moves or changes.  If it is a method, it gets a special place in memory and any children of your class call that exact function.  If it is a variable, it gets initiated at the start of the program and all references to get sent directly to that location, no mater where in the program you are.</p>
<p>The idea behind pluggable factories is that you silently initiate several classes that only exist to make one specific type of object.  These classes are known as makers, and they are the key to pluggable factories.</p>
<p>Makers come in many different flavors and styles, but we will focus on one type for now.  Let us define an object derived by a common interface.</p>
<pre name="code" class="cpp">
class Controller_Letter : public IController
{
    friend class Letter_Maker;
public:
    ~Controller_Letter() {}

    int fitness( void* data )
    {
    if( (char)data == _letter || (char)data == toupper(_letter) )
        return 1;
    return 0;
    }
    void perform() { printf( "%c", _letter ); }

protected:
    Controller_Letter() {}

private:
    void setLetter( char letter ) { _letter = letter; }
    char _letter;
};
</pre>
<p>Now this is a basic controller class for a project of mind, so do not pay to much attention to the methods.  From the basic idea of this controller, I would want at least 26 of these classes, but to be safe I will instead make <a href="http://www.asciitable.com/">255</a> of them.  Can you imagine a switch statement with 255 cases?</p>
<p>To make our lives easier we will construt a pluggable factory to automatically create each class.  A pluggable factory is made of three parts, a std::map, a constructor, and a pure virtual make method.  The map will store our database of makers, the constructor will be used by our children to register with the database, and the virtual method will be defined by our children so they can make their object.  Lets take a look at a basic parent maker class</p>
<pre name="code" class="cpp">
class Controller_Maker
{
public:
    static IController* newController( const std::string&amp; type, void* data );
private:
    typedef std::map&lt;std::string, Controller_Maker*&gt; maker_map;

    static maker_map&amp; getReg()
    {
        static maker_map registry;
        return registry;
    }
    Controller_Maker() {}
protected:
    Controller_Maker( const std::string&amp; type )
    {
        getReg().insert( std::make_pair( type, this ) );
    }
    virtual IController* make( void* data ) const = 0;
};
</pre>
<p>We have defined all three parts, but there is something I would like to point out to everyone.  Notice the getReg function.  It would make sense to have our registry variable static inside the class, then have the children directly access it to register themselves, HOWEVER, here is the problem.  When your program gets compiled all your static elements are juggled by the linker and eventually end up sitting in an initialization list somewhere in your binary.  Among these variables are your child makers trying to register themselves in the registry.  Imagine what would happen if a child is initialized before the registry map is.  BOOM CRASH BANG, yep, you get a splendid show of fireworks before your program disintegrates back into the void.  The getReg function is how we avoid this very nasty problem.  See, functions do not need to be setup before hand, a static function is just an address, it can be called at any time.  Therefore we put the registry inside a static function, and we can guarantee that it gets initialized before a child tries to use it, because when a child uses it they initialize it.  Simple eh?</p>
<p>So now you have a maker, an interface, and an object you want many many variations of.  How do you define the individual makers to first register with the parent maker, and second, create the desired object?  Child makers will, as you may expect, define the make function from the parent maker and call the parents constructor.  However the key to child makers are the static instances of themselves they define.  It may sound weird, but each child defines a variable inside itself of itself.  This variable is initiated at the start of the program ( because its static, remember? ) and thus the child is registered with the parent.  Here is the child maker</p>
<pre name="code" class="cpp">
class Letter_Maker : public Controller_Maker
{
protected:
    IController* make( void* data ) const;
private:
    Letter_Maker() : Controller_Maker( "letter" ) {}
    static const Letter_Maker registerThis;
};
</pre>
<p>Notice the constructor, it calls the parent with the type of object it makes, thus registered a new type of object with the pluggable factory.  Also key here is the registerThis variable.  The only purpose of this variable is to register the class without modifying any factory or project source.  This class is naturally defined with the class it creates, this way you just add a cpp to the project and you have a new object.  Impressed yet?  Lets dive a bit further.</p>
<p>If you have been paying attention you have noticed that I have not defined some key methods, namely, Controller_Maker::newController or Letter_Maker::make.  Well it does not take much imagination to define these, here they are</p>
<pre name="code" class="cpp">
IController* Letter_Maker::make( void* data ) const
{
    Controller_Letter* ret = new Controller_Letter();
    ret-&gt;setLetter( (char)data );  // Sending NULL will not hurt anything
    return ret;
}

IController* Controller_Maker::newController( const std::string&amp; type, void* data )
{
    maker_map::iterator itr = getReg().find( type );
    if( itr != getReg().end() )
        return itr-&gt;second-&gt;make( data );
    return NULL;
}
</pre>
<p>I usually keep these methods separate from the header files for neatness sake.  Here is the quick run down on these.  Letter_Maker::make will make the object it was build to make.  Think of it as a small builder ( if you have read <em>Design Patterns</em> ).  Its important to not fall into temptation and pass void* data to the new object.  Notice how I create the object then call its setLetter method?  The maker data should stay independent of the object definition.  Remember DRY?</p>
<p>Controller_Maker::newController is just what you probably expected, it simply searches the registry for the type of maker we ask for and calls the specific maker&#8217;s make function.</p>
<p>In the end, we are left with a nice set of classes that can easily encapsulate all 255 acsii characters in just 255 lines ( if someone wants to add up the maker and controller class lines be my guest ).</p>
<p>Here is how we use the maker</p>
<pre name="code" class="cpp">
IController* a = Controller_Maker::newController( "letter", (void*)'a' );
IController* b = Controller_Maker::newController( "letter", (void*)'b' );
IController* c = Controller_Maker::newController( "letter", (void*)'c' );
IController* d = Controller_Maker::newController( "letter", (void*)'d' );
IController* e = Controller_Maker::newController( "letter", (void*)'e' );
IController* f = Controller_Maker::newController( "letter", (void*)'f' );
</pre>
<p>Keep in mind that is by far the simplest way to use pluggable factories.  For more examples you can check out bafprp&#8217;s source code, pluggable factories are used for creating fields, records, and the most interesting of all is the output class, where I merged the maker and the object into one class.  And that is not all as far as I know I have barely even scratched the surface of pluggable factory design, so if you come up with a new technique, feel free to post!</p>
<p><a href="http://www.mrlwork.com/downloads/SOURCE/pluggable_factory_source.rar">Project source code here</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://charlessolar.com/post/50/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Log Files</title>
		<link>http://charlessolar.com/post/25</link>
		<comments>http://charlessolar.com/post/25#comments</comments>
		<pubDate>Fri, 18 Jul 2008 21:11:46 +0000</pubDate>
		<dc:creator>Charles Solar</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[bafprp]]></category>
		<category><![CDATA[cpu]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[review]]></category>

		<guid isPermaLink="false">http://www.mrlwork.com/?p=25</guid>
		<description><![CDATA[While working on the BAF file project I learned a very interesting life lesson. See like most new computer science graduates I have worked on few actual projects, and quite frankly the few I have finished could not be considered corporation ready. While writing a few console applications, file parsers, corba interfaces, etc I learned [...]]]></description>
			<content:encoded><![CDATA[<p>While working on the <a href="http://code.google.com/p/bafprp/">BAF file project</a> I learned a very interesting life lesson.  See like most new computer science graduates I have worked on few actual projects, and quite frankly the few I have finished could not be considered corporation ready.  While writing a few console applications, file parsers, corba interfaces, etc I learned a valuable lesson in documentation and log files.  Log files can save your life if done correctly, and if you are really up to speed they can save many long hours of debuging too.  In my case I fell in love with trace log messages.  Trace logs are the log files that trace a programs execution so you can get a general idea of where your software is failing or producing an error.  Now, most trace logs I have had the pleasure to work with are not quite where I wanted to be when I approached trace logs in my program.  Most of the time they are a little more helpful then debug messages when trying to pinpoint an application&#8217;s problem.  So when I faced the decision to add trace messages I decided to go all out.</p>
<p>My first logging framework was <a href="http://log4cplus.sourceforge.net/">log4cplus</a>, which is a very nice and complete logging framework for C++.  I used it for one linux application I wrote and it works perfectly despite being several years old.  Unfortunetly I was uncomfortable with how much work it took to write a message each new function ( two lines instead of one ) and it would not compile in windows so for my next application, bafprp, I set out to write my own.</p>
<p>When I completed the class I was left with one macro to print a log message depending on the level you wanted, ie, LOG_TRACE( string ), LOG_DEBUG( string ), etc.  I then made sure I was adding trace messages to each and every function as I made them, instead of later on in the design.  For example, an empty function would look like</p>
<p><code><br />
void BafRecord::getType()<br />
{<br />
LOG_TRACE( "BafRecord::getType" );<br />
LOG_TRACE( "/BafRecord::getType" );<br />
return;<br />
}</code></p>
<p>Each function would have a start and stop trace message.</p>
<p>Now this might raise an eyebrow or two but I assure you it definitely helps when your program crashes and you do not have a nice debugger on hand.  Like say, if a non-technical user is using it.</p>
<p>This is how my linux application was programmed and I went the extra step in bafprp to work these in while I was working.  Enough about this though, a short while ago, after adding one of the major structure types to the program my application slowed down from parsing a 12 meg file in 2 seconds to 2 minutes and I was greatly concerned over the well being of my design.</p>
<p>I tried many things, first I greatly reduced the number of memory copies my program executed, then I changed my file input so that it would read the entire file at the start and reference a data bank instead of reading the file each cycle.  However none of these things put a dent in the processing time.  So then I went online to try and find a nice and easy code profiler.  Code profilers will basically watch your program execution and tell you which function your program is spending the most amount of time in.  I ended up finding <a href="http://www.lw-tech.com/">LTProf</a> which allowed me to profile my program without recompiling or changing my program at all.  I am actually very surprised at how well it works with compiled binaries.  After running a release version of my program it was still able to accuratly determine function names and operate like it had a window into the source code.<br />
<a href="http://www.mrlwork.com/images/ltprof.png"><img src="http://www.mrlwork.com/images/ltprof-thumb.png" alt="" hspace="10" vspace="10" width="161" height="100" align="right" /></a></p>
<p>I found that my time stamp function, NowTime, which returns the current time as a string, was taking a noticably large amount of my program&#8217;s time.  Thinking back to what code uses this function I discovered the flaw.</p>
<p>When I wrote the log program I wrote the log level exception into the log class.  This way if the program tried to log a trace message it would get sent to the output class, which would then pass it on to the logs if the level was at or below the log level type.  However this was not enough.  as it turns out simply creating the log message twice in each function had a substantial effect on the processing speed of my program.</p>
<p>Needless to say as soon as I moved the log level check to the macro the process speed dropped from 2 minutes to 30 seconds.  Now some might say that trace logs this detailed are excessive, however I believe they can help greatly when dealing with a malfunctioning program.  So as a final statement, be careful when you design systems, and beaware of how to use your tools.  And if your program runs 3 times longer then a similar program, there is probably something horribly wrong.</p>
]]></content:encoded>
			<wfw:commentRss>http://charlessolar.com/post/25/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Projects Online and Open Source</title>
		<link>http://charlessolar.com/post/24</link>
		<comments>http://charlessolar.com/post/24#comments</comments>
		<pubDate>Fri, 11 Jul 2008 05:31:04 +0000</pubDate>
		<dc:creator>Charles Solar</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[bafprp]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[update]]></category>

		<guid isPermaLink="false">http://www.mrlwork.com/?p=24</guid>
		<description><![CDATA[I finally got around to setting up svn for my project. Thanks in part to some new tools I recently came across the transition was fairly painless and after about 2 hours of cleaning up my old project and trimming the fat I uploaded what I will be working on to http://code.google.com/p/anaa/ I also created [...]]]></description>
			<content:encoded><![CDATA[<p>I finally got around to setting up svn for my project.  Thanks in part to some new tools I recently came across the transition was fairly painless and after about 2 hours of cleaning up my old project and trimming the fat I uploaded what I will be working on to <a href="http://code.google.com/p/anaa/" target="_blank">http://code.google.com/p/anaa/</a></p>
<p>I also created a second project of a more work related function.  This project deals with reading and parsing Bellcore BAF files created by various soft switches in use around the world.  These records contain call records in a highly coded and formated to Telcordia specifications in their GR-1100 document.  This document is not very cheap to come by so I have started work on improving one of the best free parser&#8217;s available today, <a href="http://www.xach.com/misc/bafview/" target="_blank">bafview</a>.  You can find this project here <a href="http://code.google.com/p/bafprp/" target="_blank">http://code.google.com/p/bafprp/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://charlessolar.com/post/24/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Data Driven Apps!</title>
		<link>http://charlessolar.com/post/20</link>
		<comments>http://charlessolar.com/post/20#comments</comments>
		<pubDate>Mon, 17 Mar 2008 18:29:49 +0000</pubDate>
		<dc:creator>Charles Solar</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ramblings]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[factory]]></category>
		<category><![CDATA[research]]></category>

		<guid isPermaLink="false">http://www.mrlwork.com/?p=20</guid>
		<description><![CDATA[Ok ok, I am writing again! If you read my previous posts on dynamic npc actions then this is an update on my progress. If you have not, this is about how to create good file formats for your applications. As some might have expected this project is taking more time then expected, partially because [...]]]></description>
			<content:encoded><![CDATA[<p>Ok ok, I am writing again!  If you read my previous posts on dynamic npc actions then this is an update on my progress.  If you have not, this is about how to create good file formats for your applications.</p>
<p>As some might have expected this project is taking more time then expected, partially because I am currently downing bosses in WoW, and partially because its very hard.  So lets just cover what has been going on since my last post.</p>
<p>I spent a lot of time thinking of the best structure for my idea in terms of objects and file formats.  I do not know if I covered this before because I am to lazy to view my past posts so heres a recap of the basic composition of what I have been calling a &#8216;Puppet.&#8217;  A puppet is a game object with x number of movable joints.  These joints are built in a tree structure and move based on messages passed to his parent.  These messages are generated from a actor class who learns actions and movements as I previously discussed.  When I was designing the puppet class I hit a big fat road block.  I wanted the ability for a puppet to be independent of his underlying joint structure.  That way I could have a puppet control everything from a human to grass.  So you might think, &#8216;No problem, do some tricky interface work and have derived classes for each type of puppet.&#8217;  WRONG!</p>
<p>See I myself have read many articles about component game object design, and I do believe I wrote an article on this in the past.   However do not get the wrong idea, what I did is not EXACTLY component objects, but kind of close.  Because when I thought about components I also thought how to best describe them in a file format.  And after thinking about that I decided that I wanted a global file format to describe not only each type of puppet but the entire world.  And that the entire game will be built out of components in a tree structure built at load time from this file format.  I am getting a bit ahead of myself here so lets get some examples here.</p>
<blockquote><p> &lt;world&gt;<br />
&lt;name type=string&gt;Main&lt;/name&gt;<br />
&lt;description type=string&gt;<br />
Big world for which to run tests in<br />
&lt;/description&gt;<br />
&lt;floor type=plane&gt;<br />
&lt;p1 type=vector&gt;-1000 -1000 -1000&lt;/p1&gt;<br />
&lt;p2 type=vector&gt;1000 1000 1000&lt;/p2&gt;<br />
&lt;material&gt;dirt01.mat&lt;/material&gt;<br />
&lt;/floor&gt;<br />
&lt;joint&gt;<br />
&lt;position type=vector&gt;0 0 0&lt;/position&gt;<br />
&lt;orientation type=vector&gt;0 0 0&lt;/orientation&gt;<br />
&lt;puppet&gt;arm.puppet&lt;/puppet&gt;<br />
&lt;/joint&gt;<br />
&lt;/world&gt;</p></blockquote>
<p>This is my toy world I am working in.  The file format is xml and I use tinyXML to load and parse these files.  For those familiar with ogre, I made a resource of type XMLFile to load these.  Now here comes the clincher, this XMLFile resource will load every type of game object I desire, regardless of type or purpose.  Not only that, but I only added 2 methods to the class.</p>
<p>So let me explain a bit about these methods, they are named &#8216;build&#8217; and they are called usually immediately after loading the file.  Basically what they do is look at an element in the xml, find a builder for it, have the builder build it, and attach the new object to the world tree.  In this example, the world has no parent and all elements inside the world tags are children of the world.  I use the type descriptors so that I would not have to write many classes that do the exact same thing.  Elements that load another file, like the puppet tags, will load that file in their own world and all objects created from that are children of the puppet.  After the build the main program is not aware of any object other then the world.  Messages are passed to the world when need be, however most thought processing is done in the world object, not by the game engine.</p>
<p>Lets get an example puppet up here:</p>
<blockquote><p> &lt;puppet&gt;<br />
&lt;name type=string&gt;arm&lt;/name&gt;<br />
&lt;description type=string&gt;<br />
Generic arm<br />
&lt;/description&gt;<br />
&lt;joint&gt;<br />
&lt;name type=string&gt;shoulder&lt;/name&gt;<br />
&lt;gib&gt;upperarm.gib&lt;/gib&gt;<br />
&lt;joint&gt;<br />
&lt;name type=string&gt;elbow&lt;/name&gt;<br />
&lt;gib&gt;forearm.gib&lt;/gib&gt;<br />
&lt;joint&gt;<br />
&lt;name type=string&gt;wrist&lt;/name&gt;<br />
&lt;gib&gt;hand.gib&lt;/gib&gt;<br />
&lt;joint&gt;<br />
&lt;name type=string&gt;pinky&lt;/name&gt;<br />
&lt;gib&gt;pinky.gib&lt;/gib&gt;<br />
&lt;/joint&gt;<br />
&lt;joint&gt;<br />
&lt;name type=string&gt;ring&lt;/name&gt;<br />
&lt;gib&gt;ring.gib&lt;/gib&gt;<br />
&lt;/joint&gt;<br />
&lt;joint&gt;<br />
&lt;name type=string&gt;middle&lt;/name&gt;<br />
&lt;gib&gt;middle.gib&lt;/gib&gt;<br />
&lt;/joint&gt;<br />
&lt;joint&gt;<br />
&lt;name type=string&gt;index&lt;/name&gt;<br />
&lt;gib&gt;index.gib&lt;/gib&gt;<br />
&lt;/joint&gt;<br />
&lt;joint&gt;<br />
&lt;name type=string&gt;thumb&lt;/name&gt;<br />
&lt;gib&gt;thumb.gib&lt;/gib&gt;<br />
&lt;/joint&gt;<br />
&lt;/joint&gt;<br />
&lt;/joint&gt;<br />
&lt;/joint&gt;<br />
&lt;/puppet&gt;</p></blockquote>
<p>As you can see this file format is very flexible, the same structure that built the world can build a puppet and also a gib:</p>
<blockquote><p> &lt;gib&gt;<br />
&lt;name type=string&gt;forearm&lt;/name&gt;<br />
&lt;notes type=string&gt;<br />
Fore arm gib<br />
&lt;/notes&gt;<br />
&lt;mesh&gt;forearm.mesh&lt;/mesh&gt;<br />
&lt;input&gt;<br />
&lt;name type=string&gt;shoulder&lt;/name&gt;<br />
&lt;position type=vector&gt;0 0 0&lt;/position&gt;<br />
&lt;/input&gt;<br />
&lt;output&gt;<br />
&lt;name type=string&gt;elbow&lt;/name&gt;<br />
&lt;position type=vector&gt;7 0 0&lt;/position&gt;<br />
&lt;/output&gt;<br />
&lt;/gib&gt;</p></blockquote>
<p>I want to clarify one thing before I go on.  Elements called position or orientation, these attributes are not given any attention by the builders.  Instead those objects simply exist on the tree for someone else to read them and make the correct adjustments.  For example, the puppet&#8217;s name element simply sits as an element on the tree until a debugger opens and the entire tree structure is displayed.  At that time the debugger will go through each element and find name tags that it will use to give more information on the node.  And the description works the same way.</p>
<p>They are both created by the string builder, as denoted by the &#8216;type=string&#8217; attribute I give them.  The value is assigned and the name of the new object is set, but the type is always a string.</p>
<p>So what exactly is required to declare a new type of object?  Just a builder and an actual object.  Take this example of the string object.</p>
<blockquote><p> class ScktString : public ISocketable<br />
{<br />
friend class StringBuilder;<br />
public:<br />
void setValue( std::string val ) { _string = val; }<br />
std::string getString() { return _string; }<br />
private:<br />
ScktString( std::string propName ) : ISocketable( propName ) {}</p>
<p>std::string _string;<br />
};</p>
<p>class StringBuilder : public IBuilder<br />
{<br />
public:<br />
StringBuilder() : IBuilder() {}<br />
Socket* build( std::string element, Socket* parent );<br />
const std::string&amp; getType() const;<br />
static std::string BUILDER_TYPE_NAME;<br />
private:<br />
static const StringBuilder registerThis;<br />
};</p></blockquote>
<p>As you can see its relatively easy to create a new object.  Lets start at the builder, when the xmlfile is building it will search for a builder based on its type name, which is assigned by you.  A builder list is created at the start of the program, as each builder has a static &#8216;registerThis&#8217; variable that adds it to the builder list.  Those familar with static factories should be familiar with this.  The builder&#8217;s build method gets called with the name of the element and its parent&#8217;s socket.  A socket is an object that accepts links from children.  The builder then builds the object passing its name.  The sockable base class is for objects that can be socketed or linked with a parent.</p>
<p>So the string object is created and the string builder passes back the parent object.  This is done in case the new object has a socket himself.  In that case he would pass back his socket and the builder would build his children and attach them to him.  In string&#8217;s case however, there is no socket and a little while later the builder assigns the string object a value by calling the setValue method in the parent object with the objects name and value as parameters.</p>
<p>After all the work we are left with one tree that contains all objects in the game.  Kind of like a scene manager, but for ALL objects, not just renderable ones.  And oh, don&#8217;t forget that the entire tree was created by one instance of XMLFile.  As programmers we should always strive to achieve the cleanest and most powerful format we can muster.  This format is not only really easy to implement, but also holds unlimited power.  You want to load a texture?  Create a texture socketable object, and implement file specific loading inside it.  You want to script AI?  Either create an AI socketable object that reads children objects that decribe a strategy, or create a python socketable object that will load your ai scripts and parse them.  In this way our file format can act a proxy for another format or as the direct format.  The most important thing however is that none of our in game objects need to give file formats a single thought.</p>
]]></content:encoded>
			<wfw:commentRss>http://charlessolar.com/post/20/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Compiler</title>
		<link>http://charlessolar.com/post/14</link>
		<comments>http://charlessolar.com/post/14#comments</comments>
		<pubDate>Sat, 15 Sep 2007 16:33:32 +0000</pubDate>
		<dc:creator>Charles Solar</dc:creator>
				<category><![CDATA[Game Design]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ramblings]]></category>
		<category><![CDATA[ai]]></category>
		<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://www.mrlwork.com/?p=14</guid>
		<description><![CDATA[So heres the deal, every game needs some sort of script compiler. Regardless of how its designed, there will always be a time when the ability to edit the game without recompiling is key. But thats not the only reason, scripts allow us extra layers of abstraction so we can do complex things such as [...]]]></description>
			<content:encoded><![CDATA[<p>So heres the deal, every game needs some sort of script compiler.  Regardless of how its designed, there will always be a time when the ability to edit the game without recompiling is key.  But thats not the only reason, scripts allow us extra layers of abstraction so we can do complex things such as &#8216;pickup( itemid )&#8217; with ease.  But I am getting   distracted.</p>
<p>I have been working on this component AI idea and have come to the point where I need to start defining actor actions through scripts.  How I have it setup now is the npcActor&#8217;s state will slowly degrade over time (think the sims) and when it reaches a threshold they go and search for an object that can alleviate their problems.  Its a pretty simple design for a simple test.  As mentioned in previous posts, I want these npc&#8217;s to learn from interacting with the environment.  This combined with the mbti structure and other things should produce reasonably agile AI (see previous posts for specifics).</p>
<p>I thought of making this post to stress a key factor in my decision making process as it pertains to this project.  And that is abstraction.  The abstract is key to this project.  In an ideal world, nothing here should be hard coded, unfortunately that is a little hard to do, especially right from the get go.  So what I decided to do was to brute force my way to a reasonable demo app and work backwards from there.  Removing static code as needed to perfect the design.   For instance, I have pretty much decided on a syntax for my scripting language, but I have left much of the interpretation to genetic algorithms in the compiler.  Here is a sample script</p>
<p><code><br />
using actions<br />
using health</code></p>
<p>_actions::sit $this<br />
$sitting = true<br />
callback -actions::stand _stoodup<br />
{ $health::comfort +1 / 5 } while $sitting</p>
<p>_stoodup:<br />
$sitting = false<br />
::<br />
I am not going to explain the syntax because to any programmer the intentions should be clear.  The problem I have been facing is how to keep the intentions abstract enough to allow multiple interpretations.  I want Bob&#8217;s sitting to look different from Kim&#8217;s.  I have currently setup a system where the compiler creates these jobs for each script and at the appropriate times sends messages to actors to handle actions.  It is then completely up to the actor as to how to handle the action.  For instance, when the compiler runs over &#8216;_actions::sit $this&#8217; it will send a message to the host actor to sit on the target object.  In this case the message will not be as simple as<br />
<code><br />
msg.id = ACTION_SIT;<br />
msg.target = 0x01234567h;<br />
msg.brainless = 1;<br />
</code></p>
<p>Instead the message will contain a number of input to be inserted into a designate neural network, which would have been trained earlier to sit when given those inputs (exactly how they sit is up to the GA).</p>
<p>So then how to handle direct variable access like the &#8216;$health::comfort +1/5&#8242; line above.  Well some messages will have to be specially constructed to be brainless.  I figure I will have a range of message id&#8217;s designated for variable access, neural network input, etc.  So a msgID of 1 would be to set a variable, and 2 would send the incoming data into the NN.</p>
<p>This is not the final system, just what I am currently using for testing.  However this is the current framework for future applications.  The goal of this first program is to weed out any bugs and get a clear understanding of how I want this thing to run.</p>
<p>You can notice how this solution offers a direct line to the actor&#8217;s state of mind without hard coding everything, which is exactly what we want.</p>
]]></content:encoded>
			<wfw:commentRss>http://charlessolar.com/post/14/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

