Jump to content

Photo

My 2k Game Experiment - Gate Racer


131 replies to this topic

#1 Atarius Maximus OFFLINE  

Atarius Maximus

    Stargunner

  • 1,794 posts
  • Load "Atari2600",8,1: SYS32777
  • Location:St. Louis, Missouri USA

Posted Fri Feb 15, 2013 2:51 PM

Here's my experiment in making a 2k game, it's the first time I've tried to. I thought I'd try my luck just to see if I could make something fun to play with some replay value as well. My goal of course was to have at least 2048 Bytes free in a 4K build and I ended up with 2053 bytes free. I've always thought it would be impossible so I thought I'd try and prove myself wrong. I know "fun" is relative so I just made something I thought I might like to play more than once. :)

The game is called 'Gate Racer'. The object is to drive through the scrolling gates while avoiding hitting the barriers, sides of the road, or oil slicks. There's a clock timer (that shows minutes/seconds/tenths of seconds) at the bottom and the object is simply to survive on the road as long as you can. Your final time is displayed when you crash, hitting fire then restarts the game. I implemented left and right velocity to make it more interesting (and require a bit more skill), and the gate size and location is randomly generated. The gates will get smaller as you progress and do so very quickly. There is also a powerup you can collect (a white block on the screen) that will make you invincible for two gate passes.

I started thinking about what style of game would lend itself to such a small size. One of my all time favorite 2K games is Activision's Dragster and a good game lasts less than 7 seconds. With that in mind, I wanted to come up with a short game that requires some skill (and practice to get better) but also includes some randomization to increase the replay value. I had all sorts of ideas for this game that wouldn't fit, in addition to some core items that I really wanted in there that also wouldn't fit.

Here's a list of small features I wanted but removed due to lack of ROM space in 2K. These features would require an additional 75 bytes and would make the game feel a bit more 'complete' IMO.

-> You can't use the reset switch in-game, it needs 10 bytes. It's a short game anyway and pressing fire restarts after death.
-> No sounds. I removed the engine Rumble sound, it needs 16 bytes. I didn't put in a crash sound either, that needs another 16 bytes.
-> I eliminated my line of code that randomly increases size of the gate, it needs 13 bytes. It would allow for slightly longer games.
-> I eliminated the car moving slightly up the screen during the game, it needs 13 bytes. It would progressively make the game harder.
-> I eliminated the 'press fire to start' option at beginning of game, it needs at least 7 bytes. The game starts up as soon as you power it on.
-> The oil slick doesn't reset to the top when you die. Not sure how many bytes it would take to fix it, prob 13 or less

There were other concessions as well. I didn't even try to implement my ideas with the ball or missiles due to lack of space. There could be oncoming cars, variable speeds on the road, the ability to shoot oncoming items, sprite animations, levels of difficulty, color changes, a title screen, moving gates, and lots of other things I'm not thinking of right now.

If you want to compile this yourself you'll need the custom score graphics file and the timer.inc file included in the zip. The code is well commented, feel free to make suggestions. It's possible some of my code could be optimized to save a few bytes here and there.

So, did I succeed? Beats me. It was definitely challenging and I've never been so focused on saving a single byte of space. The end result isn't horrible but I think it could be a whole lot better in 4K.

Steve

UPDATE:

Final version attached. It includes most of the things I couldn't fit in initially plus more, thanks to all the people who assisted with their comments and suggestions. The allfiles zip contains the source and all the modified include files that you'll need to compile it. The oldversions zip contains binaries of all the development versions.

Attached Thumbnails

  • newscreen.jpg
  • titlescreen.jpg

Attached Files



#2 Cybearg OFFLINE  

Cybearg

    Dragonstomper

  • 950 posts

Posted Fri Feb 15, 2013 3:00 PM

That's pretty awesome! If your game is under 2k, though, why not put it in a 2k cartridge?
set romsize 2k

