jQuery Extraction

Relying on jQuery for DOM selection and modification still doesn’t sit right with me – It makes my feel dirty and lazy. But was incredibly convenient during the initial build of the gallery app since it allowed me to quickly “sketch” out functionality.

I’m using this post to document the changes required as I refactor jQuery out of my application let some decent DOM code in. I’m adding new utility functions to my DOMUtils file.

Quick lessons learned – I didn’t prefix my jQuery variables in any special way. Looking back I need to do this next time. Something simple like “_$varName” would have been handy. However, it’s trivial to search the project for $’s to find library calls.

Element Selection

Generally, I’m selecting elements with their ID, so this is just a simple switch to document.getElementByID(). I needed to go back up and update my RxJS observers, because these were listening to jqEl[0] to get the HTML element rather than the jQuery object. All of my JavaScript animations are handled by GSAP which takes either HTML elements or jQuery objects as arguments.

More complicated sections can be handled by the element.querySelector or element.querySelectorAll methods. Note that the latter returns a node list (array) of all matched elements. If know there is only one, you just need the first element.

So this:

_mainSearchInputEl = $('.grid__header-search input');


_mainSearchInputEl = document.querySelector('.grid__header-search > input');

Be aware: there are differences in the older get* functions and the new query* functions – both in what kind of node list they return and performance.

Viewport metrics

Whenever the window is resized or scrolled, I’m firing off an event (to a command) with the new dimensions. This is used to realign the header and footer to the new size.

Currently, I’m using this:

_currentViewPortSize = {width: $(window).width(), height: $(window).height()};

But this is just as simple:

_currentViewPortSize = {width: window.innerWidth, height: window.innerHeight};

Because of the structured needed to create the drawer for the mobile view, I’m measuring scrollTop and scrollLeft on the div that contains the gallery grid, not the body element:

var left = $(_mainScrollEl).scrollLeft(),
    top =  $(_mainScrollEl).scrollTop();


var left = _mainScrollEl.scrollLeft,
    top = _mainScrollEl.scrollTop;

Element Sizes

Rather than using $el.height() you can use el.clientHeight. el.offsetHeight returns he height including padding, borders and scroll bars.

Setting HTML


$el.html('<p>some html</p>');


htmlEl.innerHTML = '<p>some html</p>';

Adding and removing classes

http://youmightnotneedjquery.com/ provides functions for adding and removing classes. I added this block to my DOMUtils functions:

hasClass: function(el, className) {
  if (el.classList) {
  } else {
    new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);

addClass: function(el, className) {
  if (el.classList) {
  } else {
    el.className += ' ' + className;

removeClass: function(el, className) {
  if (el.classList) {
  } else {
    el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');

toggleClass: function(el, className) {
  if(this.hasClass(el, className)) {
    this.removeClass(el, className);
  } else {
    this.addClass(el, className);

 Adding and Removing DOM Nodes

All of the nodes that I’m adding to the DOM are the results of an HTML template from Underscore.

Starting with this …

var tagel = $(_tagTemplate({tag: tag}));

The first problem is that the result from the template is an HTML string, not an element. The string must be converted to an HTML element before it can be appended to the DOM.

The DOMParser method looks like a great solution, but in testing, I found that it has issues with IE9. I found a nice little technique on a StackOverFlow tread that I turned in to a function:

function HTMLStrToNode(str) {
  var temp = document.createElement('div');
  temp.innerHTML = str;
  return temp.firstChild;

And this now works:

var taghtml = _tagTemplate({tag: tag}),
    tagnode = HTMLStrToNode(taghtml);


Comparatively, node removal is straightforward


 Wrapping an element in another

Pretty easy in jQuery:

$(el).wrapInner('<div class="floatimage__wrapper" />');

To do it without jQuery, we leverage the HTMLStrToNode function above and come up with:

wrapElement: function(wrapperStr, el) {
  var wrapperEl = DOMUtils.HTMLStrToNode(wrapperStr),
      elParent = el.parentNode;
  return wrapperEl;

Usage is easy:

DOMUtils.wrapElement('<div class="floatimage__wrapper" />', el);

Finding the closest match

jquery’s closest() function comes in really handy. I found a good native solution on this StackOverFlow thread that includes vendor prefixes since the matches() function is still relatively new.




Moving to a JavaScript Application Architecture


From 2003 to 2011 I became a pretty decent ActionScript developer. Starting with single frame movies then to fully structured MVC applications.

With my team, I’d spent a lot of time looking at two powerful frameworks   Cairngorm and RobotLegs. I really liked RobotLegs, and being my first introduction to dependency injection – was really intrigued.

I ended up writing my own framework based on RobotLegs called Nori. It was pretty slick – mediators, contexts, mapping, Signals, views and tons of interfaces (any DI system has). I only used it for a few projects before a career change and a transition to consulting and design / prototyping.

Fast forward a few years and I’m trying to break into coding again with JavaScript. I’d done a fair bit of JS dev in 2000-3, but really hadn’t paid much attention to it since then.

Holy shit!

I have a lot to learn.

Writing my own …

Over the past two years, I’ve spent (too much) time looking for a starting point – Angular, React, ExtJS, Ember, Dojo, etc. I didn’t have a project so I just cycled around in this framework limbo.

Then I found a project. Time to get realz …

My team needed a gallery to showcase our work and provide simple case studies to prospective clients. I’d build something similar to this before, in haXe, that was based on Microsoft’s Pivot experiment. I decided to recreate it but with more of a Pinterest influence.

The front end would be a fluid, responsive JavaScript application that also worked on our primary browser, IE9. It would also scale to mobile phones and be accessible though our corporate GOOD app.

The back end would use SharePoint lists. SharePoint is a decent backend for database challenged teams in big companies and it also comes with a “free” content maintenance system.

I couldn’t waste time researching frameworks anymore, and I had a strong desire to actually learn the language, so I decided to writing my own. My basic task list is/was:

  1. How the hell so I set this up and what build system do I use?
  2. How do I architect this thing? How can I best create class/subclasses and implement the command pattern?
  3. How do I create a global event system (pub/sub) system with command mapping?
  4. What’s cutting edge? FRP, Reactive programming and RxJS!

The project started in November as a part-time/between-other-work project. I’m wrapping up the front end now with the back end still to go. My purpose for this post, is to document my thought process and hopefully solicit some feedback on my approach.

Here’s a break down of what I’ve learned and done over the past few months. I know that it’s nearly useless without screen shots (source code on GitHub) but I’m working on that.

The project source is available on GitHub.

Project setup and build options

No respecting front-end dev writes HTML or CSS anymore. Attending Meet Ups around Charlotte, I saw how people were using Sass and Jade tempting. I have give the credit to the talented Tessa Harmon for introducing these to me at a Charlotte Front-End Developers meeting.

Both of these preprocessors resonated with me as being a much more efficient way to produce CSS and HTML – variables and mixins, oh my! The biggest challenge is working with these in a typically Windows based corporate environment. Lucky, I was able to get a Mac at work. I’ve been developing prototypes with Jade and Sass for a few years at this point with the excellent CodeKit app. On the Windows side, Prepros looks like a great alternative.

I’ve found the indented syntax style of Sass to be the best fit for me. Not only does it go very well with the style of Jade, it’s saves a ton of typing. The fewer braces and semicolons you need to worry about, the better.

I’d seen Grunt but hadn’t used it. Reading articles. like this one from Chris Coyier, really simplified the concepts. It was pretty easy to get it all up and running and enabled a much simpler build process than I was able to achieve with CodeKit. So I have SASS + Jade processing, CSS linting, CSS minification, JSLinting, JS concatenation + minification and live reload all working well.

Being able to work with JavaScript in a modular way, split across many files, is a critical workflow feature. I was used to splitting up my classes in to single files and I was able to preserve that with this process thanks to these tools.

Other libraries

I went back and forth on jQuery. On one hand, the efficiencies gained by utilizing it’s selector and DOM manipulation engines cannot be underestimated, but on the other – I wanted to learn how to do this on my own. In the end, I decided to use it, it just saves too much time.

Having to support IE9 meant that CSS animations were not possible. While developing in Flash, I relied heavily on the awesome GreenSock animation platform and with a JS version available, it was a no-brainer.

I’d struggled a bit with the view styling. Do animations count as “style” (CSS) or functionality (code)? I didn’t have a choice in this situation, but now I’m firmly on the side of code – the control and possibilities presented by JS animation libraries over CSS is too much to ignore.

To handle HTML templating, I compared Mustache.js and Underscore.js. Mustache provided a nice single purpose solution, but Underscore did all I needed it to plus provided a ton of additional functionality that I might need later on. So I went with it.

What’s next

  • Clean up my CSS classes by implementing the BEM system
  • Optimize my Grunt file.
  • Learn more about git and GitHub

OOP / classes, subclasses / structure / commands

I came from a strongly classed development environment. So naturally I wanted to recreate that in JS. But JS doesn’t do classes but it does do objects. I couldn’t use ES6 because of IE9.

Finding way to create namespaces was key and paired with the revealing module pattern, made for a great solution. I implemented the approach Kenneth Truyers documented for my application.

I do have a few global objects, for utility classes, but generally my application structure is:

All of the major parts of the app (bold, above) are constructed like this:

APP.AppController = function () {

// private var
// private methods

return {
// public api

These are effectively singletons.


Both the Cairngorm and RobotLegs frameworks handled the heavy lifting of controller duties in commands. The separation of core functionality outside of the controller made extending the app very simple. Command classes are single responsibility, small and have access to all of the actors in the application.

My commands have a single entry point, an execute() method, that takes one object parameter for passing in data. In my framework, commands are only invoked in response to an event. For every command there is a corresponding event that is published from somewhere in the application. This is discussed in the Events section below.

In my current implementation, they’re synchronous, but I can see needing asynchronous in the future as I’m loading data from sources.

Pattern for subclasses – commands and subviews

To implement commands and sub views, I had to seek an alternate class/object creation pattern. Creating multiple instances of objects with the module pattern isn’t entirely straightforward. Although there are several methods of extending new objects with the properties of an existing object (jQuery’s extend(), etc.), the private methods of the closure aren’t readily accessible in the subclasses. Composition would be been a way to handle this, but I choose a different approach.

I discovered Eric Elliot’s Fluent JS talk on prototypal OO. His StampIt pattern was just what I was after, but I wanted a more accessible approach. I stumbled on an article by Jake Lucas which described a method just like Eric’s, but broke it down so that it was easier for a noob, like myself, to understand.

Using commands as an example, I have this as the abstract command class

APP.AppController.AbstractCommand = {
  state: {},

  methods: {

    app: APP,
    appController: APP.AppController,
    appModel: APP.AppModel,
    appView: APP.AppView,
    eventDispatcher: APP.EventDispatcher,

    execute: function(data) {
      console.log('Abstract command executing with data: '+data);

  closures: []

And then I create a new command instance by using a factory method to create a new object and then override the execute method of the new command

APP.AppController.ItemSelectCommand = APP.AppController.createCommand(APP.AppController.AbstractCommand);
APP.AppController.ItemSelectCommand.execute = function(data) {
// new implementation


A few disadvantages for this approach:

  1. Alternate coding style compared to the modules
  2. Lots of boilerplate to create the objects

What’s next

  • I’m not entirely satisfied with my approach on commands and subviews. I want to look at other ways to subclass modules.
  • Look at ES6 transpilers so that I can leverage these features now.

Event system (pub/sub)

A publish/subscribe system is key for maintaining loose coupling between components of the application. For my app, I wanted to create a global system similar to the EventDispatcher in AS3.

When I last coded AS3, I was heavily using Robert Penner’s Signals implementation over native events. His approach won me over especially consider the fragility of the “magic strings” naming of event types. They were easier to work with and implement than native events. There is a JS port of it that I initially used, but later decided that it wasn’t worth the additional overhead.

Looking to simplify my approach, I found a great example from Michaël Duerinckx on his blog. It demonstrated exactly what I needed and was straight forward. I created an object APP.Events.Events that stored all of my event strings as constants.

Generally, I’m using events to invoke an instance of a command class – there is 1:1 relationship – the APP.Events.ITEM_SELECT event has a corresponding APP.Controller.Command.ItemSelectCommand associated with it. This mapping is handled by an EventCommandMap class.

I had implemented a command mapping solution in my Nori AS3 framework that was based on Joel Hook’s Signal Command Map for RobotLegs and Omar Gonzalez’s for PureMVC. I greatly simplified my original approach and with some helpful hints from a friend, had it working with my EventDispatcher.

In the controller, commands are mapped like this:

mapCommand(APP.Events.ITEM_SELECT, APP.AppController.ItemSelectCommand);

And trigged like this (‘id’ being wrapped in an object and passed to the command’s execute() method):

_eventDispatcher.publish(APP.Events.ITEM_SELECT, id);

The command map handles determining what command class should be instantiated and executed.

What’s next


Future State: FRP, Reactive programming and RxJS

Functional programming is the current hotness in JavaScript. Honestly FRP is still kind of a dark art to me, but it’s clearing up thanks to excellent articles explaining the concepts, libraries like RxJS from Microsoft and tutorials from Netflix.

While I’m not ready to architect a reactive application, I am using Array methods forEach, map, filter, etc. pretty heavily. There are some performance issues with these, but it’s completely worth it for code readability. I’m only dealing with up to hundreds of objects so I’m not likely to see these in my current implementation. But it does make filtering my data more sane:

function filterProperties() {
  _filterProperties.forEach(function(filter) {
    var props = [];
    _data.forEach(function(item) {
      if(item.hasOwnProperty(filter.filter)) {
        var itemPropVal = item[filter.filter];
        if(typeof itemPropVal === 'string') {
        } else if(itemPropVal instanceof Array) {
          props = props.concat(itemPropVal);
    filter.data = ArrayUtils.unique(props).sort();
    filter.menuData = getDataFormattedForMenu(filter.data);

I’ve implemented RxJS for some events – primarily execution environment: browser, mouse, touch, etc. The pure simplicity of this approach is really cool. Just cool.

_itemOverStream = Rx.Observable.fromEvent(_containerEl[0], 'mouseover')
  .subscribe(function (id) {

I need to delve deeper in to this, replacing my events and turning my classes into RxJS emitters.

Wrap up

So that’s been my learning path for the past few months. I’ve omitted a few dead-ends and research for brevity (ha!). I still have the back end of this to work though, but I’ve a similar setup at another company so it shouldn’t be that difficult.

I’m going to write a few more posts on various aspects of this – my view components and looking at AMD/CommonJs or WebPack.

If you made it this far, please comment! I’m seeking advice on my approach and rationale.

Thanks for reading.

Smart WBT Players

Just a Saturday morning thought –

Smart WBTs. I’ve always liked the idea.

A long time ago, I wrote several Flash based WBT presentation tools – content was externalized in my own XML schema, played in my nice player. These things are pretty common. Even in modern HTML5 / JavaScript land, a nice player that can present any type of content is a big efficiency. I was taking apart the Articulate Storyline 2 Player JavaScript the other day and it does the same thing. It’s fun to see how other developers tackled the problem.

But one idea I had (around 2005) was: What if the player was smart enough to not only present the content, but understand what the learner was trying to do? What if it’s a typical learner that’s mashing Next as quickly as possible to get to the test and the system noticed this (based on time per page) and prompted you to just go to the test? What if the learner sat on a question or tried 5 times and couldn’t get it right? It would notice and ask if you’d like to go back to that part of the content for a quick review?

I had it all coded up and working perfectly – but it’s hard to get business partners to buy into that when deadlines come. I couldn’t get anyone interested in the idea we just moved on without it. But I never forgot it.

I did bring the idea back with the Social Sim “engine” I built, but never completed my vision for it.

This morning I saw the Synaptic JavaScript library on GitHub. A JavaScript based neural frakin’ network. How cool would that be integrated into a WBT player? If the WBT learned how you interacted with it and altered it’s own behavior.

That would indeed be pretty cool.

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


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);
				_bindingMap[propName] = setter;
			// if the signal doesn't have any listeners yet, set it up
			if(onPropertyChangeSignal.numListeners < 1)

		 * Remove the bindings for a property
		public function unbind(propName:String):void
				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
				var vo:PropertyChangedVO = new PropertyChangedVO(name, value, oldvalue);

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

		 * Construtor
		public function BindableModel() 


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.