I Got Mine

The Apple iPad arrives, right on time.

At 11:14 this morning [Saturday, April 3, 2010], our Apple iPad was delivered to our office door.

This is the first piece of hardware that I can recall ever pre-ordering, and I actually placed the order within the first minute that it was possible.  Since the iPad was announced, I have read lots of skepticism about its value and usefulness, and I am resistant to hype.  (In fact, I often avoid things that are probably quite good simply because of the hype attached; for example, I have thus far refused to see Avatar.)  With the iPad, though, I could immediately comprehend its potential, especially for games and particularly for the kind of games that I enjoy creating and playing.

While awaiting a delivery, whether it be books, music, or hardware, I tend to almost obsessively check the package tracking.  In the case of this highly anticipated product release (witness the latest episode of Modern Family), I was apparently not alone.  Despite several different rumors to explain the odd tracking data from UPS, many of which ended with a conclusion about shipments being delayed, the actual explanation is likely to be much simpler.  My guess:  Because there were 200,000 units being shipped from China, they were originally packaged in huge lots destined for each distribution point (in our case, Louisville, Kentucky) and not scanned individually until they arrived there.  (I seriously doubt my iPad flew nonstop from Guangzhou to the Bluegrass State.)

Interestingly, I happened to be awake at around 5:33am, having just watched an exciting (and wet) Formula One qualifying session live from Kuala Lumpur, Malaysia.  The wind was apparently coming from the right direction, and I heard the airplane carrying my shipment fly almost directly overhead.  The “arrival scan” was 22 minutes later, though it actually took two more trucks, and a couple more scans, before it arrived here.  (The iPad Dock is still in transit, via a different carrier with distribution in a different, albeit neighboring, state.)

Anyway, there will certainly be a proper review in the future, but right now I feel that it is time to get started playing around with our latest software platform.

The most surprising aspect so far was that Apple had UPS require identification in order to receive delivery of the iPad package.  The only “problem” so far is that I did not get to use my alternative title, “iSad” (had it not arrived).

Productivity Boost

Prolific Development Through Isolation

Over the past several weeks, I have been working very hard on a number of exciting new projects, all of which are making great progress.  In the process, though, I have managed to neglect and get a couple of weeks behind on my email, while essentially ignoring all other forms of inbound communication.

The result is that my productivity has increased greatly, while only missing one important piece of information.  Therefore, I have decided to make these changes to my workload permanent.  As of today:

  • I will shut down our email server.  It receives, literally, thousands of messages daily, of which 99.9% is spam; even messages addressed only to my legitimate email addresses are more than 96% spam.  Besides, the old hardware is locking up on a regular basis anyway.
  • I will remove telephone service from the office.  Our two voice lines are used almost exclusively for answering telemarketing calls, and our fax line is disconnected most of the time due to the high volume of spam faxes.
  • I will bring an end to our social media experiment.  In the time that I have been focusing on programming, I have not checked Facebook at all and do not feel that I missed anything.  I feel likewise about Twitter, which I have never checked.
  • I will no longer spend any more than one hour per year writing joke posts for this blog.  It is really too nice outside to be in here right now.
  • I will create a private contact page on our web site exclusively for those who pay us money.  Those wishing to pay us money can initiate contact via blog comments.
  • I will keep the post office box, despite the junk mail, as it is a direct means for us to receive money.  One can avoid the online back and forth by just attaching a check to your message and sending it to our business address.

I can feel my productivity on the rise already!

Most Popular Solitaire 2.02

Our entry level product for Mac OS X and Windows is updated.

This week, Goodsol Development released Most Popular Solitaire 2.02, a maintenance release of this popular solitaire title.  The product contains 30 of the most popular solitaire games, including FreeCell, Spider, and Klondike (known to many as simply “Solitaire”), plus 13 more bonus variants (not available in the evaluation version).

Ostensibly, this update contains a few bug fixes and does not change much about the product itself, though internally it takes a sizable step forward.  This version brings the code up to the latest (properly tested) version of the Goodsol Solitaire Engine, so future updates will be easier to build and maintain (on multiple platforms).

Most Popular Solitaire is available for only $16.95 via secure server, and trial versions are also available for Windows and for Mac OS X.

More is yet to come.

A couple of weeks ago, I decided to challenge myself to completing three products in three weeks.  I have been sequestered in my office, for the most part, since then.  As much as I would like to proclaim the two Most Popular Solitaire 2.02 SKUs as two of those, the truth is that they were not even considered, so there are still three products (and SKUs) yet to come, albeit not next week.