Also, if you used a custom .inc inlcludes file, i'll bet you could get an extra 100-200 bytes by cutting out all the stuff you don't need.

#3 Atarius Maximus OFFLINE  

Atarius Maximus

    Stargunner

  • Topic Starter
  • 1,794 posts
  • Load "Atari2600",8,1: SYS32777
  • Location:St. Louis, Missouri USA

Posted Fri Feb 15, 2013 3:07 PM

I mentioned why it's not a 2k bin in the remarks in the source code but forgot to mention it in my original post. It won't compile with the 'set romsize 2k' option because of the custom score graphics file, it's been expanded.

When compiling, I get this error:

Error: segment: f7fc vs current org: f80c
GateRacer.txt.asm (2820): error: Origin Reverse-indexed.

I need to remove 16 bytes from the ORGs at the beginning of the file as explained by SeaGtGruff here: http://www.atariage....e-graphics-asm/. I tried it and couldn't get it to work. Honestly it didn't bother me that much as despite the 4K binary there's only 2k of data in it. It's still a 2k game. :)

Steve

EDIT: Oh yeah, about the timer.inc file. I didn't look at it at all, SeaGtGruff wrote it and I just used it as-is. I suppose it's possible something could be trimmed in it but I kind of doubt it.

#4 Cybearg OFFLINE  

Cybearg

    Dragonstomper

  • 950 posts

Posted Fri Feb 15, 2013 4:06 PM

After reading this post and fiddling around, I figured out what was wrong. The fixed, working score_graphics_timer.asm file that will allow the set romsize 2k option is attached below.

The problem is this, from the top of the file:


ifconst ROM2k
  ORG $F7AC

As Gruff explains, since you're using a version of score_graphics.asm that's just had two extra sprites added (for the . and the : ), you need to decrease that ORG by the equivalent of 16 bytes, since each sprite is 8 bytes (1 byte per row, 8 rows per sprite), which leaves you with this:


ifconst ROM2k
  ORG $F79C

Also, if you change every "if something > 0 ..." to "if something ..." and every "if something = 0 ..." to "if !something ...", you save JUST enough bytes for sound effects. See attached. :D

Attached Files



#5 Atarius Maximus OFFLINE  

Atarius Maximus

    Stargunner

  • Topic Starter
  • 1,794 posts
  • Load "Atari2600",8,1: SYS32777
  • Location:St. Louis, Missouri USA

Posted Fri Feb 15, 2013 5:30 PM

After reading this post and fiddling around, I figured out what was wrong. The fixed, working score_graphics_timer.asm file that will allow the set romsize 2k option is attached below.

The problem is this, from the top of the file:


ifconst ROM2k
ORG $F7AC

As Gruff explains, since you're using a version of score_graphics.asm that's just had two extra sprites added (for the . and the : ), you need to decrease that ORG by the equivalent of 16 bytes, since each sprite is 8 bytes (1 byte per row, 8 rows per sprite), which leaves you with this:


ifconst ROM2k
ORG $F79C

Also, if you change every "if something > 0 ..." to "if something ..." and every "if something = 0 ..." to "if !something ...", you save JUST enough bytes for sound effects. See attached. :D

Fantastic! Thank you so much for your help. I'm out of time to make any changes for today, but hopefully I'll be able to take a look again this weekend. Adding audio to this game would definitely make it better :)

#6 Gemintronic OFFLINE  

Gemintronic

    Jason S. - Lead Developer & CEO

  • 8,772 posts

Posted Fri Feb 15, 2013 11:33 PM

I feel this should be renamed Drunk Racer. Controls shouldn't be part of the challenge :) That being said, it's awesome for what it is! Complete gameplay in 2k.

I never knew about the timer score mini kernels. We REALLY, really need a pinned topic with all the mini kernels that have been 'brewed over the years..

#7 Cybearg OFFLINE  

Cybearg

    Dragonstomper

  • 950 posts

Posted Sat Feb 16, 2013 12:41 AM

Do it, loon.

