Deep Canyon

Copyright © 2018 by Víctor Parada


This is a little game for the 2018 NOMAM's BASIC 10-liners Contest. This program fits in the PUR-80 category, and it was written using Atari BASIC for the 8-bits ATARI XL/XE.


Drive your parachute and land on the bottom of the canyon before you get too many lethal shots.


DEEP start You are a paratrooper that is falling inside a canyon.
DEEP move Move to the left or to the right to avoid obstacles.
DEEP narrow The canyon gets narrower as you go down.
DEEP hit Each time you hit an obstacle or wall, the hurt indicator bar increases.
DEEP dark As you go down, it gets darker.
DEEP win You win the game if you reach the ground before the bar is full.
DEEP gameover You loose if you got too many hits during the descend.

Development of the game

Games programmed in Atari BASIC are rather slow for many reasons:

To speed up things, fortunately it was possible to call a machine language routine to perform complex tasks like to copy some blocks of memory from one addres to another or to put a P/M sprite on screen and move it around.

Other BASIC dialects for the Atari 8-bit computers that were based on this interpreter solved some of the speed problems and included many new extensions to perform that tasks directly from BASIC statements.

But the new "stock" PUR-80 category at the NOMAM tenliners contest does not allow neither other interpreters than Atari BASIC, nor USR extensions. This limits the number of things that could be done.

The main problem was the memory management. Without a MOVE statement, the only other way to move a chunck of memory is using string variables, but it is not possible to access every byte of the computer memory as it can be done with POKE, only the memory reserved for string variables using DIM statement can be initialized and data be copied between the variables or inside one of them as substrings.

Knowing how the memory pointers are managed by Atari BASIC, I tried to hack them and make BASIC think that the whole memory is inside a string variable, so I could use substrings assignments to move a block of memory from one buffer to another area to create animations, but it had some problems that made this method useless.

Then it came another idea: define a big string variable and change O.S. vectors to point inside of the string. For example, assign a block of a string for the screen memory, so screen elements should be assigned to a substring. Of course there are some restriction, like page boundaries for some HW objects like PMBASE. To align them, a simple filler could be used.

One method to align data was to compute a base index to skip as many bytes as required from the beginning of a string to reach a starting point in a page or 1K boundary, and then use that index as a base in all the substring assignments. This had two problems: it was required a floating point addition operation on every substring referenced slowing down the program, and it requires at least 2 or 4 extra chars in th listing for every reference.

Another method was to define a dummy string variable of a size that make the following variables in the DIM statement be aligned with memory pages. This require more bytes to declare the variables, but many other are saved later in the code as the substrings indexes are fixed.

Using the first method, I did a simple proof of concept that scrolled screen memory from the bottom to the top of it like in the game Descend by Kevin Savetz (NOMAM 2017) using only substring assignments. That was faster than using screen O.S. routines and data conversion... Wow! The problem was that texts need to be assigned as internal code, not as ATASCII code, but it is not a real problem, as it is the same when MOVE was used in other BASIC dialects.

DEEP prototype

Scrolling prototype

The test required 6 full lines of code. That gave me 4 lines to include a player and I had to decide if it would be another char or a P/M graphics. I opted for a player, because it would be smoother than blocks and P/M collisons could be used to check for that state.

In the test I used randomly pre-generated patterns of ASCII symbols displayed in ANTIC 4 graphics mode, so they seemed to be like foliage and that gave me the idea of a forest. Instead of a spaceship, a paratrooper seemed to be appropiate and I designed a very simple one using a single player. I named the game as "Deep Forest".

The first line of the screen was initially reserved as a text line to display the score, lifes and the "game over" message, but it turned into a health bar, and the final status of the game was also displayed there.

DEEP prototype

Paratrooper in the "Deep Forest"

I had to use FOR-NEXT with STEP 0 loops to manage the game and span blocks of statemente between many lines and not to cut lines in the middle. No GOTO statemente were used until then because the destination statemens were not the first one in a line.

When the game was almost ready, I needed some extra space to add sound, and I had to reorganize the code. While doing that, I noticed that the base index of the string was used so many times in the code, and I could save them if I change the method of the added index for the string buffer to the dummy string variable. A side effect was that the statements were realigned in a way that the first statement of the game loop was at the beginning of a line, so I could remove the FOR-NEXT for that loop and replace it with ON-GOTO.

I had to choose what to do with the remaining space in the listing. There was not enough space to redefine the charset, but I could increase a bit the difficulty to the game, by adding some extra obstacles in the blank string that was used to create the path and randomize the substring position of it when copying the bytes.

DEEP prototype

Inserting extra objects to add difficulty

To accomodate the main loop as a destination of the last GOTO statement, I had to distribute some of the initialization statements arround that point. I mean, as some of the instructions to initialize the game had to be put inside the main loop because there was no room en the previous lines. To execute the same code in every loop didn't harm the program.

Still some free bytes... Hum... Let's change the color of the background as the paratrooper goes down: from a light blue sky to a dark blue. Nice, but as another playfield element was also blue, I had to change it, and I did it to a red/brown one. The forest turned into a canyon.

DEEP prototype

New game title: "Deep Canyon"

I noticed that the path most of the times went to the left. The number of all possible values of a long uniform random sequence should be the same, and the path should end in the center of the screen. So why it was going to the left? Because the width of the path was narrowed from time to time by removing the last byte from the right!!! As way to compensate that distortion was to ponder the expression and increase the possibilities to move the path to the right insead of to the left. The first prototype has a 25% of possibilities to choose the left, 25% for the right and 50% to stay in the same position than before, while in the last version of the game, there is 31% to choose the left, 31% to stay and 38% to move to the right, which is compensated with the removal of the rightmost byte of the path every some lines.

The last few bytes in the initialization lines were used to enlarge the player and to add extra random objects in the path. After all those changes, the scroll was not as fast as the initial proof of concept, but it results in a playable game.

Just before sending this game to the contest, I made some changes in the code to make it even harder, because I always won during the tests. ;-)

Return to my 10-liners page.

© 2018 by Víctor Parada - 2018-03-04