Friday, February 27, 2009

Bugs, bugs, and more bugs

One nice thing about the (relatively) small userload we have right now is that reboots and the occasional crash aren't so much of a problem. Which is good, because today has been awful.

A confluence of factors served to get some really terrible code into the system, but by far the biggest one was my acceptance of pretty well untested code without thoroughly testing or reviewing it myself. This was the cause of several crashes and an almost-severe memory corruption fault (which was fortunately cleared by a crash in a different, unrelated section of code.) While my code was definitely not bug-free, it was at least not crash worthy material.

The only saving grace in this mess is that I found and fixed a bug that has been occasionally plaguing the system for over ten years: memory structs on players were not being properly cleared in an obscure scenario, resulting in use of mob structures after death. Were it not for the crash-resistant pooling memory architecture that we've been using since 1996, this would have caused major problems over the years. As it was, it simply cut warnings and bailed.

In exchange for this though, I now have a host of other plausible wierdnesses, including a bug that appears to corrupt the destruct timer on dead players. Again, the design of the codebase is happily tolerating this and simply cutting warnings, but it is disturbing nonetheless.

Tuesday, February 24, 2009

WxWidgets Review

Now that I've had a chance to settle down and not work on the client for a couple of weeks, I'm probably in the right frame of mind to write a proper review of wxWidgets.

First off, wxWidgets is a multi-platform GUI toolkit. It's been used to build a variety of applications, including the current version of the Alter Aeon Mud client. It works on a bunch of different platforms, including Linux, Windows, Mac, and a handful of less popular operating systems. I've used it to build the most recent versions of the Alter Aeon Mud Client, a standalone executable designed for the players of Alter Aeon. It has a graphical automap and basic colored-text console facilities.

In the case of standard dialogs and standard types of objects, it works quickly and well. Everything always looks 'as it should' for the platform it's on. Unfortunately, things work less well for even slightly more complicated objects.

Take for example the standard wxTextCtrl object. This uses what's known as a 'native' library - the guts of this object are based on the system libraries where it's built. On Windows it uses one of the standard text window DLLs, while under Linux it can use GTK or other libraries. Because of differences between these system libraries, the behavior of the wxTextCtrl on different platforms is vastly different.

Scrolling may or may not work depending on the platform; URLs, if enabled, may or may not display in Windows depending on the version and service pack level. Performance varies; disabling certain features may break window formatting, and Append may insert arbitrary line feeds after ever call. When editing text, attempts to move the cursor past the end of the text triggers a system beep at full volume. The list goes on, and not all of these are fixable without editing wxWidgets itself.

One recommended solution for these kinds of problems is to use the wxRichTextEdit class. This is a ground-up reimplementation of the text window, with an interface similar to the wxTextEdit class but far more comprehensive. This class actually works pretty well, and it's consistent across platforms as you'd expect.

The only problem is that it's slow. Dog slow. A dog with no legs slow. Using it as a text console display becomes almost useless beyond a few thousand lines of text. And that was pretty much the whole point of what I wanted to do.

Fortunately, there's another solution: the Scalia wxStyledTextEdit class, which is an add-on module from another open source project. This class is designed to do fairly complex text formatting and styling, including multiple styles simultaneously and syntax highlighting. I don't actually need most of that stuff, but I figured I'd give it a try as well.

The downside of this class is that the interface to make it work is quite complex. It's a heavyweight class, designed for very complicated types of things. It's got nearly everything you could possibly need - and some things you don't, including implementation bugs. Quite frankly, I never got to testing the performance of this class, simply because I could never figure out how to change the background color of the window. It's not like I didn't try.

As a last resort, the drawing primitives in wxWidgets are actually pretty good. In approximately one week, I was able to construct my own text window class with the features and performance that I required for this application. Remember that if you have a lot of trouble with one particular module, getting out a wxDC and building your own is always a viable option, and if it doesn't work it's no-one's fault but your own.

Compared with my experience with QT, there is absolutely no comparison: QT has better documentation, better cross platform support, fewer cross platform bugs, better performance, and a more consistent design. Unfortunately, QT is LGPL, requiring an installer for binary applications, and the QT libraries are upwards of 50 MB in most builds. So on that count, wxWidgets wins: it makes drastically smaller and easy to work with executables.

Score for wxWidgets: 5/10

It does most of what it's supposed to do, but don't use it for anything important.

Thursday, February 19, 2009

