20111220

Sandwich Mechanics: Um, What's Chia?

Welp, that's enough about toppings. Back to basics, and that means bread. This post is dedicated to my good friends CT and COM, who sent me a Christmas card that implored me to write more blogs about sandwiches. But don't worry; if you are tired of bread (how can you make a sandwich without it!?) I have a few other topics coming up eventually. Patience, young sandwhopper.

Let's take it back to that oh-so-familiar bread aisle at Safeway, looking at the wall of Oroweat flavors. What's this? Huh, I see Whole Grain and Chia.. Chia? What the heck is chia? Er, well, okay, let's try it out. Why not, right?

So I took the stuff home and opened it up in preparation for making a sandwich. The Dill Rye taught me to sniff deeply of the flavors, so I did that in this case, too. WOAH! This smells great. It was unmistakeably sweet and aromatic. I made my sandwiches and eagerly awaited lunch.

And as I took that first bite it was there to greet me again, like a wonderful new friend you've just seen for the second time. The bread was tinted with a sweet taste on the back that was enough to make its presence known, but not so much to be sickly or sugary. This is pretty incredible stuff, to have such a distinct flavor that is actually noticeable through all of the other strong flavors I use in my sandwich.

Aside from the distinctive and delicious taste, the other properties of the bread are quite favorable as well. Sometimes whole grain breads tend to be very fibrous and kind of soft, but this stuff was reasonably sturdy. I used it in sandwiches and dipped it in tomato soup--though the sweet taste didn't go very well with it--and its absorbancy is quite good.

It's been a few weeks since I had it, but the crust is not too thick either, if you're one of those people who counts the crust as an unwelcome tagalong for the bread.

But we still haven't answered the mystery: what is chia? Well, let's just look it up here... What's this? Saliva hispanica!? Spanish spit!? Oh wait, it's salvia. Whew. So apparently it's a seed. No wonder I haven't heard of it. Who cares about seeds? I'll say one thing: nice job, chia; you taste pretty pretty great.

20111212

Sandwich Mechanics: Cranberry Honey Mustard....!?

Been a little while since I wrote one of these. I've been busy writing a little code and playing some games... but we're putting a stop to all that nonsense right now, because it's time for another Sandwich Mechanics.

I've been doing a lot of bread posts lately, but that stops right now, because I have a story for you gentlemen. Just let me tell you....

So there I was in the grocs shop the other day, buying my usual selection of lunchmeat (probably'll write about that eventually), when I spotted something out of the ordinary. Wait, rewind a second. I also mean we're rewinding the clock back to the week before Thanksgiving, 2011, which is when this is taking place.

So I'm at the deli, totally not buying a turkey, because my in-laws rule at making a turkey, and I'm not old enough to yet. The deli at my Safeway has some neat spreads and sauces for sandwiches laid out nearby, and today they had one right up on the counter, as if it's something special.

Oh wait. Wait a second. What is THIS?? Cranberry. Honey. Mustard. I read it in color too. I read it in dazzling, tangily, zestily imagined color. Be cool, Newt, be cool. I glanced around nonchalantly, and it took a real effort of will not to just grab the bottle right now, like an addict.

So that's my story. THE END.

What, you want to know what it's like? It blends the three flavors together beautifully. It's got that slightly bitter, slightly sour cranberry taste that leads off, and that mingles harmoniously with the sharpness of mustard, but it's all tempered by the honey.

It tints the meat in the sandwich with this really great background flavor, but at the same time doesn't overpower anything. Really, it is a very well done spread. If you can find some (they're still selling it as of this week), at $3 for a bottle, I highly recommend it, especially if you like the flavors it purports to have.

I can't quite find a link to it, but this link to Beano's sauces is the closest I can get.

20111201

Sandwich Mechanics: Schwarzwald Dark Rye

November is winding down here, and the smell of baking bread is in the air. Wait, sorry, I meant the smell of store-bought bread that had been baked some time previously is in the air.

The last post, about wrapping a sandwich in plastic wrap, featured the Dill Rye sitting pretty in the pictures. Dill, as opposed to what? you might wonder. I wondered, too, so I bought a different type of rye. There are at least four different kinds of Oroweat1 rye at the store, and this time I decided to give the Schwarzwalder Dark Rye a try instead.

Funny thing, I never even read the word "Schwarzwalder" on the packaging until I was looking it up just now. It just looked like "Dark Rye" to me. But I look again, and there it is! Well, what is a Schwarzwalder, anyway? Apparently, Schwarzwald is the Black Forest region of Germany, so this bread must have originated there. Cool.

So what sort of bread is it? I went into it with high hopes, having just had a very successful encounter with the Dill Rye. I opened the package and inhaled deeply, hoping to catch some fascinating scent to go along with the bread... but nothing. It just smelled like regular rye. Oh well, the Dill Rye was extraordinary in that regard.

To be honest, I didn't think much of this bread. It tasted like rye, but not strongly. Really, it didn't have too much flavor at all. Very bland. Worse still--and this is by far my strongest indictment of it--the texture was like cardboard. It was dry and not very good. The texture and dryness was enough to even make an otherwise enjoyable sandwich with good ingredients noticeably worse. That takes some doing.

I slogged through a week of this bread to give you guys, you fictional readers, the word to heed my warning when it comes to this one. One might also expect that a dry texture would be accompanied by some redeeming qualities like low absorbancy or resilience to soaking, but no, the bread was average in these regards too. This comes after eating it both in sandwiches and as a soup vehicle.

I needn't say too much more about this bread. Just don't bother with it. If you have a hankering for rye, so far the Dill Rye is far superior in every aspect.


1. Oh my god, I've been spelling it Orowheat this whole time, when it's actually Oroweat. You've gotta be kidding me.

20111112

Sandwich Mechanics: How to Wrippity Wrap

It's been like three days since my last sandwich post, wherein I talked about some bread I was eating. Let's not talk about bread this time. Well, we'll talk about sandwiches, which necessarily involve bread, but what I mean is that we won't talk directly about it. It's implied.

I pack sandwiches every day, rather, every day I'm not too lazy or get up late or haven't done the groceries that week or have unexpectedly expired ingredients... anyway, often. I'm an efficiency nut, so I try to do things cheaply and quickly. By "things", I of course include the act of wrapping my sandwiches.

The pedestrian, unenlightened way to wrap a sandwich is, er, not to--why are you wrapping it anyway? Just stuff it in a Ziploc and be done with it, right? Yeah, you could do that, but if you don't want to be a chump, you can pinch a few pennies1 and have a little fun in the process.

My preferred alternative to the Ziploc is plastic cling wrap. It doesn't matter what kind you get, but, as we'll see, the cutting mechanism on the box can make a difference. I prefer Kirkland Signature Plastic Wrap2, because I'm a Costco junkie.

I've developed a quick and easy procedure to do the wrapping. I imparted this knowledge to some of my friends who came in to visit for PAX, and now it is time to pass it on to you. I hope you'll be as amazed as they were.

The Procedure

First, pull out some plastic wrap onto the counter and use the cutter thingy to cut it. Having a nice clear counter like this is super useful, but I'm sure you can make do with whatever. The sliding cutter on the box is really useful, much better than the serrated blade, because handling plastic wrap without it getting caught on itself is sticky business.

Put the sandwich in the middle of the wrap, length-wise like shown in the picture.

Now grab the top of the wrap and bring it down over the sandwich.

Likewise, grab the bottom and fold it up over the sandwich.

Fold the left side over the sandwich. I find it helps to put my hand in place to have somthing to fold over.

Take the whole sandwich in your hand and fold it to the right, which is equivalent to folding the right side over it. I just find it quicker this way.

Pat down your sandwich to seal the wrapping. Now you've got a happy sandwich, all snug in its plastic home!


1. Actually, if you have good tupperware containers, you could put your sandwiches in those and pinch all the pennies. There are considerations for this too. For example, they take up room in the dishwasher, and maybe you don't want to reuse them without washing them.

Also, you'll want a box that fits the sandwich properly. In particular, it shouldn't be too large or tall, or else the bread might slide around. There's nothing really binding a sandwich together (like cheese binds pizza to some extent), so the container has to preserve the integrity until you're ready to eat.

2. ilovecostco.com has to be the most upper-middle-class-American thing ever to exist... except maybe this blog series itself.

20111108

Sandwich Mechanics: Dill Rye

It's time for another episode of Sandwich Mechanics. Last time we spent way too much time talking about what this blog series is. Having invested that time previously, we can skip all that nonsense and talk about some sandwiches. How does that sound?

So I picked up some weird bread the other day at the grocs shop. I usually don't like rye bread, but I'm the only one eating it in sandwiches for the time being, so I figured I'd take advantage of this opportunity to be a bit daring. My principle so far has been to pick out something new that's on sale at Safeway. I saw three or four varieties of rye bread (thanks, Oroweat, for having entirely too many flavors of bread) and decided to grab one pretty much at random.

The flavor I chose this time was Dill Rye. My only real encounter with dill is that my dad would put it in when he made kielbasa and saurkraut, and even then I bet the flavor of the kraut overpowered it, so I wasn't really sure what to expect. "Seasoned bread", I guess.

Well, this Dill Rye is pretty nice, actually. The first thing I noticed when I opened it was an aromatic, savory smell that came off of the bread. Apparently dill has a savory fragrance? My bad; I didn't know! But it smells really nice, and the smell comes through slightly in the taste, even buried under the spreads, meat, and cheese.

Texture wise, this is a relatively tough bread. I don't want to say "tough", though, because that sounds like I'm talking about hardtack or something. What I mean is it's sturdy and not flimsy. I think this is probably a feature of the rye family as a whole, but we'll evaluate that later...

In addition to being sturdy, it is clearly fibrous. That comes through in its low absorbancy. When I spread Miracle Whip on it, almost none soaks in. This is a desirable property, because it means I don't have to spread as much topping for the taste of it to remain intact, as opposed to it being diluted by the bread flavor. I also used it to dip in some soup the other day. It made a pretty good soup vehicle, again due to the low absorbancy.

Since this entire blog series deals in minutiae, it's worth mentioning the packaging and form factor. The loaf comes in a weird kind of "half-loaf", where there's a crust piece on only one side. It's still double-wrapped in the usual Oroweat fashion, but without a twist-tie at the top. Instead, there's a sticker on one end that is used for folding the bag down like a flap and sticking it closed. By the end of the week, the sticker is starting to lose its effectiveness. I'm not a big fan.

Having the half-loaf is actually good, though, since I don't tend to make good use of the end-pieces. The bread itself is shaped kind of oblong. Four slices of bread don't fit on the plate too well, but these things barely matter.

I've been eating it for about a week now, and I have to say it's pretty great. I would get it again!

20111103

Sandwich Mechanics: Intro and Potato

Hi there. If you've read any of the posts on this blog, you may know that I do some programming. What you may not know is that I also dabble in cooking... sandwiches. Well, you might say that making sandwiches shouldn't be construed as cooking. You might also be wrong, though, so you should think about that, too.

Actually, no, making sandwiches isn't cooking in my eyes. I believe I've even said it myself. But I think a lot about making sandwiches. No, I don't mean I think, "oh I ought to make a sandwich". I mean that while I'm making sandwiches I think quite a bit about them. If you know me at all, this may come as no surprise to you, but I overthink things a lot.

So I make sandwiches for myself and the wife, and sometimes I make so many of them that I want to write about what I think about when I do so. This is a blog series that will cover all kinds of aspects of sandwich making, from reviews of different breads, to construction techniques, to choices of toppings, and even thoughts on slicing the sandwich.

I like my introductory posts like I like my sandwiches: with some meat in them. Oh, that was bad. Brace yourself; that's just the beginning. So today I will talk about some bread.

Oroweat Country Potato Bread

Oroweat is interesting in that they have like ten million different varieties of bread, all found in my local Safeway. Country Potato Bread is probably the one that we have been buying for the longest. TLDR right up front: it's pretty tasty bread, most people agree.

The packaging on this Oroweat stuff is actually pretty good. They double wrap the bread--once in the usual thin plastic bag with the little plastic holder contraption, and once within using a thicker plastic bag that you have to rip through. It's inconvenient at first, but I'm convinced it extends the life of the bread, so that's okay in my book. I realize there are those like the great philosopher Hedberg who think it's just one more step on the way to toast, but really, I think it has its value.

The bread itself is not too hard. This is important because you don't want to be eating crackers. You want bread. The bread is not incredibly sturdy, but it's not terrible. And the sturdiness is a measure of how the bread holds up when soaked with sauces or spreads. It's definitely not sturdy enough to really take a slice of tomato without some kind of divider or membrane (??) in between, but it won't get soggy and floppy just from some spread.

And the lack of sturdiness means that it can get pretty squashy if you're not careful when transporting the finished sandwich. I've had some comically misshapen sandwiches at lunch a few times. People were all, "What is that?" And I had to patiently tell them that it's a sandwich, god, can't you see that? This isn't a deal-breaker as far as this bread is concerned.

When you're taking it out of the bag, it also has the chance to rip a little. Man, I'm making this bread sound like a wet paper towel. It's not that bad. Just... just, be a little gentle, yanno?

So how does it taste? Tastes like regular white bread, but heartier and with the distinct taste of potatoes. It's a good taste, with a full body behind it. You should definitely give it a try.

I can't believe I wrote five paragraphs about bread. And I'm gonna do it again in a few days.

20111013

Making my Comp Shut Up

For some reason the keyboard filter driver that comes with my new Asus netbook doesn't work properly. Only some of the special function keys actually work. The most important one that doesn't work is the mute toggle. Instead it just, well, does nothing. This is pretty annoying, so I wanted to get the functionality back.

So I set out to write a program to toggle the mute of my netbook. Turns out not too many people have done this properly on Windows 7 or Vista. I found one CodeProject program to control audio, but it was written in managed code, and I needed to register to download it.

Look at me: I'd rather re-implement something like this than register for a site to download the already-done work. I don't know if that's good or not.

Anyway, that guy was on the right track. You use the new MMDevice APIs to do everything. Here's the code, for people's reference.

And link against mmdevapi.lib.

#define UNICODE 1
#include <windows.h>
#include <atlbase.h>
#include <stdio.h>
#include <stdlib.h>

#include <mmdeviceapi.h>
#include <endpointvolume.h>

using namespace std;

HRESULT ToggleMute();
void Usage();

const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);

int __cdecl wmain(int argc, wchar_t* argv[])
{
    HRESULT hr = S_OK;

    CoInitialize(NULL);

    if (argc > 1)
    {
        if (_wcsicmp(argv[1], L"/togglemute") == 0)
        {
            hr = ToggleMute();
            return hr;
        }
    }

    Usage();
    hr = E_INVALIDARG;

    return hr;
}

HRESULT ToggleMute()
{
    HRESULT hr = S_OK;

    CComPtr<IMMDeviceEnumerator> spDeviceEnum;
    hr = spDeviceEnum.CoCreateInstance(CLSID_MMDeviceEnumerator);

    if (spDeviceEnum)
    {
        CComPtr<IMMDevice> spDevice;
        hr = spDeviceEnum->GetDefaultAudioEndpoint(eRender, eMultimedia, &spDevice);

        if (spDevice)
        {
            CComPtr<IAudioEndpointVolume> spVolume;
            hr = spDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL, reinterpret_cast<void**>(&spVolume));

            if (spVolume)
            {
                BOOL fMuted = FALSE;
                hr = spVolume->GetMute(&fMuted);

                if (FAILED(hr))
                {
                    wprintf(L"failed GetMute: %08LX\n", hr);
                    fMuted = FALSE;
                    // but keep going; mute the system, the safer thing to do
                }

                wprintf(L"%smuting\n", (fMuted ? L"un" : L""));

                hr = spVolume->SetMute(!fMuted, NULL);

                if (FAILED(hr))
                {
                    wprintf(L"failed SetMute: %08LX\n", hr);
                }
            }
            else
            {
                wprintf(L"failed Activate endpoint volume: %08LX\n", hr);
            }
        }
        else
        {
            wprintf(L"failed GetDefaultAudioEndpoint: %08LX\n", hr);
        }
    }
    else
    {
        wprintf(L"failed CoCreate: %08LX\n", hr);
    }

    return hr;
}

void Usage()
{
    wprintf(L"Usage: soundtool.exe [/ToggleMute]\n");
}

And then I teamed this up with the magical AutoHotKey to make the scenario transparent.

^!F10::Run, F:\bin\soundtool.exe /ToggleMute, , Hide

20111008

Playing the Puppeteer at Testing

Hello, thoroughly fictional readers. It has been a while, but I have not been idle. Well, I've played a lot of video games and did a bunch of work, but I also worked on the MUD. Primarily, I've been working on combat, and I now have something roughly working that I'm not thoroughly displeased with. But this post isn't about combat, not really. It's about something far more fun and interesting than fighting baddies.

It's about testing. Yes, again (and again). And why shouldn't it be? I test software for a living, so this is supposed to be interesting to me.

The feature - behaviors

So I coded up these things unimaginatively called behaviors, which are a self-contained piece of state and functionality that can be attached to a mob (reminder: mobs are living entities, either player characters or NPCs, aka "nipics"). They have access to all the eventos that it sees (reminder: eventos are just the events that are sent around when mobs do things, e.g. walk into a room, hit someone, or die). They get called on every pulse in the main loop of the MUD, so they can keep timers to do things. And they can basically be dropped in or pulled out of a mob without affecting any of its other, well, behavior.

I coded these up so that I could attach specific behaviors for different types of combat personalities. I won't go into too much detail just yet, but the main behavior I'll be talking about causes a mob, when hit, to retaliate against its aggressor. As I wrote this code, I did a good thing: I only wrote tests for it to see that it's working. I didn't actually run the MUD for over a month, since I had confidence my tests were doing a good job. At the end I'll reveal whether they actually were effective.

New testing techniques

At some point I found the need to test interactions between multiple mobs. Over time I ended up developing quite a bit of machinery to make this very simple while at the same time verifying a lot of things even in the simplests of tests. I'll walk through two example tests to give an idea of what's going on.

The first is one of a whole class of tests I wrote, several for each command possible. All the commands I have end up relying on a lot of lower level functionality, so these tests can help find when a change I make has unintended consequences in another part of the system. Well, that was a pretty worthless sentence; this is one of the main reasons for testing at any time.

I'm rambling. Here's the test. I've put in numbered comments for things to talk about further, so heed those.

class TC_NipicActions_Say < TC_NipicActions
    def test_simple()
        # (1)
        source = $td.t1

        # note: the name "hearer" is totally arbitrary. it's just some mob
        bystander = $td.hearer

        # (2)
        $td.nipics().each() { |n|
            # (3)
            TestHelper::MobHelper.quietSayBehavior(n)
        }

        # (4)
        TestHelper.action_test(source, bystander) {
            eventos = [
                SayEvento.new(source, "hello hello hello how are you doing sir")
            ]

            # (5)
            TestHelper.doActionNow(source, :doSay, eventos[0].saidText)

            {
                bystander => eventos,
                source => eventos
            }
        }
    end

    def test_bad_notext()
        source = $td.t1
        bystander = $td.hearer
        # (6)
        TestHelper.bad_action_test(source, $td.hearer) {
            source.doSay(nil)
        }
    end
end # class TC_NipicActions_Say

(1) - $td stands for "test data", and is the object that primarily gives the test access to all of the mobs and rooms in the world. Actually, when I build a world to be used in tests, I also hand-build a corresponding TD class with the mobs built in. Here, I might as well show it.

class TD_Test1 < TD_Base
    def initialize()
        super()
        $mud = Mud.new(9876)
        $mud.loadWorld('test1')

        # hard-coded room ID referenced here
        self.room0 = $mud.worldMap.getRoom(LID.new('second', 0))

        # once I have a room, I can look up mobs in the room according to their
        # short descriptions, which I know because I wrote them in the area
        # XML file

        self.t1 = room0().bagMobsInRoom.find() { |thing|
            thing.shortDescription =~ /a short man/
        }

        self.t2 = room0().bagMobsInRoom.find() { |thing|
            thing.shortDescription =~ /a tall man/
        }

        # ...
    end

    # this declares both the accessor methods and inserts them into an internal
    # list of nipics, which I can use to find out all the nipics in
    # the area
    nipic :t1, :t2
end

(2) - as mentioned in the comment above, I can enumerate all the nipics in the world and do something to each of them. What sorts of things, you might want to know? Well...

(3) - I'm shutting them up. Maybe you recall from an earlier blog post that nipics by default will obnoxiously repeat anything they hear within earshot. Well, this test is about nipics saying things, and I don't want that weird behavior interfering... so I modify the nipics' behavior by shutting them up. What exactly does quietSayBehavior do? Here:

module TestHelper
    module MobHelper
        def self.quietSayBehavior(nipic)
            nipic.behaviors().delete_if() { |b|
                b.kind_of?(MB_ObnoxiousRepeater)
            }
        end # function quietSayBehavior
    end
end

It just finds the MobBehavior (remember I started off talking about those?) for the obnoxious repeating nonsense, and removes it. This works because I was careful to build the behaviors so that doing things like pulling one out at runtime is okay.

(4) - now, the main part of the test is a helper function called action_test. Its purpose is to let the test run some actions on some mobs, then verify that all the right eventos were seen by each involved parties. The main part of the test is a block of code that A) controls the mobs according to what the test wants, and B) returns a hash that maps each involved party to a list of eventos (in order!) that they were expected to see during the course of the test.

In this case, there are two parties (source and bystander), and since the say command broadcasts to everyone in the room, everyone should get the same set of eventos.

(5) - this doActionNow function is very easy to skim over and miss. Its name seems obvious enough until you ask, "'now', as opposed to when else?" The reason is that during testing, the MUD is actually, by default, at a standstill. Nothing really happens unless we hand-crank it. Put another way, the main loop of the MUD doesn't run during testing. Put yet another way (how many ways are there?), it's up to the test to drive the main loop when it wants to. This allows for fine grain control over timing.

This test, like most others, isn't so precise that it requires fine grain time control, so it can use doActionNow. It's worth seeing what that really does:

class TestHelper
    def self.doActionNow(mob, symAction, *args)
        mob.doAction(symAction, *args)
        pulseMudUntilIdle(mob)
    end # function doActionNow
end

The bolded function, pulseMudUntilIdle basically runs the MUD's main loop (which primarily sends pulses to all things on the MUD) for a while--until the mob in question is "idle". Idle, you may recall, refers to the mob's not having any commands pending in its command queue and no residual delay from a recently executed command. Basically, by the time the mob goes back to being idle, it is ready to immediately execute another command.

So quickly bringing it back around, doActionNow means do a command and block until it's been completely finished.

(6) - bad_action_test is a test that expects two things: firstly, that the block should hit a mobcheck due to some invalid parameter or something (in this case, trying to pass nil to doSay); and secondly, that no eventos will be produced. Obviously if the command errors out, there should be no effects visible to anyone else.

More about action_test

action_test is so widely used now that it doesn't mind being examined even more. This rabbit hole goes deep. Watch out; we're about to dive in. How about we start with the code?

module TestHelper
    def self.action_test(*parties)
        archives = {}

        # (7)
        parties.each() { |p|
            archives[p] = MobEventoArchive.new()
        }

        # (8)
        parties.each() { |p|
            p.manager.addEventoListener(archives[p])
        }

        # (9)
        expectedEventos = yield

        # (10)
        expectedEventos.each_pair() { |party, eventos|
            archives[party].checkAgainstExpectedEventos(eventos, "eventos for #{party}")
        }
    end # function action_test
end

(7) - Think back again to eventos, the system for passing around messages that something occurred. We have this thing called the MobEventoArchive, which just couldn't have a more fitting name. It just logs all the eventos that are seen by a mob for later inspection.

(8) - for each mob that is part of this test, we add our archive as an evento listener. What's nice about this is that it plugs straight in to the code for eventos; evento listeners aren't a special test hook or backdoor; they're part of the MUD proper. Anyway, this is how we wire up the evento archive to the mob, so that eventos that he sees get logged.

(9) - remember that block that was the actual meat of the test? Yeah, this yield is where we call that and get the list of expected eventos out of it.

(10) - finally, we can go through each party that is involved with this test and verify that the set of eventos they received and the order in which they were seen are as expected.

There's two things I should add about that. Firstly, of course this relies heavily on correct expected data being fed into the test--as they say, "garbage in, garbage out". Secondly, and more subtly, since this is the majority of the verification in most tests, it puts a heavy burden of trust on the evento system. It takes it for granted that if, for example, you see a SayEvento, that the player would actually see the effect of it on their screen. Or that if you see a EgressEvento, then a mob really did leave a room (not just broadcast some intent to). It's a lazy way of relying on one part of the system to transitively verify or imply other things happened.

But we're programmers, right? Being lazy is our bread and butter.

Dealing with randomness

If you're reading this blog, you're probably friends with me (fictionally, of course), which means you have at least some idea about what Dungeons and Dragons are. Whoa, looks like we're getting way off topic! No, actually, the point is that a large part of D&D is randomness - die rolling, checks for success, and all that. MUDs, based on D&D, are the same. Heck, most games have some element of randomness.

Randomness, any experienced tester will tell you, can be problematic. Usually you want deterministic test cases, so that you can verify precise conditions in the results. Of course it's possible to write tests that account for randomness, but they're more difficult, and if something breaks, the investigation time is typically longer.

But now I have all these choices that get made based on random numbers. I needed a way to deal with this in my tests. Luckily, I'm using a highly dynamic language like Ruby, where I can just hack things to bits until they do what I want. Let's go look.

For example, let's look at the damage a mob does when he hits someone else. I know it's not nice to hurt others, but combat is a big part of the MUD. Here's the code for hitting someone else:

class Mob
    def doHit(target)
        mcheck_amPhysical()
        mcheck_targetPerson(target, 'You can\'t hit that.')
        mcheck_personNearby(target)
        mcheck_physicalPresence(target)
        mcheck_targetNotSelf(target, 'Stop hitting yourself!')

        addActionDelay(10)

        hpLost = randGetHitDamage(target)

        sendEvento(room(), HitEvento.new(self, target, hpLost))
    end # function doHit

    def randGetHitDamage(target)
        return Calc.randMax(30)
    end # function randGetHitDamage
end

randMax gets a random number between 0 and the argument you pass in. I have a bunch of tests in which hitting happens, and if I want a consistent outcome, I need to control what this value is at runtime. Here we go with the Ruby magic.

module TestHelper
    module MobHelper
        def self.affixHitDamage(mob)
            mob.override_singleton_method(:randGetHitDamage) { |target|
                return 40
            }
        end # function affixHitDamage
    end
end

By calling this, it fixes the damage in place. Now my tests can assume that the damage is not changing for every hit, though the tests do themselves call randGetHitDamage to avoid knowing precisely what that fixed value is.

The subtext here is that all decisions that depend on random numbers need to be wrapped in methods (preferably tightly, as in this case), so that they can be overridden. Usually methods are used to break up code and give reusable blocks of functionality; here, they serve the added purpose of test hooks.

I know it's not strictly necessary, but can I show override_singleton_method real quick? I kind of like how it works. Yeah, I'm pretending to ask your permission. How do you like that?

class MethodOverrideError & StandardError
end

class Object # yeah, that's right, Object
    def override_singleton_method(symMethod, &blk)
        if !respond_to?(symMethod)
            raise MethodOverrideError.new("cannot override method #{symMethod} because object #{self} does not already implement it")
        end

        define_singleton_method(symMethod, &blk)
    end # function override_singleton_method
end

I wanted to make sure that I when I say override I really do mean override and not "define a new method".

There you have it. That's the general technique for how I constrain (rather than embrace) the chaos in my tests.

Putting it all together - a complex test. Wait, that was simple back there?

Using all these techniques I've shown, I'm able to create monstrously large tests that simulate multiple nipics interacting with each other. By heavily relying on the evento verification, I don't bother individually verifying many smaller things.

The code. This is a test for the most complicated scenario of the new "retaliator" behavior, which pits a mob against two aggressors and watches him systematically chase each one down and exterminates them, like you would any termite or roach.

Here's hoping my documentation is sufficient and clear.

def test_retaliate_pursue_2()
    attacker1 = $td.t1
    attacker2 = $td.hearer
    defender = $td.t2

    # calm attacker1, but not defender, which will retaliate
    TestHelper::MobHelper.calmNipicBehavior(attacker1)
    TestHelper::MobHelper.calmNipicBehavior(attacker2)
    TestHelper::MobHelper.affixHitDamage(attacker1)
    TestHelper::MobHelper.affixHitDamage(attacker2)
    TestHelper::MobHelper.affixHitDamage(defender)
    TestHelper::MobHelper.affixRetaliateHitDecision(defender, true)

    # (11)
    TestHelper::MobHelper.affixRetaliatePursuitDecision(defender, true)
    attacker1.hpRegenPerTick = 0
    attacker2.hpRegenPerTick = 0
    defender.hpRegenPerTick = 0

    # build up the eventos array according to several hits until death
    hitDamage_a1_d = attacker1.randGetHitDamage(defender)
    hitDamage_d_a1 = defender.randGetHitDamage(attacker1)
    hitDamage_a2_d = attacker2.randGetHitDamage(defender)
    hitDamage_d_a2 = defender.randGetHitDamage(attacker2)

    mbret = TestHelper::MobHelper.findRetaliator(defender)

    TestHelper.action_test(attacker1, defender, attacker2) {
        eventos =
        [
            HitEvento.new(attacker1, defender, hitDamage_a1_d),
            HitEvento.new(defender, attacker1, hitDamage_d_a1),
            HitEvento.new(attacker2, defender, hitDamage_a2_d),
            HitEvento.new(defender, attacker2, hitDamage_d_a2),
        ]

        TestHelper.doActionNow(attacker1, :doHit, defender)
        TestHelper.doActionNow(attacker2, :doHit, defender)

        ##########
        # by this time, the defender has been able to retaliate once on
        # each of the attackers
        #
        # we need to get the internal ordering of aggressors as stored by
        # the retaliator object. since the aggressors are stored in a hash,
        # this is nondeterministic, so we need to query it here. from this
        # point on, we don't refer to attacker1 and attacker2, but rather
        # firstAttacker and secondAttacker, which reflects the order in
        # which the defender will go after them.
        ##########
        ordering = TestHelper::MobHelper.getRetaliateOrdering(mbret)
        firstAttacker = ordering[0]
        secondAttacker = ordering[1]

        hitDamage_d_a1 = defender.randGetHitDamage(firstAttacker)
        hitDamage_d_a2 = defender.randGetHitDamage(secondAttacker)
        hpCount1 = firstAttacker.currentHP()
        hpCount2 = secondAttacker.currentHP()

        eventosFirstAttacker = eventos.dup()
        eventosSecondAttacker = eventos.dup()
        # use eventos to be defender's eventos

        # everyone sees first attacker leave
        e = EgressEvento.new(firstAttacker, Direction::South)
        eventos.push(e)
        eventosFirstAttacker.push(e)
        eventosSecondAttacker.push(e)

        # only first attacker sees himself enter south room
        eventosFirstAttacker.push(IngressEvento.new(firstAttacker, Direction::North))

        # only second attacker and defender see second attacker leave
        e = EgressEvento.new(secondAttacker, Direction::North)
        eventosSecondAttacker.push(e)
        eventos.push(e)

        # only second attacker sees himself enter north room
        eventosSecondAttacker.push(IngressEvento.new(secondAttacker, Direction::South))

        # defender follows first attacker first
        eventos.push(EgressEvento.new(defender, Direction::South))
        e = IngressEvento.new(defender, Direction::North)
        eventos.push(e)
        eventosFirstAttacker.push(e)

        # defender pounds first attacker to death
        while hpCount1 > 0
            e = HitEvento.new(defender, firstAttacker, hitDamage_d_a1)
            eventos.push(e)
            eventosFirstAttacker.push(e)
            hpCount1 = hpCount1 - hitDamage_d_a1
        end

        e = DieEvento.new(firstAttacker)
        eventos.push(e)
        eventosFirstAttacker.push(e)

        # now chase down second attacker. that's 2N from where we are
        eventos.push(EgressEvento.new(defender, Direction::North))
        eventos.push(IngressEvento.new(defender, Direction::South))
        eventos.push(EgressEvento.new(defender, Direction::North))
        e = IngressEvento.new(defender, Direction::South)
        eventos.push(e)
        eventosSecondAttacker.push(e)

        # defender pounds second attacker to death
        while hpCount2 > 0
            e = HitEvento.new(defender, secondAttacker, hitDamage_d_a2)
            eventos.push(e)
            eventosSecondAttacker.push(e)
            hpCount2 = hpCount2 - hitDamage_d_a2
        end

        e = DieEvento.new(secondAttacker)
        eventos.push(e)
        eventosSecondAttacker.push(e)

        firstAttacker.doAction(:walkInDirection, Direction::South)
        secondAttacker.doAction(:walkInDirection, Direction::North)

        # (12)
        # defender will retaliate, killing first attacker, then second
        TestHelper.deathTest(firstAttacker) {
            TestHelper.deathTest(secondAttacker) {
                TestHelper.pulseMudUntil('defender not mad') {
                    !mbret.uMadBro?()
                }
            }
        }


        {
            firstAttacker => eventosFirstAttacker,
            secondAttacker => eventosSecondAttacker,
            defender => eventos,
        }
    }
end

Holy crap, that's a long test. I'm actually kind of amazed it even works. Before getting to the annotations, it's interesting to note just how much of the test is dedicated to building up the expected results, as opposed to controlling the mobs. This is not an uncommon occurrence at all in testing. Really, there are only four commands that the mobs actually do: each attacker hits the defender, then each attacker runs away. All of the retaliation is automatic, so I have to predict the expected results and encode that in a set of eventos.

(11) - this affixing is needed on the defender, because on every pulse that he doesn't see any of his aggressors around, he has a chance to wander off hunting one. This removes the element of chance, forcing him always to choose "yes, puruse" for that decision.

(12) - the "death test" calls the block that it's given and verifies that the mob indicated by the argument is alive at the start, but dead dead dead by the end of it. It verifies several things about death: that the life state becomes LifeState::Dead, that it is removed from the room, and so on.

The reason I have two death tests embedded this way is that I want a single action--just waiting until the defender is no longer mad--to produce two deaths.

Conclusion

Early in this blog I said I'd reveal whether this testing was effective, compared to ad-hoc testing (just running the mud and playing it). Well, I finally fired it up the other day and fought one of these guys, and I have to say... it was pretty fun! The fight went basically as I envisioned it. I kept trying to run from that jerk (um yeah, the one that I attacked), but he ruthlessly chased me down. Maybe even too ruthlessly...

Now perhaps you see why I feel like a puppeteer in this endeavor.

20110930

installing a particular version/platform of a ruby gem

I recently installed the Windows 8 developer preview on my netbook. It runs pretty nice, but one important thing is that the development tools I installed are Visual Studio 11. This means that pre-built libraries built with earlier versions or toolchains may not link properly with libraries built with this version.

Consequently, I often needed to have rubygems I installed built from source instead of installing some native version.

I’ll pick on DevIL for a moment. If you search for the gem you’ll find:

>gem search --remote devil



*** REMOTE GEMS ***

devil (0.1.9.5 ruby i386-mingw32 i386-mswin32, 0.1.9.1 x86-mswin32-60)

now if you simply do gem install devil, you’ll get one of the pre-built mswin32 versions--not what I want. In fact, I did try them, and they don’t work, because they dllimport the wrong version of my ruby dll (which, again, I built myself).

Here’s what I did. I found out my ruby version:

>ruby -v
ruby 1.9.2p290 (2011-07-09) [i386-mswin32_110]

Then I installed the gem with these flags:

gem install --platform i386-mswin32_110 -v ruby devil

specifying the "ruby" version forced it to build from source. useful

20110921

Mixin Components and Fun

Recently I was clued in to a thing called Component-based architecture by one of my good friends. I'd never heard of it before, but I find some aspects of it very appealing.

I never thought that the strict inheritance model would work for a large system. It's hard to define multi-faceted things using a strict tree of inheritance (rather than, say, a DAG). In a nutshell, the component-based architecture dictates that classes themselves have no properties except for a collection of specialized pieces of functionality. The idea is that you can create new classes by dropping in different combinations of functionality, which offers better flexibility.

Ruby and mixins

As with many good ideas, multiple people come up with them independently. I actually use the spirit of this technique in certain places in the MUD. However, I take heavy advantage of the language features of Ruby as the mechanism for making the components work. There's a commonly used language feature of Ruby called mixins, wherein basically an interface is allowed to add instance data and methods to a class.

Here's a quick example:

# mixins are modules, not classes
module Reviewable
    def reviewScore()
        return @reviewScore
    end

    def reviewScore=(val)
        @reviewScore = val
    end

    # in Ruby you can use this shorthand for the getter and setter:
    # attr_accessor :reviewScore
end

class VideoGame
    include Reviewable
end

game1 = VideoGame.new()
game1.reviewScore = 5

class Shoes
    include Reviewable
end

vans = Shoes.new()
vans.reviewScore = 9

So the Reviewable mixin adds the reviewScore instance methods and data to a class--any class. Video games and shoes obviously have nothing to do with each other, but you could concievably review either, and the mixin lets you add that functionality very easily.

The component-based architecture model is a little different. In it, the class would have some kind of "reviewable" component, and whatever main loop needs to process the "reviewable" data would call some abstracted method on the object to fetch it. Maybe something like this?

class Reviewable
    def getData()
        return @reviewScore
    end

    def updateData(val)
        @reviewScore = val
    end
end

class VideoGame
    def initialize()
        self.components = [Reviewable.new()]
    end

    attr_accessor :components
end

def mainLoop()
    entities.each() { |ent|
        ent.components.each() { |comp|
            # consume the data from each entity's components
            print comp.getData()
        }
    }
end

"Real-world" examples

I mentioned I use the mixin model in my MUD. I'll give some examples. But there's a difference, which I'll touch on at the end. First, the examples.

Probably the best example is the Visible mixin, which provides a thing with the necessary data and attributes to be seen.

module Visible
    # initialization and such omitted for brevity
    attr_accessor :bareShortDescription, :bareLongDescription, :hugeDescription
end