My status is that the first priority, a full Mac OS X port, has taken longer than originally anticipated, but it will be announced shortly.  The second project, extending a recent product to operate on a new platform, has been forcibly pushed back for at least 9 more days.  (You figure it out; I cannot talk about it.)  The final product in this group, Pretty Good Solitaire Mac Edition 2.20 (with 100 more games and a few new features), is making good progress but…  there is only so much we can do at once.

Finally, although I have not had any time for Facebook during my challenge, I will tell you that you — yes, you! — can now become a fan of Pretty Good Solitaire.

API Design Dilemma

I need to decide how to define certain parameter types.

The general situation is this:  I am refactoring a piece of C++ code to be part of a separate library, so I am in the process of defining and documenting an API for using the included classes and methods.  A fundamental design consideration is that the library may be called by third parties, without access to the source code, so I need to make the code as close to bulletproof as possible.  (For internal development, at least I know the methods used, how the API will be utilized, and that it will not be abused terribly.)

During this process, I encountered a theoretical dilemma about how to handle certain parameters.  Specifically, I was working on method definitions that included sizes and counts that should never be negative (but, of course, I need to prepare for abuse).  As an example, say I am reviewing a method that is declared like this:

    bool FillBuffer ( byte* pBuffer, int nSize );

Here, pBuffer is a pointer to the buffer to be filled, and nSize is the size of that buffer.  Of course, it is not possible for a buffer to be a negative size, so my initial reaction was to redefine it as:

    bool FillBuffer ( byte* pBuffer, unsigned uSize );

This makes perfect sense from a theoretical standpoint, but then a practical consideration occurred to me.  I always verify parameters with an assertion and, for a public method (as here), abort the routine if verification fails, with an exception or error return as appropriate.  In this case, my original method would assert nSize to be greater than zero (and return false), which would catch any negatives.  The new method would only catch the case where uSize was zero, but if a careless programmer cast a signed integer (or, worse, let the compiler do it), the current validation check would not identify a problem.

So, there were a few obvious solutions that I considered:

  • I could leave the original definition alone, which would catch obvious parameter errors, but would be theoretically incorrect, and if a programmer wanted to pass the size of a static buffer, using sizeof(), there would be a signed/unsigned mismatch.
  • I could use the new method definition, which would be correct in theory, and just trust programmers not to abuse the method with invalid parameters (and let them suffer if they do).
  • I could use the new method definition and add a sanity check so an extremely large buffer size (i.e., likely a negative value cast improperly) would be rejected, but the drawback there is that any such check would be somewhat arbitrary, and it would limit the functionality for any programmer who truly wanted to use an enormous buffer.

Each of these solutions has advantages and drawbacks.  I dislike having a parameter take a type that is not accurate (though not so much as to not have written this code in the first place), but I dislike arbitrary limits even more.  However, I know that defensive design is important here, since a careless programmer is, in my experience, the most likely to complain that the library or API is at fault.  (I was once threatened with physical violence when I produced a critical review of code written by a nominal “programmer”.)

At this point, I am leaning toward a hybrid solution by overloading the method with both (or multiple) definitions, the original checking for negative sizes as usual before doing an explicit cast of the size value and passing processing to the new/correct method.  The advantage is that passing an actual negative number (or signed type) will result in that extra checking, and a programmer could pass a buffer size up to the limit of the unsigned type.  The disadvantages are the additional work needed to create the extra stub(s), loss of type checking during static analysis, and the fact that our careless friend could still cast a value to create problems (but then it should be quite obvious, at least).

This post is an exercise in the process of working through a problem by simply writing down the issues, which often results in a solution (or decision) by the time one is finished with the description.  (It did here.)  I would, however, welcome any comments on my proposed solution, or other suggestions.

Finally, yes, I know that int and unsigned are not ideal parameter types for this in the first place, but I used them for the purpose of illustration.  (The principle also applies to object counts and other similar parameter types.)

Pretty Good Solitaire Mac Edition 2.11

An update to our primary Mac product is published.

Goodsol Development released Pretty Good Solitaire Mac Edition 2.11 last week.  This updated version is a maintenance release that adds no features, but fixes a number of issues that were discovered in the previous version, including a couple of obscure crash bugs.  It is definitely a recommended update, and it is free to all previous PGSME customers.

Pretty Good Solitaire Mac Edition features 200 different types of solitaire games using standard playing cards, plus an additional 45 bonus games in the full (purchased) version.  You can download an evaluation version, or just purchase via secure server for only $24.95.  For more information on the product, please visit http://www.goodsol.com/mac.