New AA forum

Hey all, just a quick line to let you know that the new Alter Aeon forum system is up and running. This should hopefully provide a place for people to go on the web, instead of to the user boards in the game. It may also provide a place for new people to search and look for miscellaneous information.

On other news, I've been sick, but even so there's been a raft of changes. Most of these are minor little things, but there's a handful of very important ones such as the changing of object lists from singly linked to doubly linked. That particular change got rid of some fairly nasty lag spikes we were seeing due to very large storage lockers. As always, see the Alter Aeon changelog for full details.

For the rest of the week, I have a handful of web page things to do and clean up, and I need to figure out how to handle moving over a bunch of builders from bport to the main port. I may also get screwed for a few days next week working for my old job.

Saturday, February 14, 2009

New client release

Finally, after a week of work, there is a new Official Alter Aeon Mudding Client for all to use! This version fixes a huge number of bugs in the previous code base, and has faster scrolling among other improvements. Beeping in the input window has been killed and control-c now works again.

It has been a long, hard five-day-slog to get to this point, but using a custom window class has made so many things better. Gone are all the hacks I had to put in to make the old libraries work; now they're back to the nice clean code they should have been. Scrolling works right, select works right, context switches work right - and best of all, it's fast as hell under Windows. I really wasn't expecting this level of performance.

The final hitch was getting the input window working reliably. Through some stroke of luck I found the event handler responsible for intercepting control C and the backspace events. With some really nasty state-handling code and about two hours of experimentation, I finally have an input window class that traps out all the beeps and handles selection copy without stupidity.

If I had known this to start, it would have saved me so much time and effort. Time lost that I could have spent elsewhere; such is life. But going forward, it's so liberating - no longer am I at the mercy of crap that can't be made to work the way I want it to.

If it fails, its my own fault. And I can live with that.

Wednesday, February 11, 2009

Sucking further wxWidgets

I've managed to fix and clean up more code in the last two days than in the last four months simply by throwing out these broken toolkit parts and writing my own display class. Bugs that I never could figure out are gone; workarounds for problems that should never have been there in the first place are no longer needed. It displays, it's solid, and it works. I've been mudding with it all day long.

So far, I have a fairly primitive display class with a scroll bar, display window, and border that changes color when it locks. The display window has primitive and buggy line wrapping, but it's usable. There is currently no URL clicky support or select/copy support. Performance is even pretty good.

Performance isn't as good as it should be though - when resizing narrow, it takes far too long to recalculate line numbers. I suspect most of the time doing this is spent in pointless object conversions between various objects. First thing tomorrow, I'm going to be switching over most of the wxString objects to regular const char *'s. There's an awful lot of string processing that needs to be done, and doing it in wxString land is problematic.

After that, I need to rework the way the line data is stored so I can handle select/copy and proper line wrap. This same code will also help with URL support, so it's possible that all three could be done pretty quickly. At this point, the display window is fully featured.

Next up, after the display window, is the typing bar/input window. This one is more troublesome; it's one of those things I'd really rather not re-implement, but I suppose if I have to I can. Either way, I have to do something with it:

1) The input bar beeps if you backspace too far. This is a show-stopper. Computers should NOT make noise unless actively requested to, especially for trivially ignored failure cases. It appears to be impossible to turn off this buggy behavior in the library.

2) It also appears to be impossible to reliably set and maintain the font and font color for this object. Backspacing until it's empty often has unpredictable results. No modifications to the class have been made, and it produces different results on different windows versions more and less frequently. This smacks of being a library/DLL bug.

Hopefully I can find some other input window class that is less problematic, and still have multi-line support. Multi-line paste is mandatory, as I paste a lot of notes and descriptions.

Tuesday, February 10, 2009

wxWidgets sucks...

... but even though it sucks, I can't really blame it. I think the problem is endemic when using pretty much any large toolkit, especially younger ones or ones that are built on top of other toolkits.

First, some background. wxWidgets is a windowing library to allow people to quickly and easily develop GUI applications. It's cross platform and in general built on top of other toolkits. This means that the layers of toolkits upon toolkits is often at least two levels deep, exponentially increasing the likelyhood that bugs in one layer will foul up things elsewhere.

These sorts of interactions are causing me huge difficulties with the display and input windows in the client. After much soul searching, I have what appears to be three choices going forward, each with various pros and cons, none of which are ideal. In short:

