Downland Unearthed: Drop It Like It’s Hot

This article is part of a series exploring the reverse engineered inner workings of Downland, a game for the Tandy Color Computer, released in 1983, written by Michael Aichlmayr.

Acid drops. If you die in Downland, chances are it’s because of one of these falling bastards.

Never mind the ball with its repetitive and predictable path across the screen. These white liquid drops of death are random, fast, and relentless.

Drop in a Bucket Chamber

For each chamber, the game data defines a number of drop spawn areas. Each drop spawn area is defined by an X and Y position, plus the number of drop points it has across the area. In the first chamber seen in the image below, there are seven drop spawn areas (boxes in red):

The first drop spawn area has thirteen points across it to spawn points from (marked in green).

A curious note is that in the game data the number of spawn areas and the number of drops to spawn per area is one less than it should be. So for the first chamber, the number of spawn areas is stored as 6 (not 7) and the number of drops in the first spawn area is stored as 12 (not 13). I don’t know what the advantage of this would be, if any.

Placing Drops

Some important background: The game’s world size is 128 by 192 points. The horizontal coordinate system goes from 0 to 127. The graphics mode that the game uses is PMODE4, which is 256 by 192 pixels. That means a point on the horizontal axis corresponds to two pixels on screen. Placing an object at the horizontal position 64 means they’ll appear at pixel 128 in the middle of the screen.

When the game wants to spawn a drop, it first picks randomly a drop spawn area. Then it picks a number between 0 and the number of drop points for that area. The drop is given a location that is starts from the drop spawn area’s XY position and then offset to the right by the the drop point chosen multiplied by eight.

So like this:

dropSpawnArea = pickRandomDropArea();
randomDropPoint = rand() % (dropSpawnArea->dropSpawnPointsCount + 1)
newDrop->x = dropSpawnArea->X + (randomDropPoint * 8)
newDrop->y = dropSpawnArea->Y

That’s generally the way it works, but there are two exceptions.

The first exception is about giving room to the player. Look at the left side of the top most drop spawn area in the image above. Notice that the drop is actually offset to the left of the box where its supposed to spawn?

Enhance!

That’s because the game tries to detect whether there’s a rope nearby. It checks four points to the right and six points down. If a rope is detected, the drop is offset to the left. This gives enough room around the rope to let the player climb up without being burned to death.

The second exception is about removing that room from the player and increasing the chances of them climbing up and getting burned to death. What Downland giveth, Downland taketh away. But why?

In the drop spawning code there is a part that says that if ever the player has completed the game three times in a row (which we must all admit is some kind of superhuman feat) the X position of the drop is made even. As the positions of the drop spawn areas are on odd positions, it effectively moves all the drops one position to the left, which corresponds to two pixels in that direction. In the image below, the small bright red boxes are the ones that have been affected by that rule.

This makes it so that the drops on the right side of the vine will always touch and kill the player, forcing them do perform rope acrobatics when climbing. This makes the game pretty much impossible to play, because drops fall on both sides of the rope simultaneously very often. Well, maybe it’s not impossible but the chances are definitely not in your favor if ever you manage to get to that point.

Wiggle, Wiggle, Wiggle

When a drop is finally placed and spawned, it hangs on the ceiling for 40 frames. As it does so, the game flips its vertical speed up and down every frame so that it wiggles. There were rumors that the wiggle time was random, but it’s not. Because of how drops can be spawned over other drops it might give an effect that it’s wiggling longer.

Gravity? What Gravity?

Drops fall at a steady rate. They go down two points per every update (but not every frame! see below). No fancy physics calculations here!

Yeah, But… How Many?

The maximum number of active drops is ten. But the actual number of drops spawned depends on the chamber number and whether you’ve completed the game at least once.

The rules that determines the number of active drops in a chamber are:

  • If the chamber number is 5 or less, then the maximum number of drops is 6.
  • If the chamber number is greater than 5, then the maximum number of drops is chamber number plus one.
  • After completing the game once, the maximum number of ten drops is used for all chambers.

The maximum number of drops is also used for the title screen and the “get ready” screen. On those screens, the game lies to the drops system that the game has been completed so that it spawns all the drops. Also on those screens the game doesn’t actually wait for vblank so it just draws the drops as fast as possible.

Half The Work In Half The Time

Not all the drops are updated on every frame. The drops system only updates five drops at a time, alternating between the odd numbered and even numbered drops. This partial update means there’s more time left over for other parts of the game’s logic to be processed.

Waitaminute, You Forgot a Section!

So that’s the drops system in a nutshell. What I haven’t talked about is how the game handles the drop collisions with terrain and with the player. And also the drawing routines. I want to cover those topics more in-depth in later posts.

Comments

One response to “Downland Unearthed: Drop It Like It’s Hot”

  1. David Kroeker Avatar

    Thanks for your work on reverse engineering Downland – a truly unique game for the CoCo – and for documenting your work.
    I’m really appreciating these blog posts that delve into the details of the game design.

Leave a Reply to David Kroeker Cancel reply

Your email address will not be published. Required fields are marked *