Feb 22, 2012

Double the Budget for Free T-shirts

I read something like this from a game business book, which I don't remember the title anymore (sorry it's been a while.  If anyone let me know, I'll update this post):


"If you don't have a budget for free T-shirts for employees, make one.  If you do, double it up"

I totally agree.  From company's point of view, this is a really cheap way to show it cares about people and keep morale high.  Don't forget that people become happy or pissed off by mostly small things. So if you are in a position to make a decision on free swags, please get each of your employees at least one free T-shirt an year.

It's also very interesting to see how high morale can affect the quality of games.  Throughout my career, I have seen plenty of game developers who did more than what they were asked for when they were given free T-shirts, thus excited.  Of course, I also saw the opposite: the sweat-shop game developers who did never more than what they were required just because they were treated like factory workers.  Actually, seeing the latter more often nowadays, I'm a bit worried.

To me, game making is a form of art + technology collaboration.  So more excited your developers are, more inspiration they offer to their colleagues, which means more iterations = better games.  If you don't trust me, maybe you can ask how many free T-shirts each employees get at your favorite game studios... :)

Feb 19, 2012

Do Your Part for the Environment, Shaw

Shaw communications is a load of bullcrap.  I'm pretty sure any Shaw subscribers, whether it is cable TV, internet or digital phone, would remember that you were asked to switch to paper-free billing to save the environment.  You even probably remember the following picture, which was mailed to you at least once or twice.

image source: shaw.ca, of course an environment-friendly-fraudly company.

This is great.  Don't you think?  I switched to paperless instantly(or maybe even before I was asked) not because I cared too much about the environment.  It was just more convenient for me to receive the bill via email.  See? I'm being honest at least.  Unfortunately, Shaw is not.

So did Shaw really care about the environment?  My answer is no.  Since a lot of customers switched to paperless billing, Shaw increased the number of promotional materials PRINTED ON PAPER AND MAILED to you.  Yup, so now I'm getting more mails from Shaw.  For example, last week I received two.  One is asking me to sign up for their digital phone service(AGAIN!), and the other was some new internet or TV service, called EXO. And this EXO mail was printed on higher-quality glossier paper than your normal paper bills.

So Shaw saved some money, not the environment, by not printing your bills on paper and used that saving to print their promotional materials more aggressively.

Way to go, Shaw.  Do your part for the Environment, if you really meant, or just don't BS.  I'll accept you. I have great a fondness toward a business which's trying to make money without lies.

Feb 12, 2012

Crazy Eye Pain & Headache = MSG Side Effects?

This morning, I woke up with some crazy eye pain, headache and nausea and I had no clue what caused it.  This is my 2nd time having these symptoms.  The first one was sometime last year when I had to call in sick.  I usually don't have headaches.  Just this one is too strong for me to do any normal works: the only thing I can do is just to lie down and do nothing.

Once I got better around 11 PM, I did some web search and now I think it might be related to the high intake of MSG.  According to this site, my symptoms are MSG side effects, and guess what? I went to a Chinese restaurant last night and ate a lot!  Too bad, I don't remember what I ate last time I had this problem.  If I remembered, I would be more certain. :)

Oh well, MSG can be unhealthy anyways, so I guess it's time to cut, or reduce, MSG out of my diet?

Feb 10, 2012

[WIP] Music: Out of Reach Intro

This is something I wrote last night.. It's still intro to a song I, for now, call Out of Reach.  I quite like it, so I might finish it one day.. yes one day...



For comments, use my Facebook (one-man) band page I guess?

Feb 9, 2012

TFSA over RRSP? Probably Not for Game Devs

Image Source: http://chelleyc.uibcsites.com/files/2011/02/TFSA-vs-RRSP.jpg

Since TFSA is introduced a few years ago, there has been good debates on which one one should max out first between TFSA and RRSP.  And nowadays, a lot of financial advisers seem to advise TFSA over RRSP.

I don't think so, at least for game developers, who tend to get easily laid off, thus forced to be out of the job, compared to people in other industries. (TFSA over RRSP might make sense for people in other industries, but I don't really care).

Okay, here is the deal.  You can buy up to 18% of last year's income.  Let's say you make $100,000 am year. (for easy calculation)  If you don't buy RRSP, you will be taxed $25,454 in BC according to this online calculator whether you buy TFSA or not.  But if you max out your RRSP($18,000) you will only be taxed $18,623.  So $6,831 saving.

Sure, you pay tax when you withdraw the RRSP, but based on the income of the year when you make the withdrawal.  That's what makes RRSP a better choice for game developers.  Say, you get laid off next year and you are out of the job for 6 months.  Then your income and tax will be $50,000 and  $8,848.  You think this is not enough money to pay all your bills.  So you withdraw RRSP, $18,000.  Then your income and tax become $68,000 and $14,194.  It's $5,346 extra tax for you for that year.

Since you saved $6,831 last year, but paid $5,346 this year your overall saving is $1,485.  If you had put $18,000 in TFSA, do you think you can make $1,485 / $18,000 = 8.25% return?  Doubt it.  So to me, RRSP is a better choice in this industry.  Well, maybe you haven't laid off so far, but it can happen anytime even if you are super competent.  Sometimes, companies have to lay off people to show investors they are doing something to turn around.


Feb 7, 2012

Lying Throughout Your Career