This is our third or fourth product release in 2010 (depending on how one counts), and the regular release schedule should continue for a while yet.  Upcoming releases will include Pretty Good MahJongg Mac Edition, the first version of our MahJongg solitaire game for Mac OS X, and Pretty Good Solitaire Mac Edition 2.20, which will increase the game count to 300 (plus even more bonus games).  We also have some other titles planned in the near future, so stayed tuned for more announcements (soon).

Disk Images Revisited

There are some issues under Snow Leopard.

In a blog post last year, I gave detailed instructions on Making Mac Disk Images Pretty.  Unfortunately, I have discovered that the most recent version of Mac OS X has some issues of which developers should be aware when using that technique (not that there is any obvious alternative).

I recently upgraded my development system to Mac OS X 10.6 (Snow Leopard).  Apple is fairly aggressive with requirements for its development tools,  and I need to upgrade in order to use the latest iPhone SDK.  Of course, I already had a Snow Leopard partition that I had used for testing, so I knew that our software would work, and I never experienced any previous problems.

When the time came to build an update for one of our products (FreeCell Plus 4.00/4.01), I had a few minor niggles with Xcode 3.2.1 (the latest version), described later, but I got the product built and packaged properly.  Then it was time for testing on our other supported versions of Mac OS X, Tiger (10.4) and Leopard (10.5), and I was surprised to learn that, although the software itself ran flawlessly, the disk images showed no background image when mounted, and the folder size was wrong.  The icons were in the correct locations, relative to the top left corner of the window, so the formatting was not entirely ignored, just effectively ignored.

After some research into the problem, I found the answer in this DropDMG forum thread, where it is stated that Apple has confirmed this as a bug in Snow Leopard.  I moved DropDMG over to my Leopard partition, rebooted to that version of Mac OS X (10.5), and build my packages there.  That solved the problem, and the background images showed in all supported versions of OS X.

Conclusion: In order to have background images appear in disk images on older versions of Mac OS X, you must build the disk image under Leopard or earlier, not Snow Leopard.

Caveats: Sometimes, when opening a prepared disk image under Snow Leopard, there is a blank space on the bottom (probably not coincidentally exactly the same size as the folder toolbar), which does not appear on other versions of Mac OS X.  Also under 10.6, the folder toolbar includes a slider control for quickly changing icon sizes (a.k.a., fouling up your layout).  I have not been able to determine the cause of the former issue (yet) nor the reason for the latter.  (How often does one actually change icon sizes that this is even remotely necessary?)

There were some build issues with Xcode 3.2.1 under Snow Leopard.

As I mentioned, I experienced a couple minor build issues after the upgrade to Xcode 3.2.1, both of which were addressed, albeit with differing degrees of success.

First, the default compiler in the latest version of Xcode is GNU 4.2, which is incompatible with the 10.4 (universal) SDK, and the very first build let me know that.  Faced with a choice, downgrading the compiler to GNU 4.0 versus upgrading to the 10.6 SDK, I chose the latter, which I saw as the path of least resistance (see “Apple is fairly aggressive with requirements for its development tools” above).  Unfortunately, at least for our project, the 10.6 SDK does not function as advertised and, despite properly setting the target OS to 10.4 (and obviously not using any 10.5 or 10.6 features), a product built with the 10.6 SDK will not run under Tiger (period), although it does work under Leopard.  I switched (back) to GNU 4.0 and the 10.4 SDK and all was well.

Second, the latest version of Xcode upgrades its tools (obviously), and one seemingly innocuous change to the linker was to eliminate the need for the “-mlong-branch” compile option for certain object files (generally kernel files, which means primarily for Apple and not so much for the rest of us).  Unfortunately, a warning message was added to that effect, yet Apple did not update its PPC object files accordingly.  As a result, every time one links a universal binary (supporting PPC), the linker throws this warning: “Object file compiled with -mlong-branch which is no longer needed.”  The only permanent solution is to recompile certain (protected) development files oneself, or wait until Apple fixes the problem.

The latter issue is extremely annoying to me, because now I am in the position of either ignoring linker warnings, which I never advise, or spending hours (or days) figuring out how to rebuild a portion of the development tools.  Can you say, “not my job“?  Personally, from my experience of Apple over the last few years, my bet is that this problem will soon be addressed by a campaign to suggest that developers should not continue to be stuck in the past supporting PPC systems.

Does anybody want a piece of that action?

FreeCell Plus 4.00

A new FreeCell solitaire game for Mac and Windows

Today, on the 14th anniversary of version 1.0, Goodsol Development published FreeCell Plus 4.00, a major update to its basic collection of FreeCell-type solitaire games.

