Category Archives: Basternae and ModernMUD

Posts about the Basternae MUD and/or the ModernMUD codebase.

More Spells Are Working Now

25 more spells are working today, mostly defensive beneficial sorcerer and cleric spells like ‘fly’, ‘invisibility’, and ‘protection from fire’.  There are quite a lot more to work on, but it’s good progress.

What MUDs Have The Best AI?

Most MUDs have mobiles of very limited intelligence that stand around waiting to be killed and often don’t even bother to remember that you attacked them ten seconds ago.  Some games have more intelligent creatures that actively try to defend themselves and take down the enemy by the most effective means (always fireballing trolls, dispelling undead opponents, etc.)  What MUDs have you played with more advanced/detailed mob AI?  What was it like?

Sure, there are the obvious ones from the Basternae ancestry, but I’m looking for the ‘best of breed’ so I have a standard to measure against.

Offensive Spells

I finished up more of the new spell engine and damage spells can be used now.  I’ve only tested magic missile so far, but it worked beautifully. 😛

Changes to Affect Modifiers

Handling a skill or spell with multiple modifiers in code has always been a bit of a nuisance.  I changed that around a bit so that they work they way I want them to.

So, here’s what adding three effects looked like in code beforehand:

Affect af = new Affect( Affect.AffectType.spell, spell.Name, 12 + level / 4, Affect.Apply.intelligence, 3, Affect.AFFECT_NONE );
victim.AddAffect(af);
af.ApplyType = Affect.Apply.constitution;
af.Amount = 8;
victim.AddAffect(af);
af.ApplyType = Affect.Apply.dexterity;
af.Amount = -5;
victim.AddAffect(af);

You’ll notice that the target has 3 separate affects added just for one spell.  That’s because each affect could only handle a single modifier.

After making the modifiers into a list that can have a variable length, here’s what the same code looks like:

Affect af = new Affect( Affect.AffectType.spell, spell.Name, 12 + level / 4, Affect.Apply.intelligence, 3, Affect.AFFECT_NONE );
af.AddModifier( Affect.Apply.constitution, 8 );
af.AddModifier( Affect.Apply.dexterity, -5 );
victim.AddAffect(af);

Now it takes half as many lines of code to do the same thing and looks a lot cleaner.  The codebase also shrunk by about 300 lines of code in the process.

This also means that some spells or skills that used to show up multiple times on the score screen will only show up once.

The Spell Engine

I finally got the spell ‘plugin’ system to work as intended for the first externally-coded spell.

Each spell is stored in an XML file outside the MUD engine, i.e “Fireball.xml”.  The file has a bunch of settings for the spell like casting time, target type, modifers, etc.  It also has an optional code section for more complex spells.

Yesterday I got the simple case working, that of a single-effect spell with no custom code like detect magic.  It just sets the ‘can detect magic’ ability on the target for a number of game hours.

Today I got the more complex case working — that of a spell that uses compiled custom code.  The example spell is ‘minor creation’.  It has a lot of custom code to process keywords and select predefined objects based on those.

The code I put together a year ago almost half-worked.  It could load the spell code from the file and compile it, but when it came time to execute it failed.  Turns out that most of the issue was how namespaces were being referenced and how types were being created — lots of detailed C# reflection stuff.

Now that I’ve worked that out there are no more roadblocks to ‘modernizing’ spells.  Sure, only 2 are converted so far and there are 419 to go, but now that the groundwork is in place it shouldn’t be too difficult.

So far this is only on my local machine – not up on the server yet, but will be within a day or two.

Affect Removal Is Fixed

Looks like I sorted out that nasty little affect removal bug, so onto the next…

With this and the previous fix, now would be a great time to sign on and start testing the heck out of things.  After all, you don’t want me to run out of work to do, do you?  😛

Picking Up Items Bug Fixed

It looks like there was a nasty bug in the zone converter for two of the three format types that we convert that caused the “wear flags” to be mapped into the “extra 2” flags.  The wearable flags include the “carryable” flag, so with those being broken, that’s why things could not be picked up in most (but not all) zones.

A New Version of the Zone Editor (0.46)

I spent some time on the zone editor today. Here’s a list of changes and fixes:

  • Justice type is now selectable on the zone settings screen.
  • In walkthrough mode, the ‘help’ and ‘commands’ commands now show a list of the available commands.
  • Various minor text and appearance improvements, including adding a program icon.
  • Added the ability to edit object values so you can actually set things like weapon damage amount or armor factor.
  • Fixed a nasty bug in editing repops that would cause data corruption.
  • Added the old Basternae 2 zone guides to the help file.
  • Fixed a very nasty circular reference bug that would prevent a zone from saving in certain cases.

