Wednesday, July 26, 2017

Hugo Game II - Behind the Scenes

When a computer game runs, a lot of stuff is, of course, going on under the hood. Previously, I explained how the animation for the Jungledyret Hugo PC game was done, from rough hand-drawn sketches to the final illusion that Hugo can roam around freely inside the game's environment.

In this post I will focus on the backgrounds and the technical and artistic aspects which are thoroughly intertwined.

But before we delve into the geeky details, you may want to check out this clip, which I found on an old VHS tape. It is from the Danish TV show "Troldspejlet" (Magic Mirror) on DR's channel 1, and aired in the fall of 1995 when the Hugo PC game had just been completed. It offers a glimpse behind the scenes and a quick overview of the production process. The video is all in Danish but has English subs.

In a game like this, a new image is being assembled from all the different resources up to 60 times per second (depending on the power of the computer). As Hugo changes his position, and the "camera" moves with him, the right portion of the background must be shown on the screen, with all the different characters and objects placed correctly upon it.

Hugo's movements are of course primarily affected by user input, i.e. whether the player makes him run, jump or whatever. In addition, secondary (passive) animation snippets are invoked by various events, either when Hugo comes into contact with other "sprites" (movable objects) or when he touches trigger points, or events, located on the background. The setup below shows trigger points for stumbling, losing balance, hanging and splashing into the water. In the actual game there are of course many more types of events.

Section of event bitmap, level 3, Jungledyret Hugo PC game, 1995.

In a side-scrolling platform game, the entertainment is closely connected to the environment that the player/main character passes through, so planning the gameplay and designing the background was done simultaneously. Finally, all sketches and scribbles were touched up and combined into one big background, comprising the entire level. The whole thing is like one long movie shot, except for a couple of "cuts" where the screen fades to black and Hugo re-emerges in a different place. In this example that happens when he enters the fireplace and when he exits the chimney onto the roof.

These are the original pencil sketches of the background for level 3.

The background layout was then scanned, scaled down to match the low resolution of the game and fed into the game engine. A key element of this process was the division of the bitmap into blocks of 8 x 8 pixels. This served a number of purposes.

As Hugo and all the other sprites move around, the program must do a check for every screen update to determine if anything on the background affects each sprite. If this were to be done for every pixel in the background, it would soon bring an old 486 PC to its knees. Instead, by maintaining a table representing the background as 8 x 8 blocks, only 1/64th the number of checks need to be made.

First, being a "platform game," the program must check for "platforms," i.e. whether or not Hugo can stand in a given location. By simply testing the three or four blocks immediately beneath Hugo's feet it can quickly detect if he is on solid ground.

Below is a graphic representation of the "platform map" for level 3 (split into six parts for better viewing here on Blogger). As you can see, some of the 8 x 8 pixel blocks have a red line in them, specifying the exact level inside the block where Hugo can rest. Long before compiling the final program, the visual map's information was of course converted to simple data in a table.

At run-time, a platform level indicated by a red line is then matched up with a similar indication on each frame of the animation.

Secondly, a map of background-related events was drawn up, with trigger points indicating where Hugo would stumble, lose his balance, climb up or down, grab a fruit, swing in a liana or rope, hang and swing by the arms on a horizontal liana or rope, slide on a slope, fall into the water etc.

Trigger points are also used to limit his movements. Note that, as a safety measure, there are "stop events" all around the edges of the background to prevent him from leaving the screen. In addition to all the standard events, similar indicators are used to trigger special events such as waking up a hippopotamus or a snake in level 1, or roll a barrel or activate a robot or a girl in level 3.

If you look closely, you can see a couple of blue pixels in the bottom-left corner of every "event block." They represent a number in binary format, each corresponding to a certain event.

A third reason for the division of the backgrounds into 8 x 8 pixel blocks was optimizing for memory usage. Since the backgrounds were much too big for the available memory, the color bitmap itself had to be thoroughly compressed. That was done by re-using 8 x 8 pixel blocks of graphics as much as possible all over the place and, again, using a table to keep track of which blocks belonged where.

The wallpaper in the kids' room on the background below is only one very visible usage of these tiles. In fact, it is done everywhere on all the backgrounds. The most extreme example is in level 4 where the background is about 100 screens wide! In that case, the raw background data would take up more than 7.5 Mb, almost twice the amount of system memory in the target device. And that's without including sprites, overlays and the second background layer, not to mention music, sound effects and the code itself.

The task of making beautifully colored artwork, and at the same time optimizing for maximum reuse, required a special combination of skills on the part of the graphic artists, in this case the twin brothers Jesper and Thomas Colding-Jørgensen. And I must admit that it was only in hindsight that it struck me what incredible luck we had to have these two extremely skilled, only 19-year-old guys on the team!

