Wednesday, June 23, 2010

What Is Wrong With Alan Wake's Facial Animation

Last night I played the first couple of hours of Alan Wake and the game is good fun. A little bit of Left 4 Dead mixed with a dash of Doom 3's flashlight and other bits and pieces. The game was originally intended to be the big DirectX 10 demo for Windows Vista but somehow wound up being an Xbox 360 exclusive.

The locations and environmental effects in the game look fantastic but there is one thing that stands out as freakishly bad (other than the Lincoln, Sync and Energizer product placements), the facial animation! Every time I watch a cut scene I cringe, here's why.

I've just recently finished Mass Effect 2 and Final Fantasy XIII, here's what their facial animation looks like as a comparison for the horror that follows.

Mass Effect 2

Final Fantasy XIII

Now, my friend says Uncharted 2 on the PS3 looks amazing and who am I to disagree?

Uncharted 2
(not sure if this is ingame but it looks it to me)

...and now Alan Wake *shudder* (make sure you wait to see Rose)

So as you can see... FREAKY! It reminds me of this classic

Thursday, January 7, 2010

Welcome To the Future

I had a taste of the future today, the future that we already live in. It all started when Microsoft's Larry "Major Nelson" Hryb started tweeting about behind-the-scenes goings on at the lead up to Microsoft's CES Keynote. His tweet read, "Steve B is just walked by me...wearing a very red sweater . We are getting ready to start". Steve B in this instance is Steve "Developers, developers, developers" Ballmer, CEO of Microsoft, who was to do the talking at the keynote.

Things got more interesting as I started to watch the live stream of the keynote which was being pushed out across the internet from Las Vegas to anyone with a browser and the Silverlight plugin. The audio level was pretty low and I had to bump my system volume up to maximum in order to hear what was going on. Then Major Nelson tweeted this, "Told the stream dudes about the audio level. They're fixing"... was he in my head? No, other watchers had tweeted back to Major Nelson about the audio level.

The left channel dropped out then came back as the right channel then dropped out. When the audio stream returned in stereo at a much improved level The Major asked, "
Let me know how the audio is....they tweaked it." Myself, and I'm sure many others, replied to say that all was good which prompted Larry to offer up a final tweet on the subject, "I brought the streaming to my PC to see your tweets about audio. You guys helped fix it :)"

It was at that moment that I really thought about what was going on. It might sound like ordinary day-to-day goings on but seriously, I was watching a live video of Microsoft's head honcho half way around the world giving a speech to thousands of people while at the same time I was communicating directly with another Microsoft senior employee who was doing techy stuff in the wings. Can you imagine doing that just a few years ago? We really are living in the future.

Wednesday, November 18, 2009

LINQ To SQL Profiler And How To Swing It

[warning: technical post]

My friend showed me a cool profiler the other day by the smart chaps at Hibernating Rhinos which lets you see what is going on behind the scenes of the magic black box known as "LINQ To SQL" (L2S). I've been using LINQ to SQL for almost 2 years now and while it's far from perfect it makes my job (life!) much easier. Unfortunately by hiding the inner workings away from the developer by the time you come to look at the performance of your website (or desktop app) you're pretty much left in the dark. That's where L2SProf comes in. It hooks into your datacontext and gives you a great view of what's happening back there...


Now, the set up is pretty straightforward with L2SProf and involves adding a reference to a single DLL into your app (web or otherwise) then copying and pasting a single line of code into your startup method (e.g. Application_Start in global.asax for a website). Once you've done that you restart your application, crack open the included L2SProf.exe and voila, your LINQ to SQL datacontext's secrets are no longer secret... unless you're me. I got a big fat nothing.

After trying to sort it out with my friend and failing I jumped onto the support forums and posted a quick message asking for help. There was a bit of to-ing and fro-ing over email with not much accomplished. Then Oren Eini (AKA Ayende Rahien) popped onto the scene (then Skype) to give me some help.

First we tried writing the profiler data to a text file (a slight modification to that single line of code I mentioned earlier) and while the log file was created, nothing was written to it. Next we created a brand new web application from scratch and everything worked with the profiler showing my single datacontext call and its corresponding SQL code. Oren looked over the web.config from my original website and decided the problem wasn't in there. After fiddling around some more we came across a little bit of code I'd put in place to stop Visual Studio from trying to read my connection string from the data model project's app.config. This was our "aha" moment.

Normally you'd either have your DBML file (LINQ to SQL datacontext) in your website or if it's out in another project in your solution, you'd let Visual Studio control the database connections by dropping them into the app.config, that's not how I had it set up. This is the method I had in place in my DataContext.cs...

public MyDataContext() : base(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString)
{
OnCreated();
}


I'll let Oren explain what was going on here...

"The problem with doing it this way is that you are forcing L2S to build a new model every time that you create a data context, that is quite expensive, from a perf point of view. L2S have to use reflection to get the values each and every time. A side affect of that is that it also kills the way L2S Prof works. Here is how to make it both performance and work with L2S Prof:"

public MyDataContext() : base(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString, mappingSource)
{
OnCreated();
}


Once we did this everything fell into place, data access information pouring out of my website. So there you go, once again proving that if you don't do what Visual Studio wants you to do you can get into trouble.

Thanks a lot to Oren for his help and patience in helping me solve this problem. Now I need to go see how badly my website is performing.

Monday, October 19, 2009

Using Microsoft Ajax Minifier with Deployment Projects

It's been a while since I did a post here but this is worth it. Yesterday Microsoft's Scott Guthrie announced the new Microsoft Ajax Library (Preview 6) and the Microsoft Ajax Minifier. While I haven't checked out the new Ajax library I have had a bit of a play with the minifier.

Seeing as I was on the look out for a Javascript minifier for my current project this came at quite an opportune time. I found Stephen Walther's immensely helpful blog post about setting the Ajax Minifier to run automatically each time you build your project (you should go read that now before continuing here). The only problem with Stephen's sample is my current ASP.NET solution is set up in such a way as my website is a Website, not a Web Application so I don't have a .csproj file to edit.

Fear not! For I have found that I can simply transpose Stephen's sample code over to my deployment project's .csproj file with similar results. The following is the required markup from my deployment project's csproj file to generate minified scripts on the fly after deploying my website. I placed this at the very end of the markup, just before the closing </Project> tag.

CODE:


<PropertyGroup>
<BuildDependsOn>
$(BuildDependsOn);
MinifyJs
</BuildDependsOn>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\MicrosoftAjax\ajaxmin.tasks" />
<Target Name="MinifyJs">
<ItemGroup>
<JS Include="$(OutputPath)\js\*.js" Exclude="$(OutputPath)\js\*.min.js" />
</ItemGroup><AjaxMin SourceFiles="@(JS)" SourceExtensionPattern="\.js$" TargetExtension=".min.js" />
</Target>


Should look something like this:


The big difference here is the min.js files are generated on the fly in the DEPLOYED website (that'd be the $(OutputPath) location. Also, but not as important, my javascript files are in a folder called "js" unlike Stephen's which sit in the root of the site.

So there you go, minified Javascript files in your target site.