Why aren’t there more board games on PC? …Tablets? …Xbox?

I often hear the question of why there aren’t more board games on a certain platform. The short overarching answer is just that digital board games are a niche-market, so big game companies aren’t often willing to take the risk of making them.

However, I think there are some hints as to where board games will start showing up in the near future.

I’ll be working with the assumption that other than a few outliers (Monopoly, Risk, etc.) that are made by EA or some other huge publisher, most digital versions of board games will likely be made by indies.

Consoles?

This is a complicated one, but I think that we’re not going to see many new board games on consoles in the near future. The old-gen consoles were a mixed-bag for independent developers. Xbox 360 was really the only one that indies could easily get into. BlueLine could probably get into all of them at our current size, but it excludes any first-timers. Additionally, after Microsoft announced that they were no longer supporting XNA, the amount of games that sold on Xbox Live Indie Games (their deeply-hidden indie channel) dropped off a cliff.

What about the current generation? Sony has gone out and recruited a bunch of indies to build games for the PS4… but I doubt they’ll continue doing that much longer after launch – they’re flat-out funding games and that’s a big financial investment. Xbox is again trying to be accessible to indies with their “ID@Xbox” program (which we’ve been accepted to), but there are two major things holding back board games from Xbox One*. First: it’s expensive. Unlike other indie-friendly locations where the startup costs are around typically a couple of hundred dollars, a very lean Xbox One indie game runs upward of $5,000. Secondly, even in 2014, Xbox 360 still has about twice as many sales as Xbox One. A market with high costs and low sales isn’t great for niche games. It’ll be a while before the install-base of new consoles grows enough that a bunch of board games start popping up on there.

PC, Mac, Linux

There are a decent number of board-games coming to PC (especially on Steam) over the past year or so. I think more will continue to show up, just slowly. We released Hive and Khet 2.0 this year, and just our two-man team still hasn’t been bumped off the list of 10 Newest Releases tagged with “Board Game”. It’s entirely possible that our next game, Reversi will bump Hive off of the most-recent list, if no new board games come out in January or February.

PC, Mac, and Linux are probably the best platform for selling digital versions of board games at the moment.

Mobile

Smart phones are a great form-factor for many board games, and a bunch of games came out over the year since they became popular. However, many have had a rough time with sales in recent months/years. Most digital board games are made by fairly small devs: we survive on the Steam store’s visibility and we’d have a really rough time in mobile because you need to be on the “top downloads” list to get any traction there. Board games are usually too niche for that to happen organically and it’s too expensive to buy the number of downloads needed to fake it. This “faking it” is the current modus operandi for most mobile games. They buy huge amounts of downloads (via ads in other games) and hope that it generates enough of a following to get them to the Top Downloads list where they get to see if they’ll actually get traction. That’s usually not a great strategy for board games!

Tablets

Board gamers often lament the lack of titles on tablets – which seem like the most ideal medium for digital board games. However, I think that’ll happen even more slowly. Even though tablets are a fantastic device for playing games, the market is currently (unfortunately) just an afterthought. The games on there now are mostly because it’s easy to go to tablets from a mobile game. However, the market for tablets themselves are really small (around $3.6b compared to about $20b for PC). The reason market-size matters is just that it’s an indicator of how many games you can sell if you have great exposure. Tablets are a just a very small market at the moment, and aren’t expected to catch up to PC for about another 5 years.

We’ll get our games on tablets eventually… but it’s going to take a while. Hopefully not more than a year or so!

HTML5

It’s really hard to monetize a straightforward board game in HTML5 at the moment. If you saw Goko (who got the license to Dominion) and thought that they would ever be able to earn enough to support their big dev team & pay back all that venture capital… you probably weren’t paying attention to the margins in this industry. 😉 Nobody has made it work correctly yet. The only board game sites that are currently surviving seem to be those that don’t make any money & don’t pay any royalties. Since most of those are hobbies, you can probably expect a handful of very basic implementations to continue to come out… just not with paid licenses.

The Future

What I’m most excited for in the future is cross-platform online play. It’s super time-consuming to get it working (in part because you literally need to create the game multiple times**) but it should be a lot of fun and make it easier to find online games with other people instead of having an already-niche community silo’ed across several devices, as is currently the case with Hive which currently has different 5 different online communities.

