Saturday, July 9, 2011

wxDC DrawPoint broken under wxMAC

To follow up on my previous post, I had written my own routines for handling alpha channel support under wxWidgets, and finally everything seemed to be working properly. Both Win32 and Linux/GTK builds seemed to work exactly as expected using my alpha channel bitmaps where I needed them. For most other places, I still used wxDC primitives, as wxDC direct drawing seemed to be a bit faster than going through a bitmap/blit interface, and I still needed to use wxDC to render fonts.

I figured porting to MacOS X would be a snap, and for the most part it wasn't too bad. There were some issues with Repaint() not working the same, but adding a few explicit paint calls in the right place fixed that up.

However, something was wrong with some of the graphics in the various windows. The sky bar, normally with lots of little stars in it, still had stars in it, but instead of one pixel there were two: one at offset (0, 0), and one at offset (1, 1). I also noticed 'fuzz' on the corners of various windows and buttons, and in a handful of other locations.

Long story short, wxDC::DrawPoint() draws two pixels under wxMAC. Not one, but two. I found a couple bug reports regarding this from a few years ago, where it was basically acknowledged as a "verified bug", and the ticket was never closed. Advice was "these routines are slow and shouldn't be used for high performance drawing". Thanks guys.

I have some mighty fine choice words to say to the developers regarding this, but I'll try to keep this post on topic.

If something as fundamental as DrawPoint() is malfunctioning on a major development platform, I figured it would probably be a good idea to transition away from the classes that implement it in favor of my own drawing routines. So, I started using my bitmap class, which just happens to have a DrawPixel() function that works properly.

As expected, this fixed the drawing problems on all three platforms. But alas, using my bitmap class exposed another set of very nasty wx bugs, which I'll discuss in the next post.

wxwidgets has no alpha channel

A few months after I ported the Alter Aeon client to the wxWidgets toolkit, I decided I wanted to add alpha overlay support to the automap and main window.

Encouragingly enough, this appeared to be trivially supported: wxColor included an alpha value, bitmaps could be defined as having an alpha channel, etc. Pretty much everything looked good to go, so I started experimenting with it.

Alas, it was not to be. It turns out that there are precisely three places where the alpha channel is used:

1) loading a PNG from PNG data that has an alpha channel,
2) drawing a bitmap containing alpha channel data using wxDC::DrawBitmap, and
3) wxDC::DrawText, which politely draws text on top of the underlying pixels.

For all other locations, there simply should have been this assert:

wxASSERT("Alpha channel is stubbed here and works on precisely zero platforms ever, ha ha, the joke is on you")

After upgrading to wx 2.9 and a pile of scouting around, I came across wx/rawbmp.h, which has some direct access functions that allow access to the alpha channel. With this, I managed to get alpha channel working - but there were other problems with 2.9, so I downgraded back to stable, 2.8.12.

The alpha channel code that worked under 2.9 works properly under wx 2.8.12 in wxMAC and wxGTK, but apparently isn't implemented under Win32, which happens to be my main development platform.

Rather than bash my skull repeatedly against the wall, I did what any sane developer would do: throw out the broken toolkit module, and write one that works. In the end, I ended up with a wxBitmap derived class that has drawing functions that actually work properly and support alpha channel drawing when I need them to.

However, there's a problem with this as well, which I'll detail in a later post.

Friday, July 1, 2011

Future Plans - Clerics

The cleric class has long languished - not because it was useless, but because until recently there wasn't a lot of reason to have a really high cleric level. Prior to the 2010 christmas expansion, there weren't a lot of cleric spells or skills above level 30; and many cleric spells didn't scale in power as you gained levels, like mage and necromancer spells do.

As a result, cleric has been a useful, powerful class - but not something you want to be your primary. Our future update to cleric aims to change that.

The biggest updates to the class aren't likely to be new spells and skills. Rather, we want to fix existing spells and skills that aren't up to snuff with the rest of the class.

Take for example the 'peace' spell. This could be a very powerful, useful spell - if only it worked differently. We're currently imagining room effects, duration effects, and a handful of other options to improve this.

Another spell that's long been on the todo list is charm. The current version of charm has basically been dented into the ground to prevent charm armies. With this update, we're planning to switch it to a control point system similar to necromancers. This should make charm a lot more useful while at the same time limiting "charmy" problems.

Other things that could use similar kinds of improvement are turn undead, the ward spells, curses, and the monitor skill.

All this said, we do plan to add more spells and skills. So far these hit most of the major groups - character buffs and enhancement, a possible brew skill, some new curses, new damage spells, and a new undead spell.

The schedule for this is some time in august, about a month after the thief updates of the previous post. After this, we still have a ton of things to work on, including elemental channeling for mages, god code, and a couple of new character classes.

Thursday, June 23, 2011

Future Plans - Thieves

Now that level 35 is installed and running in the game, I figure it's probably a good idea to let everyone know about the game's direction and where we're headed. Things aren't going to be static; there's a lot of really neat stuff planned out for this year.

The next major update is scheduled for some time around mid to end of July. The focus of this update will be the Thief class, which is currently the least played class in terms of high levels, and the class with the fewest skills.

At a minimum, the thief update will include an entire tree for shadow skills. I'm not a fan of traditional ninja skills though, so don't expect Naruto style effects. The basis for the shadow skills will be a type of channeling/synergy with the shadow plane, which has already made itself known with the Guildmaster Assassin in Jo'Kerin.

Also on the high priority list are a couple of miscellaneous skills ('untanking' in group combat, room analysis out of combat), and updates to lock picking to make it more incremental and less hit or miss.

For medium priority stuff that might get implemented, we have disguise skills, bribe improvements, and haggling (possibly for bulk purchases.) My guess is that at least some of this will get into the final build.

For low priority, we've been mulling over the idea of distraction skills, but the effects are pretty ill defined right now. We also really need to take a look at the way poison damage is done, to try to make poisons function in a reasonable way. It's pretty unlikely that either of these will be done for the update.

That concludes things for the proposed thief update. Again, we hope to have it out prior to August. I think it will address a lot of the shortcomings of the thief class, without necessarily making thief into another fighter class with differently named skills.

Coming up next - clerics get some love too.

Saturday, April 9, 2011

Alter Aeon Area Openings

Draak and Shadowfax have been working for years on the Naginag Combine, and they've just completed another major expansion to it. Here is the official announcement, copied from board 8 in-game, from Shadowfax.

---

I am proud to announce the opening of the city of West Naginag and its sister area, the village of Ooahu. Usually we open areas with little fanfare, but these areas deserve special mention for a number of reasons.

Just the sheer amount of effort and time that has been put into this project is remarkable. Ten years ago, Draak and I came up the concept of the Naginag Combine. The idea was to build a collection of interrelated areas that were all part of the same empire. We showed Dentin our plans and released the first Combine area in 2002, what is now Draj and Zin. In response to the positive feedback about that area, we scheduled more Combine areas to build. I drew a picture of West Naginag during the summer of 2003. Now, after nearly eight years, it's finally finished.

West Naginag and Ooahu are a lynchpin that tie all of the mainland Combine areas together. We left it for last, but it also took so long to make because I wanted it to be perfect. Whether you want to immerse yourself in the lore, play through engaging quests, or just get some fame, eq or good xp, these areas should have something for everyone.

Once again we push the code to the limit, introducing consumables with custom spells, rechargable wands, mobs that make full use of necromancer abilities, "wearable" objects for your inventory, epic quests that unlock the secrets of the region, and a host of other fun little goodies for your enjoyment.

Friday, February 25, 2011

If you do it more than once, write a script...

There's a saying often used by Unix System Administrators: if you're going to do it more than once, write code to do it for you. For the last few days, I've been writing code to handle clan equipment automatically, so I don't have to be involved.

This has been a very time-consuming process, so much so that you might be tempted to ask, "if it's going to take so long, why not just do it by hand?" And indeed, that's tempting.

But one of the things that has occurred to me writing this code is that clan equipment is simply a complex process. Every single line of code I've written reflects some check, some detail that I would have had to remember and check manually. Each of these details is important. And the odds of me remembering them all when I do it by hand are near zero.

In short, while doing it by hand would definitely be faster in the short term, it's basically guaranteed to be wrong. And I've got direct proof of this while I'm looking at the existing clan items - they're spread out across the vnum ranges completely at random, built and set up in different ways by different builders, with some of them violating various constraints and some not. It's a complete mess.

That is what 15 years of doing it manually looks like, and that's why I'm not going to allow it to be done manually anymore. I am replacing myself with a (not so short) set of scripts. I'm ok with that, because those scripts will do a better job than I would have.

Sunday, January 9, 2011

Scaling

When we released the necromancer expansion back in November, I expected a pretty large spike of new players. I figured we'd get a bunch of new people from the announcement, but also a lot of high levels would want to try out the new class from scratch to see how it worked.

And new players we got; perhaps four times as many as usual, which again was about what I expected. What I didn't expect was that we would be nearly incapable of handling them in terms of areas and content. There wasn't really any fighting over equipment and quests, but from time to time it seemed newbies literally had to queue up to get their turn at a particular quest item.

This got me thinking about scaling. If we can't effectively handle four times the standard newbie load, we'll be limited to a player base less than four times the size of our current one. And it's not just newbie areas; we have to think about it everywhere, from areas to exp thwacking to the who list to the the size of Ralnoth. We might not have five hundred people logged in right now, but even if we did the game probably couldn't handle them all.

Here are some things I think could help with that:

- Instancing. Instancing allows you to create private copies of areas for players, so that they don't interfere with each other. This is great for quests, in that each player or group can be on their own private copy of the quest, and don't need to worry about someone else getting through it first and taking the quest item. Judicious use of instancing can help eliminate quest bottlenecks, and it makes the world seem a lot bigger than it really is.

- Gold and experience thwacking. Right now, gold and experience are thwacked globally, so that if a mob is run too much the returns on it drop for everyone. This is fundamentally dependent on the number of players; a better way would be to put thwacking on individual players, so that the actions of one player don't break the game for someone else.

- Item maxload. Having limited load on items is another thing that's fundamentally dependent on the number of players. Once the player load rises to a certain level, a maxloaded or rarity-based item will simply never load again. Maxload and rarity effectively need to be removed to fix this.

- The who listings, and other display systems. Having a five hundred person who list would be ridiculous. Beyond a certain point, you pretty much have to switch to a query system instead of a global listing system.


Some of this stuff is already in transit or is being worked on; in particular, instancing was booted in earlier this evening and is being tested as we speak. Maxload for the most part was phased out last week.

It's a decent start. One bottleneck at a time...