Uniwha?

A few years ago, I remember seeing the term “deviner” or some other novel combination of the words “developer” and “designer.” More recently, the term is “unicorn.” It’s a mythical person who can “do it all” – UX, design and development (or maybe a combination of two). I’ve also heard it called a “purple squirrel.” I like that one better.

Call me naive, but until I first heard the discussion around it, I assumed it was a common skill, because I’d been doing it my whole career! That’s just something that I was supposed to do, because like most e-learning “developers,” there was no one else to do it! I was the only developer on the project and it’d just be *insane* for an e-learning team to have a dedicated graphics guy when clip art worked just fine. (But I must give lots of credit to the two great teammates: Glenn and Ben – there were great illustrators who helped me out a lot when I needed it.)

As I embark on my new career in the front-end design/development world, I hope my history comes off as a strong point. I feel like I’m starting at the bottom in a lot of ways, but I’ve done a lot and have a solid ability to learn quickly.

From a personal advertising perspective, what I really lack is a good set of case studies for the projects that I’ve worked on. Being in the corporate world, I don’t have a good set of screen shots to show off on Dribbble or an amount of source code on GitHub to share. The personal projects that I worked on for years were focused on new features or experimentation for work projects – I’d considered them property of my employer so I didn’t put them out into the community.

I’m changing my mind on that last bit. I’ve uploaded a few old AS3 libraries and I have plans to upload a few more. I’m glad to finally share these with the community and look forward to digging up more to share.

VIM … !

Recently deciding that I needed to keep my mushy brain in shape, I’ve decided to forgo sudoku puzzles and learn: Vim. That aged text editor of Unix lore is quite powerful, or so I hear. I’ve met a local dev who is a true wizard at it – his fingers glide across the keyboard as CSS magically appears in the inky black of the terminal windows. And I can do that. I’ve learned just enough to bash out a few short paragraphs and it /is/ pretty quick.

I’m on level 7 of  Vim Adventures right now, and it’s the best way I’ve run across to learn and practice the commands. Cheat sheets line my cubical walls and my Evernote note grows daily. I’ll be good any this in a few weeks – I have to be since I’ve limited all of my coding to Vim. No more Sublime Text for me – not even Vintage mode. :w!

The not so curious case of the “Click Next Fatigue”

As someone who annually sufferers through painful elearning courses, I thought that I’d make a list to help my punishers, who are surely ignorant of the pain they’re causing. My “click next button finger” is falling off at this point!

In a past life, I used to build courses like this. I’m sure that I’ve inflicted unmeasurable “click next fatigue” on countless employees/associates/teammates/whatever. But, I like to believe that I was aware of good user experience and always fought for what was best for the user.

So here’s my list, feel free to leave your thoughts or additions in the comments.

Some helpful guidelines for keeping the victim of an elearning course happy:

1. Golden Rule: Treat me like a responsible, honest adult
2. Let me test out
3. Never disable the back or next buttons
4. Don’t make me listen for the page to be read out loud before I can click next.
5. Don’t use sound! But if you must, make it optional.
6. Do not require me to click all of the buttons/links/etc. before I can click next.
7. If all of the content will fit on the page, put it there. Don’t force me through unnecessary interactions in the sake of “making it interactive.”
8. Don’t cover the next button I need to click on next with an oversized box from another button.
9. Be honest about how long the course will take to complete.
10. Developers: Don’t let the SMEs tell you how to build the interaction. That’s YOUR job.
11. Designers: Don’t let the SMEs write the content. That’s YOUR job.
12. Keep me entertained with novel interactions. When every course that you’ve created for the past 3 years uses the same interactions – you’re doing it wrong.
13. Make the graphics pretty. Pick stock art from at least the last decade. Why is that business executive on a Motorola flip phone (or worse!)?
14. Never copy a Microsoft UI style.
15. Never copy an Apple UI style.
16. When I miss a question, let me know what the correct answer was.
17. After you’ve shown me the correct answer, don’t make me change my answer and then resubmit the question.
18. The built-in knowledge check types in practically ALL elearning authoring tools suck. Don’t use them.
19. When you have mandatory popups on a page, don’t hide mandatory clicks in there.
20. Show my progress and let me know how much longer I’ll be stuck in here.
21. Ask for my opinion with at least one free form text field in a level 1 survey.

