Friday, March 19, 2010

Improving music performance in the iPhone SDK

For people who like to copy and paste other people’s solutions without researching the problem in depth, this entry is for you (since I don’t go into depth).

I was noticing my iPhone game framerate being really jerky when playing music that I encoded using IMA4 format, so I changed it to LEI8.  The file format is somewhat big, being lossless, but the tradeoff is that I hardly notice any jerkiness now.

In short, I was previously running this to convert my files before:

/usr/bin/afconvert -f caff -d ima4 Source.mp3 Target.caf

and now I’m doing this

/usr/bin/afconvert -f caff -d LEI8 Source.mp3 Target.caf

I don’t notice any sound quality degradation either.  I also tried LEI16 but it wasn’t worth the doubled size for no noticeable quality gain (Your Mileage May Vary).

Sunday, January 31, 2010

Reflections from Global Game Jam 2010

I posted a characteristically long blog entry via my account at globalgamejam.org, which I will repost here:


I've survived the Global Game Jam, and my team created something resembling a game. To say that I'm happy with it or proud of it would be untrue, unfortunately. It's hard not to look back at all the things that could have been but weren't, or imagine what could have been added if only we had slightly more time.

In the end, we created an espresso stand themed mini-game, essentially. Was it innovative? Not really. Was it fun? Not in its 48-hour state, but there was potential at least. Was it the game I dreamed of making during the months preceding the Jam? No. Why? What went wrong? I will try to address these questions in a way that won't spiral into hopeless negativity.

My first blog entry listed the lessons I learned from my last Game Jam. I want to revisit them to see how well I did, and then see what new lessons I learned from this one:

* Find a team you mesh well with.

My teammates were cool people, but it was clear that we had very different goals and very different sets of experience. Dwelling on this will only sound like blaming, but suffice it to say I didn't do a good job here.

* Use source control.

We had an SVN server up and running pretty quickly, and this saved us. I don't even want to think about the challenges we would have faced otherwise.

* Scale scale scale

Our overall game idea was indeed very straightforward, but we aimed for far too many embellishments than we should have for a 48-hour game. Probably half of the time was spent creating/working with content in some form, rather than coding actual essential gameplay logic. Because of this, we ultimately had to cut key features of the game.

* Throw solid coding practices to the wayside

I feel we reached a really good balance here. Our code was structured in a fairly logical way but with some corners cut for the sake of time (for example, avoiding unnecessary future-proofness by hardcoding logic which assumes two players).

The lessons I learned from this Jam were mostly rehashes/reinforcements of the previous lessons:

