Yearly Archives: 2008

A New Command Processing Engine

Command processing in the old Basternae was pretty klunky. The command interpreter would just pass on any text that was entered and each command function would have to do a lot of parsing to split up the command strings and figure out what the user actually intended. About half of each command would be devoted just to breaking up strings in some cases.

Luckily with .Net we have all these nice string functions — Split, Join, Substring, IndexOf, Remove, and many more.

With the new command processing engine I’ve just written the command functions are a lot easier to read, maintain, and create more of.

Of course, I’ve had to redo every command in the process and that’s only 80% done so far, but it’s a far better system overall.

And, of course, I still have to finish the replacement spell system.

Automatic Line Wrap

When writing a zone, it can be tough to know where to end your lines of text.

While a standard terminal has 80 characters, some telnet programs start to look weird with any line that is more than 77 characters, and some terminals have 130 or more characters per line (usually depends on screen resolution).

With different zone writers writing descriptions with varying line lengths it can make the MUD look pretty inconsistent from zone to zone.

That’s why I wrote an auto-wrapping function that takes care of all of that.  It will take a description and insert line breaks as necessary.  Right now it just defaults to a 78-character terminal width, but it will be user-configurable when I’m done with it.

This means that zone writers don’t have to worry about line breaks anymore.  They can just type out their descriptions and it’ll be handled by the MUD.

Word wrapping still isn’t perfect, so I’ll need to work on that a little, but it’s pretty neat to have autowrapping in place now.

A Whole New Spell And Skill Engine

Well, maybe not a *whole* engine quite yet, but certainly two thirds of one.

I’ve generated about 500 little XML files to hold all of the skill and spell data for dynamic runtime loading.  It’s all pretty neat — skills and spells can be tweaked by hand without having to compile any code (though the MUD requires a reboot) and they’re loaded at runtime, stored in a Dictionary type, and accessed based on their names.

There isn’t a single hard-coded spell or skill value in the engine.  Hardcoded values were something that always bothered me.

Another thing I did in this process is embed “logical preference” data in the skill and spell files so that the AI engine can be improved while at the same time removing the need for thousands of lines of “spaghetti code” like in Basternae 2.  You see, each spell and skill check in B2 was hardcoded in a specific order and with a specific percentage chance.  Adding a skill or rearranging mob AI meant editing these in more than one place.

Instead (when the AI code is done), we’ll be able to set a few flags on each spell or skill and it will handle it automatically (unless a specific mob has a personality override file).

Oversimplified example:

Fireball.xml:  Type = offensive, Preference = 65, Likelihood = 40
LightningBolt.xml:  Type = offensive, Preference = 50, Likelihood = 50

This means, essentially, that a mob would have a 40% chance of casting fireball during combat, and if that didn’t go off, it would have a 50% chance of casting lightning bolt.  Changing the way the mob performs in combat is just a simple number tweak.

I have some pretty huge plans for mob AI, but this new spell/skill system goes a long way toward making those plans easy to implement.

I also have yet to embed all necessary custom code in the spell/skill files, but one thing that’ll be done is that most information needed to trigger a spell will be embedded in the file.  Instead of manually writing a dozen lines of the same code for each spell to validate the target, check saving throws, set damage type and amount, send messages, and deliver the affect(s), most spells will use one general-purpose function that checks the spell types and flags and executes the spell’s action.

This means that most standard spells that are just damage or single-affect, like “soulshield” or “fireball” won’t have any embedded code at all.  Instead, only super-involved custom spells like the enchantment spell “earthen smith” will have their own embedded instructions.

Well, that was long-winded.  It had to be — I’ve done a lot and I’m pretty proud of what I’ve accomplished with this.

Learned Something New Today

I came across this article on Scripting with C#.

Quick summary: It tells how to load and compile C# code from within a running application so that you can dynamically load scripts.

This is something I’ve been meaning to find out how to do for a while. I’ve always wanted to create a file-based spell system that loads and compiles all spells at boot time so that they aren’t so tightly integrated into the engine. As it was historically, if you removed a single hardcoded spell, such as “armor”, the entire mud would crash or at least be very unhappy.

Well, what good are 400+ hardcoded spells going to do you when you use the mud engine for a sci-fi, historical fiction, or contemporary post-apocalyptic setting? None at all. That’s why getting them once-removed from the core is something I wanted to do. Super-long-term there’s not just one MUD coming out of all this effort.

