|
18 Jun, 2009
So, there's a lot of issues with C++ and the poor support for creating new types. Particularly, it's often useful to make a type-safe integer... for example, if you have several different functions that do similar things and are easy to confuse the values, since an int is an int is an int. It'd be really nice to have the compiler help you when you pass an integer you got from one function into another that means a totally different thing.
Let's get more specific, since all this dancing about is tiresome:
typedef uint32 AxMutexId;
typedef uint32 AxSemaphoreId;
static void Lock(AxMutexId const mutexId);
static int Lock(AxSemaphoreId const semaphoreId);
So, this won't compile because the Lock function is ambiguous. Why? Because typedefs make "soft" types, which resolve to whatever they really are and do not really retain their new names to the compiler.
Okay, what about a simple namespace solution?
namespace AxMutex { typedef uint32 Id; }
namespace AxSemaphore { typedef uint32 Id; }
static void Lock(AxMutex::Id const mutexId);
static int Lock(AxSemaphore::Id const semaphoreId);
I'd be okay with this. Except again, it doesn't compile. Finally, I settled on making new types that are actually incompatible with each other, using templates. Such as:
//-------------------
template <typename T, int I>
class IntType
{
public:
IntType(T const value) : mValue(value) {}
operator T & (void) { return mValue; }
operator T const &(void) const { return mValue; }
IntType<T,I> &operator=(T const &rhs) { mValue = rhs; return *this; }
protected:
private:
T mValue;
};
//-------------------
typedef IntType<uint32,0> AxSemaphoreId;
typedef IntType<uint32,1> AxMutexId;
static void Lock(AxMutexId const mutexId);
static int Lock(AxSemaphoreId const semaphoreId);
The nice side effect about this approach is that you can pretty much treat this new type as whatever the POD type it's based on as a drop-in replacement. Warning: some certain code constructs (like the switch statement) may require an explicit cast or .Get() function to be added to get the compiler to sort itself out. But for my specific case where the values are simply indices and not handled mathematically, it works fine. It's been a clean way to create index types that the compiler can treat as a first class citizen, and I thought I'd share.
Is there anything in the new standard, or any simpler method, that accomplishes the same behavior?
11 Apr, 2009
Hooboy... looks like some folks picked up on the last post and got the wrong idea. I want to first be clear to anyone who didn't realize I was taking a poke at ourselves as much as anyone else when expressing disappointment about B&S's performance. We made the game, and in a sense it was an experiment (I'll explain below), but there's nobody to blame for the final product except us. We built something from nothing and shipped it. Whether it was a blockbuster or not, I'm very proud of completing what I started. That's huge. Anyone who kills themselves for a year or so on a project, of course, will want it to do well and is emotionally invested in the outcome, even if they're just an employee of a big company. To people who buy games, it's just another title on a list, but to the developer it's a piece of your life you will never get back. It's tough to explain to someone who isn't in the industry and hasn't had to make hard choices about how many years they have to invest in each endeavor, because so many games will stretch on for 3... 5... 9 years? And in the end, you hope it wasn't wasted. As a principal of a tiny studio, it's an even bigger part of your life because there's the ever-present guilt of seeing your family (and your partner's family) suffer to chase the dream. And truth be told, if had the runway left to really polish the game (it's very expensive to fund a game--don't try this at home kids!), it would have been prettier and had a better UI and more gameplay modes and better rendering tech. But it is what it is. Nintendo allows re-releases of titles and if there was any spare time to put into it, I'd be tinkering with the game. Maybe someday... For the time being, we have to pay off our debts and keep clothes on the kids and the wives from leaving us. :-)
As for the grand experiement gone awry, we drank the kool-aid. We were one of the early indie development houses to sign on with Nintendo to do WiiWare, and at the time, nobody knew what kind of crowd would surface to buy games there. It was very exciting, and to know there were 20 million or so Wii units in the world at that time meant that the market had incredible potential. So, we went forward with a design that I thought would appeal to the typical Wii user. In hindsight, to my horror, this was all wrong. The typical Wii user doesn't have any idea that the Wii can connect to the internet. The crowd that gravitates toward WiiWare is actually fairly hardcore, and a very small segment overall. In essence, we're trying to sell lemonaide in a biker bar. Heh. In a way, I'm thankful we had the turbulence now while the stakes are still small (in absolute terms) and we can recover from it, learn what mistakes we made, and move forward from the experience a richer development house. There's two things that are important in games: shipping and sales. We got one thing right, and that's something. Now to work on the other. Peace.
05 Apr, 2009
Some folks have been asking about Bruiser & Scratch, about what we're up to right now, and about what we're planning to do in the near and far future. Some folks are just complaining that I don't post enough. Given that there's no good way to answer all of this to each person individually, and that I'm pretty sure we can release the information, here's the scoop.
Bruiser & Scratch has been available on WiiWare for a while, and as expected, we haven't been blown away by sales figures. Partly, this is our fault for allowing the game to ship when it wasn't Crash Bandicoot. Oops. I know, I know, we should have made a chintzy 2D version of the game, cut the characters, cut the story, and basically shipped it 6 months earlier. We'd probably have gotten more sales because for some reason, people ignore shitty art when it's "retro styled", but it's flame-on if there's even a whiff of 3D going on. Also, if we'd released earlier there would be less puzzle game exhaustion on the part of the user base.. by the time we came out, there were more than enough puzzle games on WiiWare to go around. The initial reviews skewered us, and that's all she wrote.
So, what have we been doing in the meantime? Jeff and I have been working on Ghostbusters Wii with our friends at Red Fly, doing some heavy lifting tech work for an unannounced title at Red Fly, working on some of our own prototypes, and porting a really cute family-friendly game to the Wii for Conspiracy Games. All at the same time. So, pardon me for being a little lax on the updates.
One cool mention is a dear friend, Will Loconto, was nominated for Best Original Instrumental for The Heist this year at GDC by the Game Audio Network Guild Awards people. He helped us out on Bruiser & Scratch and is doing the remastering for our port work with Conspiracy. Very cool. He was up against Afrika and Little Big Planet, both of which swept awards this year, but to be nominated is quite the feat. Congrats Will!
And that pretty much wraps up our first quarter. On the off-chance you are a publisher looking for a small but talented studio to do a game for you, drop me a line. As busy as we are, I'll make time for you. :-)
JH
03 Mar, 2009
A small tidbit for frustrated developers. I have Visual Studio 2005 and generally like it a lot... still lacks some of the features that we had in 1995 with VC6, but the improvements have grown on me. However, occasionally I'll run into a serious snag that makes no sense and I have to spend hours or days worrying about it. Here's one of them, and how to solve it:
I have a large solution with about 50 projects in it, mostly libraries. I had all the dependencies set correctly and everything was great. One day, I added a project and stuck all of libjpeg in there. Suddenly, whenever I compiled anything, it was rebuilding continually. After a week or two of being angered by this, I finally took the time to figure out what was going on. I noticed that even though I told it to do Minimum Rebuild (/Gm), there was never an .idb file written next to the .pdb file. Turns out that for this and several other projects that contain only .c files, I have to disable Minimum Rebuild which for some reason writes out an .idb and fixes the issue. I believe this has to do with the library containing only .c files and defining no classes. Forcing the build type to C rather than C++ does not change this behavior. And seeing as how such things are tough to figure out, I wanted to post it on the off-chance it helps someone.
JH
|