FreeCell Plus 4.0 is an entry-level collection of 8 solitaire games, including the original FreeCell (with compatible deals), plus several similar card solitaire games, including favorites such as Sea Towers and Penguin.  The registered version includes 4 more bonus variants, all for only $9.95.  As with all of our products, one can download trial versions from the FreeCell Plus web site (or for Windows or for Mac OS X directly).

This particular update has been interesting because the previous version, FreeCell Plus v3.0, was released way back in 1998, for Windows 3.1!  Aside from being a less expensive product for FreeCell lovers, this title makes two new games available on the Mac side (and in Windows climb mode): Two Cells (standard) and Three Cells (bonus game).

We are just getting ramped up for a very productive year, with two releases already, plus three or four more in the pipeline for the next couple of months.

Goodsol Solitaire 101 Mac Edition 2.00

A new product release for the New Year

Last week, Goodsol Development released Goodsol Solitaire 101 Mac Edition 2.00, as our first new product for 2010.  Now equivalent versions of Goodsol Solitaire 101 are available for both Windows and Mac OS X.

Goodsol Solitaire 101 is a collection of 101 of the most played solitaire games the world over, plus 34 bonus games for customers, and it includes support for climb mode.  You can download the product for Mac OS X here (or for Windows here) and purchase the game now for only $19.95 here.

In the several days since its release, Goodsol Solitaire 101 Mac Edition 2.0 has (as of this writing) taken the #4 position in the Cards & Puzzle category at Apple Downloads, which translates into #9 in the general Games category.  (Most Popular Solitaire 2.01 is still hanging in there at #15 of the 20 games on the first list, too.)

This release is the first of many expected throughout 2010, including some new products, major upgrades, and probably support for a new platform as well.  There are already two more products scheduled for publishing in the next few weeks.  This New Year is starting out to be as strong as last year ended, and I hope only to build on this momentum.

Beatles-style sweep of the top 3 positions, anyone?

Compartmentalization

Separating business matters from personal issues

Recently, I received the first newsletter of the year from (friend and former colleague) Steve Pavlina.  For those of you who do not already know about Steve Pavlina, he founded Dexterity Games (now defunct) and published Dweep, an award-winning puzzle game.  He was also the President of the Association of Shareware Professionals and was inducted into the ASP Hall of Fame in 2005.  After this success, he left the game industry to pursue a career in motivational speaking and personal development, writing the book, Personal Development for Smart People.

Anyway, the meat of the newsletter, nestled in between the various sales pitches and recommendations from which he earns his living, was a section entitled, “Living by Your Own Rules“.  This intrigued me, as it seemed to correspond nicely with my personal plans for 2010, so I read on.  However, I quickly discovered that his ideas did not mesh with my own in this case.  It had little to do with the actual content of his writings, but his radical ideas of sharing his personal life (specifically, his sexual preferences and desires) in the place in which he does his business.

Specifically, Steve made a blog post with his 2010 goals in which he reveals his personal goal of pursuing “Alternative Relationship Styles” and goes into detail (for which you will need to read his post).  I have no problem whatsoever with his choice to pursue this lifestyle, but I do question the wisdom of presenting this in a forum in which he currently (by his own numbers) sells six figures a month; it seems risky to the point of potential self-destruction.  More to the point, I wonder what benefit to his business (not to mention personal reputation) he seeks to gain from this pursuit.  (I do see a great benefit in finding compatible sexual partners, though.)

Steve is good at taking things to the extreme, completing college in only three semesters, ramping up his healthy eating through vegetarianism to a vegan diet and finally raw foods, and now personal openness to a radical degree.  He calls this last part “courage”, which it certainly takes, but I am not sure that courage is always the best choice.  Aristotle’s Doctrine of the Mean suggests that the opposite of cowardice is rashness, and this might apply here.  The more common idiom is, “All things in moderation, and moderation in all things.

Personally, I think that it is still wise to compartmentalize to some degree, especially keeping business issues separate from (potentially) controversial personal issues, such as politics, religion, and sexuality.  Discussing the particulars of these in a business context has the potential of alienating people with little chance of significant gain.  I do not have a problem seasoning my business posts with personal items, and I definitely have business friends with whom I share more, but any proclivities I may (or may not :)) have should remain discrete.

Ultimately, I guess that I am intrigued at Steve’s attempt to alter societal norms, and I wish him the best of luck, but I am also glad that it is he, rather than I, who is taking the risk of falling flat on his face.  (Ridicule I could handle; starvation, not so much.)

What do you think?