Repop editing is still pretty cryptic, but at least changes show up in the repop’s description in real time now.

The really confusing thing at the moment is editing object values. In DikuEdit, the values would change description when the object type changed so you could see what you were editing. The new editor does not do that yet, so you either have to already know what you’re doing or you have to guess, neither one of which could be much fun, so that’s going to be something fairly high up on the to-do list for future changes.

You can get the new version HERE.

A Bunch of Little Fixes

I had a chance to tinker with the code today. I made a bunch of relatively minor fixes (code-wise). Here’s the list:

– Fixed game menu consistency so same one appears every time.
– Some minor text changes and/or typo fixes.
– Made the help editor a little easier to use and added a ‘delete entry’ button.
– Made the MUD screen editor a little easier to use.
– Fixed the immortal ‘slay’ command.
– Fixed the immortal ‘load object’ command.
– Fixed the ‘history’ and ‘!’ commands, the latter of which would instantly crash the MUD when used.
– Improved the issue system and added the ability for immortals to create issues.
– Some help entry additions and improvements.

There are two major bugs right now that will take some digging to fix properly: Items can’t be picked up, and spell/skill effects never seem to wear off.

Even though there’s still quite a lot of work to do before the codebase conversion could be considered ‘complete’, it’s becoming a bit more fun to work on.

A Linux Build of the Client

I have no clue how to build a .deb or .rpm package yet, so it’s just a .zip for now.

Though I have it working on my own Ubuntu 9 machine, I haven’t the faintest idea whether the client will run on other Linux boxen. At the very least, you’ll probably need to have the wxWidgets 2.8 libraries installed to run the client on Linux. I suppose at some point I’ll figure out how to build installer packages.

Version 0.14 of the client for Linux is now available for download. Hopefully there’s someone who can try it and let me know the result. In this case, it’ll probably be “I had to add libraries X and Y and Z before it would run”. Then again, since wxWidgets is so widely used on Linux (VLC, Audacity, etc), chances are good that most people will already have the necessary pieces installed.

Initial Mac Version of the Client

I fixed the “can’t send text” problem in the client for the Mac and Linux versions.  There are still some text problems that only show up in non-Windows versions, but I was able to log in and play for a bit without much trouble.

Though I have it working on my own machine, I haven’t the faintest idea whether the client will run on other Macs.  I’ve created an application bundle and compiled it in a way that it should supposedly run on OSX 10.5 and 10.6, but I only have 10.6, so no idea whether it will work.  And, since my machine is set up as a developer machine I have no idea whether a “normal” user’s machine will have all the libraries it needs.  That’s the trouble with being a Mac “noob”.

Version 0.14 of the client for Mac is now available for download.  Hopefully there’s someone who can try it and let me know the result.

Another Client Update

I tracked down a nasty threading problem in the status window that would explode things horribly at random intervals. Version 0.14 of the client is now available.  That’s not to say there isn’t the possibility of other horrible explosions lying around just waiting to leap out… so let me know if you find any.

A Minor Client Update

Version 0.13 of the client is now available.  Cleaned up one or two things with text processing and added command scrollback (where you can push the up arrow to retrieve previous commands).  As always, let me know of any glitches you find.

Zone Permissions Received From Gharl

Gharl was nice enough to grant permission to use his zones on Basternae 3.  This includes “The Church of Eternal Dusk”, “The Motte and Bailey of Duke Delwyn”, and “Zalkapfaan, City of the Headless”.   Thank you, sir.  Forward progress!

Generating Maps

Generating maps on Basternae 2 was a bit of a pain.  It was done with about 1000 lines of hacked-together C code that I wrote that read in an ASCII file, asked you the dimensions and map type (surface, underdark, etc), and then brute-forced it into a simple zone file.  It was not elegant, but it worked, usually.  Unless, of course, you entered a wrong number, had an extra character on one line, or anything like that.

The surface map I showed yesterday is just an enlarged 120 x 50 bitmap.  I only used 9 colors when creating it — one for each terrain type.  There is no accompanying ASCII text file.

It’s entirely possible with a lot of grunting and swearing that I could convert it into an ASCII file which I could then import into that old C program.  Why bother?  There has to be a better way.  Turns out there is.

Last night I created a small application that does one thing and only one thing — generates maps for Basternae.

Here’s how it works:

