Share/Save/Bookmark Subscribe

Wednesday, September 26, 2012

Using Git for Unity 3D projects

I was recently asked by a collaborator why we'd switched to using Git for our Unity projects, and I thought the bullet points I passed to him might serve useful to someone else considering the switch, so here we go:

We previously used Asset Server (via VPN) but switched to Git due to a number of advantages, including:
  • Easy remote access from anywhere, highly performant on most networks. Important for our highly distributed team, and frequent access requests from non-team individuals.
  • Supports branching, allowing us to safely work on multiple features without breaking our main build. This has become particularly important to us since we'll need to be able to support a main release with hotfixes while safely working on future version features.
  •  Excellent support for tagging and selective reverts. Has already saved us a number of times :)
  • Supports offline work beautifully, it's still possible to commit when the network goes down, move onto other tasks, and handle merges later.
  • History is available offline as well.
  • Diff based versioning, as opposed to Asset Server's timestamp based versioning.
  • Better merge and conflict handling.
  • No need for additional per seat client licensing.
  • 3rd party cloud hosted packages available (GitHub in our case) to take management off our hands.
It's by no means perfect of course, and does take some adjustments to workflow, for example:
  • Know what belongs in Git and what doesn't. Basically everything in /Assets and /ProjectSettings, nothing from /Library or other temp locations, and nothing that is frequently autogenerated like Mono projects. 
  • .meta files must always be committed with their assets, some simple rules:
  • Always open the project in Unity before a commit, to allow it to update metas.
  • If you add an asset or folder, it's up to you to commit the meta
  • Move/delete objects in Unity, not the filesystem, so it updates metas accordingly (git detects these actions correctly, moves actually show up as moves in history)
  • If you delete an asset or folder, it's up to you to commit the meta deletion
  • Always delete folders that no longer contain assets and commit the meta deletion
  • Notify the team before you push (we use our Skype group status for this) to avoid pushblocking someone that's doing a large push with something small and trivial.
  • Ideally when starting on what could be a large/time consuming feature, create a local branch so if you need to switch back to master to fix something small you can.
  • Regardless of workflow, there are some difficulties/disadvantages that need to be taken into account when considering the switch:
    • Since each user clones the entire repository, much more disk space is required.
    • It's essential for all users to understand the commit/pull/resolve conflicts/push process, or they can potentially cause serious damage.
    • Not built into Unity, so one more tool to learn.
    • Since game project assets are so large, occasional cleanup is needed to keep repo size down. 

    Posted via email from Matt's thoughts

    Sunday, May 15, 2011

    iSkinned with Decalgirl

    When I still had a PSP, the thing attracted dirt and fingerprints like mad and it felt like I spent more time cleaning it than playing on it. I tried a couple of skin solutions, but they all had some issue or other-too thick so the analog stick got blocked, began peeling off too easily, etc. Then I stumbled on decalgirl.com, read rave reviews about their skins and decided to import a kit. It turned out to be a great choice, and together with a screen guard changed the way I used my PSP.
    So when @justinpaver was going to be heading over from the states for a visit I jumped at the chance to have him bring some decalgirl skins over.
    In addition to skinning my and Nat's phones, I got a skin kit for my MacBook too.
    Applying the skins is not a task to be rushed, I had to set aside about 30 minutes per device. The phone kits also come with a code for a matching desktop background, which is pretty cool (pity the same isn't available for the MacBook). The result is pretty cool, and with no sticky residue being left behind on the devices after the covers are removed, it's a great way to keep them in good nick.

    Posted via email from Matt's thoughts

    Wednesday, March 23, 2011

    The Gift Of Life - Thanks Dad

    Ten years ago today, I was on the receiving and of a miracle. A miracle made possible by my Dad's generosity, the awesome skills of medical professionals and the Lord's good grace. After spending my life to that point dealing with sick kidneys, they finally failed me completely and I needed a new kidney - which my Dad selflessly offered to donate. I was 21 at the time, and without the new kidney I quite simply wouldn't be here today-or at least would be living my life dependent on a dialysis regime (which is not fun). My kidney is now ten years old and going strong.

    Those of you that know me, and didn't know about this are quite possibly amazed (most people are when they find out), because I live a normal and healthy life. I don't seem 'sick' - and that's because I'm not. The transplant gave me what I'd never had- a completely healthy kidney- and I've been careful to look after it since. The negative "effects" are limited to regular checkups with a specialist and taking daily immuno-suppressants, not a bad deal :)

    I'm one of the lucky ones. There are hundreds, if not thousands of people of all ages, from all walks of life, that desperately need transplants and can't get one from a family member for whatever reason. They have their names on a list, and are hoping and praying to be the lucky recipient of a 'cadaver' organ. 

    YOU CAN GIVE THESE PEOPLE A NEW LIFE LIKE I GOT. All you need to do is:
    1. Register as an organ donor with your local donor organization. In SA that's the Organ Donor Foundation (http://www.odf.org.za)
    2. Carry your donor card in your wallet or bag at all times
    3. Discuss your choice with your family. They will ultimately be the ones that have to give the go ahead to harvest your organs, so they need to know about and your wishes and know to respect them.
    Please, don't believe the rubbish some people insist on spreading about donation: 
    • Doctors and paramedics will not give you inferior treatment to secure organs.
    • Your organs will not be sold for some crazy profit to the highest bidder. 
    • Your body will be treated with the utmost respect and will be perfectly fine for open casket display if that's what you want.

    Posted via email from Matt's thoughts

    Tuesday, January 25, 2011

    New arrivals

    We adopted these two from someone moving to a smaller place and looking for a good home for them. The grey one is Misty and the other is MJ.

    Posted via email from Matt's thoughts

    Monday, January 17, 2011

    Is Unity 3D ready for console game dev?

    Over the last couple of months I've been getting my hands dirty with Unity 3D on a project for Luma Arcade, and for the most part it's been a fantastic experience. Unity's 5 or so years of building their tools and having a large user base to test it and provide feedback really shines through. Getting simple concepts going is laughably easy (as evidenced by 48 hour gameplay challenges like the recent Game.Dev one) thanks to the intuitive interface. The powerful art tools and C# scripting also allow those early efforts to be extended and polished into top notch products.

    Unity has a reputation in some circles of being a tool limited to mobile, web, or relatively simple PC and Mac games. Their recent push into the traditional console market, with versions of their engine for Xbox 360 and PS3 (there is already a Wii version) is set to change that. For the most part, I would say they are ready for the jump and many developers will welcome their powerful toolchain as another option when targeting these platforms. There are however, some issues I personally feel need serious attention before Unity becomes the ideal tool for medium- and large scale console development which I would like to point out here. Please note that these are my own views, and not necessarily those of Luma, it's directors or employees.

    Outdated and unstable IDE support
    Unity has the developer-friendly ability to generate project files that allow devs to work with a Unity project file in Monodevelop (which is bundled with Unity) or Visual Studio. These projects can be fully debugged like a natively developed project as well. This is the theory anyway and I've seen the system in work on other developers' systems. My personal experience however (and based on reports online I'm far from being alone alone in this) is that Monodevelop will crash within minutes of trying to debug a unity project. The generated projects are also in the outdated Visual Studio 2008 format, and are re-generated whenever a file is added within Unity so manually upgrading the projects to 2010 format is not a practical option. This leaves those of us with up to date software out in the dark. Considering the importance of being able to debug properly, this is a huge issue that needs addressing. Giving developers the option to output 2010 format projects should be a fairly trivial improvement, the stability issues on Monodevelop will of course be more of a challenge.

    C# as second class citizen
    Unity has script/code support for JavaScript, C# and Boo. The focus in documentation and samples is quite heavily skewed towards JavaScript, and there are some areas (such as lack of proper support for namespaces, quirks trying to import C# code and  outdated API support) that point to C# being a second class citizen as far as Unity scripting is concerned. Moving into the console development space, C# is the natural language choice for most teams due to it's similarity with the still-dominant C++. There is no doubt that javascipt's flexible nature holds some advantages over C#'s more traditional rigidity, but I'd wager familiarity will win out in this case and console teams will go with C#. For this reason I believe Unity would benefit from a greater focus on it's C# support. It does appear this is already happening, as online documentation at least now (mostly) includes examples from both languages.

    Non nestable prefabs
    Unity's excellent prefab system allows the creation of reusable template objects called prefabs that can easily be added to a scene and then have minor changes applied per instance, but still benefit from later tweaks to the prefab. The problem here is that these prefabs can't be nested, so for example if a wheel prefab is created, then added to a car which is then prefabbed, the connection to the wheel template is lost and any future changes to the wheel prefab will not be passed on to the wheel instances in the car. This diminishes the value of prefabs somewhat, and ideally support should be added for this.

    Binary object formats
    Unity's scene and object files (including their reusable prefabs) are binary, and as such not mergeable by typical version control systems. Considering the modular component model Unity uses, multiple developers or artists often need simultaneous change access to these files as they work on different functionality on the same object. This leads to blocking cases which would potentially get even more acute with larger teams. Ideally these should be an easily mergeable text format such as XML. There are of course potential performance advantages to using a binary format, but there's no reason these can't be generated when doing a build for the target platform, with the working format being XML.

    Asset server
    Sticking with the topic of version control, there is Unity's integrated asset control system called Asset Server (for which an extra seat license is required). Now while the idea of asset control built into the development environment is appealing, the reality is that this system is not nearly as extensive as the likes of SVN. It also has some serious issues such as updating of certain project files (particularly .asset files defining project wide behavior) causing a project to become unusable. I for one would welcome the replacement of the proprietary asset server system with a more common standard like SVN, or possibly even something like Git or Mercurial that supports distributed teams-an increasingly common occurrence in our industry.

    Focus on non-paying customers
    Free license Indie developers have taken Unity a long way, and their admirable support for the indie market has arguably been a massive part on getting the platform to where it is today (and for that reason the following is likely to be flame bait). There comes a time however, when paying customers have to take precedence, and if Unity want to push into the console market that change of direction will have to come sooner rather than later. Unity's brilliant feedback system in which users vote for for improvements and new features is a prime example of a place where this change is needed. Free users get the same weight in this system as paying customers, and as a result blue-sky features that matter less to professional developers (such as Linux support) end up drowning out improvements that would help professional development such as some of the changes mentioned above.

    Licensing model
    Another example of unity's heritage in smaller developers is their license model. They typically charge a per-seat, per platform license. Recently they also announced a mass licensing deal with EA that gives all of that publisher's in-house devs full access to Unity's tools. Sadly not all professional developers have the clout EA does, and this leaves a big gap for medium to large studios that would rather buy a group license than deal with seat licenses. A bulk license system is needed, ideally with discounts in place as the group size increases.

    Posted via email from Matt's thoughts

    Sunday, January 02, 2011

    Gamedev in South Africa, 2010

    Published by Leslie Young back in November, I've only just picked up
    on this now. It's an excellent retrospective of what local game devs
    (both indie and pro) have been up to over the last year. In short,
    it's been a pretty damned exciting year, let's hope 2011 is even
    better!

    http://www.gamedevsa.com/2010/gamedev-south-africa-2010

    Posted via email from Matt's thoughts

    Friday, December 31, 2010

    Fun with initialization order

    Here's something I meant to post ages ago, when I was doing J2ME to Flash conversions, and got caught out by assumptions about the evaluation order of values passed to a method or to initialize an array. It's one of those really subtle issues that had me scratching my head to figure out what had gone wrong in a piece of code.

    Consider the following (pseudo)code:
    1 2 3 4 5 6 7 8 9 
    function evalTest(val1, val2, val3)
    {
         print("val1: "+val1+", val2: "+val2+", val3: "+val3);
    }

    int val = 0;
    int arr = { ++val, ++val, ++val };
    print("arr: ["+arr[0]+", "+arr[1]+", "+arr[2]+"]");

    Now what would you expect the output to be? I had unwittingly assumed the result would consistently be:
    arr: [1, 2, 3]
    val1: 1, val2: 2, val3: 3

    As it turns out, the answer varies from language to language (which is why I got snagged by code working 'correctly' in one language but 'breaking' in another):

    Java:
    1 2 3 4 5 6 7 8 9 10 11 
    int val = 0;
    int[] arr = {++val, ++val, ++val};
    System.out.println("arr: ["+arr[0]+", "+arr[1]+", "+arr[2]+"]");

    val = 0;
    evaluationTest(++val, ++val, ++val);

    void evaluationTest(int val1, int val2, int val3) {
      System.out.println("val1: "+val1+", val2: "+val2+", val3: "+val3);
    }

    Result:
    arr: [1, 2, 3]
    val1: 1, val2: 2, val3: 3
     
    Actionscript:
    1 2 3 4 5 6 7 8 9 10 
    function evaluationTest(val1:Number, val2:Number, val3:Number) {
            trace("val1: "+val1+", val2: "+val2+", val3: "+val3);
    }
    var val:Number = 0;
    var arr:Array = [++val, ++val, ++val];
    trace("arr: ["+arr[0]+", "+arr[1]+", "+arr[2]+"]");
     
    val = 0;
    evaluationTest(++val, ++val, ++val);

    Result:
    arr: [3, 2, 1]
    val1: 3, val2: 2, val3: 1
     
    Some others:
    C++ undefined:
    C# guaranteed to be right to left:

    Posted via email from Matt's thoughts

    Saturday, December 18, 2010

    DSTV Mobile on Nokia N96

    With all the marketing Multichoice is doing around DSTV Mobile, I thought I'd brush off the N96 and put it's DVB-H receiver to the test again (previous attempts proved fuitless). This time around it all worked pretty smoothly on the first attempt-if a bit confusingly. Nokia's "Live TV" allowed me to purchase a DSTV Mobile subscription (currently free). I did find though that on restarting the phone after removing and reinserting the SIM, the app had lost my subscription data-no big deal for free promos, but I can see some really irritated users when their paid subscription goes missing. Note that while the app doesn't use 3G to receive the actual TV signal, it does need a cellular data connection to validate licensing (which means no using the service out in the bundus to catch the cricket or rugby).
    The app itself is actually pretty well put together, with different program guide views in portrait and landscape, the ability to set program alarms and auto-tuning events, and both fullscreen and windowed (with programming info) views. Parental controls are enabled by default, and set to an age limit of 15, so it's possible first time viewers will have to hunt around for the default unlock code (12345 in case anyone gets here searching for it). Another interesting quirk is that the app locks the video down against both screenshots of content (note the attached shaky cam files taken from my iPhone) and TV out. I suppose I'm not entirely surprised, but this level of lockdown seems seriously ridiculous considering you'll ultimately need a full DSTV subscription anyway when the service goes paid in a couple of months.
    The content available in the DSTV mobile package is fairly limited, with the focus heavily on sports, but what's there comes through clearly. I have to say I was pleasantly surprised at both the video and audio quality and the glitch-free nature of the experience, this is no frustrating streamed video. Not being much of a TV watcher, and given the content, I can't say I could see myself paying for the service but I can definitely see the value to avid sports fans and even the 'distract the kids' value of Cartoon Network.

    Download now or watch on posterous
    ChannelO.mov (1054 KB)

    Posted via email from Matt's thoughts

    Saturday, October 23, 2010

    Testing out the new posterous app

    Posterous has for some time had an app on the iPhone called "PicPosterous", focused on posting multiple images from the device direct to a posterous album (and of course optionally adding a blog post). Checking on the app store today, I saw the sneaky buggers had at some point released a new app called (imaginatively enough) "Posterous".
    This is my first post from that app, so let's see how it goes. I'm most interested in seeing if autoposting of multiple images works (in the past, in Facebook for example, a new album would be created by PicPosterous with just the first image, the rest would all make it to posterous but not facebook). To test this I've added two hopefully prescient screenshots from the incredibly awesome and devilishly addictive iPhone game, "game Dev Story". If you haven't checked it out yet, do so now (but first warn your loved ones they may not see you for a couple of days. Or weeks)!
    From an editing point of view, the new posterous app uses the standard iPhone editor (so no text styling), and allows enabling or disabling geotagging, autoposting and private settings for the post. Tags can be added (with a nifty chooser that shows past tags), and of course media can be attached. At this stage only photos and videos can be attached (new or from the library) but no audio recordings. There's also unfortunately no multiple-select for images and videos, so each has to be added individually.
    In addition to posting to any of your posterous blogs, the app also allows you to view past posts. I've yet to check if they can be edited, and since there's no way to save a draft, I'll try it after posting this.
    Like posterous itself, the app is dead simple and intuitive, just what you need (well, most of it) and no more.

    Posted via email from Matt's thoughts

    Saturday, September 25, 2010

    Molting rain spider

    We lucked out catching this rain spider while it was molting at a
    friend's house. The wives wanted to kill it :P

    Posted via email from Matt's thoughts

    Saturday, August 28, 2010

    Reefsteamers train to magaliesburg

    Today we took the Reefsteamers steam train from Maraisburg station to Magaliesburg. The train departs a little after 9am, winding out of Joburg at a nice lazy pace. We had initially tried to book a 3 seater coupe, but they were sold out for this trip so we settled for regular single seats. This turned out not to be a great idea, the regular seating area is way too noisy for those of us without kids and the screaming tolerance they build ;) We were lucky enough to find a coupe who's occupants hadn't pitched and 'upgraded'. I'd definitely suggest anyone planning on taking the trip to hold out for one of these compartments, they make for a great experience. Make no mistake, these are vintage commuter trains in their original state, no Rovos level niceties, but they are a nice way to relive those old trips to holiday spots by rail.

    After about two and a half hours of relaxed travel through the countryside (including some shunting stops on the single gauge track), the train dropped those travelers who had booked for lunch at the Magaliesburg Country Hotel, and then carried on to drop the rest off at the self catering picnic grounds. Sadly the lunch at the hotel wasn't much to write home about, but the dessert at Wimpy around the corner was great. Whether going with kids or without, I'd suggest skipping on the hotel dinner and rather going for a Wimpy burger or the picnic option.

    The trip back was somewhat shorter at about ninety minutes, due to fewer shunting stops, but was no less relaxing-especially with bellies full of food.

    Overall, this was a fun experience at a reasonable price. It would also definitely be a great way to entertain kids and introduce them to an older, slower paced way of doing things.

    Posted via email from Matt's thoughts

    Thursday, August 26, 2010

    The Harvest

    The Harvest is a Luma Arcade developed and Microsoft Game Studios published title under development for the upcoming Windows Phone 7 platform. The game is developed in C# using Microsoft's XNA set of API's on top of the .Net Compact Framework. The high production quality bar for a game on a (not yet final) mobile platform meant serious work on squeezing every ounce of performance out of the engine. In addition to the usual engineering challenges of developing a truly AAA 3D title, and working closely with the MGS publishing team in a senior role, this project gave me the incredible opportunity to visit Microsoft in Seattle to work with them directly on performance challenges, gameplay and usability fine tuning, audio balancing and more. 

    From Xbox.com:
    On a future Earth, the invading alien Harvesters use humans and animals to create cyborgs: crude amalgamations of flesh and machinery. Mankind, in the form of the Global Defence Force, now fights a war against The Harvesters using human controlled mechanized infantry units. As a member of the GDF army, you have been sent to investigate reported Harvester activity in the ruins of an ancient city once used as a military base. As you explore, fight off wave after wave of The Harvester horde, find hidden upgrades, and defeat imposing enemy boss units in order to return Earth to its rightful inhabitants.
    Designed from the ground up to be the best looking 3-D mobile phone game to date, The Harvest™ features innovative touch screen gameplay, along with visceral combat, and opportunities for exploration, character customization, and more. This action RPG experience is an Xbox LIVE-enabled game for Windows Phone 7, and will immerse you into a deep and intriguing story where it is vital that the GDF is victorious.

    For videos of The Harvest in action, see the recently posted playthroughs on GameTrailers.com.

    Posted via email from Matt's thoughts

    Tuesday, August 24, 2010

    Champ Chase

    Champ Chase was a project by I-Imagine for the Nelson Mandela Children's Fund's "Champion for Children" campaign. Released as an online flash title as well as a J2ME mobile game, the challenges here were to quickly build a Flash equivalent to I-Imagine's flexible J2ME engine, as well as expand on the company's in-house high score system and communicate with it from flash.

    The game is a 2D platformer aimed at educating young players about various dangers they may encounter such as criminals, drug abuse and online predation. This was achieved through a combination of stylized characters associating each concept with a familiar object or animal with typically negative connotations, as well as more direct information provided at key points. The game is simple and fun, placing the player in the role of a protector saving children from these dangers.

    Posted via email from Matt's thoughts

    Sunday, August 22, 2010

    Death of optimism

    I have always been supportive of South Africa and positive about it's people and future, the guy who would argue down naysayers at work, at the dinnertable, wherever negative sentiments might arise. For every pessimistic complaint about our politicians, our crime levels and our problems I would provide a counterpoint.

    My family has been on the victim's end of it's fair share of property and contact crime. We've been tied up, stabbed and held at gunpoint in armed robberies. We've had cars and small items and even the entire stock of our shop stolen. Most families in this country have had similar experiences, regardless of race or background. Despite this I have always sung South Africa's praises to all who would listen, firmly believing these problems would be solved.

    For every corrupt politician shamelessly leeching funds needed by the poor and downtrodden to fund an opulent lifestyle, I have firmly believed there is another dedicated, hardworking individual with a love for their homeland  and the fire of justice in their belly. For every potholed road I've been able to point to a glowing new advancement in public transport. For every dirty downtown street I've been able to counter with encouraging stats about waste management and recycling. Dropping educational standards? Growth in industry and sheer number of people getting an education will sort that out in the long term.

    But none of that matters anymore. As of this Thursday past my optimism is gone, taken by the thugs with knopkierries beating on a door, the other side of which had been barricaded by my wife and one of her patients to keep these monsters out. Who were these vicious villains? Were they drugged up kids on a narcotic warpath? Career criminals looking for their belongings? Perhaps escapees from the mental ward come to exact their revenge on the institution? No, they were my wife's highly trained and respected colleagues in medical work. Nurses and other staff that work in the public hospitals. Professionals entrusted with the care of our sick and downtrodden, wanting to drag co-workers out of the hospital and physically assault them for not partaking in their illegal strike. Health care workers forgoing their oath of service to haul non-striking theater staff out of active operating theaters, regardless of the already anesthetized patients who's lives lay in the balance.

    At the same time schoolbusses were announcing they would discontinue their services during the strike action for fear of being targeted. By schoolteachers. Let me spell that out: school buses full of children the potential target of violence by school teachers. I  am completely in favor of industrial action, of underpaid and undervalued workers having the right to express their unhappiness and disillusion, especially when these are the workers carrying out two of the most important jobs imaginable: caring for our sick and teaching our young. However strike violence is not a valid part of this action, and nothing on earth justifies these same caregivers turning on each other and on their charges, nothing.

    Because of the hair-trigger nature of racial debate in our country I have to emphasize that this is not about race. There were members of various races on both sides of that door. This is simply about the people of our country failing at a basic human level-to have empathy for our sick and young. Even in times of war, hospitals and schools are considered places of safety and refuge. Violating them in any way whatsoever is looked on with great scorn and leads to trials in The Hague. Yet here are our own medical staff and teachers violating that universal principle-for a pay rise. What kind of a people must we be, when those in our community we are expected to trust more than any other must be feared like common thugs? How can we be expected to carry on "Leading SA" and hoping for a bright future for our beautiful rainbow nation? Well I for one can't. My hope and faith and optimism -fundamental parts of my being- have been wrenched from me by the dogs that threatened the life of my wife while she was in the act of helping someone.

    Cry the Beloved Country. Indeed.

    Posted via email from Matt's thoughts

    Sunday, June 27, 2010

    Great Netbook case on the cheap

    Nat and I were in a PNA for something, and spotted their leather Bible
    cases-which happen to be just the right size for a netbook and are
    under 200 bucks!
    This is a simple one, there were full combos with a separate
    compartment for a (paper) notebook, pen loops, etc in the same price
    range. Compare that to 300+ for a neoprene sleeve, and you have a
    damned good deal.

    Posted via email from Matt's thoughts

    Saturday, June 12, 2010

    Some great productivity keyboard shortcuts in Windows 7

    Windows 7 may basically be Vista with a fresh coat of paint and with a bit a of steroid injection, but it also comes with some great productivity enhancements to the UI, like Aero Snap (pulling a window to the top or sides of the screen snaps it to fullscreen or half screen, respectively). What's even better for keyboard-centric users like myself are the keyboard shortcuts around those features:
    • Windows Key + Left/Right: Resizes the current window to half the size of the screen it's currently on, and snaps it to the left or right edge of the screen, respectively. Pressing one of these repeatedly will cycle the window through original size and snapped half size across different screens. These are fantastic for comparing documents side-by-side.
    • Windows Key + Up: Maximizes the current window.
    • Windows Key + Down: Restores the current window to it's previous size if maximized, otherwise minimizes it.
    • Windows Key + Shift + Left/Right: Switch the current window between screens. Really useful when you usually have your notebook dual screened with an extra monitor, and windows start on the wrong screen (ie hidden) when that extra monitor's not available :)
    For mobile warriors, these two are great:
    • Windows Key + X: Opens the Mobility Center, a really useful control panel that allows you to quickly change audio, power, wifi, display, sync and presentation settings.
    • Windows Key " P: Opens a panel that lets you quickly cycle between multiscreen/projector layouts.
    All the Windows 7 shortcuts are available on Microsoft's site, all the usual suspects are there, as well as some new ones not mentioned here.

    Posted via email from Matt's thoughts

    Monday, May 24, 2010

    Flash development workflow for traditional dev teams, Part 2

    Part 1 of this walkthrough ended off with a flash animation linked up to a main application class that would allow regular updates of that application. This time around we'll see how to access objects in your application added in Flash from the library. Once these are in place, your artists can go nuts customizing them, as long as the basic setup stays the same.

    The Menu and Button classes
    Let's set up a simple menu class that will allow us to continue to gameplay, or quit the animation. In Flashdevelop, create a new class in your package (right-click the package, Add->New Class) called Menu, specifying MovieClip as it's base class. Add two MovieClip members to it for the buttons, called playBtn and quitBtn:
    1 2 3 4 5 6 7 8 9 10 
    /**
    * Play button.
    */
    var playBtn:MovieClip;

    /**
    * Quit button.
    */
    var quitBtn:MovieClip;

    As with the App class, add basic singleton functionality, but this time initialize the singleton in the menu constructor:
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 
    /**
    * The Menu instance.
    */
    private static var instance:Menu;

    /**
    * Singleton accessor.
    */
    public static function getInstance():Menu
    {
    return instance;
    }

     /**
    * Creates a new Menu and sets the singleton pointer.
    */
    public function Menu()
    {
    instance = this;
    }

    Note I'm not clearing the singleton pointer at any stage, but it will be replaced the next time an instance is created, releasing the reference to the last object and allowing it to be garbage collected. This isn't a singleton in the purest sense, but it does allow us global access to the most current instance. Actionscript doesn't have destructors and I'm yet to find a replacement that I'm 100% happy with.

    Finally, add a function onButtonReleaseHandler to handle button presses, and implement the (extremely simple) menu logic:
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 
    /**
     * Handles an onRelease event.
     * @param source The MovieClip that triggered the onRelease event.
     */
    public function onButtonReleaseHandler(source:MovieClip):Void
    {
    switch(source) {
    case playBtn:
    App.getInstance().playGame();
    break;
    case quitBtn:
    fscommand ("quit");
    break;
    }
    }

    You'll also need to import the App class at the top of the file, using it's fully qualified name:
    1 
    import us.benic.matt.App;

    Note: I've switched on the actual source object here. Actionscript's switch statement is extremely flexible, unlike that in C++ and Java, any object can be used as a case, including strings.

    Here is the completed Menu class:
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 
    import us.benic.matt.App;

    /**
    * Menu for the Flash Workflow demonstration.
    * @author Matt Benic
    */
    class us.benic.matt.Menu extends MovieClip
    {
    /**
    * Play button.
    */
    var playBtn:MovieClip;

    /**
    * Quit button.
    */
    var quitBtn:MovieClip;

    /**
    * The Menu instance.
    */
    private static var instance:Menu;

    /**
    * Singleton accessor.
    */
    public static function getInstance():Menu
    {
    return instance;
    }

    /**
    * Creates a new Menu and sets the singleton pointer.
    */
    public function Menu()
    {
    instance = this;
    }

    /**
    * Handles an onRelease event.
    * @param source The MovieClip that triggered the onRelease event.
    */
    public function onButtonReleaseHandler(source:MovieClip):Void
    {
    switch(source) {
    case playBtn:
    App.getInstance().playGame();
    break;
    case quitBtn:
    fscommand ("quit");
    break;
    }
    }
    }

    Now we need a simpleMovieClip subclass called Button that will notify the menu when it is pressed. Flash does have it's own Button class, but it's really inflexible in that Button components can't use a custom Button subclass. The norm seems to be to just use a custom MovieClip subclass, and the functionality in the Flash Button class can easily be implemented anyway. For our purposes, a simple class that calls the Menu singleton's onButtonReleaseHandler when it is released will suffice:
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
    import us.benic.matt.Menu;

    /**
    * Button for the Flash Workflow demonstration.
    * @author Matt Benic
    */
    class us.benic.matt.Button extends MovieClip
    {
    /**
    * Creates a new button and sets it's onRelease to notify the Menu instance.
    */
    public function Button()
    {
    // Notify menu instance when released
    onRelease = function ():Void {
    Menu.getInstance().onButtonReleaseHandler(this);
    }
    }

    }

    Changes to the App class
    At this point very little needs to be added to the App class, it just needs the function the Menu class called, playGame. This will move the main clip to the Level frame:
    1 2 3 4 5 6 7 8 
    /**
    * Play the game.
    */
    public function playGame():Void
    {
    gotoAndStop("Level");
    }

    You may also want to remove the trace call in onEnterFrameHandler. It's demonstrative purpose has been served, and outputting text on every frame will just slow down the animation.

    The Menu and Button MovieClips
    Now we need the actual visual elements used for the menu. First create a new MovieClip in the library (Ctrl+L or Windows-Library to open the library, right click in the library->New Symbol...) called PlayButton. Set it's Type to MovieClip, check the Export for ActionScript checkbox, and specify it's Class as your fully qualified Button class's name (ie including the package):

     

    Clicking Ok to dismiss the Create New Symbol dialog causes Flash to open that symbol for editing. Use the flash tools to create a simple button. Eg add a Rectangle for a background, and a TextElement for the text to end up with something similar to this:
     
    Copy that symbol as a starting point for the Quit button, right click the symbol in the Library and select Duplicate. In the Duplicate Symbol dialog name the symbol QuitButton and as before enable Export for ActionScript and set it's class to your Button class:


    Again, dismissing the dialog with Ok opens the component on the stage. Edit it to say Quit instead of Play.

    Now create another new Symbol, this time calling it Menu and setting it's class to your Menu class:


    Drag the PlayButton symbol from the Library to the stage, and then do the same with the QuitButton. The result should look something like:

    The buttons now need to be named to match the members added to the Menu class earlier. To do this, click on a button on the stage to select it (not it's template control in the library), open the Properties window with Ctrl+F3 or Windows->Properties and replace the <instance name> text in the topmost textbox with the appropriate name. Your Play button should be called playBtn and your Quit button quitBtn:


    Putting it all together
    The last thing to do is add your newly created menu to the appropriate frame at the top level of the timeline. Return to the top level by clicking on Scene 1 above the stage. In the timeline, on the Objects layer, add new keyframes (right click->Insert Keyframe) below the Menu and Level labels (should be frames 10 and 20 respectively). Now with the new keyframe under Menu selected, drag the Menu symbol from the library onto the stage. Frames 10 to 20 on the Objects layer should now be grayed out to indicate content exists on those frames.

     

    If you now run the animation with Ctrl+Enter, the menu will be displayed, and clicking Play will take you to the Play frame (which is currently empty). The Quit button may appear to do nothing, but that is just because fscommand ("quit") has no effect when run from the Flash environment. When the generated .swf file is run by double clicking it in an explorer window, the effect is as expected.

    The full project so far is attached to the post. That's it for part 2, the next post will go into adding and manipulating objects programmatically.

    A note on variables linked to stage objects
    In this example, I used variables within a class who's only link to visual objects is their name. That's scary. Actionscript won't tell you if one of these objects is missing, it will just carry on as if nothing is wrong. You can't even expect an error or exception when you call a method on one of these nonexistent member objects. That's terrifying. Now you may be tempted to insist on creating all objects yourself, programmatically, but that's once again taking a certain amount of creative control (placement) away from the artists, which is kind of the whole point of Flash. The only way to be 100% sure objects you expect to be there are actually there is to check them against null and handle the missing case by throwing an exception/error or making the mistake known some other way.
    Related to this is the interesting little issue that numeric values in flash are represented by the Number class, as opposed to some kind of integral type, and must be properly initialized like any other object or will be null. This can catch you by surprise with some really wierd behavior, so if you start seeing NaN's in output, there's an uninitialized Number somewhere.

    Click here to download:
    WorkFlowProject.zip (10 KB)

    Posted via email from Matt's thoughts

    Displaying UTF8 from MySQL with PHP

    I had some issues displaying localized text in a PHP based internal tool recently, it turns out the solution was really simple-the MySql connection just needs to know that the connection must be UTF8. Probably no-brainer stuff for all you PHP-Ninjas.. news to me :)

    To do this with a PDO connection, just add an init command when you create the PDO command:

    1 2 3 
    $this->pdo = new PDO("mysql:host=".$this->host."; dbname=".$this->databaseName,
    $this->user, $this->password,
    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

    Thanks to Rob Allen for the tip, variation for other connection methods can be found on his blog.

    Posted via email from Matt's thoughts

    Friday, May 21, 2010

    Some useful regular expression patterns when porting code between languages

    I'm currently moving a lot of code from Java to Actionscript, and regex has been a lifesaver. Here are some of the patterns that proved invaluable, and that would work on most c-style languages. The Actionscript replacements are obviously specific to that language, but changing them for a different output language really would be trivial:

    Find non-parameter variable declarations and assignments
    Note: this will find returns as well, see the next pattern
    (\w+)(\s)(\w+)(;|\s=)

    Flash replacement:
    var$2$3:$1$4

    Will replace:
        int myInt;
        boolean myBool = true;
    With:
        var myInt:int;
        var myBool:boolean = true;   

    Find resulting returns in Flash
    This will match all the wonky return statements resulting from the previous replacement.
    var(\s)(\w+):return;

    Flash replacement:
    return$1$2;

    Will replace:
        var true:return;
    With:
        return true;

    Find parameter variable declarations
    (\w+)(\s)(\w+)(,|\))

    Flash replacement:
    $3:$1$4

    Will replace:
        public int foo(int intParam, boolean boolParam) {
    With:
        public int foo(intParam:int, boolParam:boolean) {

    Find function signatures with parameters in c/java format
    (\w+)(\s)(\w+\([\s?\w\s\w+,?]*\))(\s?\{)

    Flash replacement:
    function$2$3:$1$4

    Will replace:
        public int foo(int intParam, boolean boolParam) {
    With:
        public function foo(int intParam, boolean boolParam):int {


    Find function signatures with parameters in Actionscript format
    (\w+)(\s)(\w+\([\s?\w+:\w+,?]*\))(\s?\{)

    Flash replacement:
    function$2$3:$1$4

    Will replace:
        public int foo(intParam:int, boolParam:int) {
    With:
        public function foo(intParam:int, boolParam:int):int {

    Find numeric types
    (,|;|\(|\)|=|\s)(int|long|short|float|double|byte)(,|;|\(|\)|=|\s)

    Flash replacement:
    Number

    Will replace:
        var myInt:int;
        long myLong;
        float foo(byte bar) {
    With:
        var myInt:Number;
        Number myLong;
        Number foo(Number bar) {

    Posted via email from Matt's thoughts

    Sunday, May 16, 2010

    Untitled

     

    Copyright 2007 All Right Reserved. shine-on design by Nurudin Jauhari. and Published on Free Templates

    Afrigator