Writing A MUD Engine Is Hard

Seriously.

I don’t mean just writing a basic telnet chat server with a few objects and commands you can interact with.  Any amateur programmer can do that.

No, I mean writing a full-featured MUD engine that supports all of the features MUDders have come to expect from a game like Basternae 3.  It’s really dang hard.

I’ve spent hundreds of hours working on this rewrite and it’s still pretty far from done.  The area format is still changing quickly enough that I don’t have a working zone editor I can pass out, and I still have a whole spawn engine to write (for those of you who know MUD internals, it’s more-or-less the Basternae equivalent of “resets”.)  I also have to write some sort of mob-action-scripting engine.

It’ll be worth it when I’m done because I’ll have an engine that has been completely written by me and nobody will be able to say what I can and can’t do with it, but it sure is arduous — it takes a damn long time to write 100,000+ lines of code (as you can see by noting that the B3 blog posts beginning about a year ago).  And I’m no newbie coder — I’ve been writing code for more than 20 years, MUDs for 6-8 years depending on how you count the gaps, and commercial code for 3 years now.

That’s why Basternae 3 isn’t open yet.  I could easily have taken the old zones and code up and just went with that, but that’s not something that supports my long-term plan.  Maybe I’ll mention more about that plan at some point.

Humpy Dumpty It Ain’t

A little less than a week ago I mentioned that I had broken the heck out of the codebase.

Well, it’s all back together again.  The MUD engine and the zone converter are as healthy or healthier than they were before, the weather’s nice, and all is well with the world.

MUD Connection Stats on FindMUD

One thing I’ve been working on is an automatic ‘ping’ routine that checks the MUDs listed on FindMUD every few days and shows the connection results on a MUD listing so you know whether a particular MUD is still alive or not.

Since I’m no PHP expert, it tends to be rough going sometimes. I know just enough PHP to be dangerous — it’s a lot like C but not *enough* like C for me to be comfortable yet.

Even so, I’ve managed to put together a semi-automatic routine that checks these connections. Here’s how it works:

  1. I go to the site and export the master MUD list. This is a one-click PHP script that gives me a CSV file.
  2. Paste the CSV file into a desktop application I wrote in C# .NET that cycles through the list and tries a connection to each MUD. It generates two SQL queries for me — One that updates the IP addresses for any MUDs whose servers have moved and one that updates the connection results table in my database.
  3. Take those those two queries and execute them on my database server.

It’s a seven minute process and not too much work, but it would be nice if it were fully automatic and happened at a specified interval instead of “whenever I do it”.

The two roadblocks I have at the moment are that the shared hosting I’m using for FindMUD doesn’t seem to allow outgoing telnet connections and they also don’t allow connections to a database from outside the server. Even though I could whitelist my IP address(es) in order to connect to the DB I don’t really want to open up any of my databases.

Being able to do #1 would automatically make #2 a non-issue since connections would be made from the server running the ping test. When I get hosting for Basternae 3 it’ll be on a server I can do whatever I want on, so this process should be able to become fully automatic.

Fedora Core 8 Just Doesn’t Work

I’ve never had any luck with Fedora Core.  The latest version, 8, wouldn’t even get past the disk partitioning screen for me.  There’s a reason why I’m an Ubuntu devotee — after all, it managed to install itself quickly and easily with no stupid questions and worked flawlessly from the start.

Last time I ran Fedora it was on a set of 4 Dell desktops.  I started with 4 and later tried 5.  There was something wrong with the SATA driver and the hard drives would forget their data after about two weeks on average.  After reinstalling two or three times on each machine I ended up switching to Ubuntu.  No problems at all after that, although I did really want a “Fedora Core killed my family” shirt.  Too bad they don’t exist.

So, it looks like the Linux port of client/server development will still be on Ubuntu.

If you can’t run reliably on Dell hardware it’s time for you to go home.

Mass Refactoring

In the interest of making sure the MUD can be modified easily well into the future I’ve broken the heck out of the codebase.

Yep.

I’ve been refactoring, rearranging, renaming, and restructuring things so they make a lot more sense. That has inevitably broken a few things, but it will be far easier to add new types, flags, and enumerations in the future — things like adding a new terrain type without breaking existing terrain types or having to recompile the editor and re-convert all of the zones.

Believe me, we had quite a headache with zone file format changes on Basternae 2 and I don’t want to repeat it.