I kind of agree with loon. The amount of weave may be a bit excessive, especially since it largely comes down to chance: whether an oil stick happens to have spawned in front of where you were trying to go or not and whether or not the opening spawned close enough for you to reach it without careening out of control. Maybe making it 1/2 or 1/4 the current amount would allow it to come down to a bit of skill rather than pure luck.

#8 Atarius Maximus OFFLINE  

Atarius Maximus

    Stargunner

  • Topic Starter
  • 1,794 posts
  • Load "Atari2600",8,1: SYS32777
  • Location:St. Louis, Missouri USA

Posted Sat Feb 16, 2013 8:22 AM

Do it, loon.

I kind of agree with loon. The amount of weave may be a bit excessive, especially since it largely comes down to chance: whether an oil stick happens to have spawned in front of where you were trying to go or not and whether or not the opening spawned close enough for you to reach it without careening out of control. Maybe making it 1/2 or 1/4 the current amount would allow it to come down to a bit of skill rather than pure luck.


Thanks for the feedback, Cybearg and theloon. I agree with you guys about the controls, it's difficult. I also know that the randomization does introduce the element of luck to get a high score. I had considered naming it "Ice Racer" with a blue background because of the controls. :) I'll revisit the controls and see what I can do. I could completely remove the code that makes you slide back and forth as that would free up a ton of space for other things.

#9 Gemintronic OFFLINE  

Gemintronic

    Jason S. - Lead Developer & CEO

  • 8,772 posts

Posted Sat Feb 16, 2013 10:22 AM

In a way you've got the same challenge as the developers did in Marble Madness: make the controls feel lose and analogue whilst not being frustratingly out of control.

#10 Atarius Maximus OFFLINE  

Atarius Maximus

    Stargunner

  • Topic Starter
  • 1,794 posts
  • Load "Atari2600",8,1: SYS32777
  • Location:St. Louis, Missouri USA

Posted Sun Feb 17, 2013 11:22 AM

Thanks to Cybearg's help, I was able to make a few enhancements and compile it in an actual 2K bin. This new version adds some sounds, there's now an engine rumble sound when you're playing and a crash sound when you crash. The crash sound will stay on until you reset, there was not enough space to set a timer to turn it off. I changed the oil slick sprite to the ball to save a few more bytes, and (most importantly) I changed the left/right velocity to make it a bit easier to control your car. It's much less frustrating now and you'll crash a lot less. There's now 4 bytes left in the 2K ROM, not really any space left to make enhancements in this version. I'll update the first post with the new version shortly. I haven't spent much time playing the new version yet, I'll post my new high score a bit later. :)

#11 Atarius Maximus OFFLINE  

Atarius Maximus

    Stargunner

  • Topic Starter
  • 1,794 posts
  • Load "Atari2600",8,1: SYS32777
  • Location:St. Louis, Missouri USA

Posted Sun Feb 17, 2013 11:37 AM

I forgot to mention one additonal improvement in my last post. I was able to re-add the "press fire button to start" option. The game now doesn't start as soon as you launch it, you need to press the joystick button to begin. A minor thing, but a big improvement. :)

#12 Gemintronic OFFLINE  

Gemintronic

    Jason S. - Lead Developer & CEO

  • 8,772 posts

Posted Sun Feb 17, 2013 11:37 AM

That car wreck sprite feels like it could be cut out. Could you play with NUSIZ and/or color cycle the car sprite instead?

#13 Atarius Maximus OFFLINE  

Atarius Maximus

    Stargunner

  • Topic Starter
  • 1,794 posts
  • Load "Atari2600",8,1: SYS32777
  • Location:St. Louis, Missouri USA

Posted Sun Feb 17, 2013 11:44 AM

@theloon - not a bad idea. That would save some more space. If I did that, any thoughts on what to use the extra space for? It of course wouldn't be very much. :)

#14 Gemintronic OFFLINE  

Gemintronic

    Jason S. - Lead Developer & CEO

  • 8,772 posts

