More progress with the Night Trap HTML5 port

You can find the first three parts of this series here:

I’m still making progress on this HTML5 port of Night Trap. The playable version hasn’t changed at all, but I’ve been consistently making changes to the Alpha branch, which currently has over 200 commits. I find myself working on it for a week, then to prevent burnout, taking a break and playing some video games. Life is all about balance, right?

Some road bumps

I ran into a bug with the video player which I couldn’t resolve for about one week before I finally realized it was due to a bug with the way Chrome handles loading of HTML5 video. It seems that video requests stay pending forever, if a request for the same video has been made more than once.

The worst part is that it’s a well known issue, and has been for nearly three years! It seems to get brushed under the rug and merged with another bug and marked as resolved.  The bug report illustrates it well:

Steps to reproduce the problem:
1. Load any page with HTML5 video
2. Open network tab
3. Check the requests and see one pending request to the video src

What is the expected behavior?
The pending request should end at some point.

What went wrong?
The request stay pending as long as the site is open. If multiple video are loaded, eventually all the pending request will block any network operation as all sockets are occupied with a these requests.

When I try to load the video in Firefox, Edge, IE, 11, or Safari, it works fine. Sadly, I may just have to have an alert that says it will not work in Chrome.

Refactoring

I’ve done a ton of refactoring since my last post. Most notably, I’ve stopped using constructor functions which require the new keyword and instead adopted Kyle Simpson’s OLOO (Objects Linking to Other Objects) pattern.  That Stack Overflow post illustrates why, well:

OLOO embraces the prototype chain as-is, without needing to layer on other (IMO confusing) semantics to get the linkage.

So, these two snippets have the EXACT same outcome, but get there differently.

Constructor Form:

function Foo() {}
Foo.prototype.y = 11;

function Bar() {}
Bar.prototype = Object.create(Foo.prototype);
Bar.prototype.z = 31;

var x = new Bar();
x.y + x.z;  // 42

OLOO Form:

var FooObj = { y: 11 };

var BarObj = Object.create(FooObj);
BarObj.z = 31;

var x = Object.create(BarObj);
x.y + x.z;  // 42

What I argue OLOO offers is that it’s much simpler to just express the objects and directly link them, than to indirectly link them through the constructor/new mechanisms. The latter pretends to be about classes but really is just a terrible syntax for expressing delegation (side note: so is ES6 class syntax!).

OLOO is just cutting out the middle-man.

What this really helped me with though, was the Object.observe function I said I was using the last post, to monitor events happening in the different rooms. How else would I update the video.src attribute as a new clip is about to begin when a user is watching an empty room?

Object.observe only works on objects and not functions, so I originally had a constructor function for each room, which I was then turning into an object so that it was observable. It was gross.

Changing timestamps

I was able to get in touch with Paul, the gentleman who created the SCAT tool that I use to export and dissect the videos, and he clarified quite a bit aobut the numbers I was dissecting. I was off by a bit:

One quick thing: In your Gamasutra post you got everything about the timecodes right except for the last number. It’s not milliseconds — it’s a frame number.The timecode is 30 frames per second, but the game runs at 15 fps, so all (?) of the frame numbers are even numbers.

Also, the file name of each video is a code in the format MMSSFFRB:

MM is minutes

SS is seconds

FF is frames

R is room number

B is what I call “branch number”. The game branches to different videos depending on which flags in the game have been set.

 

Because of this, I had to go back and relabel each of the clips in my excel spreadsheet. This was very time consuming, but in the end, allowed me to create a visual solution, which not only helped speed up the overall process, but also reduce the number of mistakes I would make.

To do this, I read the excel spreadsheet, then exported the data (by hand!) to Visio. I created my own little system to help visualize the flow of events for each room. Below is a system of events for the Bathroom in the first 5 minutes of the game.

visio snip

Starting from the left, the 180291 is the video file which should start playing at the 0:18 mark. When the clip has finished it displays a still image of the room.

Following that, at  the 0:37 mark, clip 352291 starts playing. The triangle shows that there is an opportunity to catch an auger here. If caught, proceed to clip 480291. If the user fails to catch the auger, proceed to the dark green box, clip 43192, which should start playing at 0:43. When that is done, display a still.

Not so bad, right?

Closing

I’ve still got a bit more to go, but not much. All of the clips are in place, and the videos transition seamlessly. I can also catch augers.

I still need to work out some bugs for edge cases, and need to revamp the UI to illustrate how many augers have been captured, and how many potentially could be captured. I’m hoping to have this done within the next 6 weeks, so I’ll be sure to update it here again!

-----------------------


subscribe-to-youtube

Leave a Reply