Old School MMORPG

Before World of Warcraft (certainly the most successful MMORPG ever), there was the MUD: Multi-User Dungeon.

I remember discovering MUD’s back in undergrad. Had a great time playing them, met some good people, and frankly if not for them I wouldn’t be a computer programmer today. The natural progression was starting as a player, but then wanting to get into the creation side of MUD’s. Certainly you can create worlds without knowing how to code, but I wanted to run a MUD and shape the world… so I had to learn how to program. I picked myself up a book on the C programming language, bought a development environment (THINK C), and got to work. I also recall that at my undergrad institution, the mainframe everyone used for email and such was a VAX-VMS system… no way to run a MUD there. But over in the CS department? They had 486’s running some flavor of Unix (SCO, I think), and I managed to finagle myself an account even though I wasn’t a CS student. 🙂 Good times.

Of course, pure MUD’s were text-based. We dreamed about making graphical MUDs, even thinking of ways to combat the limits of the age. For instance, if all you had was a 2400 baud modem, you can’t be pushing massive amounts of graphics over that slow connection (you kids today think a web page taking 3 seconds to load is slow? back in my day….). Besides, we lacked the time and resources to develop such things, but it was always on my mind.

I guess that’s why modern MMORPG’s don’t appeal to me — been there, done that, got over the addiction.

However, Daughter keeps seeing commercials for various MMORPG’s and they’ve perked her interest. Heck, with LEGO Universe about to come out, Oldest is curious too. However, they all hit the same snag: monthly subscription fees, and Dad isn’t going to pay for it. If they want to spend their own money on that they can, but so far they’re unwilling. 🙂

Nevertheless, Daughter keeps inquiring and it hit me: why not try a MUD? Sure it’s low-tech, but it’s no different from reading a book vs. seeing the 3-D IMAX movie adaptation (i.e. it’s text, you get to use your imagination instead of perceiving someone else’s).

Of course, the geek in me won’t let it be just any MUD! No… my dreams of running my own MUD may have faded but they’ve never left me. I went searching for codebases and found tbaMUD which seems to be a good foundation (I won’t bore you with the lineage). Back in the day, I did things to get MUD servers running on Classic Macs, but it never really worked like people wanted. With Mac OS X being Unix-based and most MUD codebases being biased towards Unix well.. download and see! So I obtained the tbaMUD source, fiddled with it a bit to get it working in Xcode, and ta da… I’ve got a MUD server running here at home. 🙂  It’s not connected to the world at-large but hey… I got to get my geek on, and we’ll see what Daughter thinks of it.

So with that… she should be awake soon. We’ll start up a telnet session later this morning and see what she thinks.

Don’t assume; assert.

For the love of Knuth

If you write code that makes assumptions, assert on those assumptions and assert in a manner that the developer stuck with maintaining your code will see them.

Doing so would save much hair loss, and cut down on the number of times the original author of the code gets damned to hell by the maintainer.

Thank you.

IKImageBrowserView pain

IKImageBrowserView… oh, you are so neat, so full of power and potential.

And you can bite my shiny metal ass.

What a pain you are. How one moment rearranging works, then the next it doesn’t. That I mimic sample code and yet it still doesn’t work. I’m sure it’s something I’m doing, but when other developers also describe the ImageKit classes as “black magic” and curse you (and I’ve had pains with your brother, IKImageView), I know my journey into the abyss is not a solo one.

Onward through the fog….

BWToolkit

BWToolkit is a library of code for Cocoa development.

Actually, it’s more than just a library of code. It comes with an Interface Builder (version 3) plugin that simplifies development and use of the framework. BWToolkit is open source under the generous BSD license, and you can obtain it as source code or you can obtain it as a nice “drop and play” package.

I’ve stumbled across BWToolkit a few times in my development work, but it wasn’t until recently that I could begin using it (seems to have a requirement of Mac OS X 10.5 as a minimum…. doesn’t state that explicitly, but you can see it in some of what it does plus examining the source code). In my use of it so far, it’s been really well done and a real joy to development. Having been an engineer of the PowerPlant C++ Mac application framework back in the day, I know what it can be like to write reusable code modules like this, and BWToolkit has a lot of spit and polish.