Posted Sun Feb 17, 2013 11:49 AM

If I had my druthers the slide would be even less. The oil slick should use missile1 so you can color it black. Also, the oil slick moves at a different rate from the road. Not sure if you already do this but you could add a speedup over time.

#15 Cybearg OFFLINE  

Cybearg

    Dragonstomper

  • 950 posts

Posted Sun Feb 17, 2013 12:07 PM

Maybe you'd have enough space left to allow the explosion sound to stop after a while if, instead of plotting out the entire playfield, you drew it with two pfvlines, instead:


 pfvline 0 0 11 on
 pfvline 31 0 11 on


#16 Gemintronic OFFLINE  

Gemintronic

    Jason S. - Lead Developer & CEO

  • 8,772 posts

Posted Sun Feb 17, 2013 12:11 PM

He wouldn't need the borders of the road drawn with playfields statement if he used PF0 = %10000000 or something similar :)

#17 Atarius Maximus OFFLINE  

Atarius Maximus

    Stargunner

  • Topic Starter
  • 1,794 posts
  • Load "Atari2600",8,1: SYS32777
  • Location:St. Louis, Missouri USA

Posted Sun Feb 17, 2013 1:27 PM

Great ideas! I'll see what I can do. Not much time to work on it any more today, I'll make some revisions again tomorrow.

#18 Piggles OFFLINE  

Piggles

    Star Raider

  • 88 posts

Posted Sun Feb 17, 2013 1:40 PM

This is rather fun. Only got to 32.5 seconds so far. I think you've got a good game. I suggest going all out for a 4k update of this game with the things you would have added. I like battling the momentum of the sharp left and right turns.

#19 bogax OFFLINE  

bogax

    Dragonstomper

  • 693 posts

Posted Sun Feb 17, 2013 1:56 PM

I think you could shave a few bytes here
(untested)

rem player movement code
rem
if joy0right then direction = 1
if joy0left then direction = 0
if !joy0left && !joy0right && direction && velocityx then velocityx=velocityx-0.0030
if !joy0left && !joy0right && !direction && velocityx then velocityx=velocityx+0.0030

rem player movement code
rem
if joy0right || joy0left then direction = direction ^ 1 : goto skip
if !velocityx then goto skip
if direction then velocityx=velocityx-0.0030 else velocityx=velocityx+0.0030
skip


#20 Atarius Maximus OFFLINE  

Atarius Maximus

    Stargunner

  • Topic Starter
  • 1,794 posts
  • Load "Atari2600",8,1: SYS32777
  • Location:St. Louis, Missouri USA

Posted Mon Feb 18, 2013 11:29 AM

That car wreck sprite feels like it could be cut out. Could you play with NUSIZ and/or color cycle the car sprite instead?

Excellent Idea. I removed the crash sprite and it freed up a bunch of space.

If I had my druthers the slide would be even less. The oil slick should use missile1 so you can color it black. Also, the oil slick moves at a different rate from the road. Not sure if you already do this but you could add a speedup over time.

I've got the slide pretty much how I want it in this version, and added a no-slide option on the right difficulty switch. I changed the oil slick to missile1 as you suggested, it does look better. The oil slick does not speed up over time.

Maybe you'd have enough space left to allow the explosion sound to stop after a while if, instead of plotting out the entire playfield, you drew it with two pfvlines, instead:

pfvline 0 0 11 on
pfvline 31 0 11 on

Great Idea Cybearg, that worked perfectly and saved some space.

He wouldn't need the borders of the road drawn with playfields statement if he used PF0 = %10000000 or something similar

Great Idea. I used that along with the pfvline and I really like how the road looks now.

This is rather fun. Only got to 32.5 seconds so far. I think you've got a good game. I suggest going all out for a 4k update of this game with the things you would have added. I like battling the momentum of the sharp left and right turns.

I most likely will expand the game in the future, I just want to be happy with the 2K version first. I find it hard to know when to stop working on a project. :)