Do you know of any digital board games coming out in the near future? Let us know in the comments below.

*: There are actually three, but one of them is technical and it’s covered by an NDA so I can’t talk about it until it’s fixed.
**: I realize that Unity/MonoGame/etc. take a ton of work away from porting, but if you want the game experience to be really good, it should be designed once for consoles (with gamepads) then another way for PC/Mac/Linux (to allow gamepad and/or mouse/keyboard) and have another – probably significantly different – interface for touch/drag devices with unreliable screen resolutions.

Buy the Hive Pillbug expansion and get the Xbox 360 version free!

PillbugThere’s been a lot of excitement around the upcoming release of the Pillbug expansion for Hive.

We have great news: if you buy the Pillbug expansion when it comes out, the package will have a code on it which will let you unlock the Pillbug in the Xbox version of Hive!

While this is a pretty big update… we have even better news coming up soon. Join the mailing list to keep up with our announcements:

Join our mailing list to receive announcements
(we have some big things coming up)!
E-mail address:
 

Announcing our next game: Khet 2.0 for Xbox 360!

Khet 2.0
Keeping up with the exciting pace of this year so far… we have an awesome announcement to make:

BlueLine Game Studios has been given an exclusive license to bring the extremely popular Khet 2.0 board game to Xbox!

Khet 2.0 is an Egyptian-themed two-player game with real lasers. It has been growing in popularity world-wide, and has a successful iPhone/iPad version.

The game is already well into development, and we are using the same board game engine that we wrote while making Hive for Xbox. The Xbox version of Khet 2.0 is planned to have single-player (against AI), local multiplayer, pass-n-play (if you only have one controller), online multiplayer, full 3D graphics & camera-control, a global highscores list… and frickin’ lasers!

If you want to be notified when the game goes into Alpha/Beta testing or for the final release, please sign up for the BlueLine Games “Release Announcements” mailing list.

New game: Hive for Xbox 360!

After more than 15 months of work, many nights of play-testing by our devoted Alpha team, and close to a kiddie-pool worth of Mountain Dew… it’s finally here!

Hive for Xbox 360!

Hive screenshot

When you think you’re starting to get good, add me on Xbox Live – “SeanColombo” – and I’ll gladly play a round with you!

If you have any questions, suggestions, or feedback… please leave them in the comments below!

Konami Code in XNA – for Windows, Xbox, and Windows Phone (WP7)

The Konami Code is a fun part of gaming culture and a very common method for adding Easter Eggs to games. After more than a year of work on Hive, I started thinking how absurd it was that we don’t have any Easter Eggs yet. When I went to look for a module for the Konami Code in XNA (because: how could there NOT be one?!), I found that the only solution currently out there seemed to be Charles Cox’s Konami Code for WP7.

At the time of this writing, BlueLine doesn’t make any WP7 games though: just Xbox 360 games that we hope to release to PC soon. To avoid completely reinventing the wheel, and to make sure my solution would be backward compatible to anyone already using Charles Cox’s module for WP7, I decided to just piggyback on that code. I’ll send my code back to him too, so hopefully he can add it to the version on his site. I’ll also structure this post to be very similar to his post so it can be merged more easily.

The solution is a single class file that you can drop into any XNA project, and by adding a small snippet of code to your update routine, you can have Konami Code functionality in minutes.

C# – KonamiCode.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
#if WINDOWS_PHONE
using Microsoft.Xna.Framework.Input.Touch;
#endif
using Microsoft.Xna.Framework.Media;

namespace KonamiCodeXna
{

    // A delegate type that represents the code has either been entered right or wrong
    public delegate void CodeEnteredEventHandler(object sender, KonamiCodeEventArgs e);

    public class KonamiCodeEventArgs : EventArgs
    {
        /// <summary>
        /// The player index that entered the code.
        /// WARNING: This can be null (eg: on WP7, or when the code was entered using the keyboard).
        /// </summary>
        public PlayerIndex? PlayerIndex { get; private set; }

        public KonamiCodeEventArgs(PlayerIndex? playerIndex)
            :base()
        {
            this.PlayerIndex = playerIndex;
        }
    }

