VM_REPLACE_TILE
is a GBVM instruction used to replace a contiguous block of background tile definitions in VRAM with new tile data from a specified tileset.
Purpose:
This instruction allows for dynamic and efficient updates to the graphical data of background tiles. Unlike VM_REPLACE_TILE_XY
which changes a tile at a specific map coordinate, VM_REPLACE_TILE
modifies the definition of the tiles themselves in VRAM. Any part of the background map that uses these modified tile IDs will then display the new graphics. This is essential for:
When VM_REPLACE_TILE
is called, it copies LEN
number of tiles from the source TILEDATA
(starting at START_IDX
) into VRAM, beginning at TARGET_TILE_IDX
. Any background map that references these TARGET_TILE_IDX
values will automatically update on screen.
Syntax:
VM_REPLACE_TILE TARGET_TILE_IDX, TILEDATA_BANK, TILEDATA, START_IDX, LEN
TARGET_TILE_IDX
: The starting tile ID in VRAM where the new tiles will be written. This is the index into the VRAM tile data where the first tile of the new block will be placed.TILEDATA_BANK
: The memory bank number where the source tile data (TILEDATA
) is located. This is crucial for accessing graphical data that might be in a different ROM bank.TILEDATA
: The address (label) of the tileset containing the new tiles. This points to the raw graphical data (pixels) for the tiles you want to load.START_IDX
: The starting tile index within the TILEDATA
array. This allows you to select a subset of tiles from the new tile data to copy.LEN
: The number of tiles to replace. This specifies how many tiles, starting from TARGET_TILE_IDX
in VRAM, will be overwritten with data from TILEDATA
.Usage Example: Animating a Water Tile
Imagine you have a water tile (e.g., tile ID 10) that you want to animate to show a gentle ripple effect. You have a small sequence of water animation frames (e.g., 3 frames) stored in a separate tileset.
; In your game loop or a dedicated animation script:
; Define the VRAM tile ID for the water animation (e.g., where the base water tile is)
WATER_TILE_VRAM_ID:
.R_INT8 10 ; Example: VRAM tile ID 10 is our base water tile
; Define the animation frames for water (these would be in your assets)
TILESET_WATER_ANIM_BANK:
.R_INT8 BANK(TILESET_WATER_ANIM)
TILESET_WATER_ANIM:
; Frame 0 of water animation
.BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
; Frame 1 of water animation
.BYTE 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
; Frame 2 of water animation
.BYTE 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02
; Variable to track current animation frame
VAR_WATER_ANIM_FRAME:
.R_INT8 0 ; Start at frame 0
; Variable for animation speed/timer
VAR_ANIM_TIMER:
.R_INT8 0
ANIMATE_WATER_LOOP:
; Increment animation timer
VM_RPN
.R_REF_MEM .R_INT8, VAR_ANIM_TIMER
.R_INT8 1
.R_OPERATOR +
.R_INT8
VM_STOP
VM_SET_INT8 VAR_ANIM_TIMER, 0
; Check if it's time to advance frame (e.g., every 15 frames)
VM_IF_CONST .LT, VAR_ANIM_TIMER, 15, END_ANIM_UPDATE, 0
; Reset timer
VM_SET_CONST VAR_ANIM_TIMER, 0
; Advance animation frame
VM_RPN
.R_REF_MEM .R_INT8, VAR_WATER_ANIM_FRAME
.R_INT8 1
.R_OPERATOR +
.R_INT8
VM_STOP
VM_SET_INT8 VAR_WATER_ANIM_FRAME, 0
; Loop animation frames (0, 1, 2, then back to 0)
VM_IF_CONST .EQ, VAR_WATER_ANIM_FRAME, 3, RESET_WATER_FRAME, 0
VM_JUMP CONTINUE_WATER_ANIM
RESET_WATER_FRAME:
VM_SET_CONST VAR_WATER_ANIM_FRAME, 0
CONTINUE_WATER_ANIM:
; Replace the VRAM tile at WATER_TILE_VRAM_ID with the current animation frame
VM_REPLACE_TILE WATER_TILE_VRAM_ID, TILESET_WATER_ANIM_BANK, TILESET_WATER_ANIM, VAR_WATER_ANIM_FRAME, 1
; TARGET_TILE_IDX: WATER_TILE_VRAM_ID (e.g., 10)
; TILEDATA_BANK: TILESET_WATER_ANIM_BANK
; TILEDATA: TILESET_WATER_ANIM
; START_IDX: VAR_WATER_ANIM_FRAME (0, 1, or 2)
; LEN: 1 (replacing one tile at a time)
END_ANIM_UPDATE:
VM_IDLE 1 ; Yield control for one frame
VM_JUMP ANIMATE_WATER_LOOP
In this example, VM_REPLACE_TILE
is used within a loop to continuously update the VRAM definition of WATER_TILE_VRAM_ID
with different frames from TILESET_WATER_ANIM
. This creates a smooth, looping animation for all water tiles on the background map that use WATER_TILE_VRAM_ID
. The VAR_ANIM_TIMER
controls the speed of the animation.
Analogy to other programming languages/game engines: This is analogous to dynamically updating a texture atlas or sprite sheet in graphics memory, or changing the definition of a tile in a tilemap system at runtime:
sprite
property of a Tile
asset, which then affects all instances of that tile on the map.texture
or region
of a TileSet
resource, which then updates all cells using that tile.It provides a powerful way to create dynamic and animated backgrounds by directly manipulating the underlying tile graphics in VRAM.