Some things I like about it:

  • Drop and play. Just download the distribution, install the IB plugin, ensure the framework is added to your project (link to it, copy it into your resulting bundle) and that’s it. So simple.
  • Use is very simple, because there’s no extra work. Just edit merrily away in Interface Builder.
  • It’s got a lot of those widgets that you commonly want to use but there’s nothing standard from the OS for you to use. Oh sure you could make the widgets, but BWToolkit makes things like the BWAnchoredButtonBar, BWAnchoredPopUpButton, BWUnanchoredButtonContainer and so on… it just helps round out those commonly used widgets so all you have to do in IB is just drag and drop and get on with your work.
  • I love the BWSheetController. I wish I had thought of that class! It’s so common to have a xib with a main window (e.g. document) and then you need to display a sheet on the window. To display the sheet, there’s a lot of infrastructure code you have to write every time, and it’s the same code over and over — perfect candidate for a reusable class to factor that out. With BWSheetController it’s even better because it’s just adding an instance of the controller to the xib, hooking up some outlets, and viola… functional sheet with just a few clicks. Wonderful!
  • Most of the classes are based upon Cocoa classes. For instance, BWSplitView is an NSSplitView, the button classes are typically just aggregates of other NSButton’s. It’s good to subclass where it makes sense, instead of fully recreating from scratch.
  • The use of the BSD license pretty much means there’s little reason NOT to use BWToolkit. It makes your life a lot easier, little restriction upon use, it’s free (beer and speech). What’s not to like?

Some things I don’t like:

  • I found a bug (BWSplitView’s show up in initial random locations if the host window’s “visible upon launch” setting is not on). I reported the bug via email but have received no reply from the author (it’s been long enough). Granted, it seems he’d prefer filing it in his bug tracking system, but I don’t have the cycles right now to do that so I wanted to at least email to ensure the bug didn’t slip through the cracks. So, I’m not sure how active the project is right now. *shrug*
  • There’s not much documentation. Granted, there’s enough to get you going, and eventually you can figure things out. But to make a well-rounded distribution, full documentation of the classes/widgets and an accompanying sample application that shows everything off would make for a better final product.
  • Some of where documentation would be very useful would be things like bottom bars…. you can do bottom bars now so, what’s the point of this class? What advantage does it provide? Or is it a holdover from long ago when the OS provided no means whatsoever? In which case, is the bottom bar class smart about the OS version? Again, one could figure it out from reading code, but formal documentation is better.

All in all, a nice little toolkit.

Still can’t GetLabel()

So we’re at a point in our development cycle where we can finally upgrade our toolset. Installed Xcode 3.2.3, using the LLVM-GCC4.2 compiler, the 10.6 SDK, and setting 10.5 as our minimum OS.

Of course now I compile code and lots of OS function deprecation warnings come up. Time to clean up the source code.

If you need to obtain a Finder label, the old-school way was to use GetLabel(). Even today we still have to use GetLabel(), despite the fact they have deprecated it since 10.5. And while they deprecated it in 10.5, they didn’t provide a replacement API until 10.6. Unfortunately this replacement API isn’t 100% workable.

1. It’s an Objective-C API, in AppKit. Specifically: -[NSWorkspace fileLabels] (and -fileLabelColors).

The old API was a pure C API so you could easily use it anywhere, and we use it in a pure C++ library. Fine. I can create a .mm file with an extern “C” function to provide my own C wrapper and mimic GetLabel()‘s API. But it’s just extra work.

2. It’s only available as of Mac OS X 10.6.

It’s not a huge problem, but it’s irritating they deprecate the old way and didn’t provide a new way until the next OS revision.

3. -fileLabels crashes.

Isn’t that wonderful? They provide a new API and the new API doesn’t work.

And it’s not like it’s any sort of difficult API to work with either. It’s just a simple call.

But how can you get it to crash? Simple. Call [[NSWorkspace sharedWorkspace] fileLabels] 3 times. The first time will be OK. The second time might generate the crash but could also just generate console messages. The third time, you should crash or certainly generate bad messages in the console. If you didn’t crash the third time, certainly on the fourth you should. But typically 3 calls and boom.

-fileLabelColors doesn’t have this problem.

Investigating it, it seems there’s something being double-released/freed/deleted inside of -fileLabels. You can turn on garbage collection and it won’t crash, but lots of ugly console messages are generated.

What also bugs me? How did this API ship with such a bug?  Didn’t they test it? Didn’t they unit test it? Did they only test it under garbage collection? Did they write the API only for the Finder and figure if the Finder wasn’t crashing that was a good enough test to say a public API for the OS would work?  I mean, I can understand complex bugs, I can understand how code paths can be what they are and how bugs can ship (been a professional software engineer for over 15 years). But something like this? I can’t see how this managed to get out the door.

*sigh*

rdar://problem/8301881 Seems it was also reported as rdar://problem/8084710.

So… there’s no GetLabel() replacement for me until they fix it, 10.7 if I’m lucky. Yes I’ve considered other workarounds, no they won’t work in my particular context, or with a lot of work I could get it working but it’s not mission critical and I have bigger issues to deal with.

Updated: Apple DTS wrote back saying this is a known issue being tracked under its original number: rdar://problem/7287108, which as you can see is at least the third report of the problem. So we can only hope Apple’s going to fix it, but I bet we won’t see it until 10.7 at the earliest.