    /// <summary>
    /// Class for easily using the KonamiCode in XNA apps (Windows, Windows Phone, and Xbox).
    /// 
    /// Originally written for Windows Phone 7 by Charles N. Cox.
    /// Expanded to work on Xbox and Windows by Sean Colombo.
    /// </summary>
    public class KonamiCode
    {
        public event CodeEnteredEventHandler CodeEnteredRight;
        public event CodeEnteredEventHandler CodeEnteredWrong;

        // Track the progress by each PlayerIndex. If playerIndex is irrelevant, just key off of "null" instead.
        private Dictionary<PlayerIndex, int> numCorrectByPlayerIndex;
        private int numCorrectKeyboard;

        // To be able to tell when buttons are pressed/released, these vars will keep track of state from previous tick.
        private Dictionary<PlayerIndex, GamePadState> previousGamePadStateByPlayerIndex;
        private KeyboardState previousKeyState;

        public KonamiCode()
        {
            numCorrectKeyboard = 0;
            numCorrectByPlayerIndex = new Dictionary<PlayerIndex, int>();
            previousGamePadStateByPlayerIndex = new Dictionary<PlayerIndex, GamePadState>();
        }

#if WINDOWS_PHONE
        enum DirType
        {
            DirTypeUp,
            DirTypeDown,
            DirTypeLeft,
            DirTypeRight
        };

        private DirType[] correctSequence = new DirType[8] {
            DirType.DirTypeUp,
            DirType.DirTypeUp,
            DirType.DirTypeDown,
            DirType.DirTypeDown,
            DirType.DirTypeLeft,
            DirType.DirTypeRight,
            DirType.DirTypeLeft,
            DirType.DirTypeRight };

        public void checkGesture(GestureSample gs)
        {
            bool rightCode = true;
 
            switch(correctSequence[numCorrect])
            {
                case DirType.DirTypeUp:
                    if (gs.Delta.Y > 0 || (Math.Abs(gs.Delta.Y) < Math.Abs(gs.Delta.X)))
                        rightCode = false;
                    break;
                case DirType.DirTypeDown:
                    if (gs.Delta.Y < 0 || (Math.Abs(gs.Delta.Y) < Math.Abs(gs.Delta.X)))
                         rightCode = false;
                    break;
                case DirType.DirTypeRight:
                    if (gs.Delta.X < 0 || (Math.Abs(gs.Delta.Y) > Math.Abs(gs.Delta.X)))
                        rightCode = false;
                    break;
                case DirType.DirTypeLeft:
                    if (gs.Delta.X > 0 || (Math.Abs(gs.Delta.Y) > Math.Abs(gs.Delta.X)))
                        rightCode = false;
                    break;
            }

            this.RecordSuccessByPlayerIndex(rightCode, null);
        }
#else
        private Keys[] correctKeySequence = new Keys[]{ // for the keyboard
            Keys.Up,
            Keys.Up,
            Keys.Down,
            Keys.Down,
            Keys.Left,
            Keys.Right,
            Keys.Left,
            Keys.Right,
            Keys.B,
            Keys.A
        };

        private Buttons[] correctButtonSequence = new Buttons[]{ // for gamepads
            Buttons.DPadUp,
            Buttons.DPadUp,
            Buttons.DPadDown,
            Buttons.DPadDown,
            Buttons.DPadLeft,
            Buttons.DPadRight,
            Buttons.DPadLeft,
            Buttons.DPadRight,
            Buttons.B,
            Buttons.A,
        };
        private List<Buttons> buttonsToCheck; // which buttons to check for being up/down each tick. For performance reasons, we'll only check the buttons that are part of the sequence.

        /// <summary>
        /// Should be called once each update loop when listening for the code.
        /// </summary>
        public void checkKeyboard()
        {
            bool rightCode = false;
            KeyboardState keyboardState = Keyboard.GetState();

            // Only evaluate the state if SOMETHING was pressed (we only care about the sequence, not that they're IMMEDIATELY after each other).
            if (WasAnyKeyPressed(keyboardState))
            {
                if (WasKeyPressed(correctKeySequence[numCorrectKeyboard], keyboardState))
                {
                    rightCode = true;
                }

                this.RecordSuccessByPlayerIndex(rightCode, null);
            }

            previousKeyState = keyboardState;
        }

