Archive for the 'Issues and Bugfixes' Category

Unit Testing With MbUnit

Thursday, July 10th, 2008

In general either code works or it doesn’t and it’s easy to tell whether it does or doesn’t work. At least until you reach a certain level of complexity. At some point a project gets large enough that you can’t tell which project/dll your error is coming from, let alone which of the 100K or even 50M lines of code is doing naughty things.

Today I had a problem that was easier to solve by creating unit tests to point out where the flaw was. The tool uset? MbUnit.

Here’s an example of an MbUnit test I wrote in order to find a string processing bug:


using System;
using System.Collections.Generic;
using System.Text;
using MbUnit.Framework;
namespace UnitTests
{
[TestFixture]
public class MUDStringTests
{
[RowTest]
[Row(12, "12.box", "box")]
[Row(1, "cheese", "cheese")]
[Row(1, "1.pie", "pie")]
[Row(1, ".chicken", "chicken")]
public void NumberArgument(int expectedValue, string inputString, string expectedOutput)
{
string str = String.Empty;
Assert.AreEqual(expectedValue, BasternaeMud.MUDString.NumberArgument(inputString, ref str));
Assert.AreEqual(expectedOutput, str);
}
}
}

What this does is check whether we’re getting the expected output when we give a certain piece of input. It’s handy for detecting anomalies without having to boot up the server and/or mess with production code. Mind you, there’s no such thing as ‘production code’ since we don’t have a server up yet, but this sort of thing is likely to be handy in the future.

I’m not the type that has any chance of turning into a ‘write the unit tests first’ and ‘unit tests are more important than code’ evangelistic freaks, but in some (or many) cases it can be easier than using trial-and-error to track down a bug.

I still hate the way WordPress formats my code.

Miscellaneous Fixes

Tuesday, July 8th, 2008

I made a few changes to character creation today.  There were a few places where it was case-sensitive — you could create a “Troll” but not a “troll” and there were a few weird state changes.  For instance, when creating a character you would see the menu twice the first time it was displayed.

I also fixed a few immortal commands that will make it easier to create immortals and set command permissions for their abilities.

The say, emote, whisper, yell, shout, ask, and immtalk commands were broken (all messages came across blank), and are now fixed.

Issue Code Is Working

Monday, July 7th, 2008

I finished testing the issue code today.  We now have a functional ‘help desk database’ for the MUD.  It’s primitive, but it should do the trick and can be expanded/changed as necessary.  At least we’ve eliminated the bug, idea, typo, and ‘helps needed’ files that admins would rarely, if ever, look at.  Here’s an example of usage:

< > issue update 2 This is a test issue.
Issue 2 updated with text This is a test issue.

< > issue close 2 Testing the issue entry system.
Issue 2 closed with resolution Testing the issue entry system.

< > issue show 2
Issue Number: 2   Priority: high   Type: helpentryrequest
Is Closed: True   Opened by Imm: True   In Room: 0
Created by: Xangis   Time: 7/6/2008 11:14 AM   Text:
disarm
Entered by: Xangis   Time: 7/6/2008 11:32 AM   Text:
this
Entered by: Xangis   Time: 7/6/2008 11:36 AM   Text:
This is a test issue.
Closed by: Xangis   Time: 7/6/2008 11:37 AM   Text:
Testing the issue entry system.

< > requesthelp disarm
Help entry request recorded.  Thank you.

< > issue list
Issues:
[3] (lowest) Help Request: disarm
[4] (lowest) Help Request: issue
[5] (lowest) Help Request: ignore

< > Issue Number: 3   Priority: lowest   Type: helpentryrequest
Is Closed: False   Opened by Imm: True   In Room: 0
Created by: Xangis   Time: 7/6/2008 11:25 AM   Text:
Help Request: disarm

< > issue priority 3 lowest
Issue 3 priority set to lowest.

TODO List Added

Saturday, July 5th, 2008

I’ve added a to-do list under the ‘Pages’ section. It’s not quite complete and the formatting isn’t all that great, but it might be a useful way to keep track of what needs to be done. At the very least it’ll give readers some idea what I’m working on.

So far I’ve been using simple “todo.txt” files in each of my Visual Studio projects, but that keeps them from being all in one place and is a bit disorganized.

Fixes and More Fixes

Sunday, December 16th, 2007

I have the client and server running well enough that I’m able to create a character and log in to test all of the available commands. In the first pass, just logging in and typing the command name to see what happens, I’ve found a fixed quite a few glitches. I haven’t fixed all that I’ve found yet, but at least it’s progress.

It finally feels like this is turning into a game again.

Character Creation Works Again

Saturday, December 8th, 2007

More or less. The color screens have not yet been reimplemented, so it ain’t pretty yet.

A Help Desk?

Monday, December 3rd, 2007

I’ve written what is essentially an online help desk system for the MUD to keep track of bugs, ideas, and typos. I’m sure it’ll need to be adjusted with use, but at least now the immortals should be better able to keep track of where the problems are and what needs to be done with them.

Fixing Communication Routines

Friday, November 30th, 2007

So I ran into a few glitches and buffer problems in the communication routines. I rewrote a few functions, simplifying them in the process, and things are a lot smoother now. At the very least they should be more stable than communications on Basternae 2.

The character creation process has a handful of glitches to work out. I’ll probably do that before I take on area loading, which will be the largest of the data format conversion projects.

Combat Bug Fixed

Saturday, June 9th, 2007

It was far easier to fix than I had expected.

Here’s what I was doing:

std::list<CharData *>::iterator it;
CharData * wch;
for( it = CharList.begin(); it != CharList.end(); )
{
wch = *it;
<stuff happens to wch here, and during combat wch could potentially be killed and deleted>
}

When there was a death in combat, the iterator would get corrupted, because in the destructor for CharData an iterator would remove the CharData from the CharList, corrupting the iterator in the violence update. Due to the chain of function calls between the violence update and where the CharData was actually deleted, there was no way to update the original iterator or do any sort of “safe” removal.

After tinkering around a bit, reading some message boards, it turns out that using a second iterator saves me. One of the iterators is incremented safely, the other damaged/destroyed, and things move on happily because we’re not referencing the broken iterator.

std::list<CharData *>::iterator it;
std::list<CharData *>::iterator jt;
for( it = CharList.begin(); it != CharList.end(); )
{
jt = it++;
ch = *jt;
<dangerous deletion stuff happens here>
}

Pretty strange, but it works.

Plenty To Fix

Friday, June 1st, 2007

I’ve ran some testing of this new rewrite-in-progress.

As expected, there were a few problems with some of the string functions. Those were easy enough to fix.

But, it’s now time to break out valgrind, because there are a few things that need some re-engineering and I need to see exactly how they’re broken. One thing that might take some work is a problem that happens if a character gets deleted in combat.

The violence updates iterate through a std::list. Each character in that list gets to take their swings at another character. If that target character dies, but is due to take some swings later in the list, the list gets borked because it has no way of knowing that that character was actually killed, deleted, and removed from the list (because that happens elsewhere in the program).

Since this is a combat-based game, fixing that is not optional.

I’m not sure whether it’ll take returning “hey that guy’s dead” info, or whether it’ll be a complete rewrite of combat updates, but I’m sure I’ll figure it out. I recall dealing with deaths at odd points in the code was always a hassle with Basternae 2, so rather than put a band-aid on it, I’d like to come up with a universal solution that works everywhere in the code.