Clean Code

I’ve been programming for along time now. My first program was probably back in 5th or 6th grade when I had to get checked off on basic computer skills in elementary school. I think they were pretty progressive for 1989. It would have been as BASIC program on an Apple II and gone something like this:

10 PRINT "Hello!"
20 GOTO 10

I got into this seriously in 8th grade programming games in BASIC on the TRS-80s in the typing lab. Then moved though various lanauges (QuickBasic, Pascal, C++, Lingo, Javascript, ActionScript 0, 1 and 2) before landing where I currently am: an ActionScript 3 developer working with the Flash Platform.

Throughout all of this, I really just concentrated on syntax of the language and getting stuff done. But two years ago, I started using design patterns and looking beyond the code into the technique 9or craft) of coding. And in the past few weeks, I’ve really started thinking seriously about how bad I code and how want to code. In my freshman year of college, my first English assignment was a required paper titled: “My Writing Sucks and And Why.” Now I’m doing this mentally.

I picked up a copy of the excellent Clean Code by Robert C. Martin and have just started to read it. A few weeks from now, I fully intent to be a better programmer and look back on the code that I’ll write today and think: “What the hell was I thinking?!”

Note, I’d consider ActionScript 0 to be what ever the hell we were writing for frame scripts in Flash 4. That was painful.

On using SWCs …

So I’m pretty late to this party. Up until now, I’ve been using 2 methods for sharing assets on my Flash projects:

    1. An assets proxy that a coworker of mine wrote.
    2. Nothing. Ok this doesn’t count.

The assets proxy loads a SWF file and view elements can pull assets from it like

assetsProxy["linkageID"];

Can it get easier? This does a great job of separating content from code in a reusable way and keeping the main app SWF small, however, you have to wait for the assets SWF to load. And write a lot of boilerplate code to set it up, start it loading and listening/responding to the loaded event.

So what’s another way? Enter the SWC. ActiveTuts has a great tutorial on how to create and use them.

My scenario: I have a collection of learning interactions that have a lot of little clips in the libraries. Many of these are the same across interactions and really should be shared in some way. A lot of them also have class files associated with them since they need a little more functionality than a basis extended Sprite.

These classes were mixed in with my project classes and this created a special case with using a SWC: You have to set it up so that the classes are imported from the SWC instead of the class file in the project folder. It took me a few hours to figure this out – classes specific to assets in your SWC file must not be in the class path of the project file.

So I created a separate directory for all classes needed for my assets SWC and it all started working. For now, I just dumped it all in the lib folder because I can’t think of a better place. The project classes are safely in the src folder, nice and separate.

With this SWC linked in FDT and the SWC added to the library path of the FLA this is a quick snip of my code:

package screen
{
	// this class is in the SWC, need to import
	import assets.view.WheelList.WheelListItemSprite;

	// stuff

	private function drawList():void
	{
		// stuff
		var item:WheelListItemSprite = new WheelListItemSprite();
		// stuff
	}
}

The library of my interaction FLA went from over 10 clips to none. And they’re all separated and ready for reuse in other interactions.

Nori Bindable Model

Here’s the super simple bindable model class that I’ve created for Nori. I’ve never actually developed a project with Flex, but I really like the idea behind it’s data binding implementation. I tried to create something similar for Flash/AS3.