        /// <summary>
        /// Should be called once each update loop when listening for the code, for each playerINdex
        /// that is being listened to (will track their progress separately so that their keypresses
        /// don't interfere with each other).
        /// </summary>
        /// <param name="playerIndex"></param>
        public void checkPlayerIndex(PlayerIndex playerIndex)
        {
            bool rightCode = false;

            int numCorrectSoFar = 0; // the number-correct-so-far corresponds to the index in the sequence that should be expected
            if (numCorrectByPlayerIndex.ContainsKey(playerIndex))
            {
                numCorrectSoFar = numCorrectByPlayerIndex[playerIndex];
            }

            // This is called once per tick, then re-used by the other functions below.
            GamePadState currentGamePadState = GamePad.GetState(playerIndex);

            // Only evaluate the state if SOMETHING was pressed (we only care about the sequence, not that they're IMMEDIATELY after each other).
            if (IsAnyButtonPressed(playerIndex, currentGamePadState))
            {
                if (WasButtonPressed(correctButtonSequence[numCorrectSoFar], playerIndex, currentGamePadState))
                {
                    rightCode = true;
                }

                this.RecordSuccessByPlayerIndex(rightCode, playerIndex);
            }

            previousGamePadStateByPlayerIndex[playerIndex] = currentGamePadState;
        }

        /// <summary>
        /// Returns true if any key is currently pressed down, false otherwise.
        /// 
        /// If a user presses a key and holds it down, this method will return
        /// true every time it's called while that key is held down.
        /// </summary>
        /// <returns></returns>
        //public bool IsAnyKeyDown(KeyboardState keyboardState)
        //{
        //    Keys[] keys = keyboardState.GetPressedKeys();

        //    // Some systems return an empty array when nothing is pressed, some return one item containing Keys.None
        //    bool nothingPressed = ((keys.Length == 0) || ((keys.Length == 1) && (keys[0] == Keys.None)));
        //    return (!nothingPressed);
        //}

        /// <summary>
        /// Returns true if any key was JUST pressed, false otherwise.
        /// 
        /// This means that if a key is pressed and held down, the first
        /// tick will return true and subsequent ticks will return false even while
        /// the key is still being held down.
        /// </summary>
        /// <returns></returns>
        public bool WasAnyKeyPressed(KeyboardState keyboardState)
        {
            Keys[] keys = keyboardState.GetPressedKeys();

            bool somethingNewIsPressed = false;

            // Some systems return an empty array when nothing is pressed, some return one item containing Keys.None
            bool nothingPressed = ((keys.Length == 0) || ((keys.Length == 1) && (keys[0] == Keys.None)));
            if (!nothingPressed)
            {
                IEnumerable<Keys> newlyPressed = keys.Except(previousKeyState.GetPressedKeys()); // ignore keys that were already down on the previous tick.
                somethingNewIsPressed = (newlyPressed.Count() > 0);
            }

            return somethingNewIsPressed;
        }

        private bool WasKeyPressed(Keys keyToCheck, KeyboardState keyboardState)
        {
            return (previousKeyState.IsKeyUp(keyToCheck) && keyboardState.IsKeyDown(keyToCheck));
        }

        /// <summary>
        /// Returns true if any of the buttons RELEVANT TO THE KONAMI CODE were pressed. For performance, does not
        /// check all buttons each tick, just checks the buttons that appear in the correctButtonSequence.
        /// </summary>
        /// <param name="playerIndex"></param>
        /// <param name="currentGamePadState"></param>
        /// <returns></returns>
        private bool IsAnyButtonPressed(PlayerIndex playerIndex, GamePadState currentGamePadState)
        {
            bool somethingPressed = false;

            if (buttonsToCheck == null)
            {
                // Not all users will have my (Sean's) Set<> class, so abuse a Dictionary instead.
                Dictionary<Buttons, bool> buttonSet = new Dictionary<Buttons, bool>();
                foreach (Buttons button in correctButtonSequence)
                {
                    buttonSet[button] = false; // the bool is trash basically. this is just a cheap way to implement a set.
                }
                buttonsToCheck = buttonSet.Keys.ToList();
            }

            foreach (Buttons button in buttonsToCheck)
            {
                somethingPressed = (somethingPressed || WasButtonPressed(button, playerIndex, currentGamePadState));

                if (somethingPressed)
                {
                    break;
                }
            }

            return somethingPressed;
        }

