Help with one single large code reading.

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
Timaeus
Posts: 12
Joined: Wed Jul 13, 2022 1:06 pm

Help with one single large code reading.

Post by Timaeus »

Basically, I would like to know how to code a boss that have 3 moves and do them in a random order.

Everytime a RTS is reach, the game must have some condition to not read the first move again until another one is meet (or, for normal enemies, while they are on screen). I got the following logic down myself for a 2 moves boss/enemy:

LDA miscfunction
BEQ move1

move2
RTS

move1
LDA 1
STA miscfunction
RTS



miscfunction is a simple command that I will use to hold a value, since I do not know how to do it with the carry or stack, for example.

I tested this one and it worked nicely for a normal enemy (he will keep stuck in move 2 until he leaves the screen, but I can add properties to him to make sure that it will always happen)

Now, for a 3 moves boss with fixed moves order, it should be something like this (If it is not, please correct me):

LDA miscfunction
CMP 1
BEQ move2
CMP 2
BEQ move3

move1
Movement code
Condition for next move to happen
BEQ 01
RTS
INC miscfunction
RTS

move2
Movement code
Condition for next move to happen
BEQ 01
RTS
INC miscfunction
RTS

move3
(movement code)
Movement code
Condition for next move to happen
BEQ 01
RTS
LDA 0
STA miscfunction
RTS

this way, the order will be move1, then move2 and finally, move3

I want to know how to add a randomizer to make the order (1,2 and 3) be random (1,3,2) (2,3,1) etc.

If possible, I would like to know a way to make the boss be able to do the same move twice and one way where he cannot (example: after move1, it must go to move2 or move3).

Thanks.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Help with one single large code reading.

Post by tokumaru »

You can think of the different moves as different states, since each move is not instantaneous, it actually takes several frames to complete a move. On each object update, you must execute one step of the current move, until the move is complete, at which point you select a new state to switch to, according to whatever rules you want to set for this object. If you want the next move to be random, make a decision based on the output of your random number generator. Since each state gets to select what the next state is, you can easily leave out transitions you don't want to allow, or use other criteria to include or exclude certain transitions (e.g. cannot go from move 1 to move 2 if health is > 48).
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: Help with one single large code reading.

Post by Oziphantom »

to get a random number go to the random number section of https://codebase64.org/doku.php?id=base:6502_6510_maths and choose one that works for you, for this case I would go with https://codebase64.org/doku.php?id=base ... 8-bit_prng but you should only have one for your entire game so pick one that meets its needs.

then you do
- jsr randomNumber
and #3
cmp #3
beq -
this will get you 0,1,2 randomly

for the cases were you want to force it to be a new state add
cmp miscfunction
beq -
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Help with one single large code reading.

Post by tokumaru »

And if you want to control the probabilities of each option getting picked, you can alternatively split the 0-255 range of numbers into smaller ranges of different sizes (a larger range means a larger chance that the random number will fall in that range), and map each range to one of the possible results. Something like this:

Code: Select all

  ;gets a random 8-bit number
  jsr GetRandomNumber

  ;prepares the carry flag for the tests that will follow
  sec

  ;tests if between 0 and 127 (50% probability)
  sbc #$80 ;(128 out of 256)
  bcs :+
  lda #$00
  jmp UseResult
  :

  ;tests if between 128 and 191 (50% probability)
  sbc #$40 ;(64 out of 256)
  bcs :+
  lda #$01
  jmp UseResult
  :

  ;tests if between 192 and 255 (50% probability)
  sbc #$40 ;(64 out of 256)
  bcs :+
  lda #$02
  jmp UseResult
  :

UseResult:
NOTE: The last test is there just for clarity, but it's not really needed, since the random number is guaranteed to be in the last possible range if it's not in any of the previous ranges. This means you can skip the last test altogether and just LDA #$02 instead.
Post Reply