Yearly Archives: 2007

Astyle Rocks!

I’m EXTREMELY picky about the formatting of my code. There are a few commonly-known formats for code: ANSI, Kerninghan & Ritchie, GNU, Linux, and Java.

I have a a very strong preference for ANSI style, but with one minor modification: I like my switch statement case labels to be indented. That’s not a strong preference, as long as the brackets look right.

This drives me nuts (ARRR!):

if( a == b ) {
return;
}

This makes me happy:

if( a == b )
{
return;
}

So, the fact that a lot of code has the former annoys me every time I see it, and I either change it, or frown and move on.

Today I discovered an excellent program, astyle:

http://astyle.sourceforge.net/

It lets you choose what formatting to give your code, goes through it all, and changes it to be however you want. The way I think code should be is:

astyle –style=ansi -s4 –indent-switches

All of a sudden it looks pretty, and I can read it without twitching. Not only does it do everything I mentioned Visual Studio doing in my May 15th post, it also rearranges brackets to be where I want them.

It’s very unlikely that I’ll bring on any programmers, but if I do, I’ll definitely have a stated “official lysanctioned” code formatting style.

The Road To C++

I’ve gradually been changing more pieces of code from C to C++. As each piece goes from being a random function dangling somewhere to a piece of a coherent class the code begins to make a little more sense.

So many bits and pieces are going to benefit from being private data members. In a lot of cases there were hoops that had to be jumped through to handle values properly. Race, for instance. If a character was polymorphed into another race, some of the functions in the game would react to the new race and others would react as if nothing had happened, so a troll turned into a lizard might still lumber into the room.

With the ability to make some data members private, we can make it so that nobody can look at player->race, but instead have to call player->GetRace() which will be smart enough to check for polymorph. The same can be said for checking or adjusting ability scores, hitpoints, and all sorts of things that can be modified by spells.

It’s a phenomenally massive undertaking, but with the proper amounts of time and insanity it can be done right.

Goodbye Shared Strings

Shared string management has been completely removed from the code. Gone. Done for.

The result: greater stability at the cost of higher memory requirements and a slight reduction in processor power requirements (which aren’t even a concern). The removal automagically fixed a few bugs due to the less-than-perfect shared string management.

Next task: Getting Thendar’s zones attached and loading. Some load code modifications will probably be needed.

Code Reformatting

One thing I’ve always found annoying is the way that different applications and operating systems handle tabs. In some programs a tab will move you over 4 spaces. Other apps will have different sizes, like 5 or 6 spaces. This can cause things that line up in one app to look totally out of whack on another.

When editing code this can be very annoying, especially if you check things by seeing whether braces line up and visually analyzing code flow.

Just yesterday I discovered some neat tools in Microsoft Visual Studio that I had never known about. They are edit->advanced->untabify and edit->advanced->format. What that does is convert all the tabs in a file to spaces and then reformat it according to the Visual Studio automatic formatting rules, which are perfectly aligned with my personal preferences. Because all the tabs are now spaces the file will look the same in any editor.

Editing code just got a whole lot less annoying.

Lines and Lines of Code

One of my favorite free little toys for Microsoft Visual Studio is the Project Line Counter (http://www.codeproject.com/macro/linecount.asp). A count of the current Basternae codebase shows:

110,815 lines total
89,446 lines of code
9,880 lines of comments
2,003 mixed (code + comment) lines
13,492 blank lines

Progress continues on changing to std::string, constructors and destructors, and converting manually-handled lists (direct pointer-setting) to std::list.

Hammering and Tinkering

I’ve been ripping and tearing a bit more and there have been quite a few internal changes:

  • Much of the use of char * has been replaced with std::string, which is a bit more powerful and somewhat safer.
  • Almost all of the shared string routines are no longer being used and the shared string manager will be removed soon.  This means that the MUD will take up more memory, but will ultimately end up being more stable and less prone to “string weirdness”, segfaults, etc.  The shared string manager was a fine idea in 1996 when the typical desktop system was a Pentium 1 running at somewhere between 60 and 150 MHz and would typically have about 16-32MB of RAM.  In fact, most MUD codebases were designed to run well on a slowish 486 PC (i.e. 486DX-33).  I remember Illustrium Arcana, the first MUD I worked on, being SUPER SUPER FAST on a Cyrix 6×86 200MHz processor with 32MB of RAM.
  • Many of the “new” and “free” routines that were used in the C code have been converted to constructors and destructors.  This is good because we don’t have to worry whether a creation or destruction routine is called on a mob, object, room, etc.  The initialization and deinitialization how happens automagically.
  • Two zones have been connected and are loading – the Thri-Kreen hometown Thannik’Tzil and the Kobold Village, both written by me.
  • I’ve been exchanging emails with Thendar and she has granted permission to use all of her zones – Plateau, L’strizzen, Ice Palace, Gypsy Quest, Court of the Muse, and a few others.

It’s still just running on my home PC and is far from stable (I still have quite a lot of major changes to make too), but it is gradually coming together to look like something.

And It Begins

I’ve been working with the old Magma 3.0 codebase for almost a week now. Things I’ve done so far:

  • Removed all of the old outdated OS-specific code (Sequent, Apollo, Amiga).
  • Removed all instances of sprintf (a very dangerous function prone to buffer overflows). These have been replaced with snprintf, which is safer. Over 1000 functions have been replaced.
  • Converted all major structs to classes (a C to C++ conversion).
  • Broken the single monolithic merc.h header file into many different header files in order to make the code easier to maintain.

I’m also working on removing or replacing most of the old predecessor code and adding support for just about every area format I can find.  When this is all over it will be a full codebase rewrite in C++.

The goal is to build an engine that is easily extended and modified, with OLC, easy-to-add mods and scripts, and plenty of ways to add fun things to the game without it being too unstable. Original Magma was incredibly unstable because it was built in a hurry — the codebase was based on reverse-engineering the format of existing areas for Basternae 1. There was very little testing at first and it took years for the engine to fully develop into a robust form.

It may take a few years for this new engine to develop into a fully robust form, too, but this programmer knows a vast amount more than he did eight years ago when building Basternae 2 was begun.