        private bool WasButtonPressed(Buttons button, PlayerIndex playerIndex, GamePadState currentGamePadState)
        {
            bool wasPressed;
            if(previousGamePadStateByPlayerIndex.ContainsKey(playerIndex)){
                wasPressed = (previousGamePadStateByPlayerIndex[playerIndex].IsButtonUp(button) && currentGamePadState.IsButtonDown(button));
            } else {
                wasPressed = currentGamePadState.IsButtonDown(button);
            }
            return wasPressed;
        }
#endif

        /// <summary>
        /// Records a successful/unsuccessful keypress by PlayerIndex. In cases where the
        /// PlayerIndex is irrelevant (often, on WP7 there is only one player), then null
        /// can be used.
        /// 
        /// NOTE: This method is typically called from other helpers such as checkGesture
        /// and checkGamePadHelper instead of being called directly.
        /// </summary>
        /// <param name="rightCode"></param>
        /// <param name="playerIndex"></param>
        public void RecordSuccessByPlayerIndex(bool rightCode, PlayerIndex? playerIndex)
        {
            if (rightCode)
            {
                // PlayerIndex is null for keyboard and non-null for game pads.
                if (playerIndex == null)
                {
                    numCorrectKeyboard++;
                    if(numCorrectKeyboard >= correctKeySequence.Length)
                    {
                        //reset the code, fire the event
                        numCorrectKeyboard = 0;
                        KonamiCodeEventArgs args = new KonamiCodeEventArgs(playerIndex);
                        CodeEnteredRight.Invoke(this, args);
                    }
                }
                else
                {
                    if (numCorrectByPlayerIndex.ContainsKey((PlayerIndex)playerIndex))
                    {
                        numCorrectByPlayerIndex[(PlayerIndex)playerIndex]++;
                    }
                    else
                    {
                        numCorrectByPlayerIndex[(PlayerIndex)playerIndex] = 1;
                    }

                    if (numCorrectByPlayerIndex[(PlayerIndex)playerIndex] >= correctButtonSequence.Length)
                    {
                        //reset the code, fire the event
                        numCorrectByPlayerIndex[(PlayerIndex)playerIndex] = 0;
                        KonamiCodeEventArgs args = new KonamiCodeEventArgs(playerIndex);
                        CodeEnteredRight.Invoke(this, args);
                    }
                }
            }
            else
            {
                //wrong type, reset the count, send event
                if (playerIndex == null)
                {
                    numCorrectKeyboard = 0;
                }
                else
                {
                    numCorrectByPlayerIndex[(PlayerIndex)playerIndex] = 0;
                }
                KonamiCodeEventArgs args = new KonamiCodeEventArgs(playerIndex);
                CodeEnteredWrong.Invoke(this, args);
            }
        }

    }
}

To Use the Class

It’s really just three things:

  1. Instantiate a KonamiCode object.
  2. Subscribe to the CodeEnteredRight event (and, if you want, the CodeEnteredWrong event)
  3. Update it once, each game-tick (ie: in Update()).

Getting it Into a Default Project

To mirror the example given in Charles’ original post, I’ll show how to use this module in an example project to have the same outcome that his original code did, but have it also work on Windows and Xbox 360 (in addition to WP7).

Game1

//**Start Code For This Sample - REPLACE YOUR GAME1 CONSTRUCTOR WITH THIS
KonamiCode konami = new KonamiCode();
Color clearColor = Color.CornflowerBlue;
 
public Game1()
{
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";
 
    // Frame rate is 30 fps by default for Windows Phone.
    TargetElapsedTime = TimeSpan.FromTicks(333333);
 
    konami.CodeEnteredRight += new CodeEnteredEventHandler(konami_CodeEnteredRight);
    konami.CodeEnteredWrong += new CodeEnteredEventHandler(konami_CodeEnteredWrong);
 
    TouchPanel.EnabledGestures = GestureType.Flick;
 
}
 
void konami_CodeEnteredWrong(object sender, EventArgs e)
{
    clearColor = Color.Tomato;
}
 
void konami_CodeEnteredRight(object sender, EventArgs e)
{
    clearColor = Color.MediumSeaGreen;
}
//**End Code For This Sample

Update

