Sunday, March 20, 2016

GRAVITEN (An Atari Gravitar rip-off in 10 lines of BASIC)

UPDATE April 3, 2016: 2nd Place!

GRAVITEN is my second entry to the 2016 NOMAM 10-liner BASIC game competition. Like NUTS!, this one is in the PUR-120 category. It's inspired by Gravitar's Red Planet 3 stage by Atari. I got the idea last Friday night playing Gravitar on my Atari 2600 10-in-1 joystick game. I had tried playing it as a kid, but found it too hard. Download my version here and run it on the Altirra emulator (800XL). (Direct link to ATR file.) If you play, please post your high-score in the comments!

Pilot your ship around the spiral to the planet's core. Reach the core and advance to the next level. Complete each level quickly to maximize points. But, be careful! Touch the wall and you lose a life.You get 3 lives to start and 1 additional life per level. Even numbered levels have atmospheric drag (indicated by gray background in the text window) and odd are in vacuum (indicated by black background). Gravity increases every two levels, starting at zero. Play through all 8 levels to complete the mission.  Controls: up to thrust, back to flip, left/right to rotate.

I learned a couple new things to write this game. I used Altirra's debug features to borrow the ship bitmap from Asteroids. Altirra can report the ANTIC register values allowing one to find the player-missile pixel graphics in memory. I also learned to use the TurboBasic XL parser tool (tbxl), which is really useful for at least two things: (1) storing binary data in strings using ATASCII characters and (2) optimizing code to squeeze into minimal space.

The Code

0DIMA$(96):A$=" ......................... {a whole bunch of ATASCII} ......................... ":A=.39269908:DIMA(1,15)
2?"Stand by ";:A=.0174532925:F.B=0TOC STEP9:D=38*B/C*COS(B*A)+45:E=25*B/C*SIN(B*A)+15:F.F=1TO5:CI.D,E,F:N.F:?".";:N.B
4POKE559,46:DO:?:?,"press FIRE to start";:W.STRIG(0):WE.:CLS:H=1e3:I=0:J=3:K=70:L=18:M=8:N=0:O=0:?:?I,J;:W.J:POKE657,22
5?H;" ";:M.G+512,G+513,127:M.M*5+G,G+512+INT(L),5:POKE53248,INT(K):P=Q:Q=STICK(0):R=(Q&4=4)-(Q&8=8):S=(P&2=2)&(Q&2=0)
6T=Q&1=0:M=(M+16+R+8*S)MOD16:IFT:SO.0,250,10,10:N=A(0,M)*.05+N:O=A(1,M)*.05+O:END.:IFI MOD2=0:N=N-.01*N:O=O-.01*O:END.
7N=I DIV2*2e-5*(135-K)+N:O=O-I DIV2*2e-5*(44-L):K=K+N:L=L-O:POKE53278,1:PA.1:U=PEEK(53252):IFU:K=70:L=18:M=8:N=0:O=0
8SO.0,50,U*8-6,15:PA.9:CLS:IFU=1:J=J-1:IFJ=0:?,"TRY AGAIN":END.:END.:IFU=2:H=(I+1)*1e3+H:IFI=7:?,"MISSION COMPLETE!":EX.
9END.:I=I+1:J=J+1:SE.0,I*2+3,4:SE.2,0,4-I MOD2*4:END.:?:?I,J,H;:END.:SO.0,0,0,0:H=H-1:WE.:?,"SCORE:";H:SO.0,0,0,0:LOOP

There are a couple of things worth pointing out in this code: the spiral path generation (in line 2) and the ship dynamics (in lines 6 & 7). The path is carved out of a solid field of color - this allows me to use missile-playfield collision detection to find out when the ship hits the wall. A TurboBASIC XL PAINT command is used to fill the screen. The spiral path is generated using a pair of parametric equations describing the polar coordinate equation r = aΘ. For each point on the curve, five concentric circles are drawn in the background color, which erase the foreground to create the path. A couple of lines are drawn to repair the top and bottom and to enclose the whole payfield in COLOR 1. Finally, a small box is plotted with the CIRCLE command in COLOR 2 for the goal.

The ship dynamics are borrowed from the earliest video games (Spacewar! and much later Asteroids), which based their game play on similar physics. Those two and other games used thrusters, gravity and drag in their game play. In Gravitar, there's gravity located in different places depending upon the scene. Here, the gravity is centered on the core (goal) and approximated so that it weakens as one progresses into the planet. The strength of the gravity is scaled by the level so higher levels become increasingly more difficult. I made it fairly weak because I'm not a very good gamer. In Asteroids, the ship encounters atmospheric drag - maybe it's the dust and debris ablated from the main rocks. I enable drag every other level. It's slightly easier to play with drag - it acts as a damper to over zealous thrust. You can almost point the ship where you want to go and hit the thursters. Without drag, once the ship starts moving in a direction, it doesn't change until a counter acting thrust is applied or gravity is present.

Thanks for reading.


  1. Great game! Thanks for game & explanations. It's astonishingly smooth despite use of BASIC.

    1. Thanks! I think BASIC is OK moving one thing around - more than that gets tricky in my limited experience.