Jump to content
Mallard Games

Velocity Isn't Randomized

Recommended Posts

I am using this bit of code to decide if the velocity is going to be positive or negative when a new game is started.

GetRandomByte
	lda Random
	asl
	eor Random
	asl
	eor Random
	asl
	asl
	eor Random
	asl
	rol	Random								; performs a series of shifts and bit operations
	rts
	jsr GetRandomByte						; generate a random number
	lda #%10000000							; 1 in most significant bit mean greater then 127
	bit Random								; was it less then 127?
	bne RandomVX							; if it was then branch
	lda #$ff								; set the starting duck's x velocity to -1
	jmp RandomVXDone						; and jump cause we're done
RandomVX
	lda #$01								; set the starting duck's x velocity to 1
RandomVXDone
	sta DuckVX								; store duck's initial x velocity
	jsr GetRandomByte						; generate a random number
	lda #%10000000							; 1 in most significant bit mean greater then 127
	bit Random								; was it less then 127?
	bne RandomVY							; if it was then branch
	lda #$ff								; set the starting duck's x velocity to -1
	jmp RandomVYDone						; and jump cause we're done
RandomVY
	lda #$01								; set the starting duck's x velocity to 1
RandomVYDone
	sta DuckVY								; store duck's initial y velocity

However no matter what the velocity always stays the same.

 

Bin: https://www.dropbox.com/s/ikjnebg1moyn0k4/duckgame.bin?dl=1

 

Edited by Mallard Games

Share this post


Link to post
Share on other sites

I'm not an expert, but that GetRandomByte routine looks weird.
The only effect that it has on the "Random" address is to perform a "rotate left" instruction ("rol Random").
Looks like the pseudo-random value here is the accumulator, and you're overwriting it right after you call the subroutine (with "lda #%10000000").


Moreover,

bit Random


will set the N and V flags to match bit 7 and 6 of the value in the address tested ("Random" in this case) so you can use bmi/bpl and bvs/bvc to branch depending on the value of those two bits (the value in the accumulator doesn't matter)
So instead of

lda #%10000000    
bit Random        
bne RandomVX      

you can do

bit Random
bmi RandomVX        ;branch if negative (most significant bit = 1)

 

Share this post


Link to post
Share on other sites

Did you seed Random with a value?  If not, it looks like its going to be zero every time.  If you step through on the debugger, do you see new values on each frame?

Share this post


Link to post
Share on other sites

You're using a Fibonacci LFSR

 

Here's the Galois LFSR from Batari BASIC

 

randomize
   lda    rand
   lsr
   bcc    noeor
   eor    #$B4
noeor
   sta    rand
   rts

Edited by bogax

Share this post


Link to post
Share on other sites

Are you advancing the linear shift register on any random input?

 

A linear shift register will produce the same series of values over and over again (which is, why it can be used in the TIA for storing/latching positional values). Another way to understand it is by looking at it as a way of hashing a series of sequentially incremented input values to another value space. (The series produced by the LFSR until it returns to its first value on encountering its "stop code" may be shorter than the 256 values of a byte.*) So, while we get some scrambling out of this, it's still deterministic and not random.

 

We still need to introduce some source of random on our own, otherwise the LFSR will produce the same series of "random" numbers over and over again, starting from the initial reset value – and the gameplay will be always the same. However, we can't alter the sequence, but, what we may do, is skipping some values. E.g., we may run the LSFR for an extra step every frame a button is pressed or on any other input, by this using the user as a source of random. It may be preferable to do so even before the actual game is started, so that the game already starts in a "more random" state.

 

Edit:

*) This is also why having an overly complicated LFSR code isn't always preferable, as applying multiple shift and XOR operations may actually shorten the series (period) produced and we may end up with less random, as the series repeats after just 40 values or so. There's nothing wrong with keeping it simple, like in the Batari BASIC example above.

Edited by NoLand

Share this post


Link to post
Share on other sites

Yeah I can see a couple of things, when you use lda you're undoing the prior randomization stored in the accumulator . Also, the jsr's all loop to one another. Even if your randomization works the program flow could theoretically end up looping forever. It would be better to have a routine with a predictable execution time, like any of the examples already posted.

Edited by Sknarp
edited for clarity

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...