//**Start Code For This Sample - REPLACE YOUR UPDATE LOOP WITH THIS
protected override void Update(GameTime gameTime)
{
    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit();
 
    #region Konami code updating
#if WINDOWS_PHONE
	while (TouchPanel.IsGestureAvailable)
	{
		GestureSample gs = TouchPanel.ReadGesture();
		konamiCode.checkGesture(gs);
	}
#else // WINDOWS || XBOX
	// Need to check the code for each game pad that's in-use.
	foreach (PlayerIndex playerIndex in new PlayerIndex[] { PlayerIndex.One, PlayerIndex.Two, PlayerIndex.Three, PlayerIndex.Four })
	{
		if (GamePad.GetState(playerIndex).IsConnected)
		{
			konamiCode.checkPlayerIndex(playerIndex);
		}
	}

	// Then check the code for the keyboard (if there is one, there will be just one so it's checked separately, not per-player).
	konamiCode.checkKeyboard();
#endif
	#endregion

    base.Update(gameTime);
}
//**End Code For This Sample

Draw

//**Start Code For This Sample - REPLACE YOUR DRAW METHOD WITH THIS
protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(clearColor);
 
    // TODO: Add your drawing code here
 
    base.Draw(gameTime);
}
//**End Code For This Sample

If you run into any issues, please let us know.

Games using this Konami code class

If you put this into a game, let us know when it’s out! We’ll add it to this list of XNA games that have Konami Code built in, using this class.

Hive for Xbox starting Alpha Testing!

Something's not right about the placement of that cursor... good thing we're doing an Alpha test!


Development has been cruising right along on Hive. While we’re still a few months away from a final version, we’ve gotten to the point that the game is playable as local multiplayer “pass-n-play” (where you share the same controller).

Obviously that’s very limited functionality, but it’s a very important milestone. Right now, players can start to hammer on the game to make sure the rules are exactly as expected and that the controls feel right.

We know there are a lot of die-hard Hive fans out there, and we’d love to have your feedback while we continue to develop the game so that we can make sure to do justice to the boardgame.

That’s why we’re starting a private Alpha Test and asking anyone interested to apply!


Hive Alpha Test

Here is some more info:

  • You need an Xbox-controller with a cord and a PC with .NET installed.*
  • You’ll get a download-link and will be notified when new versions of the alpha are available to download (probably every couple of weeks).
  • You will be invited to a private Alpha Test forum, where you can leave as much feedback as you want and discuss things with us as well as the other testers.
  • The PC Alpha-test version of the game will expire in a few months since we don’t have rights to distribute the game on PC (we got special permission for this Alpha Test).
  • We’ll need your email address. We will only email you about things relating to the Alpha test.**
  • Your name (or alias, if you prefer) will appear in the credits of the game.

Apply for the Private Alpha

If you’d like to be part of the Alpha, please do one (or more) of the following:
UPDATE: PLEASE NOTE THAT THE ALPHA IS OVER. THE GAME IS NOW AVAILABLE ON XBOX 360 AND ON STEAM!

  • Tweet that you’d like to be in the alpha (here is a pre-assembled tweet!), and follow @BlueLineGames so that we can direct-message you more info.
  • “Like” the BlueLine Game Studios facebook page then post on our wall that you want to be in the Alpha Test (we’ll fb-message you more info).
  • We prefer the other two methods but if you don’t have twitter or facebook, just send an email to “sean” at this site (bluelinegamestudios.com).

Thanks in advance for helping us make sure that Hive for Xbox is the most amazing adaptation imaginable of the game we all love!
– Sean


* Download .NET for free here. Xbox doesn’t have a good way to let non-developers test games that are currently in development, but we can just build the game for PC and run the test there. We’d like testers to plug the Xbox controller into their USB port though, so that they can get a feel for whether the controls work right. Technically, you don’t need a wired controller if you happen to have a Wireless Gaming Reciever for Windows.
** If you want to be notified for all of our new game announcements and releases, please sign up for our mailing list.

Configurable-radius deadzone for thumbsticks in XNA

Yesterday, while co-working at The MADE (a cool game museum that lets Bay Area developers work out of some of their space), the topic of thumbstick deadzones came up. Ian Stocker mentioned that he had recently made a blog post about using the Xbox analog sticks as a DPad in XNA.

Since Hive deals with hexagons, I didn’t do my implementation quite the same. The deadzone code I used is separate from the code for getting directions, so it should work regardless of what your game is using the thumbsticks for.