This is the entire colored background for level 3. The checkered holes are where the second, rearmost, background layer fits in (more on that below). At run time this bg layer moves at a slower speed than the front layer, creating the impression of depth.

And these are the four parts of the multiplane scroller's back layer.

Since the game was designed to run on a 486, 66 MHz PC equipped only with a standard VGA graphics card, certain tricks were necessary in order to achieve a sufficiently high frame rate for a real-time game (preferably 60 fps). Simply assembling every new frame in the computer's system memory and then copying it to video mem just wouldn't cut it. It would be way to slow.

Instead, in order to gain more speed, various hardware features included in the VGA standard were utilized (I'm going to up the level of geekiness a notch here, just for the fun of it). That required giving up on the regular, simple-to-use 320 x 200 pixels video mode 13h, and instead tweaking the video card into the less orthodox 320 x 240 so-called "Mode X," thereby gaining access to the VGA card's built-in scrolling feature (which was probably invented mainly in order to scroll text in DOS text mode, but could be put to alternative use in a 2D game like ours), while allowing for use of the full 256 kb video mem, as well as achieving a 40 lines higher vertical resolution with an aspect ratio of 4:3 (like the screen's), resulting in square pixels (instead of mode 13h's slightly stretched pixels).

With "Mode X" enabled, the rendering of the game's visuals goes as follows: At startup of each level, the first full background frame is copied from system memory to video, not just once, but to three identical buffers, all located in video memory (one screen is 320 x 240 = 76.800 pixels, so with 256k at 1 byte per pixel there is room enough for three video buffers, plus a bit of space between them). Then, when the background starts moving, we simply ask the video card to scroll the picture. This happens almost instantaneouly without burdening the computer's main CPU. Now only those 8 x 8 pixel blocks that are missing around the edges of the screen have to be copied from system memory - to all three video buffers, indeed, but still saving valuable time.

Next, moving at approximately 40% of the main (front) layer's speed, the back layer of the parallax scroller is drawn from system memory, using the "hole" in the main background as a mask. And on top of the whole thing, the sprites: Hugo, other characters, props and effects like water etc.

But here's the catch: In the regular mode 13h, the card's four video planes of 64 kb each are "chained" together, allowing pixel values to be written to the screen in a simple, linear way (1, 2, 3, 4, 5, 6, etc.), while limiting the usable video memory to only 64.000 bytes. In Mode X, conversely, the four planes are unchained, giving access to the entire 4 x 64 = 256 kb, but at the same time somewhat complicating the way data is written to the screen. Since the image data is now divided across the four planes, with pixel no. 1 on the first plane, no. 2 on the second plane, no. 3 on the third etc., all sprites (as well as the rearmost background layer) had to be "sliced up" and pre-stored like this: pixel no. 1, 5, 9, 13... etc. on plane one, then plane two: pixel 2, 6, 10, 14... etc., then plane three and four. This was of course done up front, so the image data could be drawn directly to the screen at run time.

Hugo's face representing remaining lives during the game. On the right
the same image is formatted for quick "blitting" in Mode X.

After the rendering of a frame is completed, the program waits for the "vertical retrace" (when the monitor's raster beam has finished drawing the entire picture), and then flips the page, i.e. forces the video card to show data from the second buffer (page) in video memory on the screen. Now, before we start composing the next frame, all sprites (and back bg layer) must be cleared from the first buffer. This is done by copying the corresponding sections of the background from the third buffer, which is maintained in video memory for this sole purpose. The trick is that the copying can be done much faster from v-mem to v-mem than copying data from regular system memory.

All this sounds like a pretty complex process, which it certainly is, but back in 1995 it was absolutely necessary in order to deliver the desired real-time gaming experience.

Here's what the combined background looks like, including the second (parallax scrolling) layer.

And here are the five stages of the background bitmaps in full size.

I'll just throw in a couple of photos with some of the guys from the production not featured in the video above. Top picture: With back turned, graphic artist Thomas Colding-Jørgensen talking to lead programmer Brian Bramsted. Bottom picture (left to right): Programmer Ruvan Fernando, coordinator Mogens Dester, producer Per Holst and programmer Felix Bryde Nielsen.

Evidently, with everyone highly focused on the work, noone has time for the photographer. Notice how the Danish summer sunlight is firmly shut out for an optimal coding environment, while the empty bottles give a clue to the nutrition of the staff. The careful observer may also detect a certain trend in hairstyle dominating the industry in the mid-90's.

Brian Bramsted and Thomas Colding-Jørgensen, 1995.

Ruvan Fernando waking up from a power nap on the couch, as Felix Bryde Nielsen presents
the latest progress to the production team, Mogens Dester and Per Holst. My feeling is
the latter were just a little bit out of their natural habitat here.

You can download a cracked English version of the game from the website Abandonia. A Danish version can be obtained on this blog. The game requires DOSbox to run under modern Windows operating systems.

1 comment: