Equipment Systems Improvement

Part of rapidly putting together a prototype is knowing that, at some point, I’ve got to go back and clean up the code. Make it work, first, then make it work right (and finally, make it work fast if you need to). Before I can go any further it’s a good idea to clean up the code and solidify one of the most fragile systems, which is the equipment/weapons/attack generation code.

When Creatures Attack

Part of the code upgrade from Soulcaster 2 to Soulcaster 3 is the way creatures attack one another. Since we’re going to have lots of complex equipment, magic, and creatures in the game, there needs to be a flexible system that can handle a wide variety of special abilities:  Life steal, stuns, poison, regen, invulnerability, mind control… All of these things need special code, and need to be informed of the events of an attack so they can play their special role.

Exposing events for customization like this is called adding hooks.

There are two phases to any attack: targeting (finding a suitable foe) and collision (the actual hit where damage is done). Let’s look at both of these in depth to see how it handles everything behind the scenes.

In this case, our immortal archer, Shaedu, is wielding a bow with a poisoned arrow. A rat is nearby.

rat1

Back from the Rabbit Hole

GDC is approaching, and I’m showing Escape Goat 2. That gives me less than three weeks to get everything together, meaning I should have something pretty playable in about a week, so I can playtest with a bunch of friends before showing it to the media.

For the most part, the new systems are in place. We’re running in high resolution, lighting and shadow casting is working, even the new world layout is implemented. One major remaining bug is the squish detection, something that has plagued me since the start of the project. I changed enough of the physics system in the upgrade from EG1 to EG2 that squish tolerance isn’t working properly. This means the goat gets squished in places he shouldn’t–such as after a teleport into a corner, or from getting grazed by a falling block. Definitely something that needs to be fixed before GDC.

Getting DPad Input from Thumbsticks in XNA – The Right Way

If you want to simulate 4-way DPad movement with the left or right analog thumbstick in XNA, my advice is to never use Buttons.LeftThumbStickUp, etc. This is because the default behavior doesn’t take into account the dead zone for the stick, which varies from controller to controller.  (The dead zone is the location near the center of the stick position, where it won’t send any movement value to the Xbox.)

You might test on a controller with a large dead zone and have no problem, then someone else will play your game with a very small dead zone, and they will find the control “sticking” in that direction.  I’ve had some controllers where the dead zone was so precise, I could have my thumb off the joystick and it would still be transmitting a tiny movement value.

I suggest adding a large dead zone, to make sure you only get simulated DPad input for large, deliberate movements of the analog stick.  Here’s some code that works for me, adjust as necessary to fit your control scheme:

static Buttons GetThumbstickDirection(PlayerIndex player, bool leftStick)
{
    float thumbstickTolerance = 0.35f;

    GamePadState gs = GamePad.GetState(player);
    Vector2 direction = (leftStick) ? 
        gs.ThumbSticks.Left : gs.ThumbSticks.Right;

    float absX = Math.Abs(direction.X);
    float absY = Math.Abs(direction.Y);

    if (absX > absY && absX > thumbstickTolerance)
    {
        return (direction.X > 0) ? Buttons.DPadRight : Buttons.DPadLeft;
    }
    else if (absX < absY && absY > thumbstickTolerance)
    {
        return (direction.Y > 0) ? Buttons.DPadUp : Buttons.DPadDown;
    }
    return (Buttons)0;
}