There was someone who did (have to) leave my company recently.  He is one of those people who have to jump around companies after short stays. Yeah, you know why.  And today, I happened to read his blog post explaining why he was leaving. A lot of my co-workers enjoyed it because it reminded us of the Lord of the Rings, arguably the best fantasy fiction to date.

Image Source: http://images.wikia.com/lotr/images/9/9e/Smeagol.jpg


I am not going to point out all the lies because 'someone' desperately needs those to stay in this industry.  I just suspect pretty soon 'someone' will have to find a job outside of this beautiful city, Vancouver, because he seems to be very well-known here.  Furthermore, dealing with a possible defamation charge is not something I want to do at this moment although I'm pretty sure I would enjoy it because I'll win no matter what: my claim is not false, that is. (after all, I'm still a lawyer, hah!)  Just it's a headache dealing with an idiot with no clue, but if anyone asks me personally, I wouldn't hesitate to tell him/her. I'm an honest guy and can't lie or hide anything.

Oh, speaking of lies, I know how to distinguish facts from opinions or judgement.  That's one thing I was trained for really hard at my lawschool.  For the same reason, I call him a liar for claiming false facts, not because of his out-of-mind judgement or opinions.  But if he truly believes in what he claims, I guess he has absolutely no minimum required skillset to be an engineer, or this place will be his new home.





Feb 4, 2012

Animation Sharing between Different Characters with Same Topology in Unity


Image Source: http://answers.unity3d.com/questions/191282/sharing-animations-between-models.html


So let's say you have multiple characters with different bone lengths, but you just don't have manpower to author different animations for all of them. Can we share animations, instead?  Sure, why not, if you can live without transition and scale animations on joints: in other words, you are only gonna use rotations. Think it this way. When you rotate your right elbow inward by 90 degrees, your pose will look same as your shorter friend applying the exactly same rotation on his right elbow. Got it?

Okay, so I was searching Unity forum to see if rotation-only animation is officially supported.  Didn't look like it.  Then next up.  Can we somehow trim out non-rotational info from an anim file in the pipeline? I was not able to find the answer again, or even anyone asking. (Sorry, after finishing this post, I actually found someone asking, but noone really answered.)

And the good news is....... -drum rolls- .... I figured it out! :D

So this is what I came up with and it works great: (code shown below)

  1. Make a script called ConvertToRotationOnlyAnim.cs inside of Assets/Editor folder.
  2. Add a menu item invoking this script.
  3. Import your animation into Unity.  (doesn't matter where it's from as long as Unity sees it as animation)
  4. Right-click on the imported animation asset and select the menu item we just added at step #2.
  5. In the Script, copy over only the curves which have "m_LocalRotation" as propertyName field.
  6. Now set the new _rot animation clip to your game object's animation component.
  7. Hit play and enjoy... :)
And here is the full source code I wrote for this.  Hopefully the comment is self-explanatory:

using UnityEditor;
using UnityEngine;

using System.IO;

public class ConvertToRotationOnlyAnim
{
    [MenuItem("Assets/Convert To Rotation Animation")]
    static void ConvertToRotationAnimation()
    {
        // Get Selected Animation Clip
        AnimationClip sourceClip = Selection.activeObject as AnimationClip;
        if (sourceClip == null)
        {
            Debug.Log("Please select an animation clip");
            return;
        }

        // Rotation only anim clip will have "_rot" post fix at the end
        const string destPostfix = "_rot";

        string sourcePath = AssetDatabase.GetAssetPath(sourceClip);
        string destPath = Path.Combine(Path.GetDirectoryName(sourcePath), sourceClip.name) + destPostfix + ".anim";

        // first try to open existing clip to avoid losing reference to this animation from other meshes that are already using it.
        AnimationClip destClip = AssetDatabase.LoadAssetAtPath(destPath, typeof(AnimationClip)) as AnimationClip;
        if (destClip == null)
        {
            // existing clip not found.  Let's create a new one
            Debug.Log("creating a new rotation only animation at " + destPath);
            
            destClip = new AnimationClip();
            destClip.name = sourceClip.name + destPostfix;

            AssetDatabase.CreateAsset(destClip, destPath);
            AssetDatabase.Refresh();

            // and let's load it back, just to make sure it's created?
            destClip = AssetDatabase.LoadAssetAtPath(destPath, typeof(AnimationClip)) as AnimationClip;
        }

        if (destClip == null)
        {
            Debug.Log("cannot create/open the rotation only anim at " + destPath);
            return;
        }

        // clear all the existing curves from destination.
        destClip.ClearCurves();

        // Now copy only rotation curves
        AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(sourceClip, true);
        foreach (AnimationClipCurveData curveData in curveDatas)
        {
            if (curveData.propertyName.Contains("m_LocalRotation"))
            {
                AnimationUtility.SetEditorCurve(
                    destClip,
                    curveData.path,
                    curveData.type,
                    curveData.propertyName,
                    curveData.curve
                );
            }
        }

        Debug.Log("Hooray! Coverting to rotation-only anim to " + destClip.name + " is done");
    }
}




Update (Mar 21, 2011): One anonymous commenter enhanced this by allowing local root bone translation.  Without this you won't be able to translate your model :) 


Change this line to:
if (curveData.propertyName.Contains("m_LocalRotation"))


this:
if (curveData.propertyName.Contains("m_LocalRotation")
  || (curveData.path.Equals("Bip01 Pelvis")
  && curveData.propertyName.Contains("m_LocalPosition")))


Thanks anonymous! ( not the hacker group :P )