I exchanged emails with one of our long-standing clients yesterday. I worked with this individual more than two years ago in integrating the SCORM Engine with their LMS, and was aware that he was a solid developer. In this most recent exchange, I noticed that his job title had changed, and so I congratulated him on his promotion. This was his response:

“Yes, thanks Tim. I’m the PHB of the dev group these days. Should be no problem to get you that data. I’ll try running it later this afternoon.”

This is such a perfect response, and makes me want to hire this guy away from our client (which we won’t be doing, mind you.) To me, this conveys so many things… confidence in that he doesn’t have to say how good he is, humility in that he can already mock himself.

Note to our prospective hires and current employees: Be so good that you don’t have to tell me, but not so proud you can’t make a little fun of yourself.

To that end, we make mistakes with our software sometimes. Given the overall quality of the software, we’re willing to admit them when they come along. I ran into one of those issues this morning, and I thought I’d share it in the context of this post. For you non-technical readers, this is the point at which I delve into technical minutiae, feel free to evacuate at any time…

One of the core integration layer functions in the SCORM Engine allows us to pass detailed data regarding a learner’s progress to the host LMS; it’s called RollupRegistration. Like other integration layer functions, it can be implemented however the client likes, but it’s almost always implemented via a stored procedure we provide to our clients. In this stored procedure, we collect the current state of two values: success_status and completion_status. In this default procedure, we used the values 0, 1, & 2 to represent unknown, incomplete, and complete (in the case of completion_status). There’s nothing wrong with this except that we have values that correspond in our Logic.Types classes… and they correspond poorly. In the Types definition, the enumerated values are 1, 2, & 3… yup, off by one.

This mistake (or lack of clarity) on our part hadn’t reared its head to this point. 2007.1 has been in circulation for more than a year, and no one had attempted to establish correspondence with these types in the code… Well, today, we discovered this inconsistency with a client who was confused by it (rightly).

Our answer? “Yup, you’re right… that’s confusing. No doubt.” We offered our apologies.

So, going forward, what’s the answer? Our recent release of the SCORM Engine, 2008.1, happens to have addressed this elegantly in our ScormEngineManager class. The ScormEngineManager is an enhanced approach to interacting with the SCORM Engine from the host LMS… And worthy of its own post another time.

On this issue, though, we’ve handled this by pushing the host LMS interaction out of the stored procedure layer and into the code, where we are handling the types properly and providing the already enumerated values to the host LMS like this:

public override void RollupRegistration(ExternalRegistrationId externalReg, ExternalConfiguration externalConfig)
{
RegistrationSummary regSummary = ScormEngineManager.GetRegistrationSummary(externalReg, externalConfig);

// Completion is an enumeration: UNKNOWN, INCOMPLETE, COMPLETE
Completion completionStatus = regSummary.CompletionStatus;

// Success is an enumeration: UNKNOWN, PASSED, FAILED
Success successStatus = regSummary.SuccessStatus;

// Total time in seconds tracked by ScormEngine (not as reported by course)
long totalTime = regSummary.TotalSecondsTracked;

// Score is unknown until explicitly reported by the course
bool scoreIsKnown = regSummary.ScoreIsKnown;
// Score is from -100.0 to +100.0
double score = regSummary.Score;

// TODO: VanillaCo:
// RollupRegistration is run whenever the course pushes data back to the ScormEngine.
// You should extend this method to update your LMS from the values above.

}

Our hope is that this option is far clearer and yet every bit as powerful. If it isn’t, then every prior option is still available to the host LMS. Further, we hope that our candor conveys our competence.

Tim is the chief innovation and product officer with our parent company LTG, though he used to be CEO here at Rustici Software. If you’re looking for a plainspoken answer to a standards-based question, or to just play an inane game, Tim is your person.