Captain Spazer Posted September 27, 2016 Share Posted September 27, 2016 (edited) Here's my second game, it's a racing game that started out as a techdemo to see what I could do with DPC+ Multisprites and I found it to be quite fun so I wanted to share it. Danger Lexicon: Neon Racer: These guys come in many colors and your goal is to drive past them or blast them for points. Pothole: Watch out, if you hit these potholes you will surely die! Neon Railing: A collision with the Neon Railing is not recommended as your atoms will be spread across the galaxy! Controls: On the titlescreen press the reset switch to start the game. Move the joystick left and right to steer your car, press the fire button to shoot neon lasers and blast the other cars for points! When the game is over press the reset switch to start over. Known glitches: Sometimes the other racers stack on top of each other looking a bit funky. What's it about? The highscore of course, my high score is 175, can you beat it? Suggestions & Honest reviews are greatly appreciated! NTSC Version: Neon Run NTSC.bin PAL Version: Neon Run PAL.binSPECIAL THANKS TO RANDOMTERRAIN FOR ALL ASSISTANCE ON THE DPC+ Edited September 27, 2016 by Captain Spazer 3 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted September 27, 2016 Share Posted September 27, 2016 Random thoughts: Every Atari 2600 game made since 1982 should start if the player presses the Reset switch or the fire button (whichever one the player chooses to use). You can control the randomness so a new object will only appear within the lines and not hop around because it started outside the lines. Object animations would be nice. A game over type of screen would also be nice so it's clear that the game is over. Since there is no crash sound effect, a player might just think that the game crashed. Then on the game over screen, after the 2-second freeze, the player can press the Reset switch or the fire button to restart the game (whichever one the player chooses to use). Quote Link to comment Share on other sites More sharing options...
Captain Spazer Posted September 27, 2016 Author Share Posted September 27, 2016 Right on, I'll make improvements in the areas you suggested, stay tuned for an upgraded version. Quote Link to comment Share on other sites More sharing options...
Captain Spazer Posted September 28, 2016 Author Share Posted September 28, 2016 (edited) Okay, I've done some animations on the cars, I added sound for when you crash, and a 2-second lockout for when the game is over, and I'm fiddling with controlled randomness, but I can't really get the desired results, any pointers on what I might be doing wrong with this code that handles the cars random positions? if player2y>180 then c=1 if c=1 then player2x=255 : player2y=255 : c=2 if c=2 then player2x=rand : player2y=0 : c=0 if c=0 && player2x<30 then c=1 if c=0 && player2x>130 then c=1 Edited September 28, 2016 by Captain Spazer 1 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted September 28, 2016 Share Posted September 28, 2016 Look at the "Did You Know?" chart here: randomterrain.com/atari-2600-memories-batari-basic-commands.html#rand Instead of player2x = rand, you'd use something like player2x = (rand&63) + (rand&31) + (rand&15) + (rand&1) + 21 or something similar. You can put your playfield in this example program and see exactly how far to the left and right a sprite can be placed before it is touching the lines on the side: randomterrain.com/atari-2600-memories-batari-basic-commands.html#ex_dpc_13_objects Once you know how far left and how far right a sprite can be for your particular game, you can select the correct "rand&" combinations and the correct starting position. For example, if you don't want sprites to start at a position that is less than 21, that's the number you add at the end of the "rand&" combinations. If you don't want your sprites going past 131, subtract 21 from 131 and you get 110. Now you have to figure out how many of those "rand&" things you'll need. 110 - 63 = 47. 47 - 31 = 16. 16 - 15 = 1. 1 - 1 = 0. And that gives us this: player2x = (rand&63) + (rand&31) + (rand&15) + (rand&1) + 21 Now the sprite will always fit between the lines. It's a version of controlled randomness. I just added this to the bB page: randomterrain.com/atari-2600-memories-batari-basic-commands.html#random_sprite_placement Quote Link to comment Share on other sites More sharing options...
bogax Posted September 29, 2016 Share Posted September 29, 2016 this lets you choose between one of eight random number shemes r0..r7 and bar graphs the result each bars height is how often its number came up r0..r7 should return a number in temp1 the result is modded to 0..31 routine is called 255 times graphing the result then waits for you to press fire it then reseeds the rand from a counter and graphs another 255 while it's waiting you can select among routines using joy0 up - down r0 is just rand r1 is RTs scheme for numbers 0..26 r2 is a range of 0..31 scaled to 0..26 the 0..31 are produced with rand & 31 r3 is rand scaled to 0..26 r4 is rand scaled to 0..31 r5 is rand & 31 r6..r7 are rand & 30 which procduces even numbers 0..30 notice the RT's scheme has the numbers bunching in the middle graph_rand.bas graph_rand.bas.bin Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted September 29, 2016 Share Posted September 29, 2016 this lets you choose between one of eight random number shemes r0..r7 and bar graphs the result each bars height is how often its number came up r0..r7 should return a number in temp1 the result is modded to 0..31 routine is called 255 times graphing the result then waits for you to press fire it then reseeds the rand from a counter and graphs another 255 while it's waiting you can select among routines using joy0 up - down r0 is just rand r1 is RTs scheme for numbers 0..26 r2 is a range of 0..31 scaled to 0..26 the 0..31 are produced with rand & 31 r3 is rand scaled to 0..26 r4 is rand scaled to 0..31 r5 is rand & 31 r6..r7 are rand & 30 which procduces even numbers 0..30 notice the RT's scheme has the numbers bunching in the middle Can you make a DPC+ version of that? Since the score doesn't change in your posted example, it's hard to know which r# I'm looking at and I don't understand most of the explanations in your post. Are you saying that there is a better way to have a limited range of random numbers so they'll be spread out more evenly? If so, is there a simple way to do it that doesn't involve techniques that are over the heads of most casual bB users? I also have this on the bB page above the chart: Warning: Using only division or only AND seems to create visible patterns. Mixing up division with AND seems to get rid of the patterns. Since the DPC+ kernel has better random numbers, I hoped that it might automatically spread them out more evenly. Quote Link to comment Share on other sites More sharing options...
RevEng Posted September 29, 2016 Share Posted September 29, 2016 Nice rand app, bogax! Your r2 solution appears to be 0-22, instead of 0-26. It's alway worth noting some values are twice as likely to come up as others, though these are distributed fairly evenly through the range. So good for a screen position solution that OP wants, but not as good where even distribution is required, like a dice/card simulation. Quote Link to comment Share on other sites More sharing options...
bogax Posted September 29, 2016 Share Posted September 29, 2016 (edited) Can you make a DPC+ version of that? Since the score doesn't change in your posted example, it's hard to know which r# I'm looking at and I don't understand most of the explanations in your post. Are you saying that there is a better way to have a limited range of random numbers so they'll be spread out more evenly? If so, is there a simple way to do it that doesn't involve techniques that are over the heads of most casual bB users? I also have this on the bB page above the chart: Warning: Using only division or only AND seems to create visible patterns. Mixing up division with AND seems to get rid of the patterns. Since the DPC+ kernel has better random numbers, I hoped that it might automatically spread them out more evenly. I forgot to mention that I moved playfieldposition to aux1 in order yo get a contiuous 32 bytes I'm not very familiar with the DPC+ kernel but I seem to recall that space is even tighter with it I don't think the quality of the random numbers matters the way you do it its just that there's more ways to get the middle numbers which is not to say the DPC+ prng wouldn't help if you were using that method with the bB prng (which has a cycle length of 255) and you needed 5 components you reduce the nunber of possibilities to 51 (255 / 5) what I don't like about it is you have to call rand multiple times there's javascript here anged rand code generator save it with an html extension then open it in your browser hmm somethings bugged the URL is http://pastebin.com/6PZ2kLtU Edited September 30, 2016 by bogax Quote Link to comment Share on other sites More sharing options...
bogax Posted September 30, 2016 Share Posted September 30, 2016 (edited) Nice rand app, bogax! Your r2 solution appears to be 0-22, instead of 0-26. It's alway worth noting some values are twice as likely to come up as others, though these are distributed fairly evenly through the range. So good for a screen position solution that OP wants, but not as good where even distribution is required, like a dice/card simulation. oh, heck yep I goofed it should be temp1 = rand & 31 : temp1 = (((temp1 / 2 + temp1) / 4 + temp1) / 2 + temp1) / 2 I think the distribution is fairly well illustrated the problem is (I think) the limited precision here I've added the asm version so r2..r4 are progressively better precision if the ARM has hardware multiply you should knock together a routine to do it as a function (in 32 bits ) for the DPC+ kernel graph_rand.bas graph_rand.bas.bin Edited September 30, 2016 by bogax 1 Quote Link to comment Share on other sites More sharing options...
RevEng Posted September 30, 2016 Share Posted September 30, 2016 I'm not sure it's the precision, so much as something inherent with the method - I just wrote a C test with floats, and it has the similar weakness with 0, 5, 10, 16, and 21 being twice as likely as the other numbers. I think each addition of the rand and the shifted version of itself spreads out the range, and creates spots of lower probability. Your suggested idea for DPC+ is good, but we're pretty much done for adding functionality to it. I jumped through all sorts of hoops to squeeze bB DPC+ down (uglifying the source in the process) to add what functionality I could. IIRC we're just a few bytes away from stuffing the DPC+ bank. Maybe the next go around with a bus stuffing kernel, batari will implement user-defined ARM assembly subroutines in other banks. Quote Link to comment Share on other sites More sharing options...
bogax Posted September 30, 2016 Share Posted September 30, 2016 I'm not sure it's the precision, so much as something inherent with the method - I just wrote a C test with floats, and it has the similar weakness with 0, 5, 10, 16, and 21 being twice as likely as the other numbers. I think each addition of the rand and the shifted version of itself spreads out the range, and creates spots of lower probability. Your suggested idea for DPC+ is good, but we're pretty much done for adding functionality to it. I jumped through all sorts of hoops to squeeze bB DPC+ down (uglifying the source in the process) to add what functionality I could. IIRC we're just a few bytes away from stuffing the DPC+ bank. Maybe the next go around with a bus stuffing kernel, batari will implement user-defined ARM assembly subroutines in other banks. I don't think extra precision in the math will help much if you don't have extra random bits here I've added three r5 is 16 bit math with 8 bits of random r6 is 16 bit (plus the carry) math with 16 random bits (rand called twice) r7 is 16 bit math with only 5 random bits graph_rand.bas graph_rand.bas.bin 1 Quote Link to comment Share on other sites More sharing options...
RevEng Posted September 30, 2016 Share Posted September 30, 2016 Yeah, the extra bits of randomness are certainly required. Nice on the 16 bit solutions, though there's a half-way solution too. If you take your original r3 version and use 8 bits of random until the final divide, the values with lower probability only differ from the rest by ~10%. Worth it for just a few more more cycles. Quote Link to comment Share on other sites More sharing options...
bogax Posted October 1, 2016 Share Posted October 1, 2016 (edited) Yeah, the extra bits of randomness are certainly required. Nice on the 16 bit solutions, though there's a half-way solution too. If you take your original r3 version and use 8 bits of random until the final divide, the values with lower probability only differ from the rest by ~10%. Worth it for just a few more more cycles. and as you mentioned those extra 10% are well distributed (if those are the right terms ) if one in three consecutive numbers comes up 10% more often, it'll basically be that way for any range of three consecutive numbers you choose. having said that it's been a while since this topic was discussed but my recollection is that RTs method produces a sort of trapezoidal distribution, at either extreme the probabilities fall off but in the middle it's probably as good as or better than any other method so if you want a range of 20..150 maybe you don't care that 20..30 and 140..150 don't come up as often it's having to call rand so many times that I think is not so good the time it takes being one, but not the only, reason I jimmied it so there's room for 20 routines r8 uses mod it requires a variable but works well I think edit: for some reason the forum seems to eat the ends of my posts I added a version number to the name RT mentioned not being able to see the routine number in the score I wonder if that's a difference in bB or kernel versions or something rnd = (rand & 31) + rnd mod27 if rnd > 26 then rnd = rnd - 27 : goto mod27 temp1 = rnd return graph_rand0004.bas graph_rand0004.bas.bin Edited October 1, 2016 by bogax Quote Link to comment Share on other sites More sharing options...
RevEng Posted October 1, 2016 Share Posted October 1, 2016 r8 uses mod it requires a variable but works well I thinkClever that you added the previous rand to the current rand&31, to remove the seam that using mod usually produces. When looking for ranges less than 128, IMO this should be preferred to the "grab another rand" solution commonly used. (except if memory is tight) It's simple, has a better worst-case iteration count, and the probability distribution should be completely even for each value. RT mentioned not being able to see the routine number in the score I wonder if that's a difference in bB or kernel versions or something When I compile you .bas, the number of scanlines is huge. I think the reason is the playfieldpos variable is getting stepped on. Your basic code seems to treat the memory between var0 and the alphabet vars as continuous and all available, but bB puts playfieldpos smack between them, at $D5. Did you by chance reorder playfieldpos in your 2600basic.h, at some point? Quote Link to comment Share on other sites More sharing options...
bogax Posted October 1, 2016 Share Posted October 1, 2016 (edited) Clever that you added the previous rand to the current rand&31, to remove the seam that using mod usually produces. When looking for ranges less than 128, IMO this should be preferred to the "grab another rand" solution commonly used. (except if memory is tight) It's simple, has a better worst-case iteration count, and the probability distribution should be completely even for each value. When I compile you .bas, the number of scanlines is huge. I think the reason is the playfieldpos variable is getting stepped on. Your basic code seems to treat the memory between var0 and the alphabet vars as continuous and all available, but bB puts playfieldpos smack between them, at $D5. Did you by chance reorder playfieldpos in your 2600basic.h, at some point? yeah, somewhere up there I mentioned that I moved playfieldpos to aux1 ($F0) it appears that dimming it in bB (re)dims it and DASM doesn't complain so I've added it to the bB 0005 is otherwise the same as 0004 edit: DASM does complain (I forgot to save 2600basic.h) so 0005 is the same as 0004 (in needing a modified 2600basic.h) for numbers greater than 128 since rand - mod < 256 - mod and rnd < mod then rnd + 256 - mod < 256 and rnd + rand - mod < 256 ( I hope that makes sense) so you could do this temp1 = rand if temp1 >= mod then temp1 = temp1 - mod rnd = rnd + temp1 if rnd >= mod then rnd = rnd - mod temp1 = rnd return graph_rand0005.bas graph_rand0005.bas.bin Edited October 1, 2016 by bogax 1 Quote Link to comment Share on other sites More sharing options...
bogax Posted October 1, 2016 Share Posted October 1, 2016 (edited) bah I forgot to save 2600basic.h so DASM does complain I guess you have to go in to 2600basic.h and change playfieldpos to $F0 (or something else out of the way) Edited October 1, 2016 by bogax Quote Link to comment Share on other sites More sharing options...
bogax Posted October 1, 2016 Share Posted October 1, 2016 started a new thread so we can stop walking all over Captain Spazer's topic Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.