Named pipes and unwanted hangs

The past few days I’ve been dealing with a wonderful little problem.

They’re called “named pipes“.

The main product I work on in my day job was doing some filesystem scans and would hang for some unknown reason. After much investigation we noticed the file it was hanging on was a named pipe file way down in the bowels of the system (a temporary file created by the com.apple.notify process). What was happening was well… it’s a pipe. Something in my app was opening that pipe and thus the app “hung” because it was now wanting to read from the pipe. Thing is, my app doesn’t care about pipes at all, it’s just working with files. As well, we weren’t explicitly opening the file; we would call some other OS routine and somehow somewhere in that OS function’s implementation it called open() and thus we hung.

And so, what a bear this is.

In the end we decided to check for and avoid pipe and socket files at all costs. Any means by which a file can “get into” the app, we put up a wall at the perimeter so no such files can even get in. We figure we keep them out at the wall, then we don’t have to spend lots of CPU cycles internally to constantly deal with them (tho critical code should still perform checks). Plus, since one big part of the problem is we can’t control what others do and if they might open() the file, we have to nip it in the bud as soon we become aware of the file and minimize how much “work” is done on the file in case some other function might open() the file and we risk hanging.

To check is pretty simple. Code something like this (NB: I tried using the “code” tags and less-than/greater-than signs for the #include, but WordPress’ editor seems to get confused… so I just used the “pre” tag, which isn’t quite giving me the results I want either… oh well.).

#include "sys/stat.h"

bool
FileUtilities::IsUnsupportedFilesystemItem(
const char*    inPath)
{
    bool is = true; // assume failure, because if we fail on such 
                    // a simple operation something really has to be wrong
    if (inPath != NULL)
    {
        struct stat statInfo;
        int retval = lstat(inPath, &statInfo); // use lstat() instead of stat() because 
                                                   // we want to minimize resolutions or other "work"
        if (retval == 0)
        {
            if (!S_ISFIFO(statInfo.st_mode) && !S_ISSOCK(stat.st_mode))
            {
                is = false;
            }
        }
    }
    return is;
}

How you actually cope with it or if you consider them problems or not is up to you and your code and your situation. The key of the above is to get the file’s mode then check the FIFO and SOCK flags. If set, reject the file.

For most people, this isn’t going to be an issue or a problem. I mean, we went around for quite some time and never dealt with the issue. And in daily use, most people aren’t going to see pipe or socket files.

But it’s worth noting and thinking about. Nothing wrong with being a little defensive.

Self-document code is anything but

If you know me, or maybe you can just tell from my blog, I can be verbose.

It’s how I am. I tend to prefer more information to less. I think you get further in life by knowing more, not less.

But I also know this wears on a lot of people. They just want the bottom line and don’t care why or how you got there. IMHO that’s a pity because then they never truly understand and can never arrive at educated conclusions on their own. OK fine, a baby is made, that’s the bottom line. If you want to stop there and never know more, that’s your business. But in my book, knowing how to make that baby is interesting, and then going through the motions of making that baby even more interesting. 🙂  Like I said, it’s good to have knowledge and information.

I write software for a living. There’s great debate about documenting code, be it formalized documentation apart from the code or writing comments in the code itself. I’ve never jived with folks that say code should be self-documenting and that’s all the documentation you need. Sure, you should write readable and maintainable code. Naming your variable “numberOfObjects” is far better than just naming the variable “i”. But you must have comments. Why? Precisely.

Self-documenting code can tell you what and how, but it cannot tell you why. For that, you must use external documentation.

You must go through the effort of writing comments to explain bits of code. Depending on the code, you may also want to write larger external documents (e.g. in a word-processor) that explain the greater architecture and how all the parts of the code fit together and how to use it all. This is something that cannot be conveyed by reading the code itself, and I just don’t understand those that think this sort of documentation is a waste of time and somehow if you do it makes you “not a real programmer”.

Well buddy, real programmers know the moment after the code is written it must start being maintained. If you can’t remember what you had for breakfast a week ago, can you expect to remember why you wrote this code when you come back to it in 6 months?

Case in point. Just yesterday I was working on a bug in our software where the application would hang. All signs and symptoms were odd but somehow made sense to each other. When our QA guy told me one key point (“looking at the permissions flags, there’s a ‘p’… what’s that?”) it all came back to me. The file was a named pipe and I dealt with this very problem in the past. I went looking in code for where I previously dealt with it. I found it. The comment was dated over 5 years ago.

5 years ago.

When I fixed the problem — 5 years ago — I added copious comments to the source code to explain the problem in great detail; 50 lines of comments. I know many would say that was ridiculous! That it’s just his (annoying) verbosity! Well, thank goodness for it because without it there would have been no way I would have remembered that 5-year-old problem in such great detail and know exactly how to fix it (again) today.

Here’s an article by Jef Raskin discussing the same thing. Jef Raskin would know.

So yeah… people tell me I’m verbose. I really don’t care. I am who I am and I know when to be curt and I know when to ramble on. There are times when comments aren’t needed (don’t tell me what or how), but you do need to explain why and not be afraid to go into detail because the code you may have to maintain may be your own. Do yourself a favor and explain yourself. And if someday that code gets to be maintained by someone else, do them a favor and explain yourself.

I’ve never known anyone to say there’s such a thing has having too little ammo. I feel the same way about code comments and information. 🙂

xml standalone

Apple changed the NSXML/CFXML implementation in Snow Leopard to use libxml. Generally a good move, but so far it appears to have caused some problems:

  • The notion of -[NSXMLDocument isStandalone] changed, at least in the sample code I’m using as a reproducible case for the bugs. In 10.5 the value is NO, in 10.6 it’s YES.
  • Having the XML declaration contain standalone="yes", at least in the sample code, eventually causes the libxml parser to crash. Maybe not always, but if you send the sample code an AppleScript of
    tell application "SimpleScriptingPlugin"
        beep
    end tell

    the sample app will crash. Force [myNSXMLDocument setStandalone:NO] and no more crash. Or run it under Leopard regardless of the standalone setting and no crash.

It’s taken many months of investigation and going back and forth with Apple to figure out this OS bug, mostly because due to how the problem comes up we were chasing down other avenues (was this an AppleScripting problem? Still could be, at least in part.). But for now, it seems we’ve a few issues with how NSXMLDocument generates XML, how NSXMLDocument regards being standalone (and across the OS versions), and then how libxml ungracefully handles that specification. Hopefully with my further information, Apple will be able to properly remedy all of this. Yes, it’s all properly filed with Apple, so they’re aware.

I tell you. This crash problem has been plaguing me and our users for quite a while. We’ve been able to provide the users with ways to work around things, but it’s not optimal. My hope is now with this information we can provide a better solution in our code and hope that Apple will soon fix this in the OS. Finally hitting upon this last night was quite the euphoric moment. 🙂  Granted, there may still be other things to deal with for this, and I could be premature in celebrating… but certainly it’s more info for Apple towards fixing the problem, and it’s still a hopeful step in the right direction for me and the users of my product.

Safari 5

Apple released Safari 5 yesterday.

Being a software developer as long as I’ve been, I know better than to get the 5.0 release — wait for the inevitable 5.0.1. 🙂

But I’ve been having so many problems with Safari lately (I think more due to the websites visited than Safari itself, e.g. Facebook) I figured what the hey. I needed to reboot my machine anyways, the Safari 5 install would require a reboot, so might as well.

So far I’m pleased with the update. Rendering of pages is a lot faster than with Safari 4. The new “reader” feature is pretty spiffy, like Quick Look for a multi-page web story. It makes the text bigger, more readable, better layout, no ads. That it’s more readable is certainly a big win. I’m sure I’ll be using this feature more and more as I get used to it being there.

There are finally “extensions” for Safari. I’ll be curious to see what people come up with.

iPhone 4

Being a Mac developer, it used to be an annual ritual to attend Apple’s World Wide Developer Conference (WWDC).

I was supposed to attend this year, but opted out of it because I knew it’d be nothing but an iPhone love fest. I’ve nothing against that, just that it’s nothing directly relevant to my present-day money-making, so the cost of sending me out there isn’t worth it. Nevertheless, I still like trying to catch the keynote because important things happen. Funny thing is, I remember when WWDC specifically was NOT a horse-and-pony show. That the keynote was purely a developer thing, there weren’t product announcements and other such things. Ah, to be an old-fart remembering the good old days. 😉

The iPhone 4 looks to be rather impressive, both from a consumer perspective and an internals geek perspective. iOS 4 as well looks to be quite a nice advancement as well. Apple’s really working to knock things out of the park and continue to set the bar that the rest of the industry will chase. Will I buy an iPhone 4? No, only because I don’t really need what it offers. But without question I like what’s being offered. As soon as I heard about the “front facing phone” I knew it would be about video chatting, and lo, FaceTime.

I am curious about the details of the WiFi stuff messing up the demos. Exactly why did that cause such a problem?

I did notice, no mention of 4G. I wonder why not.

Of course, we’re still stuck with AT&T. *sigh*

But as you could see from the keynote, it’s all about the iPhone. Don’t get me wrong, for Apple that’s where it should be. But it reinforces why I’m happy I stayed home. WWDC just isn’t what it used to be. And even while the topics have changed well… let’s just say the old WWDC’s were a lot more fun. You old timers know what I’m talking about. 🙂