Desert

Game available in Itch.io.

Soruce code in Github.

Programming grid games in assembly for VIC-20.


Movement verbs

Desert uses two memory addresses to register the position of the player(the X and the Y), so each verb have to check the right address. Here you have the code.

  
;--- Movement -----------------------------

North_Cmd
        ; Y has reached de limit
        ldx player_y
        cpx #$f
        beq PR_No_Exit

        inx
        stx player_y

        jmp Reduce_Water_Life

South_Cmd
        ; Y has reached de limit
        ldx player_y
        ; Cero
        beq PR_No_Exit

        dex
        stx player_y

        jmp Reduce_Water_Life

East_Cmd
        ; X has reached de limit
        ldx player_x
        cpx #$f
        beq PR_No_Exit

        inx
        stx player_x

        jmp Reduce_Water_Life
        
West_Cmd
        ; Y has reached de limit
        ldx player_x
        ; Cero
        beq PR_No_Exit

        dex
        stx player_x

        jmp Reduce_Water_Life


PR_No_Exit
        lda #str_no_exit
        jsr PRTSTR
        rts
  

There is little more to say.

Answers to verbs

Executing the actions so verbs are similar to Pursuing Tom Ram. Here you have some examples.

CPlayer can only drink if she is in an oasis or she carries a filled flask. You have both checks in the code.

  
Drink_Cmd
        lda current_loc_type
        cmp #OASIS_LOC
        bne @Check_Flask

        ;jsr Print_Ok
        jmp @Drink

@Check_Flask
        ldy #F_FLASK
        jsr read_flag_y
        beq JMP_Print_You_Cannot

        ldy #F_FILL_FLASK
        jsr read_flag_y
        beq JMP_Print_You_Cannot


        ldy #F_FILL_FLASK
        jsr clear_flag_y
        ;jsr Print_Ok

@Drink
        jsr Set_Initial_Water
        JSR PrintWater
        rts

JMP_Print_You_Cannot
        jmp Print_You_Cannot

  

A similar command is Fill, because player can only fill a flask if she has one and she is in the oasis. Code is not here but you can get it in the repository.

Take command uses a chain. You saw the chains in the guide about Pursing Tom Ram.

  
;--- Take Command ---------------
Take_Cmd
        ; Take Idol
        lda current_loc_type
        cmp #IDOL_LOC
        bne @Take_Flask

        ldy #F_IDOL
        jsr read_flag_y
        bne Invalid_Take

        ldy #F_IDOL
        jsr set_flag_y
        jsr Print_Ok
        
       rts

@Take_Flask
        lda current_loc_type
        cmp #FLASK_LOC
        bne @Take_Compass

        ldy #F_FLASK
        jsr read_flag_y
        bne Invalid_Take

        ldy #F_FLASK
        jsr set_flag_y
        ;jsr Print_Ok
        lda #str_take_flask
        jsr PRTSTR

        
        rts

@Take_Compass
        lda current_loc_type
        cmp #COMPASS_LOC
        bne @Take_Ankh

        ldy #F_COMPASS
        jsr read_flag_y
        bne Invalid_Take

        ldy #F_COMPASS
        jsr set_flag_y
        ;jsr Print_Ok

        lda #str_take_compass
        jsr PRTSTR

       rts

@Take_Ankh
        lda current_loc_type
        ;sta mem_mon
        ;sta mem_mon+1
        cmp #ANKH_LOC
        bne Invalid_Take ; No more items

        ldy #F_ANKH
        jsr read_flag_y
        bne Invalid_Take

        ldy #F_ANKH
        jsr set_flag_y
        jsr Print_Ok

        rts

Invalid_Take
        jsr Print_You_Cannot
        rts
  

Finally, some code depends on the player carrying an object. One example is the flask. Another example is the compass and the command Guide.

  
;--- Guide command --------------
Guide_Cmd
        ; Check if you have compass
        ldy #F_COMPASS
        jsr read_flag_y
        beq Invalid_Take

        lda #str_compas_point
        jsr PRTSTR

        lda player_y
        ;sta mem_mon
        sec
        sbc #DESTINATION_Y
        ;sta mem_mon+1
        beq @Check_X
        bcc @Y_Minus
        ; X is bigger, go south
        lda #str_south
        jsr PRTSTR
        jmp @Check_X

@Y_Minus
        lda #str_north
        jsr PRTSTR


@Check_X
        lda player_x
        ;sta mem_mon
        sec
        sbc #DESTINATION_X
        ;sta mem_mon+1
        beq @End
        bcc @X_Minus
        ; Y is bigger, 
        lda #str_west
        jsr PRTSTR
        rts

@X_Minus
        lda #str_east
        jsr PRTSTR
@End
        rts
  

Guide command is long because the command has to check where the player is, where the city is and generate the right message. The key action is to subtract the position of the city and the player, once for x axis (so you can print easo or west), and another one for y axis (so you can print up or down).

For example, take a second look to this piece of code

  
	sec
        sbc #DESTINATION_Y
        ;sta mem_mon+1
        beq @Check_X

  

If the result of sbc (subtraction) is bigger to 0, the player is at the west of the city, so he have to move to the west. You may search the part of the code where the west is printed.

The Temple

The Temple is a special location. If the player finds the temple and have the Ankh (an Egyptian cross), he may enter using the command Enter. While player remains in the temple she can sleep, to recover life, drink or fill, like an oasis and exit the temple.

One more thing, if player is in the temple, the loc prints a message saying than player is in the temple (not lost in desert).

First task, how do I know if player is in the temple? When player enters the temple, I move the X coordinate to a value outside the map. With this value, I know when the player is in the temple.

  
;--- Enter_Cmd ----------------
Enter_Cmd
        ; Chaek you are in temple LOC
        lda current_loc_type
        cmp #TEMPLE_LOC
        bne Print_You_Cannot ; No more items

        ; Chack you have the Ankh
        ldy #F_ANKH
        jsr read_flag_y
        beq Print_You_Cannot

        ; Move to a special loc
        lda #$10
        sta player_x
        sta player_y

        ; Temple is like an Oasis
        lda #OASIS_LOC
        sta current_loc_type
        jsr Loc_Temple

        rts
  

If player is in temple, a specific location message is printed. See the code at PrintLOC subroutine.

  
PrintLOC
        ; check if player is in the temple
        lda player_x
        cmp #$10
        bne @Not_in_Temple

        jsr Loc_Temple
        jmp MainLoop
@Not_in_Temple
	; other code


Loc_Temple
        jsr CLRS
        jsr PrintStats

       lda #str_in_the_temple
       jsr PRTSTR

        rts
  

There is no Exit verb to exit the temple. Instead, the player has to move to go back to the desert location of the temple. I have to write a specific subroutine to move player when she is in the temple an goes to any cardinal point. This is the code.

  
;-------------
ExecuteCommand
        ;lda verb_index ; already loaded
        lda player_x
        
        ; check if player is in the temple
        cmp #$10
        bne @Jump_to_Cmd

        ; Player is in temple
        lda verb_index

        ; check if is a movement verb
        sec
        sbc #$4
        bcs @Jump_to_Cmd
        
        ; It is a movement verb
        ; I place the player in the temple loc
        lda #TEMPLE_X
        sta player_x
        lda #TEMPLE_Y
        sta player_y

        ; Repeat main loop
        jmp LocLoop