This tutorial will teach you how to add a new sprite for use indoors or in the overworld. ## Contents 1. [Determining which kind of sprite will be needed](#1-determining-which-kind-of-sprite-will-be-needed) 2. [Define a new constant](#2-define-a-new-constant) 3. [Design and include the GFX files](#3-design-and-include-the-gfx-files) 4. [Defining properties](#4-defining-properties) 5. [Define which maps will use each sprite](#5-define-which-maps-will-use-each-sprite) ## 1. Determining which kind of sprite will be needed Sprites can either face the player or be completely still. Depending on the purpose of the sprite you're adding, there is a small difference in how they're handled. Most of the sprites in the game are regular ones, which can face any direction. Still sprites, on the other hand, won't face it's direction even if the player interacts with it. Some examples of still sprites are the overworld Pokéballs and the asleep Gambler in Viridian City. For this tutorial, I'll add a regular sprite (Brock from GSC) and a still sprite (a 1-frame, edited GSC Equine icon as a sprite). ## 2. Define a new constant Edit [constants/sprite_constants.asm](../blob/master/constants/sprite_constants.asm). For regular sprites: ```diff ; overworld sprites ; SpriteSheetPointerTable indexes (see data/sprites/sprites.asm) const_def const SPRITE_NONE ; $00 const SPRITE_RED ; $01 ... const SPRITE_SEEL ; $3c + const SPRITE_BROCK ``` For still sprites: ```diff FIRST_STILL_SPRITE EQU const_value const SPRITE_POKE_BALL ; $3d const SPRITE_FOSSIL ; $3e ... const SPRITE_GAMBLER_ASLEEP ; $48 + const SPRITE_EQUINE ``` ## 3. Design and include the GFX files Regular sprites can either be 16x48 if they don't need to move, or 16x96 if they need to move. Still sprites are 16x16. ```diff SECTION "NPC Sprites 1", ROMX ScientistSprite:: INCBIN "gfx/sprites/scientist.2bpp" ... LoreleiSprite:: INCBIN "gfx/sprites/lorelei.2bpp" SeelSprite:: INCBIN "gfx/sprites/seel.2bpp" + +SECTION "NPC Sprites 3", ROMX + +BrockSprite:: INCBIN "gfx/sprites/brock.2bpp" +EquineSprite:: INCBIN "gfx/sprites/equine.2bpp" ``` ## 4. Defining properties Edit [data/sprites/sprites.asm](../blob/data/sprites/sprites.asm). Here you'll define how many tiles each graphics, defined in the prior session, will need. ```diff SpriteSheetPointerTable: table_width 4, SpriteSheetPointerTable ; graphics, tile count overworld_sprite RedSprite, 12 ; SPRITE_RED ... overworld_sprite SeelSprite, 12 ; SPRITE_SEEL + overworld_sprite BrockSprite, 12 ... overworld_sprite GamblerAsleepSprite, 4 ; SPRITE_GAMBLER_ASLEEP + overworld_sprite EquineSprite, 4 ``` ## 5. Define which maps will use each sprite Edit the corresponding file in [data/maps/objects](../blob/data/maps/objects). I changed `SPRITE_SUPER_NERD` to `SPRITE_BROCK` in [data/maps/objects/PewterGym.asm](../blob/data/maps/objects/PewterGym.asm) so Brock's sprite would show up. ```diff PewterGym_Object: db $3 ; border block def_warps ... def_objects - object SPRITE_SUPER_NERD, 4, 1, STAY, DOWN, 1, OPP_BROCK, 1 + object SPRITE_BROCK, 4, 1, STAY, DOWN, 1, OPP_BROCK, 1 object SPRITE_COOLTRAINER_M, 3, 6, STAY, RIGHT, 2, OPP_JR_TRAINER_M, 1 object SPRITE_GYM_GUIDE, 7, 10, STAY, DOWN, 3 ; person def_warps_to PEWTER_GYM ``` I decided to change the asleep Gambler sprite in [data/maps/objects/ViridianCity.asm](../blob/data/maps/objects/ViridianCity.asm) with the Equine sprite. ```diff ViridianCity_Object: db $f ; border block def_warps warp 23, 25, 0, VIRIDIAN_POKECENTER ... object SPRITE_GIRL, 17, 9, STAY, RIGHT, 4 ; person - object SPRITE_GAMBLER_ASLEEP, 18, 9, STAY, NONE, 5 ; person + object SPRITE_EQUINE, 18, 9, STAY, NONE, 5 ; person object SPRITE_FISHER, 6, 23, STAY, DOWN, 6 ; person object SPRITE_GAMBLER, 17, 5, WALK, LEFT_RIGHT, 7 ; person def_warps_to VIRIDIAN_CITY ``` Since it's used in the overworld, [data/maps/sprite_sets.asm](../blob/data/maps/sprite_sets.asm) needs to be edited as well. ```diff MapSpriteSets: table_width 1, MapSpriteSets db $01 ; PALLET_TOWN db $01 ; VIRIDIAN_CITY ... ; sprite set $01 table_width 1 db SPRITE_BLUE db SPRITE_YOUNGSTER db SPRITE_GIRL db SPRITE_FISHER db SPRITE_COOLTRAINER_M db SPRITE_GAMBLER db SPRITE_SEEL db SPRITE_OAK db SPRITE_SWIMMER db SPRITE_POKE_BALL - db SPRITE_GAMBLER_ASLEEP + db SPRITE_EQUINE assert_table_length SPRITE_SET_LENGTH ``` ![](https://i.imgur.com/SGWSter.png)