* Find a team that you mesh well with, part 2: I had been excitedly anticipating this event for months in advance, and all my friends knew because I talked about it constantly. Naturally I arrived early, brought tons of supplies/food/drinks with me, set up my laptop with source control, etc. ahead of time. I should have immediately seeked out other developers who shared the same passion. And remember, you are inevitably going to have to compromise on a design idea. So find people who have design goals as close as possible to yours (e.g. don't group with someone who is passionate about Myth-esque puzzle games if you really want to make a retro shooter)

Speaking of design, I might get flak for saying this, but for a 48-hour game, a designer with little or no programming experience is dead space unless they're also an artist. Everyone is a designer. Everyone has ideas. Yes, there are good designers and there are horrible designers. But even a great designer who does nothing but design is not worth it on a 48-hour game. More likely than not, a dedicated designer will only increase the scope of the game by dreaming up infeasible features, causing friction with the developers who actually have to [dare I say] do the work.

If you're lucky, you'll find a programmer who is already good-enough at art. The artistic bar is not exactly high for a 48 hour game, so "good-enough" is all you need. A dedicated, exceptional artist is a great asset as well though, because it's often the aesthetics that really boost the appeal of games of this scope.

I didn't mention sound designers, because again, the scope of the game is so small that sound is often an afterthought, but they can be a great addition if you can afford the opportunity cost.

* Scale scale scale, part 2: Your design should be iterative even for a 48 hour game, but a crucial point is that this design should start extremely simple. Find a core mechanic, keep the mechanic DEAD SIMPLE, and if you have time, iterate on it. Here's a counter-example of what I mean:

For our espresso game, "Cheap Shots", the original plan was to have players create different drinks by pressing buttons in a particular sequence on an Xbox controller. So, one drink might be A, B, B, X and another might be X, Y, A, B (the buttons were supposedly associated with different ingredients). Before we had even completed implementing this basic mechanic, we began dreaming up new ways to add ingredients; for example, holding the trigger and releasing it at a particular time might be associated with steaming milk, or turning the thumbstick on the controller might be associated with stirring the drink. This was a mistake from the start. I ended up spending precious amounts of coding time trying to implement these special case scenarios (keep in mind they all required additional UI assets as well), while core gameplay mechanics were being neglected (score board, game timer, essential UI elements, etc.)

Further, we spent what felt like half of our time dealing with mountains of sound assets that were completely non-essential to the gameplay. These were the types of niceties that could be added after the fact, when the core gameplay was done.

So, in short, it's not just the game that needs to be simple; the core mechanic needs to start dead-simple and optionally build from there after you have a complete gameplay experience.

Here are some additional lessons I learned, though some are minor:

* Make sure that your working environment is comfortable.

DigiPen was great. There was an active work environment with plenty of space. But when you're working for 48 hours almost nonstop, even the minor things can become major annoyances. I was foolish enough to position myself in the middle of a long table, separated enough from my team that any time they called me over, I needed to practically climb over my table or else squeeze by several people to get to them. After the 25th time having to do this, I was ready to relocate.

Also, make sure you have the best setup you can get; a large monitor, comfortable mouse, etc.

As soon as you sense an annoyance, fix it, or it'll be a thorn in your side for the next 48 hours.

* Time is precious; don't waste it.

Yes, I know, this is obvious. My point isn't about goofing off excessively or being lazy. If you're inclined to do that at a game jam, you're probably not passionate enough for it to begin with. I'm talking about other time wasters. For example, you don't need to notify your team about every single change that doesn't affect them, show them every cool thing you added, or ask them questions that you can easily find the answer to yourself (i.e. "Where is X defined in the code?"; there's a search function for that). Remember, assuming you picked a good team, their time is every bit as valuable as yours. Every time you interrupt them in the middle of coding, you break their concentration. You force a "context switch", and it takes them time to regain their focus. Don't have needless conversations in which you explain at length how you intend to implement something; just do it. And similarly, don't explain at length how someone elsemight possibly implement something, unless they are requesting your help or are working on a shared component. They could be using that time to actually implement rather than discussing it.

In the off chance that anyone actually read through this in its entirety, I hope it provides some value.

Tuesday, January 26, 2010

Error: Cannot read configuration file due to insufficient permissions – possible solution

I wanted to post an incomplete solution to this problem that I’ve encountered a couple times now.  I’m not sure the exact cause but the jist of it is that I’ve got a web site I’m hosting via IIS7 on a remote server which I can access just fine.  But when I try to host this on my local machine for debugging purposes, I get an error which resembles this when I access the page:

Server Error in '/xxxxx’ Application.

Filename: redirection.config
Error: Cannot read configuration file due to insufficient permissions

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.UnauthorizedAccessException: Filename:redirection.config
Error: Cannot read configuration file due to insufficient permissions

ASP.NET is not authorized to access the requested resource. Consider granting access rights to the resource to the ASP.NET request identity. ASP.NET has a base process identity (typically {MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6) that is used if the application is not impersonating. If the application is impersonating via <identity impersonate="true"/>, the identity will be the anonymous user (typically IUSR_MACHINENAME) or the authenticated request user.

To grant ASP.NET access to a file, right-click the file in Explorer, choose "Properties" and select the Security tab. Click "Add" to add the appropriate user or group. Highlight the ASP.NET account, and check the boxes for the desired access.

The Solution:

1. Identify the user under which your web site’s application pool is running under.

2. Add this user as a User Account on your local machine and add them to the IIS_IUSRS Group (the names have been obscured to protect the innocent).

image

Sunday, January 17, 2010

Indie game developer YouTube/Vimeo channels

On one of my sister blogs, I posted a link to some independent game developer video channels.  I’ve tried to get D-Roc to make a similar video series with me, but he wouldn’t have it.  I’m convinced we could make something every bit as compelling or more (or at least have fun doing it), but alas, it wasn’t meant to be.  Maybe I’ll create my own series some day.

Tuesday, January 12, 2010

Creating a file share with a custom name – an unpleasant Windows 7 user experience

 

I usually run into this issue when I have two folders of the same name that I want to share, but I want sensible share names to distinguish them from one another.

For a concrete example, let’s suppose you have local folders on your PC called c:\project\tools and c:\development\tools (stupid names, I know).  You want to share both of these to the outside world, so you browse to c:\project, right-click the tools subfolder and click Share:

image

If everything works properly, it auto-assigns a share name of \\yourmachinename\tools.  Congrats.

But now you want to share c:\development\tools, so you follow the same process.  Here is what happens:

image

The folder is automatically shared as tools2.  Note that there is absolutely no option to choose a different name at this time.  Whether you like it or not, your folder is initially going to be shared as the name tools2.

So, now that it’s shared as tools2, you want to somehow change the share name.  To do this, you need to right-click the folder, navigate to its Sharing properties and click Advanced Sharing… (because apparently renaming a share is an advanced feature).

image

In the Advanced Sharing dialog, you’ll notice in the Settings group that it displays the current share name and lets you add additional share names.

image

What you must do is first Add a new share name (you can’t delete the existing one until you do), and give it the name you prefer (in this case, toolsdev).

image

Now you’ve got two share names for this folder, so delete the extraneous tools2 name.

image image

Now, to make matters worse, if you’ve already assigned permissions to the tools2 share, you’ll have to reassign them.  I’m not sure why this is the case.

image

Congrats!  You’ve finally created a shared folder of the name you desire, but it took about 5 steps more than it should have.

Monday, November 16, 2009

Using Command-line arguments in Windows Services – a “gotcha”

This can’t really be considered a “gotcha” more than just a “pay careful attention to the perhaps unintuitive documentation” scenario.  Also, this assumes basic knowledge of creating Windows Services.

So here’s the situation: I wrote a Windows Service, and I wanted to optionally enable verbose debug output (since services are a bit of a pain to debug) using a command-line option.  Services, after all, can be started with command-line arguments.  But regardless of what I entered as the command-line arguments, the OnStart(string[] args) method of my service would always report that “args” was empty – that is, no arguments.

After some quick Bingoogling, here’s what I found:

The arguments in the args parameter array can be set manually in the properties window for the service in the Services console. The arguments entered in the console are not saved; they are passed to the service on a one-time basis when the service is started from the control panel.

I still thought that I was doing the right thing, by going to my service’s properties, typing command-line arguments, clicking OK and then right clicking the service and choosing Start:

image

image

But no luck!  The solution was very simple: Click Start from within the Properties window.  As soon as you click OK (which intuitively would seem to save the changes to the Start parameters, as is the case in every other properties dialog in the history of mankind), the Start parameters disappear.

Saturday, October 31, 2009

Pressure Sensitivity Problem with Wacom Bamboo Pen Tablet in Windows 7

Okay, this isn’t my usual coding-related post, but I hope it helps someone.  There are a million different threads about Wacom tablets not working properly with various software on various system configurations, and there’s no shortage of suggested solutions, so I’ll describe my specific situation and its specific solution:

Problem: Wacom tablet pen pressure sensitivity does not work in Adobe Photoshop CS4.  More specifically, it draws at full brush thickness all the time, unless I double-tap the tablet quickly and then begin drawing immediately after, which surprisingly allows pressure sensitivity to work.

My Configuration: Windows 7 Ultimate, Wacom Bamboo Pen tablet (the most basic model), Adobe Photoshop CS4 (as mentioned above)

Solution: In short, disable using the “press and hold” pen action as a right-click equivalent in the Windows tablet pen control panel.  To do this:

Click the Windows button, and in the search box type “Change tablet pen settings".  Open the item that appears.

image

In that dialog, in the Pen Options tab (the default), in the Pen actions group, select the Press and hold pen action and then click the Settings… button.

image

Then, in the dialog that appears, uncheck Enable press and hold for right-clicking and click OK.

image

Windows’ Tablet PC settings are fighting with the tablet’s usefulness, doing their best to turn it into a primary input device rather than a dedicated drawing instrument.  In my specific case, you’ll notice that every time you tap the pen and start drawing (interpreted by Windows as a “tap and hold”), a circle will start drawing around the tap location, and once it finishes drawing, the equivalent of a right-click is received.  This is not a Wacom thing; it’s a Windows thing, and it’s messing with your ability to use your pen with proper pressure sensitivity.

Since my Bamboo tablet pen has a button on it which maps to a right-click by default, I don’t need the “press-and-hold” right-click functionality, and you likely don’t either.

I hope this saves someone some frustration.