We discussed the methods that we used for adding a “deadzone” to the analog sticks. A deadzone is the area near the center of the stick where you ignore input because slight movements (or even old controllers while their sitting still) could trigger unintended input otherwise. He explained that his deadzone was square and thought that people might benefit from my code which makes a circular dead-zone, so here it is!

I did the entry-level trigonometry so that you don’t have to! 😉

Example usage of the thumbstick “deadzone” code.
[crayon lang=”c#”]
PlayerIndex playerOne = PlayerIndex.One;
GamePadState gamePadState = GamePad.GetState(playerOne);
Vector2 leftThumbstickState = gamePadState.ThumbSticks.Left;
if ( ThumbstickMovementIsSignificant(leftThumbstickState) )
{
// Actually use the leftThumbstickState.
}
[/crayon]

And this is the general code that I put in my GamePadHelper.cs.
[crayon lang=”c#”]
///

/// Returns true if the movement is significant, false if the movement was so slight
/// that it shouldn’t be counted. This uses a reasonable default for how much to ignore.
///
///

/// ///
public static bool ThumbstickMovementIsSignificant(Vector2 thumbstickState)
{
float percentToIgnore_default = 35.0f;
return ThumbstickMovementIsSignificant(thumbstickState, percentToIgnore_default);
}

///

/// Determines if the thumbstickState passed in is significant enough, given the constraint
/// of how much movement should be ignored.
///

/// /// Percentage of the unit-circle which is ignored. If 25.0f, then the inner-quarter of movements will be considered too slight. If 50.0f, then the inner half will be ignored, etc.. public static bool ThumbstickMovementIsSignificant(Vector2 thumbstickState, float percentToIgnore){
bool isSignificant = true;
if (percentToIgnore > 0)
{
// Uses pythagorean theorem to see if the hypotenuse ends inside of the “significant” area or not.
float a = thumbstickState.X;
float b = thumbstickState.Y;

// Thumbstick numbers are in a unit-circle so scale the percentToIgnore to the range of 0.0 to 1.0
float minHyphotenuseLengthForSignificance = (percentToIgnore / 100);

// This function is likely to be called every tick, so we square the minimum hyptotenuse instead of comparing it the sqrt of a^2 + b^2 (square roots are a bit slow).
if (((a * a) + (b * b)) < (minHyphotenuseLengthForSignificance * minHyphotenuseLengthForSignificance)) { isSignificant = false; } } return isSignificant; } [/crayon] I haven't played around with the thumbsticks that much, so I'm not sure how big of a deadzone is ideal. I stuck with the default of percentToIgnore_default = 35.0f;, which means that the inner 35% of the thumbstick’s radius is ignored. Feel free to tweak the default or pass in a custom value as the second parameter to ThumbstickMovementIsSignificant().

Hope the code is helpful! 🙂

Announcing our first game: Hive for Xbox 360!

We’re buzzing with excitement for this announcement…

BlueLine Game Studios has been given an exclusive license to bring the extremely popular Hive boardgame to Xbox!

If you’re not familiar with it yet, Hive is a boardgame that’s grown a huge following.  It was created by British Inventor John Yianni of Gen42 Games.  In his own words:

Hive is a board game with a difference. There is no board! The pieces are added to the playing area thus creating the board. As more and more pieces are added the game becomes a fight to see who can be the first to capture the opposing Queen Bee.

Hive for Xbox 360The gameplay is really easy to pick up, but just like chess the possibilities in gameplay are endless.  This makes it great for starting right up with family, friends, and roommates but complex enough to give even the sharpest minds a challenge for years to come.  …and I really do mean that: the geniuses at American Mensa saw fit to give Hive the prestigious Mensa Select award!

I think the versatility has a lot to do with why Hive has become such a worldwide favorite.  People really go nuts for this game… in this fan gallery (all 42 pages of it) you can see pictures of people playing in front of the Great Pyramids, using hand-made sets, next to a pool, at the bottom of a pool, on the ocean floor (seriously), and pretty-much anywhere at any time.

We’ve already begun development and we think we have some great ideas on how to work with Gen42 Games to bring a great version of this game to the Xbox 360 …and we would love to hear your thoughts too.  So if you’re a Hive fan, pipe up in the comments! 🙂

If you’re as excited as we are, sign up to be notified when the game launches!

Update: As of Feb 8th, 2013 – Hive is now available on Xbox 360!