This means that it’ll take a few days before the codebase will build again and I’ll have some work to do on the converter and the editor, but it’ll be worth it.

I’m still looking at putting up a test server in May and so far Slicehost is the most likely candidate. Feel free to offer suggestions. Since it’s out-of-pocket and non-income-producing, my budget isn’t any more than $20 per month (should I be accepting donations for this?)

Not Winamp’s Fault

So, the upgrade to Vista didn’t turn out to be 100% successful.

It turns out that the Winamp crashing I experienced was caused by Vista’s epic failure in the audio realm.  Since they changed the way audio drivers run (user mode instead of kernel mode now), no driver from an earlier version of Windows will run.

I tried and failed to get the following sound cards to work:

Sound Blaster Live!
Sound Blaster Live! Value
Terratec Audiosystem EWX 24/96
M-Audio Audiophile Delta 44
Diamond Monster Sound MX300
Diamond Monster Sound MX400
Yamaha YMF744B
Dynex DX-SC51

The only one that worked was the Dynex card.  It’s also the only card I paid less than $10 for new.

The moral:  Only use extra-cheap soundcards.  Hi-Fi sound is not permitted.

On an upside, all of the Basternae 3 applications and utilities run fine on Vista.

Tweaking The Zone Converter

In working on the new zone editor I noticed that a few things seemed a little off in some of the test zones I was working with.  As much as I would like to blame the editor, since it’s new and untested, it turns out that the zone converter had an issue with race conversion between Basternae 2 and 3 zones.   It was a relatively simple bug, but it was one that made all converted zones look a little stupid.  Being simple, it’s been fixed with minimal effort.

Now that the converter is working pretty well I’m pretty comfortable with accepting zones that were on Basternae 2 if anyone is willing to give permission to use them.

A Price On Your Head

One thing I’m surprised never made it into Basternae — bounties.  It’s only natural that you would be able to set a price on someone’s head in a PvP MUD.

So I implemented about 60% of a bounty system today.   There are still a few details to work out, but the core of the system is in place.

Upgrading to Vista Ultimate

I hate updating software.  Many years of painful upgrade experiences have taught me not to upgrade a piece of software unless it’s horribly broken or lacks the ability to get anything done.

That’s why I was dreadfully, terribly afraid of upgrading from Windows XP to Vista on my home desktop.  Sure I’ve been running Vista since summer 2007 at work, but I don’t do much other than software development on my work PC.

Knowing full well that a clean install is the only safe way to go and that Windows always needs more RAM, I picked up a new hard drive and an extra gigabyte of RAM (memory sure is cheap these days!)  It also doesn’t help that I was running an original Windows XP Pro install from late 2001 (which has gone through half a dozen hardware upgrades on the same install).  It was tired and in need of a clean slate.

The install was remarkably, stunningly painless.  There were all sorts of things that just worked without the installer wizard having to ask me dumb questions.  It was so smooth — even to the point that it auto-capitalized the registration key while I was typing so I didn’t have to worry about whether I had caps lock on.

I almost wish I had something bad to say, but nothing went wrong and everything worked.  This is nothing like setting up an NT 4.0 system, which had a way of running differently every time you installed it on the exact same hardware configuration.

The folks who fear Vista, think it’s broken or too evil to use:  They’re idiots.  It works, and it works better than any Microsoft OS yet.  If you have the hardware to run it you probably ought to.  Now that it’s SP1 and most software developers have worked out their compatibility glitches it’s mature enough to use regularly.

My only complaints:  Folder views defaulting to music (it’s a folder full of DLLs you idiot, show me the size, date, and version — not artist, album, and rating!); kind of annoying navigating in Windows Explorer (it’s an extra click or two to get where I’m going); the folks at Winamp still haven’t gotten their act together for Vista (crash, crash, crash!)

Taking The Visual Studio 2008 Plunge

Since VS2008 somewhat rudely decided that it would become the default application for all projects, including projects that were VS2005 projects (what exactly *is* the Visual Studio Version Selector good for, anyway?), I decided to try building Basternae with 2008.

It was actually a pretty painless process.

Something changes in every version of a compiler and 99% of the time something breaks, either due to deprecation, changes in the way warnings and errors are treated, or most often due to changes in dependencies and the way they are handled. In any project of significantly large size, you can expect errors when converting to a new version of Visual Studio.