More interestingly, the Visible module also provides all of the code needed to automatically load these values from XML data files (and save them back). This mixin is used for Mobs and Dealies (items like things you'd pick up and carry) alike without modifications needed, despite how dissimilar they are.

I have modules called InputFilter and OutputFilter that can be applied to any class to advertise that they know how to process text typed by the user or printed to the user's screen, respectively.

Actually, Ruby uses mixins for this kind of thing pretty broadly. The Comparable and Enumerable mixins advertise that particular objects implement functionality needed to compare or enumerate themselves, respectively, plus they add a bunch of additional methods implemented for you.

The difference... is all inside.

I claim that this use of mixins is similar to the component-based abstraction. In both cases, the objects store some state that is sequestered wholly inside some other class or functionality. In both cases, other objects would interact with this object through some abstraction that hides the nature of the containing class--either finding the component within the object to access or just accessing the mixin's functions directly.

Which technique you use doesn't seem too important. The thing that matters most is discipline and convention. If you want to reap the benefits of these techniques, you need to follow through with consistency better than I've done. I have a lot of places where state and functionality is given to a class rather than a mixin of a class.

For example, a Mob has a lifeState member, which tells if it's alive. But what if I want an animate sword that can be "killed?" I should put this functionality into, say, a Living module. Or a really good example: there are containers, which can contain other dealies, and there are mobs, which can also hold objects in their inventory, but they're handled differently. Instead, I could make a Container mixin and treat them the same.

There's a lot of work I could do to basically be more discliplined. I can't really promise I'll get to it, but I may in places it makes sense.

20110803

Resolving Dependencies When Loading

Boring title, I know. Boring post follows. I ran across a problem, spent too long trying weird, overwrought solutions, then realized the simple answer had been staring at me all along. As always, I write this to capture the thought process.

The problem (at the highest level): when someone tries to set the current HP of a mob (any creature in the game) to be greater than its max HP, we should cap it, so that they don't get super powers all of a sudden.

As an aside, there are MUDs where the current HP can soar higher than the max HP, but only for a short time. That's a policy I can debate about internally anytime, but assuming I do want to enforce this, I should have a mechanism to do so.

Here's the code where I put it:

class Mob
...
    def currentHP=(newHP)
        # the else case for Numeric is used during loading
        if newHP.kind_of?(Numeric)
            if newHP < 0
                newHP = 0
            elsif newHP < maxHP()
                newHP = maxHP()
            end

            @currentHP = newHP

            if currentHP() == 0
                die()
            end
        else
            @currentHP = newHP
        end
    end # function currentHP=
end # class Mob

Pretty straightforward, at least at a glance. Of course, it's not so. Time to think back again to loading and saving, those eternal thorns in my side. Quick refresher: when we load up the MUD, we parse a bunch of XML files and create a bunch of objects out of what's described there. The objects are things like Mobs or Rooms or Dealies (objects). Each object can have properties. For example, a Mob has a property called current_hp:

# a numeric property loaded from the xpath "current_hp", which stores its value
# in self.currentHP, and if not found, takes its value from self.maxHP

addProp(
    PersistedProperty.new(
        'current_hp',
        ref(:currentHP),
        Fixnum,
        PersistedProperty::OptionalValue.new(ref(:maxHP))))

What happens during loading is that all the properties of an object are loaded in an unspecified order. To set the property, it calls the accessor method on the object, like Mob.currentHP=. Due to the undefined order, there's a nonzero chance that loading will try to set the property current_hp before max_hp. You can see from the code snippet before that currentHP depends on max HP for the capping logic, so it fails.

What to do? What to do? I tried two things before arriving at my solution.

Try 1: explicit dependency annotations

I said to myself, "Well, I have an ordering problem. I need to instruct the loading system not to try to set current_hp first." So I did exactly that. I added more data to PersistedProperty to check its dependencies before attempting to get or set it. Pretty straightforward stuff. NotLoaded is not a new thing; it is used in the loading system to indicate that a property has not yet been loaded. It's better than using nil, too.

##########
# if we have dependencies on other things, check all of them first. only if
# they are all loaded can we set or return our real value
##########
def getProp()
    if hasDependenciesFulfilled?()
        return @refProp[]
    else
        return PartiallyLoadable::NotLoaded
    end
end # function getProp

# setter omitted for brevity

def hasDependenciesFulfilled?()
    if dependsOn()
        dependsOn().each() { |dep|
            if dep[] == PartiallyLoadable::NotLoaded
                return false
            end
        }
    end

    return true
end # end function hasDependenciesFulfilled?

addProp(
    PersistedProperty.new(
        'current_hp',
        ref(:currentHP),
        Fixnum,
        PersistedProperty::OptionalValue.new(ref(:maxHP)),
        nil,
        [ref(:maxHP)]))

In the addProp call we simply make sure to indicate that current_hp depends on max_hp, and all is well! Modulo some problems with protoRefs that I won't get into now, it actually does work just fine. But I don't like this design.

Now there are two places that know about this dependency: Mob.currentHP=, and this place where we declare the dependency. Generally speaking, it's best not to have duplicate logic spread out like this. If current_hp suddenly doesn't depend on max_hp anymore, now two places need to be updated to be in sync. And it's really easy to forget one of them, since it's kind of off to the side.

So I add another goal: only one place should know that this dependency relationship exists.

Try 2: raise exception when failing to set due to dependency

I thought: "maybe if currentHP= fails, I should error out or raise some kind of exception." The loading system can catch and expect that, and come back to the property later, when the dependency has been fulfilled.

So I started writing up a little mechanism using throw and catch, which actually works kind of differently than in other languages. In Ruby it is a general purpose mechanism (not specialized for error handling at all) to unwind the stack.

You write a catch block, which returns a value: either the last thing evaluated in the block--just like a function--or the value passed to a throw call somewhere underneath. If you've been keeping up (*guffaw*) you may remember that I already used this mechanism in my Mobchecks code.

I started implementing this, but after thinking about it a little, decided not to. Taking a step back, the desire is to give the loading code a way to recognize the failure to set a property... but to what end? Well, if it notices a failure, it will know to try again later. Actually, this sounds pretty familiar...

Try 3: setter silently fails due to dependency

It turns out the loading code is not very performant and kind of brute-force right now. It already has this similar problem in a lot of places. The way it handles it is by checking after setting a property, to see if it "stuck".

# trying to set an unloaded property to a real value
if (NotLoaded != propVal) && (NotLoaded == prop.getProp())
    prop.setProp(propVal)

    ##########
    # sometimes we try to set the prop, but it can't really be set,
    # so here we check whether it "stuck"
    ##########
    propVal = prop.getProp()

    if NotLoaded == propVal
        DebugOutput.debugOut(LComment | LLoading){"prop #{prop} was STILL not loaded"}
        everythingLoaded = false
    end
end

So it already has a way of detecting if it failed to set a property. And so we can simply have currentHP= silently not set the value. And this works equally well for any dependency situation like this. The setter checks to see if it has enough info to be set. If not, it just doesn't, assuming later on it will be called again under circumstances where it will work. A simple solution that doesn't introduce any weird new mechanisms. That is really the best, isn't it?

20110709

Spot the Bug: Wacky Data from the Network

At work there's a discussion group called "Spot the Bug". The idea is that developers from all around the company can submit interesting bugs they've fixed, and others can try to puzzle out what the nature of the bug is. I came across a bug the other day in an aspect of programming I often neglect. I thought I'd share it here. I'll briefly describe the background of the code, then show you the code itself. In a series of hidden sections afterwards I give hints and eventually the solution, but please, I encourage you not to go look at the answer until trying it yourself. I also encourage you to copy down the code, compile it, and add to it in an effort to solve the problem.

One note: there is one main bug, and it's not a trick question like a semicolon missing or a badly named variable. The bug is not super obvious, which is why it's worth mentioning.

We have some code that receives a structure from the network. There are a few specific variations of the general structure that differ only by the size of variable length data tacked on to the end. In the GeneralThing structure, you'll see the idiom: BYTE variable[1]. It indicates that the field is really a variable length piece of data contiguous on the end.

Sure enough, if you look at SpecificThing, its variable field is 512 bytes long. You can see how you could cast a SpecificThing to a GeneralThing and safely read its variable length data by using the cbVariable ("cb" = "count of bytes") field to make sure you don't overrun.

In the code, we do some extra checking to validate that the sizes we received are safe before we process the data. Somewhere in this program there's a bug. Can you spot it?

#define UNICODE 1
#include <windows.h>
#include <stdio.h>

struct GeneralThing
{
    DWORD dw1;
    DWORD dw2;
    DWORD cbVariable;
    BYTE variable[1];
};

struct SpecificThing
{
    DWORD dw1;
    DWORD dw2;
    DWORD cbVariable;
    BYTE variable[512];
};

/*
for example, here is another such specific thing we might get from the network

struct SpecificThing
{
    DWORD dw1;
    DWORD dw2;
    DWORD cbVariable;
    BYTE variable[128]; <----- different sized variable data
};
*/

/*
** the caller supplies a GeneralThing, but since it is actually some
** SpecificThing, it also passes the overall size of the structure including
** the variable length data
*/
bool ProcessData(const GeneralThing* pThing, DWORD cbThing)
{
    if (pThing->cbVariable <= cbThing - (sizeof(GeneralThing) - sizeof(pThing->variable)))
    {
        wprintf(L"processed data - last byte is %d\n",
                pThing->variable[pThing->cbVariable - 1]);

        return true;
    }

    return false;
}

/*
** pbBuffer - destination buffer to be filled from network
** pcbBuffer - initially, max size of the buffer.
**             when the function returns, it is the number of bytes stored in
**             pbBuffer
*/
void ReadDataFromNetwork(BYTE* pbBuffer, DWORD* pcbBuffer)
{
    memset(pbBuffer, 3, *pcbBuffer);

    /*
    ** normally *pcbBuffer could change, but for this example, assume we filled
    ** the buffer completely (hence it is unchanged from the original max size)
    */
}

int __cdecl wmain(int argc, wchar_t* argv[])
{
    SpecificThing thing = {0};
    thing.dw1 = 1;
    thing.dw2 = 2;

    thing.cbVariable = sizeof(thing.variable);
    ReadDataFromNetwork(thing.variable, &thing.cbVariable);

    ProcessData(reinterpret_cast<GeneralThing*>(&thing), sizeof(SpecificThing));

    return 0;
}

Hint 1: click to show. But give it an earnest try first!

The first hint is to examine the size check closely. Understand what it's verifying, then see if there are any problems with it. Compile and run the program, and see what values are being used for the calculation.

Hint 2: click to show.

Think about padding and alignment. Look them up if you need, and see what their implications are.

Hint 3: click to show.

In case you couldn't find one, here's a good link about padding and alignment.

Solution: click to show.

GeneralThing strictly speaking has 13 bytes of data in it, but due to alignment, is padded to the next 4-byte boundary: 16 bytes. In fact, the compiler even reports this size in the sizeof keyword. The size check fails because it subtracts the non-variable-data part off of the total size given, but subtracts too much, since it includes the padding.

Here is a version of the program that shows both the bug more clearly and the bug fix.

#define UNICODE 1
#include <windows.h>
#include <stdio.h>

struct GeneralThing
{
    DWORD dw1;
    DWORD dw2;
    DWORD cbVariable;
    BYTE variable[1];
};

struct SpecificThing
{
    DWORD dw1;
    DWORD dw2;
    DWORD cbVariable;
    BYTE variable[512];
};

/*
** the caller supplies a GeneralThing, but since it is actually some
** SpecificThing, it also passes the overall size of the structure including
** the variable length data
*/
bool ProcessData(const GeneralThing* pThing, DWORD cbThing)
{
    bool fSizeCheck = (pThing->cbVariable <= cbThing - (sizeof(GeneralThing) - sizeof(pThing->variable)));

    wprintf(L"checking (pThing->cbVariable <= cbThing - (sizeof(GeneralThing) - sizeof(pThing->variable))):\n");
    wprintf(L"(%d >= %d - (%d - %d)) -> %s\n", pThing->cbVariable, cbThing, sizeof(GeneralThing), sizeof(pThing->variable), (fSizeCheck ? L"PASS" : L"FAIL"));

    return fSizeCheck;
}

bool ProcessData_FO(const GeneralThing* pThing, DWORD cbThing)
{
    bool fSizeCheck = (pThing->cbVariable <= cbThing - FIELD_OFFSET(GeneralThing, variable));

    wprintf(L"checking (pThing->cbVariable <= cbThing - FIELD_OFFSET(GeneralThing, variable)):\n");
    wprintf(L"(%d >= %d - %d) -> %s\n", pThing->cbVariable, cbThing, FIELD_OFFSET(GeneralThing, variable), (fSizeCheck ? L"PASS" : L"FAIL"));

    return fSizeCheck;
}

/*
** pbBuffer - destination buffer to be filled from network
** pcbBuffer - initially, max size of the buffer.
**             when the function returns, it is the number of bytes stored in
**             pbBuffer
*/
void ReadDataFromNetwork(BYTE* pbBuffer, DWORD* pcbBuffer)
{
    memset(pbBuffer, 3, *pcbBuffer);

    /*
    ** normally *pcbBuffer could change, but for this example, assume we filled
    ** the buffer completely (hence it is unchanged from the original max size)
    */
}

int __cdecl wmain(int argc, wchar_t* argv[])
{
    SpecificThing thing = {0};
    thing.dw1 = 1;
    thing.dw2 = 2;

    thing.cbVariable = sizeof(thing.variable);
    ReadDataFromNetwork(thing.variable, &thing.cbVariable);

    ProcessData(reinterpret_cast<GeneralThing*>(&thing), sizeof(SpecificThing));
    wprintf(L"\n");
    ProcessData_FO(reinterpret_cast<GeneralThing*>(&thing), sizeof(SpecificThing));

    return 0;
}

The use FIELD_OFFSET macro (I believe) gives the offset of the named field within a structure. In this case, the offset of the variable field in the structure is 12 -- exactly the amount we want to subtract.

20110515

I'm getting too old for PCs

Well, let me qualify that a bit: I'm getting too old for going on adventures and screwing around with my PC. I'm starting to realize that I just want my PC to work. I don't want to have to babysit it. I don't want to have to break it open, install cards, fiddle with jumpers on the motherboard, tweak settings in my BIOS, and so on. I just spent a bunch of time and money I could have instead used in doing something else to get my years-old computer limping along again. I made some stupid mistakes, and since I haven't seen appropriate coverage of them online, I'm going to write up what happened, in the hope that someone else will benefit from my time wasteage.

I hate IDE

The trouble started about 3-4 months ago, when I noticed one of my hard drives was going slow. How did I notice? Well, when I tried to play video off of the drive, it could barely maintain the framerate, and when I tried to copy files off of it, I found that my CPU was pegged servicing interrupts. It also turned out that my DVD drive wasn't working. It wouldn't play any CDs, and accessing it was very slow - about 15X slower than it should be.

This particular drive is one of two IDE/ATA devices (as opposed to SATA) that are holdovers from my older computers, so from past experience I knew that this was probably an issue with DMA.

IDE drives can operate in basically two different modes: DMA and PIO. In DMA mode, the majority of the work required for reading from or writing to the drive is offloaded to a separate piece of hardware: the DMA controller. This allows the CPU to be basically idle while it waits for disk accesses. In PIO mode, the DMA controller is not used, and the CPU has to take an active, hands-on approach whenever it needs to access the hard drive. Not only is this slower, but it also hogs the CPU's attention.

Sure enough, when I went into my device manager and looked at the advanced settings of my two ATA channels, the devices had slipped somehow into PIO mode. This is weird, since they had definitely been working in DMA mode before.

Again from past experience and research into this problem, I suspected a bad cable. IDE devices are notoriously finicky about how they are wired up, configured, and the type and quality of cable used. It's very easy, if you're not careful, accidentally to use the wrong kind of IDE cable, which will result unfailingly in PIO mode. But I had been careful about this before, so it surprised me that it suddenly stopped working.

So, dutifully, I cracked open my computer case, replaced the apparently fine looking IDE cable with a spare I had around, and booted up again. Or, well, I tried to boot up again. This leads me to the next problem.

Avoid dubious motherboards

My motherboard is kind of crappy. It's an Abit AB9 Pro. Sure, the specs on paper are fine, but it has been buggy in some way or another for a while. Now, I don't know for certain if it's the motherboard, but for a long time it's had issues booting up. It'll turn on and off repeatedly. It'll turn on and do nothing. I'll have to power cycle it several times to get a good boot. And of course, this started happening to me real bad while I was fixing my hard drives. I probably power cycled it 20 times in a row before giving up.

So I went to the web site for the motherboard to look for BIOS updates. I found that I was using BIOS version 15 while the latest released was something like 22. Wow! And some of the fixes in the meantime look like they might address my problems! This looks promising.

Flashing a BIOS is always a pain, because it almost always involves booting into DOS, not any kind of Windows. Even though I have a USB floppy drive and spare floppies that work, the Windows "Create MSDOS boot disk" option put so many files on the floppy that there wasn't enough room for the BIOS update itself! So I had to use a USB thumbdrive and mkbt to format it. Cool, I was ultimately able to flash my BIOS.

Now my crazy booting problems were not as bad - it didn't catastrophically fail to even POST every time (only sometimes). But there was another problem: Windows was crashing during startup every time. So, maybe it is pretty much just as bad.

Diagnosing a blue screen

When Windows is doing something, then suddenly stops and reboots without warning, it's usually a blue screen of death, also known as a "BugCheck", named after the piece of code that executes to handle it. I assumed this was a bugcheck, so set about diagnosing it as such.

First things first, upon rebooting after the bugcheck, Windows was nice enough during startup to give me the option to run the "Recovery Environment", which did a bunch of analysis for what seemed like forever, then told me--surprise!--that it found a bugcheck.

While in the recovery environment, I was able to open a command prompt and copy the MEMORY.DMP file (which contains the crash dump information - a blue screen of death is just a special type of crash, usually in a driver) to another computer via a thumb drive. There, I opened it in my favorite debugger, windbg.

I'm not necessarily looking for a full set of information to debug the crash; I'm unlikely to know enough of the code here to diagnose it that deeply. I'm looking for which DLL or driver is the likely suspect. So I fix my symbols and get a stack trace:

0: kd> kc
Call Site
nt!KeBugCheckEx
nt!PspUnhandledExceptionInSystemThread
nt! ?? ::NNGAKEGL::`string'
nt!_C_specific_handler
nt!RtlpExecuteHandlerForException
nt!RtlDispatchException
nt!KiDispatchException
nt!KiExceptionDispatch
nt!KiPageFault
dxgkrnl!memmove
dxgkrnl!DxgkCddSetGammaRamp
cdd!PresentWorkerThread
nt!PspSystemThreadStartup
nt!KiStartSystemThread

In bold I've pointed out the likely culprit module. Everything higher in the stack is code in Windows to handle the crash. The memmove function copies memory from one place to another. Here, dxgkrnl.sys is probably writing to memory it doesn't own. That's a pretty wide variety of possible problems.

However, I now have an idea about the module at fault: dxgkrnl.sys! I look it up on the web and find that it could be involved with almost any cause. Some sites do suggest, however, to run a memory test. This I straightaway try to do, using the recovery environment's memory test utility.

It fails! The memory test hangs at 21% every single time! I try swapping out DIMMs of memory, switching their order around, and so on. Still, it fails again and again. I come to the seemingly only logical conclusion: there's something wrong with my motherboard.

Swapping motherboards

I get my buddy to help me pick out a replacement motherboard, and what the heck, I throw in a new power supply too, in case my current 460 watt one isn't enough and was causing some of the boot problems.

Swapping a motherboard is kind of a pain. You have to unplug everything inside the case, then wire it all back up. For this generation of motherboards, it is quite a lot, including tiny audio wires and little jumpers. It took 4-5 hours straight to get everything wired up in there.

The moment of truth! Will it work? I boot up, fiddle with my BIOS settings a bit, and boot Windows.

It crashes. Again. Basically the same way as before. I try the memory test, and it fails at 21% again! I swap around my RAM, to no avail. That was an expensive way to figure out my motherboard wasn't at fault. Wow, now what?

A glimmer of hope

In desperation, I start swapping video cards, unplugging USB devices, etc. etc.. Of course, none of this works. Eventually I'm back in the recovery environment, screwing around with whatever, checking that all my drives are there intact, when I notice something.

I do a dir e:\ (dir lists the files in some folder), and see a Windows directory (so that is my system drive - fine). Then I do a dir f:\ and see another Windows directory. Why are there two copies of Windows on different drives in my computer?!

I get a sinking feeling in my gut. Suddenly, like a bolt from the blue, things become clear. I have been booting the wrong version of Windows this whole time.

Know what you've got in your box

Some months ago, my old netbook died. In an effort to get data off the drive, I pulled out its sole hard drive and plugged it into this computer. When I flashed the BIOS on my old motherboard, it reset all the settings about how the drives in the computer were ordered. As it so happens, this is of the utmost importance.

When a computer needs to boot up, it looks to a special, specific place for something called a "master boot record". This is the information about what operating systems you have, and which drives to look to for them. The MBR is stored at a certain place on "drive 0"--whatever BIOS thinks is the "first" drive in your computer. If this ordering of drives gets rearranged in some way, then your computer will be looking for the MBR in the wrong place. Not that it is difficult to fix, but in this case, it helped disguise a problem pretty badly. Also note that this only becomes a concern if you have multiple physical hard drives in your computer. I have three. So... yeah, susceptible.

So here's how the drives are broken down:

Drive 0 Old netbook hard drive. Contains MBR pointing to E: as Windows
Drive 1 Data drive. No MBR, no Windows installations.
Drive 2 My comp's Windows drive. Has MBR pointing to F: as Windows.

So this whole time I've been booting Windows (and the Recovery Environment!) from my netbook's drive. Of course it didn't work! My netbook was set up, well, for my netbook's hardware. It didn't properly handle suddenly running in a drastically different hardware environment. This also explains why the memory test wasn't working; it was probably trying to use some settings specific to my netbook that weren't compatible with my real computer.

Funny noises? IDE drives AGAIN?

So I took out my netbook's drive, fixed my MBR, and booted into the correct Windows. By the way, the correct version of the Recovery Environment actually fixed this automatically, so nice job there. Hooray! Well, kind of hooray, since there were still problems.

Mainly, neither of my IDE drives (the hard drive and DVD drive that started this whole mess) were found. And I noticed that my CPU was pegged running system interrupts. Finally, the computer was making a funny, high-pitched sound constantly.

At my job, I work on performance problems on programs running in Windows, so I decided to start by tackling the interrupts problem first. I did the first thing anyone should do when something is taking a lot of CPU time: take an xperf trace.

Once again, I'm not necessarily looking for the root cause, rather, the faulty module that can hint at what the real problem is. Looking at the Interrupt CPU summary table, I see... our good friend dxgkrnl.sys and some Unknown modules. that's not too helpful. dxgkrnl.sys, as we established earlier, could be indicative of all kinds of things, so I can't really get any information from this.

I happened upon a different trick, though, which actually did point the finger much better. Instead of looking at the Interrupt CPU summary table, I looked at the CPU Sampling By Process summary table, at the Idle process. This is weird, beacuse usually the system idle process is used to account for time where the CPU isn't doing anything. It actually seems like it is a catch-all for CPU time spent aside from any real process (including idle time).

Interesting. This points the finger at intelppm.sys, nvlddmkm.sys, and ataport.sys. I know from past experience or looking them up that these are, respectively, an Intel motherboard driver of sorts; the nVidia graphics driver; and the Windows IDE driver.

That last one was particularly interesting to me, since I was also having problems with my hard drives not showing up. Plus, I had already updated my drivers for my motherboard and video card, so I didn't expect those to be the issue.

Screwing around with IDE drives

Another funny thing about IDE drives: not only does the cable you use to connect them matter, but also the manner in which it's wired up. An IDE cable has three connectors: one for the motherboard, one for the "master" drive, and one for the "slave" drive. You set pins on each hard drive indicating whether it is the master or slave, and your cable has to connect up to match that.

By the way, the whole master/slave thing, as I understand it, is to tell the drives something about what order they're allowed to talk in, since they're sharing the same cable. Or something like that.

Anyway, the way I'd connected my drives was correct for my previous motherboard, but somehow I had to reverse the ordering of the master and slave connectors in the cable for this new one. Why can't they standardize these things? As soon as I fixed that, all my problems evaporated. No high CPU Interrupt time, my drives showed up correctly, and so on.

Even the high-pitched whining stopped after a couple days. Maybe the power supply needed to get broken in or something?

So my computer is working now. It feels like a hollow victory. If I'd been more attentive and had more perseverence, I wouldn't have jumped at buying a new motherboard. But now I know a bit better, and hopefully you do too.

20110215

More Evento Ordering Woes

I'll let you in on a little secret. I've been working on combat lately. I guess that's not a really great secret, but whatever. I have a roadmap of several features that need to be implemented to have the basic breadth of it working, which will involve simple fights against nipics, and a bit of AI that will make the player work a bit during one of those fights.

One of the most basic features of this combat is that a nipic, if attacked, should retaliate. Seems simple, right? Actually, making this work and look right took me down a rabbit hole of problems with my evento system. It seems quite a while ago, I solved one evento problem, but I recently found that that wasn't the whole story.

No death

The first problem occurred when I attacked a mob enough times that it died. Ideally this would be accompanied by a message about his untimely death, but I found that this was being swallowed somehow, and not shown. The problem turned out to be that upon losing enough HP so as to render him dead, the mob would try to send the message after tearing down his invocation queue, manager, etc.--that is, the machinery required to send that evento out. To fix this I had to make it so that non-IC invocations are allowed to run just before tearing down everything. OOC invocations, by definition not really able to affect the game world, are permitted upon death.

The way this was actually implemented is a bit clever. Now, when you call Nipic#die(), we just start the dying process. First we set our state to "dead." Then we flush all IC invocations from the queue of pending actions (known as the invocation queue). Then we send the DeathEvento. Setting our state to "dead" as early as possible ensures that any actions we try to do will not be permitted (due to being, you know, dead). Flushing IC invocations ensures that nothing the nipic already had waiting will occur.

Then we simply catch the DeathEvento in the usual course of handling messages and finish tearing down at that point. And of course, we since we stop processing any more invocations at death, any subsequent actions will also not be reached.

An early grave

The only problem with this turned out to be that you'd see things in the reverse order, much like I'd solved before. You'd hit the mob, but the death message would be displayed immediately preceding the message that you'd hit him.

The problem--which will turn out to be something of a theme--had to do with inline handling. The code for hitting someone looked something like this:

def doHit(target)
    target.loseHP(10)
    sendEvento(HitEvento.new())
end

def loseHP(amt)
    self.hp = hp() - amt
    if hp() < 0
        die()
    end
end

def die()
    sendEvento(DeathEvento.new())
end

So there are two eventos that get sent here. Because the DeathEvento is being sent at the time the loseHP call is made, that effectively puts it before the HitEvento sent by doHit.

So let's switch the order in doHit. That should fix it, right?

def doHit(target)
    sendEvento(HitEvento.new())
    target.loseHP(10)
end

Well, I didn't show you the whole picture. Remember that a nipic will retaliate when hit.

# think "onHit". aee stands for "after experience evento"
def aeeHit(evento)
    if (evento.kind_of?(HitEvento) && evento.target == self)
        doHit(evento.source)
    end
end

It is useful to see the stack at this doHit call. Note that the stack is growing upwards.

source.die()
source.loseHP()
target.doHit(source)
target.aeeHit()
target.receiveEvento(HitEvento)
source.sendEvento(HitEvento)
source.doHit(target)

What's wrong with this picture? What's wrong is that the target was effectively able to catch the HitEvento and retaliate, killing the source when in fact he himself should have been killed by the hit. So both orderings don't work properly. What we want is this order:

  1. source sends HitEvento
  2. everyone in the room sees HitEvento
  3. target loses HP, potentially dying
  4. target sends DeathEvento. everyone sees it

The way I tackled this is by not doing the loseHP call in doHit but rather in the aeeHit handler. At this point, I'd hope that everyone has seen the HitEvento, so any replies will show up correctly after it.

Replying In-line

That last sentence from the previous section? Totally not true. It was an assumption I had made, but which my code wasn't sticking to. I'd tried to fix it before, but obviously not well enough. The problem stems (here's the theme again) from sending eventos in-line with receiving them. When I say "in-line" I mean later/lower in the stack. For instance, before I fixed up the code, here's a stack you might see. I'll just embellish the stack from before.

room.forwardEvento(each occupant)
room.receiveEvento(HitEvento)
source.sendEvento(HitEvento)
source.die()
source.loseHP()
target.doHit(source)
target.aeeHit()
target.receiveEvento(HitEvento)
room.forwardEvento(each occupant)
room.receiveEvento(HitEvento)
source.sendEvento(HitEvento)
source.doHit(target)

The interesting parts are in blue. When you send an evento to your current room, it gets sent, one at a time, to each occupant. This means that higher up on the stack when the room hasn't delivered the HitEvento to the second half of the room, it's now already delivering a later evento, the DeathEvento to everyone in the room. Half the people will see it in the correct order; half will see it in the reverse order.

With such a flaw, I kind of need to justify reentrant code of this sort. The problem is, I can't really. It seemed like a good idea to deliver eventos as quickly as possible, but maybe it will cause (more) serious complications later. I'm not sure. It's a "known unknown".

How would/did I fix this? By deferring eventos until the next pulse. Either unconditionally (not what I did) or conditionally (what I ended up doing), I can put an action into either the sender or the receiver's invocation queue to deliver the evento on the next pulse. That eliminates the reentrancy and therefore the incorrect ordering.

I mentioned that I do this deferring conditionally. The conditions are based on states that a mob can be in:

  • idle, and receiving an evento
  • idle, and sending an evento
  • in the middle of receiving an evento, and want to send an evento
  • in the middle of sending an evento, and someone else is sending you one
  • in the middle of sending an evento, and need to send another one
  • in the middle of receiving an evento, and receiving another one

Actually, not all of these are possible. I'll explain each in turn.

Sending while idle, receiving while idle

These are the roots of whatever problems this system has. If a mob sends an evento while it is idle, and the receiver of the evento is likewise idle, then the evento is delivered immediately right on that stack.

Sending while already receiving

This is probably the next most common case. When a mob receives an evento and wants to respond to it, it does a sendEvento. Since it's already receiving an evento, if it responded immediately, it would run into the problems I discussed earlier, so it defers the sendEvento call until the next pulse.

Receiving an evento while someone else sends you one

To be honest, I'm not too sure this is actually possible, so I put an assert in the code to let me know if it happens.

Sending an evento while already sending one

This situation seems unlikely, but is possible due to an optimization I allow. It's very common for a mob to send an evento to the room that it's in, which means it will end up being sent to all occupants, including back to itself. With respect to ordering, there's no need to defer the delivery; intuitively the second evento has to be occurring after the first evento it's acting in response to.

So this arises when an evento sent by some mob is handled and acted on by the mob itself.

Receiving an evento while already receiving one

This is another one I'm not sure is possible, so there is an assert for it.

Slowness

All this deferring is making me slow, or so I felt (without any strong evidence to back it up). So I made some modifications to the invocation queue to make these evento changes less noticeable.

The first change was allowing multiple invocations to run on a single pulse. Previously it only allowed a single invocation to run, but now it will run invocations until the queue is empty or until there is some delay. The SendEventoInvocation and ReceiveEventoInvocation invocations both have a delay of 0 pulses, so they will be run without really getting in the way of any other eventos.

The second change I made was a refinement of the first change. It allows certain invocations to run even if the mob is currently busy (*gasp*). As you can probably guess, these invocations tend to fall into the category of evento delivery invocations, but I wrote the code so that it could expand or change without too much reworking.

while (invocation = peekNextInvocation()) && canRunInvocationNow?(invocation)
    dequeueNextInvocation()
    # ...
    runInvocation(invocation)
end

def canRunInvocationNow?(invocation)
    return (!inDelayState?()) || canRunInvocationWhileBusy?(invocation)
end # function canRunInvocationNow?

What I like about this code is that the functions are phrased like the logical question to ask at the given time. When checking if the loop to process invocations can continue and run the current one, we ask, "can I run this invocation now?" And that in turn asks its constituent questions. Only at the deepest level do we query the actual state of the object.

And with that, the state of eventing is much more reasonable now. I think it may be in a state where I can push forward towards the rest of combat. I feel like the basics are in place.

20110211

cat pats

My cat is a weirdo. Sometimes when I walk down the hall, I'll reach down and pet her as I go by.  Sometimes as my leg passes by her, she then swipes at it with her paw, maybe hopping a bit.

at first I thought she was just being a little weirdo, because she certainly is that. then I wondered: what if she's reciprocating? wouldn't that be something?

20110203

ditto

You want to know what nerds talk about at lunch? we dissect things. yesterday someone brought up the usage of the word "ditto", and we had a heated discussion about when it can and when it can't be used.

Our conclusion (or rather my conclusion, I guess) is that "ditto" is only compatible with sentences with a 1st person subject, and it modifies the subject, transplanting the speaker into the position of the speaker of the original sentence.

So I can say, "I think people are dumb", and an appropriate response is "ditto", because that person is stepping in to take my place in the sentence.

On the other hand, if I say, "people are dumb", someone can't say "ditto" to that, because there's no 1st person to step into. This construction just doesn't work.

20110202

random haps 2/2/2011

waddap. haven't been doing the regular blogging thing much. most of what I've written lately is on my destructoid blog instead. I find that, not surprisingly, more people read it, so if I have something coherent to say about games, that's the natural choice.

my wife read a thing somewhere about a dude who stopped bathing with soap, and how it didn't really affect them. I was pretty skeptical at first, since if I don't use soap when I bathe, I get fairly greasy, but I decided to give it a try anyway. To be clear, I still shower once a day, and I still scrub myself down. I just don't use soap for that.

Week 1: felt like a grease ball before, during, and after every shower. It was a bit gross, but not as gross as you might think. I also didn't smell bad or anything, so at least there's that.

Week 2: not much different than week 1.

Week 3: most of my body is no longer that oily before, during, or after the shower. notable exceptions are head, face, ears, neckbeard, lower back, and outsides of my arms near my shoulders (what the...?).

Week 4: all exceptions from before are still oily, but I also mega need a haircut, so maybe that will help with the head at least.

Surprisingly (though not if you think about it a bit), my showers actually take longer now than they used to, because I have to vigorously scrub myself to feel clean, not just wipe all over with soap. That is, I'm now manually doing the work that soap was doing before.

 

Games I finished recently:

  • alan wake DLCs
  • Digital: A Love Story
  • Enslaved (not as good as I hoped, but not bad)

now playing:

  • red dead redemption
  • dead space