1. Load in a bitmap of any size.
2. Select a menu item and the program analyzes the bitmap and generates a list of all the different colors used in it.
3. Use that list to generate a room template for each color — title, description, and terrain type.
4. Let the user edit the list of templates so you can say light green is “The Forest of Evil” and dark green is “Drachenwald Forest”.
5. Select another menu item to have the program use the template file as it goes through the image pixel by pixel and generates a room for each pixel.

The obligatory screenshot:

Basternae map generator screenshot.

I’m a bit surprised that it only took a couple hours to write.  It’s the sort of thing that the serialization, bitmap, list, and datagrid classes built into .NET make very easy to do.

It is missing one major thing — it doesn’t connect the rooms together via exits yet.  That will be easy enough to add (probably about an hour to do).  It does, however, generate a zone that loads into the editor and can be tweaked and refined further.

There’s also one neat thing about the design — the room templates can be saved off to a file and loaded again, so you don’t have to edit it all in one sitting, risk losing your work if the power goes out, and can use the same room definitions with different image variations (provided you used the same colors).

Basternae 3 Surface Map

I have a few goals with the Basternae 3 surface map:

1. Has to be fairly small. No epic 90,000-room maps that take half an hour to get to the next zone.
2. Has to have both raidable and non-raidable sections. The raidable sections should be easy to get to for both sides. The non-raidable sections should be more-or-less “safe”.
3. Should be contiguous — no randomly-spaced islands, be they large or small.

In short — I want it to be small enough that the world doesn’t feel empty when there are only a few people on, but large enough to have room a good number of zones, and for people to chase each other around a bit.  If there is an error to be made in sizing I’d prefer to err on the side of too small.

Here’s what I’ve come up with. It’s subject to modification, of course, but it captures the general idea:

Basternae Surface Map

It will be a while before it’s in the game, so it may evolve. There will also be cavern (underdark) map at some point.

Small Client Update

I’ve made a couple minor updates to the client.  First, the status window wasn’t clearing the tank and enemy condition bars when there was no tank or enemy combatant.  That’s fixed.

Next, I’ve added what appears to be working support for aliases.  They’re created accessed using the “#alias” command (#al for short).  They cannot yet be saved/loaded, but they do stay in memory as long as the client is open.  Saving/loading is probably the next thing I’ll work on.

Here’s an example:

Aliases in the Basternae Client

You can download it here.

Building The Client On Linux

It’s been 3 years since I’ve tried to build the client on Linux. I started building the client long before there ever was a Basternae 3 project, and since then plenty of files have been added and removed — for instance, we no longer use Xerces-C or SDL in the project.  I was using Ubuntu 6.06 then, and now I’m on 9.04.

After updating the old makefile, I found there were a few minor issues. Of course there was the expected forward/back slash in filenames and that’s an easy fix. There were two that were a bit of a surprise:

warning: cannot pass objects of non-POD type ‘class wxString’ through ‘...’; call will abort at runtime

error: no matching function for call to ‘wxRichTextCtrl::AddPendingEvent(wxCommandEvent)’
/usr/include/wx-2.8/wx/event.h:2400: note: candidates are: void wxEvtHandler::AddPendingEvent(wxEvent&)

The first one is because I was passing wxString arguments to the wxString::Format function.  Visual Studio was smart enough to convert those to the char* type that printf commands understand for %s, while GCC doesn’t make any assumptions and does what you tell it to rather than what you intend. Differences like that have been known to start religious wars.  Adding .c_str() to the arguments in a dozen places sorted that out for me.

The second one was a bit of a stumper, and the folks at the wxWidgets Discussion Forum helped me out. I’ve dealt with a lot of user communities for various APIs and toolkits, and the wxWidgets folks have always been the most helpful and knowledgeable.

I was able to get the client to build.  I was even able to get it to run.  I could almost even use it.  Here’s a screenshot:

Basternae Client on Linux Screenshot

The main problem with it is that the input window doesn’t actually work — you can type until you’re blue in the face but nothing ever gets sent to the MUD.  Strangely enough, if you program a hotkey and click that, the text goes across fine.  I was able to clumsily log in and fight something using that method.  I’m sure there’s some OS-specific stuff in the key handler for the input window, but that probably won’t be too daunting to figure out.

Now I’m going to have to learn how to create Debian (.deb) installer packages so I can distribute the thing.  I might also have to figure out how to do .rpm, but since I don’t run a Redhat/Fedora-based version that might be a little low on the priority list, especially since I’d have to set up VM just to build/deploy it.  I might be the only one who uses Linux that would connect to Basternae anyhow.

It would also probably not be too tough to get this working for MacOS and Solaris, but since there’s zero chance of me having a Mac to work with and the only people who run Solaris work at Sun Microsystems, those aren’t really a priority.