package com.nudoru.nori.model 
{
	import flash.utils.Dictionary;
	import org.osflash.signals.Signal;
	import com.nudoru.nori.model.bind.PropertyChangedVO;

	/**
	 * Adds data binding functionality to the abstract model
	 * Usage:
	 * 
	 * 	To set up a property to be bound:
	 * 		public function set bind_prop(value:String):void
	 * 		{
	 * 			bind_prop_field = value;
	 * 			dispatchPropertyChange("bind_prop", bind_prop_field [, old_value]);		// this is the important line
	 * 		}
	 * 	
	 * 	To bind the property:
	 * 		bindable_model.bindProperty("bind_prop", binding_listener_function);	
	 * 		bindable_model.bindtest = "hello!";
	 * 	
	 * 	The binding_listener_function may any function and as long as it takes the new property value as an argument
	 * 
	 * This class should be subclassed to create more enhanced functionality.
	 */
	public class BindableModel extends AbstractModel implements IBindableModel
	{	

		/**
		 * Signal for simple binding
		 */
		protected var _onPropertyChangeSignal	:Signal = new Signal(PropertyChangedVO);

		/**
		 * Map of the bindings
		 */
		protected var _bindingMap				:Dictionary = new Dictionary(true);

		public function get onPropertyChangeSignal():Signal
		{
			return _onPropertyChangeSignal;
		}

		/**
		 * Binds a function to a property name
		 * @param propName Name of the property
		 * @param setter Function to call when the property changes. Must take the property's value as a param
		 * @param overwrite Will remove existing setters and assign a new one
		 */
		public function bindProperty(propName:String, setter:Function, overwrite:Boolean = false):void
		{
			if(overwrite) unbind(propName);
			
			if(!isPropertyBound(propName))
			{
				_bindingMap[propName] = setter;
			}
			// if the signal doesn't have any listeners yet, set it up
			if(onPropertyChangeSignal.numListeners < 1)
			{
				onPropertyChangeSignal.add(handlePropertyChanged);
			}
		}

		/**
		 * Remove the bindings for a property
		 */
		public function unbind(propName:String):void
		{
			if(isPropertyBound(propName))
			{
				delete _bindingMap[propName];
			}
		}

		/**
		 * Determins if the property is bound to anything
		 */
		protected function isPropertyBound(propName:String):Boolean
		{
			return (_bindingMap[propName]) ? true : false;
		}

		/**
		 * Called from a setter to notify bindings of a change to the value
		 */
		protected function dispatchPropertyChange(name:String, value:*, oldvalue:*=undefined):void
		{
			if(isPropertyBound(name))
			{
				var vo:PropertyChangedVO = new PropertyChangedVO(name, value, oldvalue);
				onPropertyChangeSignal.dispatch(vo);	
			}
			
		}

		/**
		 * Listener for the onPropertyChangeSignal signal and notifys bound setter
		 */
		protected function handlePropertyChanged(changeObject:PropertyChangedVO):void
		{
			if(isPropertyBound(changeObject.name))
			{
				var func:Function = _bindingMap[changeObject.name]as Function;
				func.call(this, changeObject.value);
			}
		}

		/**
		 * Construtor
		 */
		public function BindableModel() 
		{
			super();
		}

	}
}

Nori Framework

Lately, I’ve been into learning new things – one of them has been to find out what IOC (Inversion of Control) and DI (Dependency Injection) is all about. As a working project for this, I’ve taken the Cairngorm based framework that I created at work and started to do a major rewrite around IOC. I’m basing most of it on Robotlegs.
Not much to say right now, but I’ll toss up information about it and informative links that I’ve found soon.

Social sim. engine, Part 3 – Progress!

Thanks to a wonderful confluence of events and great timing, I’m able to turn this in to a project for work – there are a handful of solutions in the queue that can use this starting next month – so I’m working full time on it over the month of Feburay.

After a few days, this is what I’ve got: click. It’s a pretty straight forward scenario, but it demonstrates all of the features that I’ve got working.

I’ve been able to keep up with my “play” metaphor and it’s working out great by providing many more opportunities for gaming rather than typical multiple choice branching.

One of the projects brought up a requirement that started a new idea – an inventory system. All I really need to do is allow the learner to reference a screen shot to get some data, but I think it can be taken farther. But more on that later.

Designing learning interactions that no one wants to use

Well, done that!

Multiple Sliders

I had a requirement to for an interaction for learners to rate up to six criteria for a given scenario. I thought of 3 different ways to do it: 1) that, 2) text entry and 3) drop down menus.

Text entry was the first idea. But that’s commonplace – can you call that an idea? I had a slider component that I’d coded for a project a year ago that was never used – so why not? The result, while interesting, fails miserably on many levels with visual clutter being the main one. I still think that it would work for up to 3 or 4 items, but it just doesn’t for this many.

So go back and do something more simple – with drop downs. I’d coded the slider to use the same basic properties as the native AS3 ones so, there wasn’t that much more effort to make this change. It’s much easier for the learner to use and saves a lot of space – so much that the scenario can be on the same screen as the question.