It was no surprise when the project didn’t build. It was, however, a pleasant surprise. It found three bad cast operations that shouldn’t have been written in the first place, the sort of thing that VS2005 should have complained about but didn’t. After spending a few seconds fixing those, everything built fine with no problems.

Visual C++ projects are a different story. You see, I’m convinced that Microsoft hates Visual C++ and just wants it to shrivel up and die. As long as Visual Basic and Visual C# projects are healthy, it’s safe to release a new version of Visual Studio. This time it was a bit of DLL hell along the lines of missing MSVCP90D.DLL and MSVCP90.DLL errors when trying to run a newly-built executable. WTF? Weren’t those installed with Visual Studio? You mean we can build C++ projects but aren’t allowed to run them?

OK, OK, so maybe it was a missing runtime redistributable. That’s fair enough and something I could live with since that’s the way .NET works. So I download the Microsoft Visual C++ 2008 Redistributable and install it. Fail. Epic fail.

After an unsuccessful Google search (plenty of people with the problem but no clear solution) I went playing with some of the project settings. The final fix was setting “Generate Manifest” to “Yes” instead of “No” in the Linker->Manifest File section.

Free Copy of Vista Ultimate and Visual Studio 2008

Today was the Microsoft “launch event” for Visual Studio and Server 2008. I attended the local presentation and walked away with a free copy of Vista Ultimate and Visual Studio 2008. It was free to attend and I got $600 worth of software out of the deal. How can you beat that? Sure the presentations weren’t very relevant to the types of development I do (all they talked about were database-driven development, MS Office add-in development, and ASP.NET web development, all of which I don’t have any involvement in.)

I may or may not switch development of Basternae 3 to VS2008 right away and probably won’t start using Vista until my next PC upgrade, but it still feels nice to get free stuff.

Current Line Counts

Lately it’s just been a bit more work on the editor (which is now at version 0.25). Here’s an updated line count:

Main Codebase:
99,360 lines total
77,693 lines of code (78%)
8,417 lines of comments (8%)
1,258 mixed (code + comment) lines (1%)
11,987 blank lines (12%)

Editor:
9,597 lines total
7,491 lines of code (78%)
1,654 lines of comments (17%)
9 mixed (code + comment) lines (0%)
443 blank lines (4%)

MUD Screen Editor:
1,147 Lines Total
887 Lines of code (77%)
184 lines of comments (16%)
0 mixed (code + comment) lines (0%)
76 blank lines (6%)

Help Editor:
696 Lines Total
512 Lines of code (73%)
142 lines of comments (20%)
0 mixed (code + comment) lines (0%)
42 blank lines (6%)

Client:
5,312 Lines Total
3,940 Lines of code (74%)
781 lines of comments (14%)
29 mixed (code + comment) lines (0%)
562 blank lines (10%)

Since we last checked in, the editor has added about 1100 lines of code, the engine has added about 450, and the help editor and client are new to the list. It’s not that the client is new, this is just the first time we’ve counted it.

This really is a fairly large project.

Memory Usage

When booting up the MUD engine with only my two zones (the Thri-Kreen hometown and the Kobold Village), Basternae 3 takes up 22,256 kilobytes of RAM.

That somehow manages to drop to 20,096 kilobytes of RAM when I connect with a single player.  I think it was probably just timed to coincide with a garbage collection.  Moving around for a while brings it back up to 20,500.

A boot up with no zones loaded starts at 22,116 kilobytes of RAM.

So, at this point the MUD engine takes about 22 megabytes of RAM plus however many zones are loaded.  I can’t imagine players taking more than 8 kilobytes, and with zones taking up about 1 megabyte per 3000 rooms, we’ve got plenty of room to grow.

With 32 megabytes available, we could support:

27,000 rooms
128 simultaneous players

No problem.

The entry-level VPN servers I’ve been looking at start at 256, but that’s for OS plus applications.  It’ll be running Linux so I’ll have about 128 megs for OS and 128 for apps.  We could run 300,000 rooms and nearly 800 players before needing to upgrade.

I definitely don’t miss the “bad old days”.  When I first started writing MUD code it was normal to only have 32 MB in an entire system.

200 Listings on FindMUD

Over the past few weeks I’ve steadily been adding more MUD listings to FindMUD.  It has now has over 200 MUD listings.  That’s not super-impressive, but it does have more than MudBytes and Betterbox and is quickly gaining on some of the older sites (many of which are rather neglected these days).