1) Use the native wxTextCtrl class. Pros - some minimal screen reader support, cut/paste works, already mostly working. Cons - scrolling doesn't work worth a shit, different performance on different windows versions, urls are unreadable for at least some people, no way to disable beeping on backspace, and easily a third of the style flags and other functions don't work or don't work correctly, often with no workaround. Further, the god damned thing intercepts certain keystrokes, specifically Control-C, before I can get at them, and there appears to be no workaround for this.

2) Use the scintilla derived display class. Pros - someone else maintains it. Cons - pain in the ass to get working, manual url and cut/paste handling, bigger, vastly more complicated than my application requires, and inability to configure simple, important things like the background color.

3) Write my own. Pros - it will do exactly what I want, when I want, with the interface that I want. Should be fast and small. Cons - I have to do all the work.

After all the crap I've been through in the last month trying to get the default text controls to do incredibly simple, obvious things, I'm heavily leaning toward option 3 at this point. In the time I've spent trying to get existing controls to work, I could have without question written my own custom primitive. Or rather, I now know enough to write my own. The road would have been rockier in the beginning.

I think this is a prime example of why I rail against toolkits in general. They are very risky; there's no guarantee that what you're using will work, or can be made to work the way you want it to. In this case, I have lost a huge amount of time trying to work around toolkit limitations.

Option 3, here I come.

Thursday, February 5, 2009

Somebody Likes Us...

I just thought I'd put up a quick note pointing at a post on ehowton's blog:

Eric's perspective of Alter Aeon

It's a neat little piece on AA, including screen shots.

Wednesday, February 4, 2009

Graphical automap

After a long hiatus, I got a new version of the Alter Aeon Mudding Client built and released for Windows. This version fixes a lot of bugs, but is still subject to the quirks and peculiarities of whatever version of Windows it runs on. This is really irritating, as the URL linking is black (and hence invisible) on some versions of windows, but not on others.

The big update is the graphical automapper, which renders squarish blocks based on terrain and some flags. Auto-generated tiles are what I'm using right now, and all things considered it's not terrible, though it's also not great. Here is a link to a screenshot of the Linux/X version of the client, to give you a rough idea. The Windows version looks similar, with slightly different font sizes and different borders/edges.

As usual, with a new release comes new bugs: the control keys appear to no longer work, the 'vanishing url' problem is still present, diagonal exits don't work (this requires a server and protocol change), and a number of more minor bugs have been reported. It's also lacking blind/visually impaired support, though the default support is already much better than for the old client.

All this (except for blind support, which may be impossible) needs to be fixed before it's suitable to take over the place of the old client. It's getting a lot closer though.

One thing I'm grudgingly coming to terms with is the player desire for triggers and variables in the client. Normal mudders aren't going to use it until it has reasonable features for scripting. I really don't want to encourage scripting, but it may be a necessary evil to getting people to use it.

My hope with this project is that low quality graphics and a visual display are better than no display whatsoever. The game is complex, well balanced, and solid - people who play it tend to stick around and find it entertaining for long periods of time. Getting people into it seems the hardest part.

A possible vote in favor of a bad client being better than no client comes from friends of existing players. I can't even remember how many times I've been told some version of the following:

"I tried to get my friend into it, but he/she just couldn't understand how a game that's only words could possibly work."

Even if it's just a cheesy icon indicating where you are, it at least gives non-mudders a reference: everyone's played old school tile-based games. I hope.

Another major concern I have is that I'm now officially encroaching on what I'd call the territory of other, vastly better funded games. This marks the first real foray into adding graphics to the system; right now that consists of low quality, autogenerated graphics, using a mapping system which doesn't even work reliably (due to area linearity and such.) What I have is crude, primitive, and unartistic.

People can get low quality graphics anywhere; and attempting to compete with modern high-quality rendered 3D games is a non-starter, unless you have a reasonably large budget. Further, the game as it stands is fundamentally not designed to be 3D rendered. It would take a major rework to add support for that, and likely result in the destruction of most of the interesting game content.

So the big question becomes: what is the next step for the client, after it's stable and usable by the default population?

Right now, the only big hitter I have on my list is another type of automap, one that uses the generated area maps from the Alter Aeon World Maps page. The server would send approximate X/Y coordinate pairs, and the client could map them to the appropriate position on the generated maps. This would give people an idea of which areas they were near, and approximately where they were at.

Beyond that, I really don't know. I'm sure something will present itself.