I think you could shave a few bytes here
(untested)

Thanks bogax. I used your idea and shaved off a few bytes in the player movement code.

Thanks to everyone for all the suggestions! I was able to use everyone's ideas in this latest build. The new version is in the first post again.

Here are the latest Changes:

1. Added Left Difficulty Switch option: A=Oil Slick Off, B=Oil Slick On.
2. Added Right Difficulty Switch option: A=X/Y Velocity Off, B=X/Y Velocity On.
3. The Crash sound will now turn off after a few seconds.
4. Timer font changed and it now turns red when you crash.
5. Eliminiated Car Crash sprite, your car now flashes colors after a crash instead.
6. Road graphics changed.

#21 Gemintronic OFFLINE  

Gemintronic

    Jason S. - Lead Developer & CEO

  • 8,772 posts

Posted Mon Feb 18, 2013 12:06 PM

One other idea besides pf-whatever line is to remember that the playfield is just a bunch of variables. When the horizontal blockade lines reach the bottom of the screen you could add new exists just by zero-ing var44, var45, var46 or var47. Likewise you could add another horizontal blockade by making var44, var45, var46 or var47 = %11111111

#22 bogax OFFLINE  

bogax

    Dragonstomper

  • 693 posts

Posted Mon Feb 18, 2013 12:42 PM

You're using the standard kernel
with no funny stuff right?
And your playfield is very simple
I think you could shave a few more
bytes if you replace your playfield
statement with this.
There's only one value in your
playfield (here called pfedge) other
than zero this just pokes it
directly in a loop with out having
to duplicate it in the code to fill
the playfield.
Hope I got those locations right
(untested)

const pfedge = $80
const pfleft = $A4
const pfright = $A7

pfclear
for i = 0 to 48 step 4
pfleft[i] = pfedge : pfright[i] = pfedge
next
anyway, you could try it

edit: oops one line short, fixed now I think

edit again after reading theloon's post
I forgot the pfvariables have names
so using them it would be
const pfedge = $80

pfclear
for i = 0 to 48 step 4
var0[i] = pfedge : var3[i] = pfedge
next

Edited by bogax, Mon Feb 18, 2013 1:02 PM.


#23 Atarius Maximus OFFLINE  

Atarius Maximus

    Stargunner

  • Topic Starter
  • 1,794 posts
  • Load "Atari2600",8,1: SYS32777
  • Location:St. Louis, Missouri USA

Posted Mon Feb 18, 2013 1:45 PM

Thanks for the tips, guys. I have 23 bytes free. Now I'm tying to figure out what to do with it. :)

#24 Cybearg OFFLINE  

Cybearg

    Dragonstomper

  • 950 posts

Posted Mon Feb 18, 2013 2:34 PM

Is that enough to put the crash-car sprite back in? I didn't see a problem with that.

#25 Atarius Maximus OFFLINE  

Atarius Maximus

    Stargunner

  • Topic Starter
  • 1,794 posts
  • Load "Atari2600",8,1: SYS32777
  • Location:St. Louis, Missouri USA

Posted Mon Feb 18, 2013 2:37 PM

I was just messing around with modifying the std_kernel.asm file, looking for things that I may be able to remove. I took out the sections below, which seem to relate to reading paddles and the "shakescreen" function, neither of which I'm going to be using. I now have 72 bytes free when compiling. :) I may still be able to trim a few more things out. Now I can at least add in a basic titlescreen and the crash sprite.

;--------------------
 ifconst shakescreen
   jsr doshakescreen
 else
   ldx missile0height
   inx
 endif
;--------------------
 ifconst readpaddle
   stx paddle
 else
   sleep 3
 endif
;--------------------
 ifconst shakescreen
doshakescreen
   bit shakescreen
   bmi noshakescreen
   sta WSYNC
noshakescreen
   ldx missile0height
   inx
   rts
 endif
;--------------------





0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users